| summaryrefslogtreecommitdiff |
diff options
7 files changed, 999 insertions, 51 deletions
diff --git a/data/unit-testing/merge.fate b/data/unit-testing/merge.fate index 13bdf83..e173ac2 100644 --- a/data/unit-testing/merge.fate +++ b/data/unit-testing/merge.fate @@ -11,7 +11,11 @@ ;;; BASIC TEST 0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (global (list int) li0) +(global (list int) li0oa) +(global (list int) li0ob) (global (list int) li1) +(global (list int) li1oa) +(global (list int) li1ob) (set li0 (merge_to_list @@ -27,7 +31,37 @@ ) ) +(set li0oa + (merge_to_list + (lambda + ( + (int a) + (int b) + ) + (- a b) + ) + (range 10 70 1) + (range 0 60 2) + ) +) + +(set li0ob + (merge_to_list + (lambda + ( + (int a) + (int b) + ) + (- a b) + ) + (range 10 40 1) + (range 0 80 2) + ) +) + (set li1 (range 10 40 1)) +(set li1oa (range 10 60 1)) +(set li1ob (range 10 40 1)) (merge! (lambda @@ -41,18 +75,54 @@ (range 0 60 2) ) +(merge! + (lambda + ( + (int a) + (int b) + ) + (- a b) + ) + li1oa + (range 0 60 2) +) + +(merge! + (lambda + ( + (int a) + (int b) + ) + (- a b) + ) + li1ob + (range 0 160 2) +) + (assert - (= (var li1) (var li0)) + (= (var li1) (var li0) (var li0oa) (var li0ob) (var li1oa) (var li1ob)) [FAILED] (var test_name) Equality test 0. ) (for (set i 0) (=< i 30) (set i (+ i 1)) (assert - (= (access li1 i) (access li0 i) (- (+ 10 i) (* 2 i))) + (= + (- (+ 10 i) (* 2 i)) + (access li0 i) + (access li0oa i) + (access li0ob i) + (access li1 i) + (access li1oa i) + (access li1ob i) + ) [FAILED] (var test_name) Basic test 0, index (var i), values: + Expected: (- (+ 10 i) (* 2 i)); li0: (access li0 i); + li0oa: (access li0oa i); + li0ob: (access li0ob i); li1: (access li1 i); - Expected: (- (+ 10 i) (* 2 i)) + li1oa: (access li1oa i); + li1ob: (access li1ob i) ) ) @@ -60,7 +130,11 @@ ;;; BASIC TEST 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (global (set int) si0) +(global (set int) si0oa) +(global (set int) si0ob) (global (set int) si1) +(global (set int) si1oa) +(global (set int) si1ob) (set si0 (merge_to_set @@ -76,7 +150,37 @@ ) ) +(set si0oa + (merge_to_set + (lambda + ( + (int a) + (int b) + ) + (- a b) + ) + (range 10 70 1) + (range 0 60 2) + ) +) + +(set si0ob + (merge_to_set + (lambda + ( + (int a) + (int b) + ) + (- a b) + ) + (range 10 40 1) + (range 0 80 2) + ) +) + (add_all! (range 10 40 1) si1) +(add_all! (range 10 60 1) si1oa) +(add_all! (range 10 40 1) si1ob) (merge! (lambda @@ -90,8 +194,32 @@ (range 0 60 2) ) +(merge! + (lambda + ( + (int a) + (int b) + ) + (- a b) + ) + si1oa + (range 0 60 2) +) + +(merge! + (lambda + ( + (int a) + (int b) + ) + (- a b) + ) + si1ob + (range 0 80 2) +) + (assert - (= (var si1) (var si0)) + (= (var si0) (var si0oa) (var si0ob) (var si1) (var si1oa) (var si1ob)) [FAILED] (var test_name) Equality test 1. ) @@ -106,11 +234,23 @@ (set j (- j 1)) ) (assert - (= (access si1 i) (access si0 i) (- (+ 10 j) (* 2 j))) + (= + (- (+ 10 j) (* 2 j)) + (access si0 i) + (access si0oa i) + (access si0ob i) + (access si1 i) + (access si1oa i) + (access si1ob i) + ) [FAILED] (var test_name) Basic test 1, index (var i), values: + Expected: (- (+ 10 j) (* 2 j)); si0: (access si0 i); + si0oa: (access si0oa i); + si0ob: (access si0ob i); si1: (access si1 i); - Expected: (- (+ 10 j) (* 2 j)) + si1oa: (access si1oa i); + si1ob: (access si1ob i); ) ) @@ -118,7 +258,11 @@ ;;; BASIC TEST 2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (global (set int) si2) +(global (set int) si2oa) +(global (set int) si2ob) (global (set int) si3) +(global (set int) si3oa) +(global (set int) si3ob) (set si2 (merge_to_set @@ -136,7 +280,41 @@ ) ) +(set si2oa + (merge_to_set + (lambda + ( + (int a) + (int b) + (int mod) + ) + (* (- a b) mod) + ) + (range 10 80 1) + (range 0 60 2) + -1 + ) +) + +(set si2ob + (merge_to_set + (lambda + ( + (int a) + (int b) + (int mod) + ) + (* (- a b) mod) + ) + (range 10 40 1) + (range 0 80 2) + -1 + ) +) + (add_all! (range 10 40 1) si3) +(add_all! (range 10 80 1) si3oa) +(add_all! (range 10 40 1) si3ob) (merge! (lambda @@ -152,62 +330,109 @@ -1 ) +(merge! + (lambda + ( + (int a) + (int b) + (int mod) + ) + (* (- a b) mod) + ) + si3oa + (range 0 60 2) + -1 +) + +(merge! + (lambda + ( + (int a) + (int b) + (int mod) + ) + (* (- a b) mod) + ) + si3ob + (range 0 90 2) + -1 +) + (assert - (= (var si3) (var si2)) - [FAILED] (var test_name) Equality test 0. + (= (var si2) (var si2oa) (var si2ob) (var si3) (var si3oa) (var si3ob)) + [FAILED] (var test_name) Equality test 2. ) (for - ( - (set i 0) - (set j 30) - ) + (set i 0) (=< i 30) - ( - (set i (+ i 1)) - (set j (- j 1)) - ) + (set i (+ i 1)) (assert - (= (access si3 i) (access si2 i) (* (- (+ 10 i) (* 2 i)) -1)) + (= + (* (- (+ 10 i) (* 2 i)) -1) + (access si2 i) + (access si2oa i) + (access si2ob i) + (access si3 i) + (access si3oa i) + (access si3ob i) + ) [FAILED] (var test_name) Basic test 2, index (var i), values: + Expected: (* (- (+ 10 i) (* 2 i)) -1); si2: (access si2 i); + si2oa: (access si2oa i); + si2ob: (access si2ob i); si3: (access si3 i); - Expected: (* (- (+ 10 i) (* 2 i)) -1) + si3oa: (access si3oa i); + si3ob: (access si3ob i) ) ) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; INDEXED TEST 0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; TODO +(global (list int) ili0) +(global (list int) ili0oa) +(global (list int) ili0ob) +(global (list int) ili1) +(global (list int) ili1oa) +(global (list int) ili1ob) + + +;; Why have the index twice? It's not useful when you don't have the possibility +;; of these indices being different. +(set ili0 + (indexed_merge_to_list + (lambda + ( + (int i_a) + (int a) + (int i_b) + (int b) + ) + (- a b) + ) + (range 10 40 1) + (range 0 60 2) + ) +) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; BASIC TEST 3 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; INDEXED TEST 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; TODO +(global (set int) isi0) +(global (set int) isi0oa) +(global (set int) isi0ob) +(global (set int) isi1) +(global (set int) isi1oa) +(global (set int) isi1ob) -;;(clear li0) -;;(clear li1) -;; -;;(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 -;;) -;; -;;(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) -;; ) -;;) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; DEFAULT_VALUES TEST 0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; TODO [COMPLETED] (var test_name) diff --git a/src/core/src/tonkadur/fate/v1/lang/computation/IndexedMergeComputation.java b/src/core/src/tonkadur/fate/v1/lang/computation/IndexedMergeComputation.java index 3a81b53..f9f8ae4 100644 --- a/src/core/src/tonkadur/fate/v1/lang/computation/IndexedMergeComputation.java +++ b/src/core/src/tonkadur/fate/v1/lang/computation/IndexedMergeComputation.java @@ -23,7 +23,9 @@ public class IndexedMergeComputation extends Computation protected final List<Computation> extra_params; protected final Computation lambda_function; protected final Computation collection_in_a; + protected final Computation default_a; protected final Computation collection_in_b; + protected final Computation default_b; protected final boolean to_set; /***************************************************************************/ @@ -35,7 +37,9 @@ public class IndexedMergeComputation extends Computation final Origin origin, final Computation lambda_function, final Computation collection_in_a, + final Computation default_a, final Computation collection_in_b, + final Computation default_b, final boolean to_set, final List<Computation> extra_params, final Type output_type @@ -45,7 +49,9 @@ public class IndexedMergeComputation extends Computation this.lambda_function = lambda_function; this.collection_in_a = collection_in_a; + this.default_a = default_a; this.collection_in_b = collection_in_b; + this.default_b = default_b; this.to_set = to_set; this.extra_params = extra_params; } @@ -59,7 +65,9 @@ public class IndexedMergeComputation extends Computation final Origin origin, final Computation lambda_function, final Computation collection_in_a, + final Computation default_a, final Computation collection_in_b, + final Computation default_b, final boolean to_set, final List<Computation> extra_params ) @@ -69,8 +77,23 @@ public class IndexedMergeComputation extends Computation types_in = new ArrayList<Type>(); - RecurrentChecks.assert_is_a_collection(collection_in_a); - RecurrentChecks.assert_is_a_collection(collection_in_b); + if (default_a == null) + { + RecurrentChecks.assert_is_a_collection(collection_in_a); + } + else + { + RecurrentChecks.assert_is_a_collection_of(collection_in_a, default_a); + } + + if (default_b == null) + { + RecurrentChecks.assert_is_a_collection(collection_in_b); + } + else + { + RecurrentChecks.assert_is_a_collection_of(collection_in_b, default_b); + } types_in.add(Type.INT); @@ -79,6 +102,15 @@ public class IndexedMergeComputation extends Computation ((CollectionType) collection_in_a.get_type()).get_content_type() ); + if (default_b != null) + { + /* + * Safe-Mode: two indices. + * Unsafe-Mode: only one index, since out-of-bound means stopping. + */ + types_in.add(Type.INT); + } + types_in.add ( ((CollectionType) collection_in_b.get_type()).get_content_type() @@ -97,7 +129,9 @@ public class IndexedMergeComputation extends Computation origin, lambda_function, collection_in_a, + default_a, collection_in_b, + default_b, to_set, extra_params, CollectionType.build @@ -128,11 +162,21 @@ public class IndexedMergeComputation extends Computation return collection_in_a; } + public Computation get_default_a () + { + return default_a; + } + public Computation get_collection_in_b () { return collection_in_b; } + public Computation get_default_b () + { + return default_b; + } + public List<Computation> get_extra_parameters () { return extra_params; @@ -163,7 +207,27 @@ public class IndexedMergeComputation extends Computation sb.append(collection_in_a.toString()); sb.append(" "); + if (default_a == null) + { + sb.append("null"); + } + else + { + sb.append(default_a.toString()); + } + + sb.append(" "); sb.append(collection_in_b.toString()); + sb.append(" "); + + if (default_b == null) + { + sb.append("null"); + } + else + { + sb.append(default_b.toString()); + } for (final Computation c: extra_params) { diff --git a/src/core/src/tonkadur/fate/v1/lang/instruction/IndexedMerge.java b/src/core/src/tonkadur/fate/v1/lang/instruction/IndexedMerge.java index 5fd86ec..96cfefc 100644 --- a/src/core/src/tonkadur/fate/v1/lang/instruction/IndexedMerge.java +++ b/src/core/src/tonkadur/fate/v1/lang/instruction/IndexedMerge.java @@ -23,7 +23,9 @@ public class IndexedMerge extends Instruction protected final List<Computation> extra_params; protected final Computation lambda_function; protected final Reference collection; + protected final Computation default_a; protected final Computation collection_in_b; + protected final Computation default_b; /***************************************************************************/ /**** PROTECTED ************************************************************/ @@ -34,7 +36,9 @@ public class IndexedMerge extends Instruction final Origin origin, final Computation lambda_function, final Reference collection, + final Computation default_a, final Computation collection_in_b, + final Computation default_b, final List<Computation> extra_params ) { @@ -42,7 +46,9 @@ public class IndexedMerge extends Instruction this.lambda_function = lambda_function; this.collection = collection; + this.default_a = default_a; this.collection_in_b = collection_in_b; + this.default_b = default_b; this.extra_params = extra_params; } @@ -55,7 +61,9 @@ public class IndexedMerge extends Instruction final Origin origin, final Computation lambda_function, final Reference collection, + final Computation default_a, final Computation collection_in_b, + final Computation default_b, final List<Computation> extra_params ) throws Throwable @@ -64,8 +72,23 @@ public class IndexedMerge extends Instruction types_in = new ArrayList<Type>(); - RecurrentChecks.assert_is_a_collection(collection); - RecurrentChecks.assert_is_a_collection(collection_in_b); + if (default_a == null) + { + RecurrentChecks.assert_is_a_collection(collection); + } + else + { + RecurrentChecks.assert_is_a_collection_of(collection, default_a); + } + + if (default_b == null) + { + RecurrentChecks.assert_is_a_collection(collection_in_b); + } + else + { + RecurrentChecks.assert_is_a_collection_of(collection_in_b, default_b); + } types_in.add(Type.INT); types_in.add @@ -73,6 +96,11 @@ public class IndexedMerge extends Instruction ((CollectionType) collection.get_type()).get_content_type() ); + if (default_b != null) + { + types_in.add(Type.INT); + } + types_in.add ( ((CollectionType) collection_in_b.get_type()).get_content_type() @@ -96,7 +124,9 @@ public class IndexedMerge extends Instruction origin, lambda_function, collection, + default_a, collection_in_b, + default_b, extra_params ); } @@ -114,11 +144,21 @@ public class IndexedMerge extends Instruction return lambda_function; } + public Computation get_default_a () + { + return default_a; + } + public Computation get_collection_in_b () { return collection_in_b; } + public Computation get_default_b () + { + return default_b; + } + public Reference get_collection () { return collection; @@ -139,9 +179,29 @@ public class IndexedMerge extends Instruction sb.append(lambda_function.toString()); sb.append(" "); sb.append(collection.toString()); + sb.append(" "); + + if (default_a == null) + { + sb.append("null"); + } + else + { + sb.append(default_a.toString()); + } sb.append(" "); sb.append(collection_in_b.toString()); + sb.append(" "); + + if (default_b == null) + { + sb.append("null"); + } + else + { + sb.append(default_b.toString()); + } for (final Computation c: extra_params) { diff --git a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 index 4d791e3..6f84490 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 @@ -1017,7 +1017,9 @@ returns [Instruction result] ), ($fun.result), ($value_reference.result), + null, ($inv1.result), + null, new ArrayList() ); } @@ -1039,7 +1041,9 @@ returns [Instruction result] ), ($fun.result), ($value_reference.result), + null, ($inv1.result), + null, ($value_list.result) ); } @@ -1095,6 +1099,57 @@ returns [Instruction result] ); } + | SAFE_IMP_INDEXED_MERGE_KW + fun=non_text_value WS+ + def0=value WS+ + value_reference WS+ + def1=value WS+ + inv1=non_text_value WS* + R_PAREN + { + $result = + IndexedMerge.build + ( + CONTEXT.get_origin_at + ( + ($SAFE_IMP_INDEXED_MERGE_KW.getLine()), + ($SAFE_IMP_INDEXED_MERGE_KW.getCharPositionInLine()) + ), + ($fun.result), + ($value_reference.result), + ($def0.result), + ($inv1.result), + ($def1.result), + new ArrayList() + ); + } + + | SAFE_IMP_INDEXED_MERGE_KW + fun=non_text_value WS+ + def0=value WS+ + value_reference WS+ + def1=value WS+ + inv1=non_text_value WS+ + value_list WS* + R_PAREN + { + $result = + IndexedMerge.build + ( + CONTEXT.get_origin_at + ( + ($SAFE_IMP_INDEXED_MERGE_KW.getLine()), + ($SAFE_IMP_INDEXED_MERGE_KW.getCharPositionInLine()) + ), + ($fun.result), + ($value_reference.result), + ($def0.result), + ($inv1.result), + ($def1.result), + ($value_list.result) + ); + } + | IMP_SUB_LIST_KW vstart=non_text_value WS+ vend=non_text_value WS+ @@ -4314,7 +4369,9 @@ returns [Computation result] ), ($fun.result), ($inv0.result), + null, ($inv1.result), + null, false, new ArrayList() ); @@ -4337,7 +4394,62 @@ returns [Computation result] ), ($fun.result), ($inv0.result), + null, ($inv1.result), + null, + false, + ($value_list.result) + ); + } + + | SAFE_INDEXED_MERGE_TO_LIST_KW + fun=non_text_value WS+ + def0=value WS+ + inv0=non_text_value WS+ + def1=value WS+ + inv1=non_text_value WS* + R_PAREN + { + $result = + IndexedMergeComputation.build + ( + CONTEXT.get_origin_at + ( + ($SAFE_INDEXED_MERGE_TO_LIST_KW.getLine()), + ($SAFE_INDEXED_MERGE_TO_LIST_KW.getCharPositionInLine()) + ), + ($fun.result), + ($inv0.result), + ($def0.result), + ($inv1.result), + ($def1.result), + false, + new ArrayList() + ); + } + + | SAFE_INDEXED_MERGE_TO_LIST_KW + fun=non_text_value WS+ + def0=value WS+ + inv0=non_text_value WS+ + def1=value WS+ + inv1=non_text_value WS+ + value_list WS* + R_PAREN + { + $result = + IndexedMergeComputation.build + ( + CONTEXT.get_origin_at + ( + ($SAFE_INDEXED_MERGE_TO_LIST_KW.getLine()), + ($SAFE_INDEXED_MERGE_TO_LIST_KW.getCharPositionInLine()) + ), + ($fun.result), + ($inv0.result), + ($def0.result), + ($inv1.result), + ($def1.result), false, ($value_list.result) ); @@ -4461,7 +4573,9 @@ returns [Computation result] ), ($fun.result), ($inv0.result), + null, ($inv1.result), + null, true, new ArrayList() ); @@ -4484,7 +4598,62 @@ returns [Computation result] ), ($fun.result), ($inv0.result), + null, ($inv1.result), + null, + true, + ($value_list.result) + ); + } + + | SAFE_INDEXED_MERGE_TO_SET_KW + fun=non_text_value WS+ + def0=value WS+ + inv0=non_text_value WS+ + def1=value WS+ + inv1=non_text_value WS* + R_PAREN + { + $result = + IndexedMergeComputation.build + ( + CONTEXT.get_origin_at + ( + ($SAFE_INDEXED_MERGE_TO_SET_KW.getLine()), + ($SAFE_INDEXED_MERGE_TO_SET_KW.getCharPositionInLine()) + ), + ($fun.result), + ($inv0.result), + ($def0.result), + ($inv1.result), + ($def1.result), + true, + new ArrayList() + ); + } + + | SAFE_INDEXED_MERGE_TO_SET_KW + fun=non_text_value WS+ + def0=value WS+ + inv0=non_text_value WS+ + def1=value WS+ + inv1=non_text_value WS+ + value_list WS* + R_PAREN + { + $result = + IndexedMergeComputation.build + ( + CONTEXT.get_origin_at + ( + ($SAFE_INDEXED_MERGE_TO_SET_KW.getLine()), + ($SAFE_INDEXED_MERGE_TO_SET_KW.getCharPositionInLine()) + ), + ($fun.result), + ($inv0.result), + ($def0.result), + ($inv1.result), + ($def1.result), true, ($value_list.result) ); 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 9fb288d..2df0868 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 @@ -3024,6 +3024,96 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor ); } + private void visit_indexed_merge_with_defaults + ( + final tonkadur.fate.v1.lang.computation.IndexedMergeComputation 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 + ( + IndexedMergeLambda.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_indexed_merge ( @@ -3031,6 +3121,13 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor ) throws Throwable { + if (n.get_default_a() != null) + { + visit_indexed_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 2f82d3c..36e7b66 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 @@ -1010,6 +1010,147 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor } } + private void visit_indexed_merge_with_defaults + ( + final tonkadur.fate.v1.lang.instruction.IndexedMerge 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 + ( + IndexedMergeLambda.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_indexed_merge ( @@ -1017,6 +1158,12 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor ) throws Throwable { + if (n.get_default_a() != null) + { + visit_indexed_merge_with_defaults(n); + return; + } + /* This is one dangerous operation to do in-place, so we don't. */ final Register holder; final ComputationCompiler lambda_cc; diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/util/IndexedMergeLambda.java b/src/core/src/tonkadur/wyrd/v1/compiler/util/IndexedMergeLambda.java index 3a501e2..e1e4e4f 100644 --- a/src/core/src/tonkadur/wyrd/v1/compiler/util/IndexedMergeLambda.java +++ b/src/core/src/tonkadur/wyrd/v1/compiler/util/IndexedMergeLambda.java @@ -30,7 +30,6 @@ public class IndexedMergeLambda /* Utility Class */ private IndexedMergeLambda () {} - /* Uses Durstenfeld's shuffling algorithm */ public static Instruction generate ( final RegisterManager registers, @@ -187,4 +186,191 @@ public class IndexedMergeLambda 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, iterator_b.get_value()); + + 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 + ) + ); + + extra_params.add(0, iterator_a.get_value()); + + 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); + } } |


