summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/tests/local_variables.fate4
-rw-r--r--data/tests/local_variables2.fate4
-rw-r--r--src/core/src/tonkadur/fate/v1/Utils.java19
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/computation/CarCdr.java125
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/computation/ConsComputation.java74
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/computation/Fold.java205
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/instruction/Map.java215
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/instruction/Range.java168
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/instruction/Shuffle.java101
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/meta/ComputationVisitor.java9
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/meta/InstructionVisitor.java9
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/type/ConsType.java115
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/type/Type.java3
-rw-r--r--src/core/src/tonkadur/fate/v1/parser/FateParser.g4303
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