| summaryrefslogtreecommitdiff |
diff options
13 files changed, 527 insertions, 19 deletions
diff --git a/data/unit-testing/access.fate b/data/unit-testing/access.fate index c829454..7c1976f 100644 --- a/data/unit-testing/access.fate +++ b/data/unit-testing/access.fate @@ -8,13 +8,16 @@ (global int i) -(for (set i 0) (< i 10) (set i (+ i 1)) +(for (set i 0) (=< i 10) (set i (+ i 1)) (assert (= (access li i) (var i)) [FAILED] ACCESS assert failed on (var i) for li. ) (assert (= (access li_ptr i) (var i)) [FAILED] ACCESS assert failed on (var i) with for li_ptr. ) + (assert (= (access (range 0 10 1) i) (var i)) + [FAILED] ACCESS assert failed on (var i) with for range. + ) ) [COMPLETED] ACCESS diff --git a/data/unit-testing/access_constant_index.fate b/data/unit-testing/access_constant_index.fate new file mode 100644 index 0000000..7399289 --- /dev/null +++ b/data/unit-testing/access_constant_index.fate @@ -0,0 +1,58 @@ +(fate_version 1) + +(global string test_name) + +(set test_name ( ACCESS CONSTANT INDEX )) + +(global (list int) li) +(global (ptr (list int)) li_ptr) + +(set li (range 0 10 1)) +(set li_ptr (ptr li)) + +(assert (= (var li.0) 0) [FAILED] (var test_name) li.0) +(assert (= (var li.1) 1) [FAILED] (var test_name) li.1) +(assert (= (var li.2) 2) [FAILED] (var test_name) li.2) +(assert (= (var li.3) 3) [FAILED] (var test_name) li.3) +(assert (= (var li.4) 4) [FAILED] (var test_name) li.4) +(assert (= (var li.5) 5) [FAILED] (var test_name) li.5) +(assert (= (var li.6) 6) [FAILED] (var test_name) li.6) +(assert (= (var li.7) 7) [FAILED] (var test_name) li.7) +(assert (= (var li.8) 8) [FAILED] (var test_name) li.8) +(assert (= (var li.9) 9) [FAILED] (var test_name) li.9) +(assert (= (var li.10) 10) [FAILED] (var test_name) li.10) + +(assert (= (var li_ptr.0) 0) [FAILED] (var test_name) li_ptr.0) +(assert (= (var li_ptr.1) 1) [FAILED] (var test_name) li_ptr.1) +(assert (= (var li_ptr.2) 2) [FAILED] (var test_name) li_ptr.2) +(assert (= (var li_ptr.3) 3) [FAILED] (var test_name) li_ptr.3) +(assert (= (var li_ptr.4) 4) [FAILED] (var test_name) li_ptr.4) +(assert (= (var li_ptr.5) 5) [FAILED] (var test_name) li_ptr.5) +(assert (= (var li_ptr.6) 6) [FAILED] (var test_name) li_ptr.6) +(assert (= (var li_ptr.7) 7) [FAILED] (var test_name) li_ptr.7) +(assert (= (var li_ptr.8) 8) [FAILED] (var test_name) li_ptr.8) +(assert (= (var li_ptr.9) 9) [FAILED] (var test_name) li_ptr.9) +(assert (= (var li_ptr.10) 10) [FAILED] (var test_name) li_ptr.10) + +(global (list (list int)) lili) +(global int i) + +(for (set i 0) (=< i 10) (set i (+ i 1)) + (add! (range 0 i 1) lili) +) + +(assert (= (var lili.10.0) 0) [FAILED] (var test_name) lili.10.0 was (var lili.10.0).) +(assert (= (var lili.9.1) 1) [FAILED] (var test_name) lili.9.1 was (var lili.9.1).) +(assert (= (var lili.8.2) 2) [FAILED] (var test_name) lili.8.2 was (var lili.8.2).) +(assert (= (var lili.7.3) 3) [FAILED] (var test_name) lili.7.3 was (var lili.7.3).) +(assert (= (var lili.6.4) 4) [FAILED] (var test_name) lili.6.4 was (var lili.6.4).) +(assert (= (var lili.5.5) 5) [FAILED] (var test_name) lili.5.5 was (var lili.5.5).) +(assert (= (var lili.4.3) 3) [FAILED] (var test_name) lili.4.3 was (var lili.4.3).) +(assert (= (var lili.3.2) 2) [FAILED] (var test_name) lili.3.2 was (var lili.3.2).) +(assert (= (var lili.2.1) 1) [FAILED] (var test_name) lili.2.1 was (var lili.2.1).) +(assert (= (var lili.1.0) 0) [FAILED] (var test_name) lili.1.0 was (var lili.1.0).) +(assert (= (var lili.0.0) 0) [FAILED] (var test_name) lili.0.0 was (var lili.0.0).) + +[COMPLETED] (var test_name) + +(end) diff --git a/data/unit-testing/access_pointer.fate b/data/unit-testing/access_pointer.fate new file mode 100644 index 0000000..39af580 --- /dev/null +++ b/data/unit-testing/access_pointer.fate @@ -0,0 +1,22 @@ +(fate_version 1) + +(global (list int) li) +(global (ptr (list int)) li_ptr) + +(set li (range 0 10 1)) +(set li_ptr (ptr li)) + +(global int i) + +(for (set i 0) (=< i 10) (set i (+ i 1)) + (assert (= (at (access_ptr li i)) (var i)) + [FAILED] ACCESS POINTER assert failed on (var i) for li. + ) + (assert (= (at (access_ptr li_ptr i)) (var i)) + [FAILED] ACCESS POINTER assert failed on (var i) with for li_ptr. + ) +) + +[COMPLETED] ACCESS POINTER + +(end) diff --git a/src/core/src/tonkadur/fate/v1/lang/computation/Access.java b/src/core/src/tonkadur/fate/v1/lang/computation/Access.java index 1b1f2b3..f914b1c 100644 --- a/src/core/src/tonkadur/fate/v1/lang/computation/Access.java +++ b/src/core/src/tonkadur/fate/v1/lang/computation/Access.java @@ -8,7 +8,6 @@ import tonkadur.parser.Origin; import tonkadur.error.ErrorManager; import tonkadur.fate.v1.error.InvalidTypeException; -import tonkadur.fate.v1.error.UnknownDictionaryFieldException; import tonkadur.fate.v1.lang.meta.ComputationVisitor; import tonkadur.fate.v1.lang.meta.Computation; @@ -53,15 +52,13 @@ public class Access extends Computation Computation parent, final Computation index ) - throws - InvalidTypeException, - UnknownDictionaryFieldException + throws InvalidTypeException { Type current_type; current_type = parent.get_type(); - if (current_type.get_act_as_type().equals(Type.REF)) + while (current_type.get_act_as_type().equals(Type.REF)) { parent = AtReference.build(origin, parent); current_type = parent.get_type(); diff --git a/src/core/src/tonkadur/fate/v1/lang/computation/AccessAsReference.java b/src/core/src/tonkadur/fate/v1/lang/computation/AccessAsReference.java new file mode 100644 index 0000000..1fe94a0 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/computation/AccessAsReference.java @@ -0,0 +1,152 @@ +package tonkadur.fate.v1.lang.computation; + +import java.util.Collections; +import java.util.List; + +import tonkadur.parser.Origin; + +import tonkadur.error.ErrorManager; + +import tonkadur.fate.v1.error.InvalidTypeException; + +import tonkadur.fate.v1.lang.meta.ComputationVisitor; +import tonkadur.fate.v1.lang.meta.Computation; +import tonkadur.fate.v1.lang.meta.Reference; + +import tonkadur.fate.v1.lang.type.CollectionType; +import tonkadur.fate.v1.lang.type.Type; +import tonkadur.fate.v1.lang.type.PointerType; + +public class AccessAsReference extends Reference +{ + /***************************************************************************/ + /**** MEMBERS **************************************************************/ + /***************************************************************************/ + protected final Reference parent; + protected final Computation index; + + /***************************************************************************/ + /**** PROTECTED ************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + protected AccessAsReference + ( + final Origin origin, + final Reference parent, + final Type type, + final Computation index + ) + { + super + ( + origin, + type, + (parent.get_name() + "." + index.toString()) + ); + + this.parent = parent; + this.index = index; + } + + /***************************************************************************/ + /**** PUBLIC ***************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + public static AccessAsReference build + ( + final Origin origin, + Reference parent, + final Computation index + ) + throws InvalidTypeException + { + Type current_type; + + current_type = parent.get_type(); + + while (current_type.get_act_as_type().equals(Type.REF)) + { + parent = AtReference.build(origin, parent); + current_type = parent.get_type(); + } + + if (!index.get_type().can_be_used_as(Type.INT)) + { + ErrorManager.handle + ( + new InvalidTypeException + ( + index.get_origin(), + current_type, + Collections.singleton(Type.INT), + parent.get_name() + ) + ); + } + + if (!(current_type instanceof CollectionType)) + { + ErrorManager.handle + ( + new InvalidTypeException + ( + origin, + current_type, + Collections.singleton(Type.LIST), + parent.get_name() + ) + ); + + current_type = Type.ANY; + } + else + { + current_type = ((CollectionType) current_type).get_content_type(); + } + + return + new AccessAsReference + ( + origin, + parent, + current_type, + index + ); + } + + + /**** AccessAsReferenceors ************************************************************/ + @Override + public void get_visited_by (final ComputationVisitor cv) + throws Throwable + { + cv.visit_access_as_reference(this); + } + + public Computation get_index () + { + return index; + } + + public Reference get_parent () + { + return parent; + } + + /**** Misc. ****************************************************************/ + @Override + public String toString () + { + final StringBuilder sb = new StringBuilder(); + + sb.append("(AccessAsReference ("); + sb.append(type.get_name()); + sb.append(") "); + sb.append(name); + sb.append("."); + sb.append(index.toString()); + sb.append(")"); + + return sb.toString(); + } +} diff --git a/src/core/src/tonkadur/fate/v1/lang/computation/AccessPointer.java b/src/core/src/tonkadur/fate/v1/lang/computation/AccessPointer.java new file mode 100644 index 0000000..22eabd6 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/computation/AccessPointer.java @@ -0,0 +1,144 @@ +package tonkadur.fate.v1.lang.computation; + +import java.util.Collections; +import java.util.List; + +import tonkadur.parser.Origin; + +import tonkadur.error.ErrorManager; + +import tonkadur.fate.v1.error.InvalidTypeException; + +import tonkadur.fate.v1.lang.meta.ComputationVisitor; +import tonkadur.fate.v1.lang.meta.Computation; +import tonkadur.fate.v1.lang.meta.Reference; + +import tonkadur.fate.v1.lang.type.CollectionType; +import tonkadur.fate.v1.lang.type.PointerType; +import tonkadur.fate.v1.lang.type.Type; + +public class AccessPointer extends Computation +{ + /***************************************************************************/ + /**** MEMBERS **************************************************************/ + /***************************************************************************/ + protected final Reference parent; + protected final Computation index; + + /***************************************************************************/ + /**** PROTECTED ************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + protected AccessPointer + ( + final Origin origin, + final Reference parent, + final Type type, + final Computation index + ) + { + super + ( + origin, + new PointerType(origin, type, "(ptr " + type.toString() + ") autogen") + ); + + this.parent = parent; + this.index = index; + } + + /***************************************************************************/ + /**** PUBLIC ***************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + public static AccessPointer build + ( + final Origin origin, + Reference parent, + final Computation index + ) + throws InvalidTypeException + { + Type current_type; + + current_type = parent.get_type(); + + while (current_type.get_act_as_type().equals(Type.REF)) + { + parent = AtReference.build(origin, parent); + current_type = parent.get_type(); + } + + if (!index.get_type().can_be_used_as(Type.INT)) + { + ErrorManager.handle + ( + new InvalidTypeException + ( + index.get_origin(), + current_type, + Collections.singleton(Type.INT), + index.toString() + ) + ); + } + + if (!(current_type instanceof CollectionType)) + { + ErrorManager.handle + ( + new InvalidTypeException + ( + origin, + current_type, + Collections.singleton(Type.LIST), + parent.toString() + ) + ); + + current_type = Type.ANY; + } + else + { + current_type = ((CollectionType) current_type).get_content_type(); + } + + return new AccessPointer(origin, parent, current_type, index); + } + + + /**** Accessors ************************************************************/ + @Override + public void get_visited_by (final ComputationVisitor cv) + throws Throwable + { + cv.visit_access_pointer(this); + } + + public Computation get_index () + { + return index; + } + + public Reference get_parent () + { + return parent; + } + + /**** Misc. ****************************************************************/ + @Override + public String toString () + { + final StringBuilder sb = new StringBuilder(); + + sb.append("(AccessPointer ("); + sb.append(type.get_name()); + sb.append(") "); + sb.append(parent.get_name()); + sb.append("."); + sb.append(index.toString()); + sb.append(")"); + + return sb.toString(); + } +} diff --git a/src/core/src/tonkadur/fate/v1/lang/computation/Cast.java b/src/core/src/tonkadur/fate/v1/lang/computation/Cast.java index 08fdfce..3906499 100644 --- a/src/core/src/tonkadur/fate/v1/lang/computation/Cast.java +++ b/src/core/src/tonkadur/fate/v1/lang/computation/Cast.java @@ -20,7 +20,7 @@ import tonkadur.fate.v1.lang.meta.Computation; public class Cast extends Computation { - protected static final Map<Type,Set<Type>> allowed_type_changes; + protected static final Map<Type, Set<Type>> allowed_type_changes; static { diff --git a/src/core/src/tonkadur/fate/v1/lang/computation/FieldReference.java b/src/core/src/tonkadur/fate/v1/lang/computation/FieldReference.java index b98141f..942077c 100644 --- a/src/core/src/tonkadur/fate/v1/lang/computation/FieldReference.java +++ b/src/core/src/tonkadur/fate/v1/lang/computation/FieldReference.java @@ -61,7 +61,7 @@ public class FieldReference extends Reference current_type = parent.get_type(); - if (current_type.get_act_as_type().equals(Type.REF)) + while (current_type.get_act_as_type().equals(Type.REF)) { parent = AtReference.build(origin, (Reference) parent); current_type = parent.get_type(); diff --git a/src/core/src/tonkadur/fate/v1/lang/meta/ComputationVisitor.java b/src/core/src/tonkadur/fate/v1/lang/meta/ComputationVisitor.java index cd164c9..23fb1c8 100644 --- a/src/core/src/tonkadur/fate/v1/lang/meta/ComputationVisitor.java +++ b/src/core/src/tonkadur/fate/v1/lang/meta/ComputationVisitor.java @@ -10,6 +10,12 @@ public interface ComputationVisitor public void visit_access (final Access n) throws Throwable; + public void visit_access_pointer (final AccessPointer n) + throws Throwable; + + public void visit_access_as_reference (final AccessAsReference n) + throws Throwable; + public void visit_new (final New n) throws Throwable; diff --git a/src/core/src/tonkadur/fate/v1/lang/meta/VariableFromWord.java b/src/core/src/tonkadur/fate/v1/lang/meta/VariableFromWord.java index 554ae86..522ad9b 100644 --- a/src/core/src/tonkadur/fate/v1/lang/meta/VariableFromWord.java +++ b/src/core/src/tonkadur/fate/v1/lang/meta/VariableFromWord.java @@ -2,6 +2,7 @@ package tonkadur.fate.v1.lang.meta; import java.util.Map; import java.util.Deque; +import java.util.Collections; import java.util.Arrays; import java.util.List; import java.util.ArrayList; @@ -9,12 +10,19 @@ import java.util.ArrayList; import tonkadur.parser.Origin; import tonkadur.parser.ParsingError; -import tonkadur.fate.v1.lang.computation.VariableReference; -import tonkadur.fate.v1.lang.computation.FieldReference; - import tonkadur.fate.v1.lang.Variable; import tonkadur.fate.v1.lang.World; +import tonkadur.fate.v1.lang.computation.AccessAsReference; +import tonkadur.fate.v1.lang.computation.Constant; +import tonkadur.fate.v1.lang.computation.FieldReference; +import tonkadur.fate.v1.lang.computation.VariableReference; + +import tonkadur.fate.v1.lang.type.CollectionType; +import tonkadur.fate.v1.lang.type.PointerType; +import tonkadur.fate.v1.lang.type.DictType; +import tonkadur.fate.v1.lang.type.Type; + public class VariableFromWord { /* Utility Class */ @@ -44,21 +52,53 @@ public class VariableFromWord result = new VariableReference(origin, target_var); + /* TODO don't rely on the other classes to generate the subrefs. */ if (subrefs.length > 1) { + Type t; final List<String> subrefs_list; subrefs_list = new ArrayList(Arrays.asList(subrefs)); subrefs_list.remove(0); - result = - FieldReference.build - ( - origin, - result, - subrefs_list - ); + for (final String subref: subrefs_list) + { + t = result.get_type(); + + while (t instanceof PointerType) + { + t = ((PointerType) t).get_referenced_type(); + } + + if (t instanceof CollectionType) + { + result = + AccessAsReference.build + ( + origin, + result, + Constant.build(origin, subref) + ); + } + else if (t instanceof DictType) + { + result = + FieldReference.build + ( + origin, + result, + Collections.singletonList(subref) + ); + } + else + { + /* TODO: error */ + System.err.println("Unimplemented error in VariableFromWord."); + + System.exit(-1); + } + } } return result; diff --git a/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 b/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 index 29048d2..077371f 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 @@ -16,6 +16,7 @@ R_PAREN: ')'; ABS_KW: L_PAREN 'abs'('olute'?) SEP+; ACCESS_KW: L_PAREN 'access' SEP+; +ACCESS_POINTER_KW: L_PAREN 'access'US('ptr'|'pointer') SEP+; ADD_KW: L_PAREN 'add'(US'element')? SEP+; IMP_ADD_KW: L_PAREN 'add'(US'element')?'!' SEP+; ADD_AT_KW: L_PAREN 'add'(US'element')?US'at' SEP+; diff --git a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 index 073b521..7dd5081 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 @@ -3667,7 +3667,7 @@ returns [Computation result] ); } - | ACCESS_KW value_reference WS+ non_text_value R_PAREN + | ACCESS_KW collection=non_text_value WS+ index=non_text_value R_PAREN { $result = Access.build @@ -3677,6 +3677,21 @@ returns [Computation result] ($ACCESS_KW.getLine()), ($ACCESS_KW.getCharPositionInLine()) ), + ($collection.result), + ($index.result) + ); + } + + | ACCESS_POINTER_KW value_reference WS+ non_text_value R_PAREN + { + $result = + AccessPointer.build + ( + CONTEXT.get_origin_at + ( + ($ACCESS_POINTER_KW.getLine()), + ($ACCESS_POINTER_KW.getCharPositionInLine()) + ), ($value_reference.result), ($non_text_value.result) ); diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/ComputationCompiler.java b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/ComputationCompiler.java index 2fab9bf..0b316e1 100644 --- a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/ComputationCompiler.java +++ b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/ComputationCompiler.java @@ -1348,6 +1348,74 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor @Override + public void visit_access_pointer + ( + final tonkadur.fate.v1.lang.computation.AccessPointer n + ) + throws Throwable + { + final ComputationCompiler extra_address_cc, base_address_cc; + + base_address_cc = new ComputationCompiler(compiler); + extra_address_cc = new ComputationCompiler(compiler); + + n.get_parent().get_visited_by(base_address_cc); + n.get_index().get_visited_by(extra_address_cc); + + assimilate(base_address_cc); + assimilate(extra_address_cc); + + result_as_computation = + new RelativeAddress + ( + base_address_cc.get_address(), + new Cast(extra_address_cc.get_computation(), Type.STRING), + TypeCompiler.compile + ( + compiler, + ( + (tonkadur.fate.v1.lang.type.CollectionType) + n.get_parent().get_type() + ).get_content_type() + ) + ); + } + + @Override + public void visit_access_as_reference + ( + final tonkadur.fate.v1.lang.computation.AccessAsReference n + ) + throws Throwable + { + final ComputationCompiler extra_address_cc, base_address_cc; + + base_address_cc = new ComputationCompiler(compiler); + extra_address_cc = new ComputationCompiler(compiler); + + n.get_parent().get_visited_by(base_address_cc); + n.get_index().get_visited_by(extra_address_cc); + + assimilate(base_address_cc); + assimilate(extra_address_cc); + + result_as_address = + new RelativeAddress + ( + base_address_cc.get_address(), + new Cast(extra_address_cc.get_computation(), Type.STRING), + TypeCompiler.compile + ( + compiler, + ( + (tonkadur.fate.v1.lang.type.CollectionType) + n.get_parent().get_type() + ).get_content_type() + ) + ); + } + + @Override public void visit_access ( final tonkadur.fate.v1.lang.computation.Access n @@ -1362,6 +1430,8 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor n.get_parent().get_visited_by(base_address_cc); n.get_index().get_visited_by(extra_address_cc); + base_address_cc.generate_address(); + assimilate(base_address_cc); assimilate(extra_address_cc); |


