summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/unit-testing/ifelse.fate61
-rw-r--r--data/unit-testing/map.fate149
-rw-r--r--data/unit-testing/merge.fate168
-rw-r--r--src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/ComputationCompiler.java98
-rw-r--r--src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/InstructionCompiler.java168
-rw-r--r--src/core/src/tonkadur/wyrd/v1/compiler/util/MergeLambda.java184
6 files changed, 826 insertions, 2 deletions
diff --git a/data/unit-testing/ifelse.fate b/data/unit-testing/ifelse.fate
new file mode 100644
index 0000000..e06be4d
--- /dev/null
+++ b/data/unit-testing/ifelse.fate
@@ -0,0 +1,61 @@
+(fate_version 1)
+
+(global string test_name)
+
+(set test_name ( IF ELSE ))
+
+
+(if (false)
+ (assert (false) [FAILED] (var test_name) Executing dead code 0.)
+)
+
+(global bool test)
+
+(set test (false))
+
+(ifelse (false)
+ (assert (false) [FAILED] (var test_name) Executing dead code 1.)
+ (set test (true))
+)
+
+(assert test [FAILED] (var test_name) ignored valid branch 0.)
+
+(if (false)
+ (assert (false) [FAILED] (var test_name) Executing dead code 2.)
+ (set test (false))
+)
+
+(assert test [FAILED] (var test_name) Executing dead code 3.)
+
+(set test
+ (ifelse (false)
+ (false)
+ (true)
+ )
+)
+
+(assert test [FAILED] (var test_name) Executing dead code 4.)
+
+(set test
+ (ifelse (true)
+ (true)
+ (false)
+ )
+)
+
+(assert test [FAILED] (var test_name) Executing dead code 5.)
+
+(assert
+ (=
+ (ifelse (= 8 (+ 4 4))
+ ( valid string )
+ ( incorrect string )
+ )
+ ( valid string )
+ )
+ [FAILED] (var test_name) Failed to select correct branch.
+)
+
+[COMPLETED] (var test_name)
+
+(end)
diff --git a/data/unit-testing/map.fate b/data/unit-testing/map.fate
new file mode 100644
index 0000000..bf8517f
--- /dev/null
+++ b/data/unit-testing/map.fate
@@ -0,0 +1,149 @@
+(fate_version 1)
+
+(global string test_name)
+
+(set test_name ( MAP ))
+
+(global (list int) li0)
+(global (list int) li1)
+(global (list int) li2)
+(global (list int) li3)
+
+(set li0
+ (map
+ (lambda ((int i)) (* i 2))
+ (range 0 10 1)
+ )
+)
+
+(set li1 (range 0 10 1))
+
+(map!
+ (lambda ((int i)) (* i 2))
+ li1
+)
+
+(set li2
+ (map
+ (lambda ((int i) (int mod)) (* i mod))
+ (range 0 10 1)
+ 2
+ )
+)
+
+(set li3 (range 0 10 1))
+
+(map!
+ (lambda ((int i) (int mod)) (* i mod))
+ li3
+ 2
+)
+
+(assert
+ (= (var li1) (var li0) (var li2) (var li3))
+ [FAILED] (var test_name) Equality test 0.
+)
+
+(assert
+ (= 0 (var li1.0) (var li0.0))
+ [FAILED] (var test_name) Test for 0: (var li1.0), (var li0.0).
+)
+
+(assert
+ (= 2 (var li1.1) (var li0.1))
+ [FAILED] (var test_name) Test for 2: (var li1.1), (var li0.1).
+)
+
+(assert
+ (= 4 (var li1.2) (var li0.2))
+ [FAILED] (var test_name) Test for 4: (var li1.2), (var li0.2).
+)
+(assert
+ (= 6 (var li1.3) (var li0.3))
+ [FAILED] (var test_name) Test for 6: (var li1.3), (var li0.3).
+)
+(assert
+ (= 8 (var li1.4) (var li0.4))
+ [FAILED] (var test_name) Test for 8: (var li1.4), (var li0.4).
+)
+(assert
+ (= 10 (var li1.5) (var li0.5))
+ [FAILED] (var test_name) Test for 10: (var li1.5), (var li0.5).
+)
+(assert
+ (= 12 (var li1.6) (var li0.6))
+ [FAILED] (var test_name) Test for 12: (var li1.6), (var li0.6).
+)
+(assert
+ (= 14 (var li1.7) (var li0.7))
+ [FAILED] (var test_name) Test for 14: (var li1.7), (var li0.7).
+)
+(assert
+ (= 16 (var li1.8) (var li0.8))
+ [FAILED] (var test_name) Test for 16: (var li1.8), (var li0.8).
+)
+(assert
+ (= 18 (var li1.9) (var li0.9))
+ [FAILED] (var test_name) Test for 18: (var li1.9), (var li0.9).
+)
+(assert
+ (= 20 (var li1.10) (var li0.10))
+ [FAILED] (var test_name) Test for 20: (var li1.10), (var li0.10).
+)
+
+(clear li0)
+(clear li1)
+(clear li2)
+(clear li3)
+
+(set li0
+ (indexed_map
+ (lambda ((int ix) (int i)) (+ (* i ix) 1000))
+ (range 10 20 1)
+ )
+)
+
+(set li1 (range 10 20 1))
+
+(indexed_map!
+ (lambda ((int ix) (int i)) (+ (* i ix) 1000))
+ li1
+)
+
+(set li2
+ (indexed_map
+ (lambda ((int ix) (int i) (int mod)) (+ (* i ix) mod))
+ (range 10 20 1)
+ 1000
+ )
+)
+
+(set li3 (range 10 20 1))
+
+(indexed_map!
+ (lambda ((int ix) (int i) (int mod)) (+ (* i ix) mod))
+ li3
+ 1000
+)
+
+(assert
+ (= (var li1) (var li0) (var li2) (var li3))
+ [FAILED] (var test_name) Equality test 1.
+)
+
+(global int i)
+
+(for (set i 0) (=< i 10) (set i (+ i 1))
+ (assert
+ (=
+ (access li1 i) (access li0 i) (access li2 i) (access li3 i)
+ (+ (* i (+ 10 i)) 1000)
+ )
+ [FAILED] (var test_name) Indexed map at (var i):
+ (access li1 i), (access li0 i), (access li2 i), (access li3 i)
+ )
+)
+
+[COMPLETED] (var test_name)
+
+(end)
diff --git a/data/unit-testing/merge.fate b/data/unit-testing/merge.fate
new file mode 100644
index 0000000..0bf7bca
--- /dev/null
+++ b/data/unit-testing/merge.fate
@@ -0,0 +1,168 @@
+(fate_version 1)
+
+(global string test_name)
+
+(set test_name ( MERGE ))
+
+(global (list int) li0)
+(global (list int) li1)
+(global (list int) li2)
+(global (list int) li3)
+
+(global (set int) si0)
+(global (set int) si1)
+(global (set int) si2)
+(global (set int) si3)
+
+(set li0
+ (merge_to_list
+ (lambda
+ (
+ (int a)
+ (int b)
+ )
+ (- a b)
+ )
+ (range 10 40 1)
+ (range 0 60 2)
+ )
+)
+
+(set li1 (range 10 40 1))
+
+(merge!
+ (lambda
+ (
+ (int a)
+ (int b)
+ )
+ (- a b)
+ )
+ li1
+ (range 0 60 2)
+)
+
+(set li2
+ (map
+ (lambda ((int i) (int mod)) (* i mod))
+ (range 0 10 1)
+ 2
+ )
+)
+
+(set li3 (range 0 10 1))
+
+(map!
+ (lambda ((int i) (int mod)) (* i mod))
+ li3
+ 2
+)
+
+(assert
+ (= (var li1) (var li0) (var li2) (var li3))
+ [FAILED] (var test_name) Equality test 0.
+)
+
+(assert
+ (= 0 (var li1.0) (var li0.0))
+ [FAILED] (var test_name) Test for 0: (var li1.0), (var li0.0).
+)
+
+(assert
+ (= 2 (var li1.1) (var li0.1))
+ [FAILED] (var test_name) Test for 2: (var li1.1), (var li0.1).
+)
+
+(assert
+ (= 4 (var li1.2) (var li0.2))
+ [FAILED] (var test_name) Test for 4: (var li1.2), (var li0.2).
+)
+(assert
+ (= 6 (var li1.3) (var li0.3))
+ [FAILED] (var test_name) Test for 6: (var li1.3), (var li0.3).
+)
+(assert
+ (= 8 (var li1.4) (var li0.4))
+ [FAILED] (var test_name) Test for 8: (var li1.4), (var li0.4).
+)
+(assert
+ (= 10 (var li1.5) (var li0.5))
+ [FAILED] (var test_name) Test for 10: (var li1.5), (var li0.5).
+)
+(assert
+ (= 12 (var li1.6) (var li0.6))
+ [FAILED] (var test_name) Test for 12: (var li1.6), (var li0.6).
+)
+(assert
+ (= 14 (var li1.7) (var li0.7))
+ [FAILED] (var test_name) Test for 14: (var li1.7), (var li0.7).
+)
+(assert
+ (= 16 (var li1.8) (var li0.8))
+ [FAILED] (var test_name) Test for 16: (var li1.8), (var li0.8).
+)
+(assert
+ (= 18 (var li1.9) (var li0.9))
+ [FAILED] (var test_name) Test for 18: (var li1.9), (var li0.9).
+)
+(assert
+ (= 20 (var li1.10) (var li0.10))
+ [FAILED] (var test_name) Test for 20: (var li1.10), (var li0.10).
+)
+
+(clear li0)
+(clear li1)
+(clear li2)
+(clear li3)
+
+(set li0
+ (indexed_map
+ (lambda ((int ix) (int i)) (+ (* i ix) 1000))
+ (range 10 20 1)
+ )
+)
+
+(set li1 (range 10 20 1))
+
+(indexed_map!
+ (lambda ((int ix) (int i)) (+ (* i ix) 1000))
+ li1
+)
+
+(set li2
+ (indexed_map
+ (lambda ((int ix) (int i) (int mod)) (+ (* i ix) mod))
+ (range 10 20 1)
+ 1000
+ )
+)
+
+(set li3 (range 10 20 1))
+
+(indexed_map!
+ (lambda ((int ix) (int i) (int mod)) (+ (* i ix) mod))
+ li3
+ 1000
+)
+
+(assert
+ (= (var li1) (var li0) (var li2) (var li3))
+ [FAILED] (var test_name) Equality test 1.
+)
+
+(global int i)
+
+(for (set i 0) (=< i 10) (set i (+ i 1))
+ (assert
+ (=
+ (access li1 i) (access li0 i) (access li2 i) (access li3 i)
+ (+ (* i (+ 10 i)) 1000)
+ )
+ [FAILED] (var test_name) Indexed map at (var i):
+ (access li1 i), (access li0 i), (access li2 i), (access li3 i)
+ )
+)
+
+[COMPLETED] (var test_name)
+
+(end)
diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/ComputationCompiler.java b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/ComputationCompiler.java
index 1473c6c..2587769 100644
--- a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/ComputationCompiler.java
+++ b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/ComputationCompiler.java
@@ -2854,6 +2854,96 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor
);
}
+ private void visit_merge_with_defaults
+ (
+ final tonkadur.fate.v1.lang.computation.MergeComputation n
+ )
+ throws Throwable
+ {
+ final List<Computation> params;
+ final ComputationCompiler lambda_cc, default_a_cc, default_b_cc;
+ final ComputationCompiler in_collection_a_cc, in_collection_b_cc;
+ final Register result;
+
+ result = reserve(TypeCompiler.compile(compiler, n.get_type()));
+
+ result_as_address = result.get_address();
+ result_as_computation = result.get_value();
+
+ params = new ArrayList<Computation>();
+
+ for
+ (
+ final tonkadur.fate.v1.lang.meta.Computation p:
+ n.get_extra_parameters()
+ )
+ {
+ final ComputationCompiler param_cc;
+
+ param_cc = new ComputationCompiler(compiler);
+
+ p.get_visited_by(param_cc);
+
+ /* Let's not re-compute the parameters on every iteration. */
+ param_cc.generate_address();
+
+ assimilate(param_cc);
+
+ params.add(param_cc.get_computation());
+ }
+
+ lambda_cc = new ComputationCompiler(compiler);
+
+ n.get_lambda_function().get_visited_by(lambda_cc);
+
+ assimilate(lambda_cc);
+
+ default_a_cc = new ComputationCompiler(compiler);
+
+ n.get_default_a().get_visited_by(default_a_cc);
+
+ default_a_cc.generate_address();
+
+ assimilate(default_a_cc);
+
+ default_b_cc = new ComputationCompiler(compiler);
+
+ n.get_default_b().get_visited_by(default_b_cc);
+
+ default_b_cc.generate_address();
+
+ assimilate(default_b_cc);
+
+ in_collection_a_cc = new ComputationCompiler(compiler);
+
+ n.get_collection_in_a().get_visited_by(in_collection_a_cc);
+
+ assimilate(in_collection_a_cc);
+
+ in_collection_b_cc = new ComputationCompiler(compiler);
+
+ n.get_collection_in_b().get_visited_by(in_collection_b_cc);
+
+ assimilate(in_collection_b_cc);
+
+ init_instructions.add
+ (
+ MergeLambda.generate
+ (
+ compiler.registers(),
+ compiler.assembler(),
+ lambda_cc.get_computation(),
+ default_a_cc.get_computation(),
+ in_collection_a_cc.get_address(),
+ default_b_cc.get_computation(),
+ in_collection_b_cc.get_address(),
+ result_as_address,
+ n.to_set(),
+ params
+ )
+ );
+ }
+
@Override
public void visit_merge
(
@@ -2861,7 +2951,13 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor
)
throws Throwable
{
- /* TODO: handle the default values if there are any. */
+ if (n.get_default_a() == null)
+ {
+ visit_merge_with_defaults(n);
+
+ return;
+ }
+
final List<Computation> params;
final ComputationCompiler lambda_cc;
final ComputationCompiler in_collection_a_cc, in_collection_b_cc;
diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/InstructionCompiler.java b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/InstructionCompiler.java
index 438dde7..147f2f1 100644
--- a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/InstructionCompiler.java
+++ b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/InstructionCompiler.java
@@ -613,6 +613,16 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor
result.add
(
+ Clear.generate
+ (
+ compiler.registers(),
+ compiler.assembler(),
+ collection_cc.get_address()
+ )
+ );
+
+ result.add
+ (
MapLambda.generate
(
compiler.registers(),
@@ -732,6 +742,147 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor
}
}
+ private void visit_merge_with_defaults
+ (
+ final tonkadur.fate.v1.lang.instruction.Merge n
+ )
+ throws Throwable
+ {
+ final Register holder;
+ final ComputationCompiler lambda_cc, default_a_cc, default_b_cc;
+ final List<Computation> params;
+ final List<ComputationCompiler> param_cc_list;
+ final ComputationCompiler collection_cc, in_collection_b_cc;
+
+ params = new ArrayList<Computation>();
+ param_cc_list = new ArrayList<ComputationCompiler>();
+
+ lambda_cc = new ComputationCompiler(compiler);
+ default_a_cc = new ComputationCompiler(compiler);
+ default_b_cc = new ComputationCompiler(compiler);
+
+ n.get_lambda_function().get_visited_by(lambda_cc);
+
+ if (lambda_cc.has_init())
+ {
+ result.add(lambda_cc.get_init());
+ }
+
+ collection_cc = new ComputationCompiler(compiler);
+
+ n.get_collection().get_visited_by(collection_cc);
+
+ if (collection_cc.has_init())
+ {
+ result.add(collection_cc.get_init());
+ }
+
+ n.get_default_a().get_visited_by(default_a_cc);
+
+ default_a_cc.generate_address();
+
+ if (default_a_cc.has_init())
+ {
+ result.add(default_a_cc.get_init());
+ }
+
+ n.get_default_b().get_visited_by(default_b_cc);
+
+ default_b_cc.generate_address();
+
+ if (default_b_cc.has_init())
+ {
+ result.add(default_b_cc.get_init());
+ }
+
+ holder =
+ compiler.registers().reserve
+ (
+ collection_cc.get_computation().get_type(),
+ result
+ );
+
+ result.add
+ (
+ new SetValue(holder.get_address(), collection_cc.get_computation())
+ );
+
+ result.add
+ (
+ Clear.generate
+ (
+ compiler.registers(),
+ compiler.assembler(),
+ collection_cc.get_address()
+ )
+ );
+
+ in_collection_b_cc = new ComputationCompiler(compiler);
+
+ n.get_collection_in_b().get_visited_by(in_collection_b_cc);
+
+ if (in_collection_b_cc.has_init())
+ {
+ result.add(in_collection_b_cc.get_init());
+ }
+
+ for
+ (
+ final tonkadur.fate.v1.lang.meta.Computation p:
+ n.get_extra_parameters()
+ )
+ {
+ final ComputationCompiler param_cc;
+
+ param_cc = new ComputationCompiler(compiler);
+
+ p.get_visited_by(param_cc);
+
+ /* Let's not re-compute the parameters on every iteration. */
+ param_cc.generate_address();
+
+ if (param_cc.has_init())
+ {
+ result.add(param_cc.get_init());
+ }
+
+ param_cc_list.add(param_cc);
+
+ params.add(param_cc.get_computation());
+ }
+
+ result.add
+ (
+ MergeLambda.generate
+ (
+ compiler.registers(),
+ compiler.assembler(),
+ lambda_cc.get_computation(),
+ default_a_cc.get_computation(),
+ holder.get_address(),
+ default_b_cc.get_computation(),
+ in_collection_b_cc.get_address(),
+ collection_cc.get_address(),
+ (
+ (tonkadur.fate.v1.lang.type.CollectionType)
+ n.get_collection().get_type()
+ ).is_set(),
+ params
+ )
+ );
+
+ collection_cc.release_registers(result);
+ in_collection_b_cc.release_registers(result);
+ default_a_cc.release_registers(result);
+ default_b_cc.release_registers(result);
+ compiler.registers().release(holder, result);
+
+ for (final ComputationCompiler cc: param_cc_list)
+ {
+ cc.release_registers(result);
+ }
+ }
+
@Override
public void visit_merge
(
@@ -741,6 +892,13 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor
{
/* TODO: handle default values. */
/* This is one dangerous operation to do in-place, so we don't. */
+
+ if (n.get_default_a() == null)
+ {
+ visit_merge_with_defaults(n);
+ return;
+ }
+
final Register holder;
final ComputationCompiler lambda_cc;
final List<Computation> params;
@@ -1547,6 +1705,16 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor
result.add
(
+ Clear.generate
+ (
+ compiler.registers(),
+ compiler.assembler(),
+ collection_cc.get_address()
+ )
+ );
+
+ result.add
+ (
IndexedMapLambda.generate
(
compiler.registers(),
diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/util/MergeLambda.java b/src/core/src/tonkadur/wyrd/v1/compiler/util/MergeLambda.java
index d09f05f..3cbed3d 100644
--- a/src/core/src/tonkadur/wyrd/v1/compiler/util/MergeLambda.java
+++ b/src/core/src/tonkadur/wyrd/v1/compiler/util/MergeLambda.java
@@ -30,7 +30,6 @@ public class MergeLambda
/* Utility Class */
private MergeLambda () {}
- /* Uses Durstenfeld's shuffling algorithm */
public static Instruction generate
(
final RegisterManager registers,
@@ -184,4 +183,187 @@ public class MergeLambda
return assembler.merge(result);
}
+
+ public static Instruction generate
+ (
+ final RegisterManager registers,
+ final InstructionManager assembler,
+ final Computation lambda,
+ final Computation default_a,
+ final Address collection_in_a,
+ final Computation default_b,
+ final Address collection_in_b,
+ final Address collection_out,
+ final boolean to_set,
+ final List<Computation> extra_params
+ )
+ {
+ final List<Instruction> result, while_body;
+ final Register iterator_a, iterator_b;
+ final Register collection_a_size, collection_b_size;
+ final Register storage;
+
+ result = new ArrayList<Instruction>();
+ while_body = new ArrayList<Instruction>();
+
+ iterator_a = registers.reserve(Type.INT, result);
+ iterator_b = registers.reserve(Type.INT, result);
+
+ collection_a_size = registers.reserve(Type.INT, result);
+ collection_b_size = registers.reserve(Type.INT, result);
+
+ storage =
+ registers.reserve
+ (
+ ((MapType) collection_out.get_target_type()).get_member_type(),
+ result
+ );
+
+ result.add(new SetValue(iterator_a.get_address(), Constant.ZERO));
+ result.add(new SetValue(iterator_b.get_address(), Constant.ZERO));
+
+ result.add
+ (
+ new SetValue
+ (
+ collection_a_size.get_address(),
+ new Size(collection_in_a)
+ )
+ );
+
+ result.add
+ (
+ new SetValue
+ (
+ collection_b_size.get_address(),
+ new Size(collection_in_b)
+ )
+ );
+
+ extra_params.add
+ (
+ 0,
+ new IfElseComputation
+ (
+ Operation.less_than
+ (
+ iterator_b.get_value(),
+ collection_b_size.get_value()
+ ),
+ new ValueOf
+ (
+ new RelativeAddress
+ (
+ collection_in_b,
+ new Cast(iterator_b.get_value(), Type.STRING),
+ (
+ (MapType) collection_in_b.get_target_type()
+ ).get_member_type()
+ )
+ ),
+ default_b
+ )
+ );
+
+ extra_params.add
+ (
+ 0,
+ new IfElseComputation
+ (
+ Operation.less_than
+ (
+ iterator_a.get_value(),
+ collection_a_size.get_value()
+ ),
+ new ValueOf
+ (
+ new RelativeAddress
+ (
+ collection_in_a,
+ new Cast(iterator_a.get_value(), Type.STRING),
+ (
+ (MapType) collection_in_a.get_target_type()
+ ).get_member_type()
+ )
+ ),
+ default_a
+ )
+ );
+
+ while_body.add
+ (
+ LambdaEvaluation.generate
+ (
+ registers,
+ assembler,
+ lambda,
+ /* Can't put it in the target collection directly, since that may
+ * be a set.
+ */
+ storage.get_address(),
+ extra_params
+ )
+ );
+
+ while_body.add
+ (
+ AddElement.generate
+ (
+ registers,
+ assembler,
+ storage.get_value(),
+ collection_out,
+ to_set
+ )
+ );
+
+ while_body.add
+ (
+ new SetValue
+ (
+ iterator_a.get_address(),
+ Operation.plus(iterator_a.get_value(), Constant.ONE)
+ )
+ );
+
+ while_body.add
+ (
+ new SetValue
+ (
+ iterator_b.get_address(),
+ Operation.plus(iterator_b.get_value(), Constant.ONE)
+ )
+ );
+
+ result.add
+ (
+ While.generate
+ (
+ registers,
+ assembler,
+ Operation.or
+ (
+ Operation.less_than
+ (
+ iterator_a.get_value(),
+ collection_a_size.get_value()
+ ),
+ Operation.less_than
+ (
+ iterator_b.get_value(),
+ collection_b_size.get_value()
+ )
+ ),
+ assembler.merge(while_body)
+ )
+ );
+
+ registers.release(iterator_a, result);
+ registers.release(iterator_b, result);
+ registers.release(collection_a_size, result);
+ registers.release(collection_b_size, result);
+ registers.release(storage, result);
+
+ return assembler.merge(result);
+ }
}