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/Fold.java209
-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/parser/FateParser.g4112
7 files changed, 571 insertions, 46 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/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<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
+ (
+ (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<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();
}
@@ -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 =