summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2020-11-09 16:38:07 +0100
committerNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2020-11-09 16:38:07 +0100
commit2ec3d993e86f64db38df970dbccfa2eacbc86de4 (patch)
tree62f6c2f1b1535105b661f50d7668c240a9d2aeef /src
parentac0576fac5b64c34bb6bac8275882861308a51a2 (diff)
...
Diffstat (limited to 'src')
-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
3 files changed, 448 insertions, 2 deletions
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);
+ }
}