summaryrefslogtreecommitdiff |
diff options
-rw-r--r-- | src/hastabel/PropertyParser.g4 | 77 | ||||
-rw-r--r-- | src/hastabel/lang/Expression.java | 11 | ||||
-rw-r--r-- | src/hastabel/lang/FunctionCall.java | 2 | ||||
-rw-r--r-- | src/hastabel/lang/NamedExpression.java | 8 | ||||
-rw-r--r-- | src/hastabel/lang/Predicate.java | 137 |
5 files changed, 222 insertions, 13 deletions
diff --git a/src/hastabel/PropertyParser.g4 b/src/hastabel/PropertyParser.g4 index 993467d..0042c56 100644 --- a/src/hastabel/PropertyParser.g4 +++ b/src/hastabel/PropertyParser.g4 @@ -90,6 +90,55 @@ id_or_string_or_fun [Variable current_node] { if (($ID.text).equals("_")) { + System.err.println + ( + "[E] The use of an joker is not allowed here (l." + + ($ID.getLine()) + + " c." + + ($ID.getCharPositionInLine()) + + ")." + ); + + WORLD.invalidate(); + } + else + { + $value = WORLD.get_variables_manager().get(($ID.text)); + + if (($value) == null) + { + WORLD.invalidate(); + } + } + } + + | + STRING + { + $value = + WORLD.get_strings_manager().get_string_as_element(($STRING.text)); + + if (($value) == null) + { + WORLD.invalidate(); + } + } + + | + function[current_node] + { + $value = ($function.result); + } +; + +id_or_string_or_fun_or_joker [Variable current_node] + returns [Expression value] + + : + ID + { + if (($ID.text).equals("_")) + { $value = null; } else @@ -144,12 +193,34 @@ id_list [Variable current_node] } ; +id_or_joker_list [Variable current_node] + returns [List<Expression> list] + + @init + { + final List<Expression> result = new ArrayList<Expression>(); + } + + : + ( + (WS)+ + id_or_string_or_fun_or_joker[current_node] + { + result.add(($id_or_string_or_fun_or_joker.value)); + } + )* + + { + $list = result; + } +; + predicate [Variable current_node] returns [Formula result]: (WS)* L_PAREN ID - id_list[current_node] + id_or_joker_list[current_node] (WS)* R_PAREN { @@ -175,7 +246,7 @@ predicate [Variable current_node] WORLD.invalidate(); } - ids = ($id_list.list); + ids = ($id_or_joker_list.list); if (current_node != null) { @@ -184,7 +255,7 @@ predicate [Variable current_node] predicate.mark_as_used(); - $result = predicate.as_formula(ids); + $result = predicate.as_partial_formula(ids); } ; diff --git a/src/hastabel/lang/Expression.java b/src/hastabel/lang/Expression.java index 9594864..a8bd3a6 100644 --- a/src/hastabel/lang/Expression.java +++ b/src/hastabel/lang/Expression.java @@ -2,4 +2,15 @@ package hastabel.lang; public abstract class Expression { + protected final Type type; + + public Expression (final Type type) + { + this.type = type; + } + + public Type get_type() + { + return type; + } } diff --git a/src/hastabel/lang/FunctionCall.java b/src/hastabel/lang/FunctionCall.java index 464ed57..c71738e 100644 --- a/src/hastabel/lang/FunctionCall.java +++ b/src/hastabel/lang/FunctionCall.java @@ -13,7 +13,7 @@ class FunctionCall extends Expression final List<Expression> params ) { - super(); + super(parent.get_function_type()); this.parent = parent; this.params = params; } diff --git a/src/hastabel/lang/NamedExpression.java b/src/hastabel/lang/NamedExpression.java index fec810f..727b3e4 100644 --- a/src/hastabel/lang/NamedExpression.java +++ b/src/hastabel/lang/NamedExpression.java @@ -2,12 +2,11 @@ package hastabel.lang; abstract class NamedExpression extends Expression { - public final Type type; public final String name; public NamedExpression (final Type type, final String name) { - this.type = type; + super(type); this.name = name; } @@ -16,11 +15,6 @@ abstract class NamedExpression extends Expression return name; } - public Type get_type () - { - return type; - } - @Override public boolean equals (Object o) { diff --git a/src/hastabel/lang/Predicate.java b/src/hastabel/lang/Predicate.java index 47b9ed8..28674d7 100644 --- a/src/hastabel/lang/Predicate.java +++ b/src/hastabel/lang/Predicate.java @@ -12,15 +12,20 @@ import java.util.ArrayList; public class Predicate { private final Collection<List<Type>> signatures; + private final Collection<List<Type>> partial_signatures; + private final Type function_type; private final Set<List<Element>> members; private final String name; private boolean is_used; public Predicate (final List<Type> signature, final String name) { + partial_signatures = new ArrayList<List<Type>>(0); signatures = new ArrayList<List<Type>>(1); signatures.add(signature); + this.function_type = signature.get(signature.size() - 1); + this.name = name; members = new HashSet<List<Element>>(); @@ -28,12 +33,22 @@ public class Predicate is_used = false; } - public Predicate (final Collection<List<Type>> signatures, final String name) + public Predicate + ( + final Collection<List<Type>> signatures, + final Collection<List<Type>> partial_signatures, + final Type function_type, + final String name + ) { this.signatures = new ArrayList<List<Type>>(); this.signatures.addAll(signatures); + this.partial_signatures = new ArrayList<List<Type>>(0); + this.partial_signatures.addAll(partial_signatures); + this.name = name; + this.function_type = function_type; members = new HashSet<List<Element>>(); } @@ -46,6 +61,11 @@ public class Predicate } } + public Type get_function_type () + { + return function_type; + } + public void add_member_ (final Element... elements) { final ArrayList<Element> params; @@ -63,6 +83,81 @@ public class Predicate } } + private boolean add_and_activate_partial_signature + ( + final List<Type> partial_signature + ) + { + boolean can_be_added; + + can_be_added = false; + + for (final List<Type> signature: signatures) + { + if (is_compatible_with_partial_signature(signature, partial_signature)) + { + activate_signature(signature); + + can_be_added = true; + } + } + + if (can_be_added) + { + partial_signatures.add(partial_signature); + } + + return can_be_added; + } + + private void activate_signature + ( + final List<Type> signature + ) + { + for (final Type type: signature) + { + type.mark_as_used(); + } + } + + private boolean is_compatible_with_partial_signature + ( + final List<Type> signature, + final List<Type> partial_signature + ) + { + final Iterator<Type> e_iter; + final Iterator<Type> s_iter; + + if (partial_signature.size() != signature.size()) + { + return false; + } + + e_iter = partial_signature.iterator(); + s_iter = signature.iterator(); + + while (e_iter.hasNext()) + { + final Type e_next, s_next; + + e_next = e_iter.next(); + s_next = s_iter.next(); + + if (e_next == null) + { + continue; + } + else if (!s_next.includes(e_next)) + { + return false; + } + } + + return true; + } + private boolean is_compatible_with_signature ( final List<Element> elements, @@ -187,7 +282,7 @@ public class Predicate public Predicate shallow_copy () { - return new Predicate(signatures, name); + return new Predicate(signatures, partial_signatures, function_type, name); } @Override @@ -242,6 +337,44 @@ public class Predicate return sb.toString(); } + public Formula as_partial_formula (final List<Expression> params) + { + final List<Type> partial_signature; + boolean is_partial; + + is_partial = false; + + partial_signature = new ArrayList<Type>(); + + for (final Expression param: params) + { + if (param == null) + { + partial_signature.add(null); + + is_partial = true; + } + else + { + partial_signature.add(param.get_type()); + } + } + + if (is_partial) + { + if (!add_and_activate_partial_signature(partial_signature)) + { + System.err.println + ( + "[E][FIXME] Can't report that no signature was found that could" + + " support partial signature." + ); + } + } + + return as_formula(params); + } + public void mark_as_used () { is_used = true; |