| summaryrefslogtreecommitdiff |
diff options
14 files changed, 1287 insertions, 67 deletions
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 @@ -25,6 +29,18 @@ public class Utils ) throws IOException { + add_file_content(filename, context, null, world); + } + + public static void add_file_content + ( + final String filename, + final Context context, + final Deque<Map<String, Variable>> local_variables, + final World world + ) + throws IOException + { final CommonTokenStream tokens; final FateLexer lexer; final FateParser parser; @@ -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/CarCdr.java b/src/core/src/tonkadur/fate/v1/lang/computation/CarCdr.java new file mode 100644 index 0000000..58e099d --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/computation/CarCdr.java @@ -0,0 +1,125 @@ +package tonkadur.fate.v1.lang.computation; + +import java.util.Collections; + +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.type.ConsType; +import tonkadur.fate.v1.lang.type.Type; + +public class CarCdr extends Computation +{ + /***************************************************************************/ + /**** MEMBERS **************************************************************/ + /***************************************************************************/ + protected final Computation parent; + protected final boolean is_car; + + /***************************************************************************/ + /**** PROTECTED ************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + protected CarCdr + ( + final Origin origin, + final Computation parent, + final boolean is_car, + final Type type + ) + { + super(origin, type); + + this.parent = parent; + this.is_car = is_car; + } + + /***************************************************************************/ + /**** PUBLIC ***************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + public static CarCdr build + ( + final Origin origin, + final Computation parent, + final boolean is_car + ) + throws InvalidTypeException + { + Type current_type; + + current_type = parent.get_type(); + + if (!(current_type instanceof ConsType)) + { + ErrorManager.handle + ( + new InvalidTypeException + ( + origin, + current_type, + Collections.singletonList(Type.CONS) + ) + ); + + current_type = Type.ANY; + } + else if (is_car) + { + current_type = ((ConsType) current_type).get_car_type(); + } + else + { + current_type = ((ConsType) current_type).get_cdr_type(); + } + + return new CarCdr(origin, parent, is_car, current_type); + } + + /**** Accessors ************************************************************/ + @Override + public void get_visited_by (final ComputationVisitor cv) + throws Throwable + { + cv.visit_car_cdr(this); + } + + public Computation get_parent () + { + return parent; + } + + public boolean is_car () + { + return is_car; + } + + /**** Misc. ****************************************************************/ + @Override + public String toString () + { + final StringBuilder sb = new StringBuilder(); + + if (is_car) + { + sb.append("(car ("); + } + else + { + sb.append("(cdr ("); + } + + sb.append(type.get_name()); + sb.append(") "); + sb.append(parent); + sb.append(")"); + + return sb.toString(); + } +} diff --git a/src/core/src/tonkadur/fate/v1/lang/computation/ConsComputation.java b/src/core/src/tonkadur/fate/v1/lang/computation/ConsComputation.java new file mode 100644 index 0000000..04d58ff --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/computation/ConsComputation.java @@ -0,0 +1,74 @@ +package tonkadur.fate.v1.lang.computation; + +import tonkadur.parser.Origin; + +import tonkadur.fate.v1.lang.type.ConsType; + +import tonkadur.fate.v1.lang.meta.ComputationVisitor; +import tonkadur.fate.v1.lang.meta.Computation; + +public class ConsComputation extends Computation +{ + /***************************************************************************/ + /**** MEMBERS **************************************************************/ + /***************************************************************************/ + protected final Computation car; + protected final Computation cdr; + + /***************************************************************************/ + /**** PROTECTED ************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + public ConsComputation + ( + final Origin origin, + final Computation car, + final Computation cdr + ) + { + super + ( + origin, + new ConsType(origin, car.get_type(), cdr.get_type(), "auto generated") + ); + + this.car = car; + this.cdr = cdr; + } + + /***************************************************************************/ + /**** PUBLIC ***************************************************************/ + /***************************************************************************/ + /**** Accessors ************************************************************/ + @Override + public void get_visited_by (final ComputationVisitor cv) + throws Throwable + { + cv.visit_cons(this); + } + + public Computation get_car () + { + return car; + } + + public Computation get_cdr () + { + return cdr; + } + + /**** Misc. ****************************************************************/ + @Override + public String toString () + { + final StringBuilder sb = new StringBuilder(); + + sb.append("(Cons "); + sb.append(car.toString()); + sb.append(" "); + sb.append(car.toString()); + sb.append(") "); + + return sb.toString(); + } +} 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..55f1877 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/computation/Fold.java @@ -0,0 +1,205 @@ +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 Computation lambda_function; + protected final Computation initial_value; + protected final Reference collection; + protected final boolean is_foldl; + + /***************************************************************************/ + /**** PROTECTED ************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + protected Fold + ( + final Origin origin, + final Computation 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 Computation 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<Type> 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 (signature.size() != 2) + { + ErrorManager.handle + ( + new InvalidArityException + ( + lambda_function.get_origin(), + signature.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_content_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 Computation get_lambda_function () + { + 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/Map.java b/src/core/src/tonkadur/fate/v1/lang/instruction/Map.java new file mode 100644 index 0000000..228423c --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/instruction/Map.java @@ -0,0 +1,215 @@ +package tonkadur.fate.v1.lang.instruction; + +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.Computation; +import tonkadur.fate.v1.lang.meta.Instruction; +import tonkadur.fate.v1.lang.meta.InstructionVisitor; +import tonkadur.fate.v1.lang.meta.Reference; + +public class Map extends Instruction +{ + /***************************************************************************/ + /**** MEMBERS **************************************************************/ + /***************************************************************************/ + protected final Computation lambda_function; + protected final Reference collection_in; + protected final Reference collection_out; + + /***************************************************************************/ + /**** PROTECTED ************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + protected Map + ( + final Origin origin, + final Computation lambda_function, + final Reference collection_in, + final Reference collection_out + ) + { + super(origin); + + this.lambda_function = lambda_function; + this.collection_in = collection_in; + this.collection_out = collection_out; + } + + /***************************************************************************/ + /**** PUBLIC ***************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + public static Map build + ( + final Origin origin, + final Computation lambda_function, + final Reference collection_in, + final Reference collection_out + ) + throws Throwable + { + final Type var_type, collection_in_generic_type; + final Type collection_out_generic_type; + final CollectionType collection_in_type; + final CollectionType collection_out_type; + final LambdaType lambda_type; + final List<Type> 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 (signature.size() != 1) + { + ErrorManager.handle + ( + new InvalidArityException + ( + lambda_function.get_origin(), + signature.size(), + 1, + 1 + ) + ); + } + + collection_in_generic_type = collection_in.get_type(); + + if (!(collection_in_generic_type instanceof CollectionType)) + { + ErrorManager.handle + ( + new InvalidTypeException + ( + collection_in.get_origin(), + collection_in_generic_type, + Type.COLLECTION_TYPES + ) + ); + + return null; + } + + collection_in_type = (CollectionType) collection_in_generic_type; + + if + ( + !collection_in_type.get_content_type().can_be_used_as(signature.get(0)) + ) + { + /* TODO */ + } + + collection_out_generic_type = collection_out.get_type(); + + if (!(collection_out_generic_type instanceof CollectionType)) + { + ErrorManager.handle + ( + new InvalidTypeException + ( + collection_out.get_origin(), + collection_out_generic_type, + Type.COLLECTION_TYPES + ) + ); + + return null; + } + + collection_out_type = (CollectionType) collection_out_generic_type; + + if + ( + !collection_out_type.get_content_type().can_be_used_as + ( + lambda_type.get_return_type() + ) + ) + { + /* TODO */ + } + + return + new Map + ( + origin, + lambda_function, + collection_in, + collection_out + ); + } + + /**** Accessors ************************************************************/ + @Override + public void get_visited_by (final InstructionVisitor iv) + throws Throwable + { + iv.visit_map(this); + } + + public Computation get_lambda_function () + { + return lambda_function; + } + + public Reference get_collection_in () + { + return collection_in; + } + + public Reference get_collection_out () + { + return collection_out; + } + + /**** Misc. ****************************************************************/ + @Override + public String toString () + { + final StringBuilder sb = new StringBuilder(); + + sb.append("(Map "); + sb.append(lambda_function.toString()); + sb.append(" "); + sb.append(collection_in.toString()); + sb.append(" "); + sb.append(collection_out.toString()); + 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/lang/meta/ComputationVisitor.java b/src/core/src/tonkadur/fate/v1/lang/meta/ComputationVisitor.java index 1cdbcf5..1c2fa85 100644 --- a/src/core/src/tonkadur/fate/v1/lang/meta/ComputationVisitor.java +++ b/src/core/src/tonkadur/fate/v1/lang/meta/ComputationVisitor.java @@ -16,6 +16,15 @@ public interface ComputationVisitor public void visit_cast (final Cast n) throws Throwable; + public void visit_cons (final ConsComputation n) + throws Throwable; + + public void visit_fold (final Fold n) + throws Throwable; + + public void visit_car_cdr (final CarCdr n) + throws Throwable; + public void visit_cond_value (final CondValue n) throws Throwable; diff --git a/src/core/src/tonkadur/fate/v1/lang/meta/InstructionVisitor.java b/src/core/src/tonkadur/fate/v1/lang/meta/InstructionVisitor.java index 30acc7d..01ff4a4 100644 --- a/src/core/src/tonkadur/fate/v1/lang/meta/InstructionVisitor.java +++ b/src/core/src/tonkadur/fate/v1/lang/meta/InstructionVisitor.java @@ -47,6 +47,15 @@ public interface InstructionVisitor public void visit_clear (final Clear c) throws Throwable; + public void visit_map (final Map c) + throws Throwable; + + public void visit_range (final Range c) + throws Throwable; + + public void visit_shuffle (final Shuffle c) + throws Throwable; + public void visit_reverse_list (final ReverseList n) throws Throwable; diff --git a/src/core/src/tonkadur/fate/v1/lang/type/ConsType.java b/src/core/src/tonkadur/fate/v1/lang/type/ConsType.java new file mode 100644 index 0000000..e01a91b --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/type/ConsType.java @@ -0,0 +1,115 @@ +package tonkadur.fate.v1.lang.type; + +import tonkadur.parser.Origin; + +import tonkadur.fate.v1.lang.meta.DeclaredEntity; + +public class ConsType extends Type +{ + /***************************************************************************/ + /**** MEMBERS **************************************************************/ + /***************************************************************************/ + protected final Type car; + protected final Type cdr; + + /***************************************************************************/ + /**** PUBLIC ***************************************************************/ + /***************************************************************************/ + + /**** Constructors *********************************************************/ + public ConsType + ( + final Origin origin, + final Type car, + final Type cdr, + final String name + ) + { + super(origin, null, name); + + this.car = car; + this.cdr = cdr; + } + + /**** Accessors ************************************************************/ + public Type get_car_type () + { + return car; + } + + public Type get_cdr_type () + { + return cdr; + } + + /**** Compatibility ********************************************************/ + @Override + public boolean can_be_used_as (final Type t) + { + if (t instanceof ConsType) + { + final ConsType dt; + + dt = (ConsType) t; + + return + car.can_be_used_as(dt.car) + && cdr.can_be_used_as(dt.cdr); + } + + return false; + } + + /* + * This is for the very special case where a type is used despite not being + * even a sub-type of the expected one. Using this rather expensive function, + * the most restrictive shared type will be returned. If no such type exists, + * the ANY time is returned. + */ + @Override + public DeclaredEntity generate_comparable_to (final DeclaredEntity de) + { + final Type resulting_car, resulting_cdr; + final ConsType dt; + + if (!(de instanceof ConsType)) + { + return Type.ANY; + } + + dt = (ConsType) de; + + resulting_car = (Type) car.generate_comparable_to(dt.car); + resulting_cdr = (Type) cdr.generate_comparable_to(dt.cdr); + + return new ConsType(get_origin(), resulting_car, resulting_cdr, name); + } + + @Override + public Type get_act_as_type () + { + return Type.CONS; + } + + /**** Misc. ****************************************************************/ + @Override + public Type generate_alias (final Origin origin, final String name) + { + return new ConsType(origin, car, cdr, name); + } + + @Override + public String toString () + { + final StringBuilder sb = new StringBuilder(); + + sb.append("(Cons "); + sb.append(car.toString()); + sb.append(" "); + sb.append(cdr.toString()); + sb.append(")::"); + sb.append(name); + + return sb.toString(); + } +} diff --git a/src/core/src/tonkadur/fate/v1/lang/type/Type.java b/src/core/src/tonkadur/fate/v1/lang/type/Type.java index fefe7cd..ac4bcb3 100644 --- a/src/core/src/tonkadur/fate/v1/lang/type/Type.java +++ b/src/core/src/tonkadur/fate/v1/lang/type/Type.java @@ -21,6 +21,7 @@ public class Type extends DeclaredEntity { public static final Type ANY; public static final Type BOOL; + public static final Type CONS; public static final Type DICT; public static final Type FLOAT; public static final Type INT; @@ -48,6 +49,7 @@ public class Type extends DeclaredEntity ANY = new Type(base, null, "undetermined type"); BOOL = new Type(base, null, "bool"); + CONS = new Type(base, null, "cons"); DICT = new Type(base, null, "dict"); FLOAT = new Type(base, null, "float"); INT = new Type(base, null, "int"); @@ -61,6 +63,7 @@ public class Type extends DeclaredEntity ALL_TYPES = new HashSet<Type>(); ALL_TYPES.add(ANY); ALL_TYPES.add(BOOL); + ALL_TYPES.add(CONS); ALL_TYPES.add(DICT); ALL_TYPES.add(FLOAT); ALL_TYPES.add(INT); diff --git a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 index b84313e..89ab79d 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<Map<String, Variable>> local_variables, World world] @init { CONTEXT = context; WORLD = world; - LOCAL_VARIABLES = new ArrayDeque<Map<String, Variable>>(); + + if (local_variables == null) + { + LOCAL_VARIABLES = new ArrayDeque<Map<String, Variable>>(); + LOCAL_VARIABLES.push(new HashMap<String, Variable>()); + } + else + { + LOCAL_VARIABLES = local_variables; + } + HIERARCHICAL_VARIABLES = new ArrayDeque<List<String>>(); BREAKABLE_LEVELS = 0; - LOCAL_VARIABLES.push(new HashMap<String, Variable>()); HIERARCHICAL_VARIABLES.push(new ArrayList<String>()); } : @@ -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(); } @@ -710,31 +731,40 @@ returns [Instruction result] | MAP_KW value WS+ inr=value_reference WS+ outr=value_reference WS* R_PAREN { - /* TODO */ - - $result = null; - } - - | INDEXED_MAP_KW value WS+ inr=value_reference WS+ outr=value_reference WS* R_PAREN - { - /* TODO */ - - $result = null; + $result = + tonkadur.fate.v1.lang.instruction.Map.build + ( + CONTEXT.get_origin_at + ( + ($MAP_KW.getLine()), + ($MAP_KW.getCharPositionInLine()) + ), + ($value.result), + ($inr.result), + ($outr.result) + ); } - | FOLDL_KW fun=value WS+ init=value WS+ inr=value_reference WS+ outv=value WS* R_PAREN + | INDEXED_MAP_KW + value WS+ + inr=value_reference WS+ + outr=value_reference WS* + R_PAREN { - /* TODO */ - - $result = null; + $result = + IndexedMap.build + ( + CONTEXT.get_origin_at + ( + ($INDEXED_MAP_KW.getLine()), + ($INDEXED_MAP_KW.getCharPositionInLine()) + ), + ($value.result), + ($inr.result), + ($outr.result) + ); } - | FOLDR_KW fun=value WS+ init=value WS+ inr=value_reference WS+ outv=value WS* R_PAREN - { - /* TODO */ - - $result = null; - } | MERGE_KW fun=value WS+ @@ -744,9 +774,20 @@ returns [Instruction result] outr=value_reference WS* R_PAREN { - /* TODO */ - - $result = null; + $result = + Merge.build + ( + CONTEXT.get_origin_at + ( + ($MERGE_KW.getLine()), + ($MERGE_KW.getCharPositionInLine()) + ), + ($fun.result), + ($init.result), + ($inr0.result), + ($inr1.result), + ($outr.result) + ); } | MERGE_KW @@ -759,28 +800,59 @@ returns [Instruction result] outr=value_reference WS* R_PAREN { - /* TODO */ - - $result = null; + $result = + Merge.build + ( + CONTEXT.get_origin_at + ( + ($MERGE_KW.getLine()), + ($MERGE_KW.getCharPositionInLine()) + ), + ($fun.result), + ($init.result), + ($def0.result), + ($inr0.result), + ($def1.result), + ($inr1.result), + ($outr.result) + ); } | SUB_LIST_KW - start=value WS+ - end=value WS+ + vstart=value WS+ + vend=value WS+ inr=value_reference WS+ outr=value_reference WS* R_PAREN { - /* TODO */ - - $result = null; + $result = + SubList.build + ( + CONTEXT.get_origin_at + ( + ($SUB_LIST_KW.getLine()), + ($SUB_LIST_KW.getCharPositionInLine()) + ), + ($vstart.result), + ($vend.result), + ($inr.result), + ($outr.result) + ); } | FILTER_KW value WS+ value_reference WS* R_PAREN { - /* TODO */ - - $result = null; + $result = + Filter.build + ( + CONTEXT.get_origin_at + ( + ($FILTER_KW.getLine()), + ($FILTER_KW.getCharPositionInLine()) + ), + ($value.result), + ($value_reference.result) + ); } | PARTITION_KW @@ -789,35 +861,69 @@ returns [Instruction result] iffalse=value_reference WS* R_PAREN { - /* TODO */ - - $result = null; + $result = + Partition.build + ( + CONTEXT.get_origin_at + ( + ($PARTITION_KW.getLine()), + ($PARTITION_KW.getCharPositionInLine()) + ), + ($value.result), + ($iftrue.result), + ($iffalse.result) + ); } | SORT_KW value WS+ value_reference WS* R_PAREN { - /* TODO */ - - $result = null; + $result = + Sort.build + ( + CONTEXT.get_origin_at + ( + ($SORT_KW.getLine()), + ($SORT_KW.getCharPositionInLine()) + ), + ($value.result), + ($value_reference.result) + ); } | RANGE_KW - start=value WS+ - end=value WS+ + vstart=value WS+ + vend=value WS+ inc=value WS+ value_reference WS* R_PAREN { - /* TODO */ - - $result = null; + $result = + Range.build + ( + CONTEXT.get_origin_at + ( + ($RANGE_KW.getLine()), + ($RANGE_KW.getCharPositionInLine()) + ), + ($vstart.result), + ($vend.result), + ($inc.result), + ($value_reference.result) + ); } | SHUFFLE_KW value_reference WS* R_PAREN { - /* TODO */ - - $result = null; + $result = + Shuffle.build + ( + CONTEXT.get_origin_at + ( + ($SHUFFLE_KW.getLine()), + ($SHUFFLE_KW.getCharPositionInLine()) + ), + ($value_reference.result) + ); } | SET_KW value_reference WS+ value WS* R_PAREN @@ -1968,9 +2074,18 @@ returns [Type result] | CONS_KW t0=type WS+ t1=type WS* R_PAREN { - /* TODO */ - - $result = null; + $result = + new ConsType + ( + CONTEXT.get_origin_at + ( + ($CONS_KW.getLine()), + ($CONS_KW.getCharPositionInLine()) + ), + ($t0.result), + ($t1.result), + ("anonymous (" + ($type.result).get_name() + ") list type") + ); } | LAMBDA_KW type WS* L_PAREN WS* type_list WS* R_PAREN WS* R_PAREN @@ -2812,25 +2927,83 @@ returns [Computation result] ); } - | CONS_KW v0=value WS+ t1=value WS* R_PAREN + | CONS_KW v0=value WS+ v1=value WS* R_PAREN { - /* TODO */ - - $result = null; + $result = + new ConsComputation + ( + CONTEXT.get_origin_at + ( + ($CONS_KW.getLine()), + ($CONS_KW.getCharPositionInLine()) + ), + ($v0.result), + ($v1.result) + ); } | CAR_KW value WS* R_PAREN { - /* TODO */ - - $result = null; + $result = + CarCdr.build + ( + CONTEXT.get_origin_at + ( + ($CAR_KW.getLine()), + ($CAR_KW.getCharPositionInLine()) + ), + ($value.result), + true + ); } | CDR_KW value WS* R_PAREN { - /* TODO */ + $result = + CarCdr.build + ( + CONTEXT.get_origin_at + ( + ($CDR_KW.getLine()), + ($CDR_KW.getCharPositionInLine()) + ), + ($value.result), + false + ); + } + + | 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 + ); + } - $result = null; + | 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 |


