From c4b0897e196dfdb685ee6c7aa542e7a0084db953 Mon Sep 17 00:00:00 2001 From: nsensfel Date: Mon, 7 Sep 2020 18:42:44 +0200 Subject: ... --- data/tests/local_variables.fate | 4 + data/tests/local_variables2.fate | 4 + src/core/src/tonkadur/fate/v1/Utils.java | 19 +- .../tonkadur/fate/v1/lang/computation/Fold.java | 209 +++++++++++++++++++++ .../tonkadur/fate/v1/lang/instruction/Range.java | 168 +++++++++++++++++ .../tonkadur/fate/v1/lang/instruction/Shuffle.java | 101 ++++++++++ src/core/src/tonkadur/fate/v1/parser/FateParser.g4 | 112 ++++++----- 7 files changed, 571 insertions(+), 46 deletions(-) create mode 100644 data/tests/local_variables2.fate create mode 100644 src/core/src/tonkadur/fate/v1/lang/computation/Fold.java create mode 100644 src/core/src/tonkadur/fate/v1/lang/instruction/Range.java create mode 100644 src/core/src/tonkadur/fate/v1/lang/instruction/Shuffle.java diff --git a/data/tests/local_variables.fate b/data/tests/local_variables.fate index 45cc67b..33d8329 100644 --- a/data/tests/local_variables.fate +++ b/data/tests/local_variables.fate @@ -1,5 +1,8 @@ (fate_version 1) +(require local_variables2.fate) + +(assert (= (var other_file_var) 1) FAILED: local from other file) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -107,4 +110,5 @@ ) FAILED: local M ) + (end) diff --git a/data/tests/local_variables2.fate b/data/tests/local_variables2.fate new file mode 100644 index 0000000..989d3f4 --- /dev/null +++ b/data/tests/local_variables2.fate @@ -0,0 +1,4 @@ +(fate_version 1) + +(local int other_file_var) +(set other_file_var 1) diff --git a/src/core/src/tonkadur/fate/v1/Utils.java b/src/core/src/tonkadur/fate/v1/Utils.java index 7cac057..9c7466d 100644 --- a/src/core/src/tonkadur/fate/v1/Utils.java +++ b/src/core/src/tonkadur/fate/v1/Utils.java @@ -2,6 +2,9 @@ package tonkadur.fate.v1; import java.io.IOException; +import java.util.Deque; +import java.util.Map; + import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; @@ -10,6 +13,7 @@ import tonkadur.parser.Context; import tonkadur.fate.v1.parser.FateLexer; import tonkadur.fate.v1.parser.FateParser; +import tonkadur.fate.v1.lang.Variable; import tonkadur.fate.v1.lang.World; public class Utils @@ -24,6 +28,18 @@ public class Utils final World world ) throws IOException + { + add_file_content(filename, context, null, world); + } + + public static void add_file_content + ( + final String filename, + final Context context, + final Deque> local_variables, + final World world + ) + throws IOException { final CommonTokenStream tokens; final FateLexer lexer; @@ -33,7 +49,7 @@ public class Utils tokens = new CommonTokenStream(lexer); parser = new FateParser(tokens); - parser.fate_file(context, world); + parser.fate_file(context, local_variables, world); world.add_loaded_file(filename); @@ -42,5 +58,4 @@ public class Utils throw new IOException("There were syntaxic errors in " + filename); } } - } diff --git a/src/core/src/tonkadur/fate/v1/lang/computation/Fold.java b/src/core/src/tonkadur/fate/v1/lang/computation/Fold.java new file mode 100644 index 0000000..e7fd2cd --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/computation/Fold.java @@ -0,0 +1,209 @@ +package tonkadur.fate.v1.lang.computation; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import tonkadur.parser.Origin; +import tonkadur.parser.ParsingError; + +import tonkadur.error.ErrorManager; + +import tonkadur.fate.v1.error.IncompatibleTypeException; +import tonkadur.fate.v1.error.IncomparableTypeException; +import tonkadur.fate.v1.error.InvalidArityException; +import tonkadur.fate.v1.error.InvalidTypeException; + +import tonkadur.fate.v1.lang.type.Type; +import tonkadur.fate.v1.lang.type.LambdaType; +import tonkadur.fate.v1.lang.type.CollectionType; + +import tonkadur.fate.v1.lang.meta.ComputationVisitor; +import tonkadur.fate.v1.lang.meta.Computation; +import tonkadur.fate.v1.lang.meta.Reference; + +public class Fold extends Computation +{ + /***************************************************************************/ + /**** MEMBERS **************************************************************/ + /***************************************************************************/ + protected final Reference lambda_function; + protected final Computation initial_value; + protected final Reference collection; + protected final boolean is_foldl; + + /***************************************************************************/ + /**** PROTECTED ************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + protected Fold + ( + final Origin origin, + final Reference lambda_function, + final Computation initial_value, + final Reference collection, + final boolean is_foldl, + final Type act_as + ) + { + super(origin, act_as); + + this.lambda_function = lambda_function; + this.initial_value = initial_value; + this.collection = collection; + this.is_foldl = is_foldl; + } + + /***************************************************************************/ + /**** PUBLIC ***************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + public static Fold build + ( + final Origin origin, + final Reference lambda_function, + final Computation initial_value, + final Reference collection, + final boolean is_foldl + ) + throws Throwable + { + final Type var_type, collection_generic_type; + final CollectionType collection_type; + final LambdaType lambda_type; + final List signature; + + var_type = lambda_function.get_type(); + + if (!(var_type instanceof LambdaType)) + { + ErrorManager.handle + ( + new InvalidTypeException + ( + origin, + var_type, + Collections.singleton(Type.LAMBDA) + ) + ); + + return null; + } + + lambda_type = (LambdaType) var_type; + + signature = lambda_type.get_signature(); + + if + ( + (parameters.size() != signature.size()) + || (parameters.size() != 2) + ) + { + ErrorManager.handle + ( + new InvalidArityException + ( + origin, + parameters.size(), + 2, + 2 + ) + ); + } + + collection_generic_type = collection.get_type(); + + if (!(collection_generic_type instanceof CollectionType)) + { + ErrorManager.handle + ( + new InvalidTypeException + ( + origin, + collection_generic_type, + Type.COLLECTION_TYPES + ) + ); + + return null; + } + + collection_type = (CollectionType) collection_generic_type; + + if (!initial_value.get_type().can_be_used_as(signature.get(0))) + { + /* TODO */ + } + + if (!collection_type.get_member_type().can_be_used_as(signature.get(1))) + { + /* TODO */ + } + + return + new Fold + ( + origin, + lambda_function, + initial_value, + collection, + is_foldl, + initial_value.get_type() + ); + } + + /**** Accessors ************************************************************/ + @Override + public void get_visited_by (final ComputationVisitor cv) + throws Throwable + { + cv.visit_fold(this); + } + + public Reference get_lambda_function_reference () + { + return lambda_function; + } + + public Computation get_initial_value () + { + return initial_value; + } + + public Reference get_collection () + { + return collection; + } + + public boolean is_foldl () + { + return is_foldl; + } + + /**** Misc. ****************************************************************/ + @Override + public String toString () + { + final StringBuilder sb = new StringBuilder(); + + if (is_foldl) + { + sb.append("(Foldl "); + } + else + { + sb.append("(Foldr "); + } + + sb.append(lambda_function.toString()); + + sb.append(" "); + sb.append(initial_value.toString()); + sb.append(" "); + sb.append(collection.get_name()); + sb.append(")"); + + return sb.toString(); + } +} diff --git a/src/core/src/tonkadur/fate/v1/lang/instruction/Range.java b/src/core/src/tonkadur/fate/v1/lang/instruction/Range.java new file mode 100644 index 0000000..2398bdf --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/instruction/Range.java @@ -0,0 +1,168 @@ +package tonkadur.fate.v1.lang.instruction; + +import java.util.Collections; + +import tonkadur.error.ErrorManager; + +import tonkadur.parser.Origin; + +import tonkadur.fate.v1.error.InvalidTypeException; + +import tonkadur.fate.v1.lang.type.CollectionType; +import tonkadur.fate.v1.lang.type.Type; + +import tonkadur.fate.v1.lang.meta.InstructionVisitor; +import tonkadur.fate.v1.lang.meta.Instruction; +import tonkadur.fate.v1.lang.meta.Computation; + +public class Range extends Instruction +{ + /***************************************************************************/ + /**** MEMBERS **************************************************************/ + /***************************************************************************/ + protected final Computation collection; + protected final Computation start; + protected final Computation end; + protected final Computation increment; + + /***************************************************************************/ + /**** PROTECTED ************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + protected Range + ( + final Origin origin, + final Computation start, + final Computation end, + final Computation increment, + final Computation collection + ) + { + super(origin); + + this.collection = collection; + this.start = start; + this.end = end; + this.increment = increment; + } + + /***************************************************************************/ + /**** PUBLIC ***************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + public static Range build + ( + final Origin origin, + final Computation start, + final Computation end, + final Computation increment, + final Computation collection + ) + throws InvalidTypeException + { + final Type t; + + t = collection.get_type(); + + if (!(t instanceof CollectionType)) + { + ErrorManager.handle + ( + new InvalidTypeException + ( + collection.get_origin(), + collection.get_type(), + Type.COLLECTION_TYPES + ) + ); + } + + if (!start.get_type().can_be_used_as(Type.INT)) + { + ErrorManager.handle + ( + new InvalidTypeException + ( + start.get_origin(), + start.get_type(), + Collections.singletonList(Type.INT) + ) + ); + } + + if (!end.get_type().can_be_used_as(Type.INT)) + { + ErrorManager.handle + ( + new InvalidTypeException + ( + end.get_origin(), + end.get_type(), + Collections.singletonList(Type.INT) + ) + ); + } + + if (!increment.get_type().can_be_used_as(Type.INT)) + { + ErrorManager.handle + ( + new InvalidTypeException + ( + increment.get_origin(), + increment.get_type(), + Collections.singletonList(Type.INT) + ) + ); + } + + return new Range(origin, start, end, increment, collection); + } + + /**** Accessors ************************************************************/ + @Override + public void get_visited_by (final InstructionVisitor iv) + throws Throwable + { + iv.visit_range(this); + } + + public Computation get_collection () + { + return collection; + } + + public Computation get_start () + { + return start; + } + + public Computation get_end () + { + return end; + } + + public Computation get_increment () + { + return increment; + } + + /**** Misc. ****************************************************************/ + @Override + public String toString () + { + final StringBuilder sb = new StringBuilder(); + + sb.append("(Range "); + sb.append(start.toString()); + sb.append(" "); + sb.append(end.toString()); + sb.append(" "); + sb.append(increment.toString()); + sb.append(" "); + sb.append(collection.toString()); + sb.append(")"); + + return sb.toString(); + } +} diff --git a/src/core/src/tonkadur/fate/v1/lang/instruction/Shuffle.java b/src/core/src/tonkadur/fate/v1/lang/instruction/Shuffle.java new file mode 100644 index 0000000..ebac30e --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/instruction/Shuffle.java @@ -0,0 +1,101 @@ +package tonkadur.fate.v1.lang.instruction; + +import java.util.Collections; + +import tonkadur.error.ErrorManager; + +import tonkadur.parser.Origin; + +import tonkadur.fate.v1.error.InvalidTypeException; + +import tonkadur.fate.v1.lang.type.CollectionType; +import tonkadur.fate.v1.lang.type.Type; + +import tonkadur.fate.v1.lang.meta.InstructionVisitor; +import tonkadur.fate.v1.lang.meta.Instruction; +import tonkadur.fate.v1.lang.meta.Computation; + +public class Shuffle extends Instruction +{ + /***************************************************************************/ + /**** MEMBERS **************************************************************/ + /***************************************************************************/ + protected final Computation collection; + + /***************************************************************************/ + /**** PROTECTED ************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + protected Shuffle + ( + final Origin origin, + final Computation collection + ) + { + super(origin); + + this.collection = collection; + } + + /***************************************************************************/ + /**** PUBLIC ***************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + public static Shuffle build + ( + final Origin origin, + final Computation collection + ) + throws InvalidTypeException + { + final Type t; + + t = collection.get_type(); + + if + ( + !(t instanceof CollectionType) + || ((CollectionType) t).is_set() + ) + { + ErrorManager.handle + ( + new InvalidTypeException + ( + collection.get_origin(), + collection.get_type(), + Collections.singleton(Type.LIST) + ) + ); + } + + return new Shuffle(origin, collection); + } + + /**** Accessors ************************************************************/ + @Override + public void get_visited_by (final InstructionVisitor iv) + throws Throwable + { + iv.visit_shuffle(this); + } + + public Computation get_collection () + { + return collection; + } + + /**** Misc. ****************************************************************/ + @Override + public String toString () + { + final StringBuilder sb = new StringBuilder(); + + sb.append("(Shuffle "); + sb.append(collection.toString()); + + sb.append(")"); + + return sb.toString(); + } +} diff --git a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 index 25882ea..c4c9645 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 @@ -52,16 +52,25 @@ options /******************************************************************************/ /******************************************************************************/ /******************************************************************************/ -fate_file [Context context, World world] +fate_file [Context context, Deque> local_variables, World world] @init { CONTEXT = context; WORLD = world; - LOCAL_VARIABLES = new ArrayDeque>(); + + if (local_variables == null) + { + LOCAL_VARIABLES = new ArrayDeque>(); + LOCAL_VARIABLES.push(new HashMap()); + } + else + { + LOCAL_VARIABLES = local_variables; + } + HIERARCHICAL_VARIABLES = new ArrayDeque>(); BREAKABLE_LEVELS = 0; - LOCAL_VARIABLES.push(new HashMap()); HIERARCHICAL_VARIABLES.push(new ArrayList()); } : @@ -377,7 +386,13 @@ first_level_fate_instr: filename ); - tonkadur.fate.v1.Utils.add_file_content(filename, CONTEXT, WORLD); + tonkadur.fate.v1.Utils.add_file_content + ( + filename, + CONTEXT, + LOCAL_VARIABLES, + WORLD + ); CONTEXT.pop(); } @@ -399,7 +414,13 @@ first_level_fate_instr: filename ); - tonkadur.fate.v1.Utils.add_file_content(filename, CONTEXT, WORLD); + tonkadur.fate.v1.Utils.add_file_content + ( + filename, + CONTEXT, + LOCAL_VARIABLES, + WORLD + ); CONTEXT.pop(); } @@ -724,7 +745,11 @@ returns [Instruction result] ); } - | INDEXED_MAP_KW value WS+ inr=value_reference WS+ outr=value_reference WS* R_PAREN + | INDEXED_MAP_KW + value WS+ + inr=value_reference WS+ + outr=value_reference WS* + R_PAREN { $result = IndexedMap.build @@ -740,41 +765,6 @@ returns [Instruction result] ); } - | FOLDL_KW fun=value WS+ init=value WS+ inr=value_reference WS+ outv=value WS* R_PAREN - { - $result = - Fold.build - ( - CONTEXT.get_origin_at - ( - ($FOLDL_MAP_KW.getLine()), - ($FOLDL_MAP_KW.getCharPositionInLine()) - ), - true, - ($fun.result), - ($init.result), - ($inr.result) - ($outv.result) - ); - } - - | FOLDR_KW fun=value WS+ init=value WS+ inr=value_reference WS+ outv=value WS* R_PAREN - { - $result = - Fold.build - ( - CONTEXT.get_origin_at - ( - ($FOLDR_KW.getLine()), - ($FOLDR_KW.getCharPositionInLine()) - ), - false, - ($fun.result), - ($init.result), - ($inr.result) - ($outv.result) - ); - } | MERGE_KW fun=value WS+ @@ -925,7 +915,7 @@ returns [Instruction result] | SHUFFLE_KW value_reference WS* R_PAREN { $result = - Range.build + Shuffle.build ( CONTEXT.get_origin_at ( @@ -2089,8 +2079,8 @@ returns [Type result] ( CONTEXT.get_origin_at ( - ($LIST_KW.getLine()), - ($LIST_KW.getCharPositionInLine()) + ($CONS_KW.getLine()), + ($CONS_KW.getCharPositionInLine()) ), ($t0.result), ($t1.result), @@ -2982,6 +2972,40 @@ returns [Computation result] ); } + | FOLDL_KW fun=value WS+ init=value WS+ inr=value_reference WS* R_PAREN + { + $result = + Fold.build + ( + CONTEXT.get_origin_at + ( + ($FOLDL_KW.getLine()), + ($FOLDL_KW.getCharPositionInLine()) + ), + ($fun.result), + ($init.result), + ($inr.result), + true + ); + } + + | FOLDR_KW fun=value WS+ init=value WS+ inr=value_reference WS* R_PAREN + { + $result = + Fold.build + ( + CONTEXT.get_origin_at + ( + ($FOLDR_KW.getLine()), + ($FOLDR_KW.getCharPositionInLine()) + ), + ($fun.result), + ($init.result), + ($inr.result), + false + ); + } + | COND_KW value_cond_list WS* R_PAREN { $result = -- cgit v1.2.3-70-g09d2