summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2020-09-19 16:32:42 +0200
committerNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2020-09-19 16:32:42 +0200
commit23f55690f4e84262230fd684a509f6c8ea436ffe (patch)
treec478c3168aef0868fb9bd46ddaf3f390d62e33a3 /src
parent63b3c43af5d402530a8c10c1f71aa0e7ca3aa06f (diff)
...
Diffstat (limited to 'src')
-rw-r--r--src/core/src/tonkadur/fate/v1/parser/FateParser.g47
-rw-r--r--src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/ComputationCompiler.java99
-rw-r--r--src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/InstructionCompiler.java148
-rw-r--r--src/core/src/tonkadur/wyrd/v1/compiler/util/PartitionLambda.java176
4 files changed, 423 insertions, 7 deletions
diff --git a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4
index f4a3d12..1289a9e 100644
--- a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4
+++ b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4
@@ -1784,7 +1784,6 @@ returns [List<Cons<Computation, Instruction>> result]
@init
{
$result = new ArrayList<Cons<Computation, Instruction>>();
- /* TODO: resolve grammar collisions */
}
:
(
@@ -1929,7 +1928,7 @@ returns [Instruction result]
}
| FOR_EACH_KW
- value_reference WS+ new_reference_name
+ non_text_value WS+ new_reference_name
{
final Map<String, Variable> variable_map;
final Variable new_variable;
@@ -1938,7 +1937,7 @@ returns [Instruction result]
elem_type = Type.ANY;
- collection_type = ($value_reference.result).get_type();
+ collection_type = ($non_text_value.result).get_type();
if (collection_type instanceof CollectionType)
{
@@ -2016,7 +2015,7 @@ returns [Instruction result]
($FOR_EACH_KW.getLine()),
($FOR_EACH_KW.getCharPositionInLine())
),
- ($value_reference.result),
+ ($non_text_value.result),
($new_reference_name.result),
($player_choice_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 487554e..767724a 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
@@ -35,6 +35,7 @@ import tonkadur.wyrd.v1.compiler.util.RemoveElementsOf;
import tonkadur.wyrd.v1.compiler.util.InsertAt;
import tonkadur.wyrd.v1.compiler.util.RemoveAllOf;
import tonkadur.wyrd.v1.compiler.util.IndexedMapLambda;
+import tonkadur.wyrd.v1.compiler.util.PartitionLambda;
import tonkadur.wyrd.v1.compiler.util.MapLambda;
import tonkadur.wyrd.v1.compiler.util.MergeLambda;
import tonkadur.wyrd.v1.compiler.util.RemoveOneOf;
@@ -2804,7 +2805,98 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor
)
throws Throwable
{
- /* TODO */
+ final List<Computation> params;
+ final ComputationCompiler lambda_cc, in_collection_cc;
+ final Address car_addr, cdr_addr;
+ final Register result;
+
+ result = reserve(DictType.WILD);
+
+ 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);
+
+ in_collection_cc = new ComputationCompiler(compiler);
+
+ n.get_collection().get_visited_by(in_collection_cc);
+
+ if (in_collection_cc.has_init())
+ {
+ init_instructions.add(in_collection_cc.get_init());
+ }
+
+ car_addr =
+ new RelativeAddress
+ (
+ result_as_address,
+ new Constant(Type.STRING, "0"),
+ in_collection_cc.get_computation().get_type()
+ );
+
+ init_instructions.add
+ (
+ new SetValue
+ (
+ car_addr,
+ in_collection_cc.get_computation()
+ )
+ );
+
+ cdr_addr =
+ new RelativeAddress
+ (
+ result_as_address,
+ new Constant(Type.STRING, "1"),
+ in_collection_cc.get_computation().get_type()
+ );
+
+ in_collection_cc.release_registers(init_instructions);
+
+ init_instructions.add(new Initialize(cdr_addr));
+
+ init_instructions.add
+ (
+ PartitionLambda.generate
+ (
+ compiler.registers(),
+ compiler.assembler(),
+ lambda_cc.get_computation(),
+ car_addr,
+ cdr_addr,
+ (
+ (tonkadur.fate.v1.lang.type.CollectionType)
+ n.get_collection().get_type()
+ ).is_set(),
+ params
+ )
+ );
}
@Override
@@ -2870,6 +2962,11 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor
init_instructions.add(in_collection_cc.get_init());
}
+ init_instructions.add
+ (
+ new SetValue(result_as_address, in_collection_cc.get_computation())
+ );
+
in_collection_cc.release_registers(init_instructions);
init_instructions.add
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 a0a5810..9cd5d43 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
@@ -55,6 +55,7 @@ import tonkadur.wyrd.v1.compiler.util.Shuffle;
import tonkadur.wyrd.v1.compiler.util.Clear;
import tonkadur.wyrd.v1.compiler.util.MapLambda;
import tonkadur.wyrd.v1.compiler.util.MergeLambda;
+import tonkadur.wyrd.v1.compiler.util.PartitionLambda;
import tonkadur.wyrd.v1.compiler.util.IndexedMapLambda;
import tonkadur.wyrd.v1.compiler.util.IterativeSearch;
import tonkadur.wyrd.v1.compiler.util.RemoveAllOf;
@@ -749,7 +750,90 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor
)
throws Throwable
{
- /* TODO */
+ final List<Computation> params;
+ final List<ComputationCompiler> param_cc_list;
+ final ComputationCompiler lambda_cc, collection_in_cc, collection_out_cc;
+
+ params = new ArrayList<Computation>();
+ param_cc_list = new ArrayList<ComputationCompiler>();
+
+ 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());
+ }
+
+ lambda_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_in_cc = new ComputationCompiler(compiler);
+
+ n.get_collection_in().get_visited_by(collection_in_cc);
+
+ if (collection_in_cc.has_init())
+ {
+ result.add(collection_in_cc.get_init());
+ }
+
+ collection_out_cc = new ComputationCompiler(compiler);
+
+ n.get_collection_out().get_visited_by(collection_out_cc);
+
+ if (collection_out_cc.has_init())
+ {
+ result.add(collection_out_cc.get_init());
+ }
+
+ result.add
+ (
+ PartitionLambda.generate
+ (
+ compiler.registers(),
+ compiler.assembler(),
+ lambda_cc.get_computation(),
+ collection_in_cc.get_address(),
+ collection_out_cc.get_address(),
+ (
+ (tonkadur.fate.v1.lang.type.CollectionType)
+ n.get_collection_out().get_type()
+ ).is_set(),
+ params
+ )
+ );
+
+ lambda_cc.release_registers(result);
+ collection_in_cc.release_registers(result);
+ collection_out_cc.release_registers(result);
+
+ for (final ComputationCompiler cc: param_cc_list)
+ {
+ cc.release_registers(result);
+ }
}
@Override
@@ -769,7 +853,67 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor
)
throws Throwable
{
- /* TODO */
+ final ComputationCompiler address_compiler, element_compiler;
+ final Register collection_size, index;
+
+ address_compiler = new ComputationCompiler(compiler);
+ element_compiler = new ComputationCompiler(compiler);
+
+ n.get_collection().get_visited_by(address_compiler);
+
+ if (address_compiler.has_init())
+ {
+ result.add(address_compiler.get_init());
+ }
+
+ address_compiler.release_registers(result);
+
+ n.get_element().get_visited_by(element_compiler);
+
+ if (element_compiler.has_init())
+ {
+ result.add(element_compiler.get_init());
+ }
+
+ collection_size = compiler.registers().reserve(Type.INT, result);
+ index = compiler.registers().reserve(Type.INT, result);
+
+ result.add
+ (
+ new SetValue
+ (
+ collection_size.get_address(),
+ new Size(address_compiler.get_address())
+ )
+ );
+
+ result.add
+ (
+ new SetValue
+ (
+ index.get_address(),
+ (n.is_from_left() ? Constant.ZERO : collection_size.get_value())
+ )
+ );
+
+ result.add
+ (
+ InsertAt.generate
+ (
+ compiler.registers(),
+ compiler.assembler(),
+ index.get_address(),
+ element_compiler.get_computation(),
+ collection_size.get_value(),
+ address_compiler.get_address()
+ )
+ );
+
+ address_compiler.release_registers(result);
+ element_compiler.release_registers(result);
+
+ compiler.registers().release(collection_size, result);
+ compiler.registers().release(index, result);
}
@Override
diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/util/PartitionLambda.java b/src/core/src/tonkadur/wyrd/v1/compiler/util/PartitionLambda.java
new file mode 100644
index 0000000..706aee2
--- /dev/null
+++ b/src/core/src/tonkadur/wyrd/v1/compiler/util/PartitionLambda.java
@@ -0,0 +1,176 @@
+package tonkadur.wyrd.v1.compiler.util;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Collections;
+
+import tonkadur.wyrd.v1.lang.Register;
+
+import tonkadur.wyrd.v1.lang.type.Type;
+import tonkadur.wyrd.v1.lang.type.MapType;
+
+import tonkadur.wyrd.v1.lang.meta.Instruction;
+import tonkadur.wyrd.v1.lang.meta.Computation;
+
+import tonkadur.wyrd.v1.lang.computation.Cast;
+import tonkadur.wyrd.v1.lang.computation.Constant;
+import tonkadur.wyrd.v1.lang.computation.Operation;
+import tonkadur.wyrd.v1.lang.computation.Address;
+import tonkadur.wyrd.v1.lang.computation.RelativeAddress;
+import tonkadur.wyrd.v1.lang.computation.ValueOf;
+import tonkadur.wyrd.v1.lang.computation.Size;
+
+import tonkadur.wyrd.v1.lang.instruction.SetValue;
+
+import tonkadur.wyrd.v1.compiler.util.registers.RegisterManager;
+
+public class PartitionLambda
+{
+ /* Utility Class */
+ private PartitionLambda () {}
+
+ /* Uses Durstenfeld's shuffling algorithm */
+ public static Instruction generate
+ (
+ final RegisterManager registers,
+ final InstructionManager assembler,
+ final Computation lambda,
+ final Address collection_in,
+ final Address collection_out,
+ final boolean to_set,
+ final List<Computation> extra_params
+ )
+ {
+ final List<Instruction> result, while_body, remove_instructions;
+ final Register iterator, index_storage, collection_size, storage;
+ final Computation iterator_target;
+
+ result = new ArrayList<Instruction>();
+ while_body = new ArrayList<Instruction>();
+ remove_instructions = new ArrayList<Instruction>();
+
+ iterator = registers.reserve(Type.INT, result);
+ index_storage = registers.reserve(Type.INT, result);
+ collection_size = registers.reserve(Type.INT, result);
+ storage = registers.reserve(Type.BOOL, result);
+
+ iterator_target =
+ new ValueOf
+ (
+ new RelativeAddress
+ (
+ collection_in,
+ new Cast(iterator.get_value(), Type.STRING),
+ ((MapType) collection_in.get_target_type()).get_member_type()
+ )
+ );
+
+ result.add(new SetValue(iterator.get_address(), Constant.ZERO));
+ result.add
+ (
+ new SetValue(collection_size.get_address(), new Size(collection_in))
+ );
+
+ extra_params.add(0, iterator_target);
+
+ remove_instructions.add
+ (
+ AddElement.generate
+ (
+ registers,
+ assembler,
+ iterator_target,
+ collection_out,
+ to_set
+ )
+ );
+
+ remove_instructions.add
+ (
+ new SetValue(index_storage.get_address(), iterator.get_value())
+ );
+
+ remove_instructions.add
+ (
+ RemoveAt.generate
+ (
+ registers,
+ assembler,
+ index_storage.get_address(),
+ collection_size.get_value(),
+ collection_in
+ )
+ );
+
+ remove_instructions.add
+ (
+ new SetValue
+ (
+ collection_size.get_address(),
+ Operation.minus(collection_size.get_value(), Constant.ONE)
+ )
+ );
+
+ 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
+ (
+ IfElse.generate
+ (
+ registers,
+ assembler,
+ Operation.not(storage.get_value()),
+ assembler.merge(remove_instructions),
+ new SetValue
+ (
+ iterator.get_address(),
+ Operation.plus(iterator.get_value(), Constant.ONE)
+ )
+ )
+ );
+
+ while_body.add
+ (
+ new SetValue
+ (
+ iterator.get_address(),
+ Operation.plus(iterator.get_value(), Constant.ONE)
+ )
+ );
+
+ result.add
+ (
+ While.generate
+ (
+ registers,
+ assembler,
+ Operation.less_than
+ (
+ iterator.get_value(),
+ collection_size.get_value()
+ ),
+ assembler.merge(while_body)
+ )
+ );
+
+ registers.release(iterator, result);
+ registers.release(index_storage, result);
+ registers.release(collection_size, result);
+ registers.release(storage, result);
+
+ return assembler.merge(result);
+ }
+}