summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/unit-testing/merge.fate317
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/computation/IndexedMergeComputation.java68
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/instruction/IndexedMerge.java64
-rw-r--r--src/core/src/tonkadur/fate/v1/parser/FateParser.g4169
-rw-r--r--src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/ComputationCompiler.java97
-rw-r--r--src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/InstructionCompiler.java147
-rw-r--r--src/core/src/tonkadur/wyrd/v1/compiler/util/IndexedMergeLambda.java188
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);
+ }
}