summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/ComputationCompiler.java107
-rw-r--r--src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/InstructionCompiler.java236
-rw-r--r--src/core/src/tonkadur/wyrd/v1/compiler/util/Fold.java132
3 files changed, 256 insertions, 219 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 0712319..2e595cd 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
@@ -22,9 +22,11 @@ import tonkadur.wyrd.v1.lang.instruction.SetValue;
import tonkadur.wyrd.v1.lang.instruction.Initialize;
import tonkadur.wyrd.v1.lang.instruction.SetPC;
+import tonkadur.wyrd.v1.compiler.util.AddElement;
import tonkadur.wyrd.v1.compiler.util.BinarySearch;
import tonkadur.wyrd.v1.compiler.util.IfElse;
import tonkadur.wyrd.v1.compiler.util.If;
+import tonkadur.wyrd.v1.compiler.util.Fold;
import tonkadur.wyrd.v1.compiler.util.Shuffle;
import tonkadur.wyrd.v1.compiler.util.RemoveAt;
import tonkadur.wyrd.v1.compiler.util.InsertAt;
@@ -1955,7 +1957,48 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor
)
throws Throwable
{
- /* TODO */
+ final ComputationCompiler address_compiler, element_compiler;
+ final Register result;
+
+ result = reserve(TypeCompiler.compile(compiler, n.get_type()));
+
+ result_as_address = result.get_address();
+ result_as_computation = result.get_value();
+
+ address_compiler = new ComputationCompiler(compiler);
+ element_compiler = new ComputationCompiler(compiler);
+
+ n.get_collection().get_visited_by(address_compiler);
+
+ if (address_compiler.has_init())
+ {
+ init_instructions.add(address_compiler.get_init());
+ }
+
+ init_instructions.add
+ (
+ new SetValue(result_as_address, address_compiler.get_computation())
+ );
+
+ address_compiler.release_registers(init_instructions);
+
+ n.get_element().get_visited_by(element_compiler);
+ assimilate(element_compiler);
+
+ init_instructions.add
+ (
+ AddElement.generate
+ (
+ compiler.registers(),
+ compiler.assembler(),
+ element_compiler.get_computation(),
+ result_as_address,
+ (
+ (tonkadur.fate.v1.lang.type.CollectionType)
+ n.get_collection().get_type()
+ ).is_set()
+ )
+ );
}
@Override
@@ -1994,18 +2037,10 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor
n.get_index().get_visited_by(index_compiler);
index_compiler.generate_address();
-
- if (index_compiler.has_init())
- {
- init_instructions.add(index_compiler.get_init());
- }
+ assimilate(index_compiler);
n.get_element().get_visited_by(element_compiler);
-
- if (element_compiler.has_init())
- {
- init_instructions.add(element_compiler.get_init());
- }
+ assimilate(element_compiler);
collection_size = reserve(Type.INT);
index = reserve(Type.INT);
@@ -2068,7 +2103,54 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor
)
throws Throwable
{
- /* TODO */
+ final ComputationCompiler lambda_cc, in_collection_cc, default_cc;
+ final Register result;
+
+ result = reserve(TypeCompiler.compile(compiler, n.get_type()));
+
+ result_as_address = result.get_address();
+ result_as_computation = result.get_value();
+
+ default_cc = new ComputationCompiler(compiler);
+
+ n.get_default().get_visited_by(default_cc);
+
+ if (default_cc.has_init())
+ {
+ init_instructions.add(default_cc.get_init());
+ }
+
+ init_instructions.add
+ (
+ new SetValue(result_as_address, default_cc.get_computation())
+ );
+
+ default_cc.release_registers(init_instructions());
+
+ 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);
+
+ assimilate(in_collection_cc);
+
+ init_instructions.add
+ (
+ Fold.generate
+ (
+ compiler.registers(),
+ compiler.assembler(),
+ lambda_cc.get_computation(),
+ result_as_address,
+ in_collection_cc.get_address(),
+ n.is_foldl()
+ )
+ );
}
@Override
@@ -2113,7 +2195,6 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor
).is_set()
)
);
-
}
@Override
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 5d46b79..931a8ca 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
@@ -41,6 +41,7 @@ import tonkadur.wyrd.v1.lang.instruction.ResolveChoices;
import tonkadur.wyrd.v1.lang.instruction.SetPC;
import tonkadur.wyrd.v1.lang.instruction.SetValue;
+import tonkadur.wyrd.v1.compiler.util.AddElement;
import tonkadur.wyrd.v1.compiler.util.BinarySearch;
import tonkadur.wyrd.v1.compiler.util.InsertAt;
import tonkadur.wyrd.v1.compiler.util.If;
@@ -74,188 +75,6 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor
return compiler.assembler().merge(result);
}
- protected void add_element_to_set
- (
- final tonkadur.fate.v1.lang.instruction.AddElement ae
- )
- throws Throwable
- {
- /*
- * Fate:
- * (add_element element collection)
- *
- * Wyrd:
- * (declare_variable local <element.type> .anon0)
- * (set .anon0 element)
- * (declare_variable local boolean .found)
- * <binary_search .anon0 collection .found .index>
- * (ifelse (var .found)
- * (nop)
- * <insert_at ...>
- * )
- */
- final ComputationCompiler element_compiler, address_compiler;
- final Address element, collection;
- final Register collection_size, element_found, element_index;
- final Type element_type;
-
- element_compiler = new ComputationCompiler(compiler);
- ae.get_element().get_visited_by(element_compiler);
-
- element_compiler.generate_address();
-
- if (element_compiler.has_init())
- {
- result.add(element_compiler.get_init());
- }
-
- element_type = element_compiler.get_computation().get_type();
- element = element_compiler.get_address();
-
- address_compiler = new ComputationCompiler(compiler);
- ae.get_collection().get_visited_by(address_compiler);
-
- if (address_compiler.has_init())
- {
- result.add(address_compiler.get_init());
- }
-
- collection = address_compiler.get_address();
-
- element_found = compiler.registers().reserve(Type.BOOL, result);
- element_index = compiler.registers().reserve(Type.INT, result);
- collection_size = compiler.registers().reserve(Type.INT, result);
-
- result.add
- (
- new SetValue(collection_size.get_address(), new Size(collection))
- );
-
- result.add
- (
- BinarySearch.generate
- (
- compiler.registers(),
- compiler.assembler(),
- new ValueOf(element),
- collection_size.get_value(),
- collection,
- element_found.get_address(),
- element_index.get_address()
- )
- );
-
- result.add
- (
- If.generate
- (
- compiler.registers(),
- compiler.assembler(),
- Operation.not(element_found.get_value()),
- InsertAt.generate
- (
- compiler.registers(),
- compiler.assembler(),
- element_index.get_address(),
- new ValueOf(element),
- collection_size.get_value(),
- collection
- )
- )
- );
-
- compiler.registers().release(element_found, result);
- compiler.registers().release(element_index, result);
- compiler.registers().release(collection_size, result);
-
- element_compiler.release_registers(result);
- address_compiler.release_registers(result);
- }
-
- protected void add_element_to_list
- (
- final tonkadur.fate.v1.lang.instruction.AddElement ae
- )
- throws Throwable
- {
- /*
- * Fate:
- * (add_element element collection)
- *
- * Wyrd:
- * (set
- * (relative_address collection ( (cast int string (size collection)) ))
- * (element)
- * )
- */
- final Address collection_as_address;
- final ComputationCompiler element_compiler, address_compiler;
-
- element_compiler = new ComputationCompiler(compiler);
-
- ae.get_element().get_visited_by(element_compiler);
-
- address_compiler = new ComputationCompiler(compiler);
-
- ae.get_collection().get_visited_by(address_compiler);
-
-
- if (address_compiler.has_init())
- {
- result.add(address_compiler.get_init());
- }
-
- if (element_compiler.has_init())
- {
- result.add(element_compiler.get_init());
- }
-
- collection_as_address = address_compiler.get_address();
-
- result.add
- (
- new Initialize
- (
- new RelativeAddress
- (
- collection_as_address,
- new Cast
- (
- new Size(collection_as_address),
- Type.STRING
- ),
- element_compiler.get_computation().get_type()
- ),
- element_compiler.get_computation().get_type()
- )
- );
-
- result.add
- (
- new SetValue
- (
- new RelativeAddress
- (
- collection_as_address,
- new Cast
- (
- Operation.minus
- (
- new Size(collection_as_address),
- Constant.ONE
- ),
- Type.STRING
- ),
- element_compiler.get_computation().get_type()
- ),
- element_compiler.get_computation()
- )
- );
-
- address_compiler.release_registers(result);
- element_compiler.release_registers(result);
- }
-
@Override
public void visit_local_variable
(
@@ -400,41 +219,46 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor
@Override
public void visit_add_element
(
- final tonkadur.fate.v1.lang.instruction.AddElement ae
+ final tonkadur.fate.v1.lang.instruction.AddElement n
)
throws Throwable
{
- final tonkadur.fate.v1.lang.type.Type collection_type;
- final tonkadur.fate.v1.lang.type.CollectionType collection_true_type;
+ final ComputationCompiler address_compiler, element_compiler;
- collection_type = ae.get_collection().get_type();
+ address_compiler = new ComputationCompiler(compiler);
+ element_compiler = new ComputationCompiler(compiler);
- if
- (
- !(collection_type instanceof tonkadur.fate.v1.lang.type.CollectionType)
- )
+ n.get_collection().get_visited_by(address_compiler);
+
+ if (address_compiler.has_init())
{
- System.err.println
- (
- "[P] (add_element item collection), but this is not a collection: "
- + ae.get_collection()
- + ". It's a "
- + collection_type.get_name()
- + "."
- );
+ result.add(address_compiler.get_init());
}
- collection_true_type =
- (tonkadur.fate.v1.lang.type.CollectionType) collection_type;
+ n.get_element().get_visited_by(element_compiler);
- if (collection_true_type.is_set())
- {
- add_element_to_set(ae);
- }
- else
+ if (element_compiler.has_init())
{
- add_element_to_list(ae);
+ result.add(element_compiler.get_init());
}
+
+ result.add
+ (
+ AddElement.generate
+ (
+ compiler.registers(),
+ compiler.assembler(),
+ element_compiler.get_computation(),
+ address_compiler.get_address(),
+ (
+ (tonkadur.fate.v1.lang.type.CollectionType)
+ n.get_collection().get_type()
+ ).is_set()
+ )
+ );
+
+ element_compiler.release_registers(result);
+ address_compiler.release_registers(result);
}
@Override
diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/util/Fold.java b/src/core/src/tonkadur/wyrd/v1/compiler/util/Fold.java
new file mode 100644
index 0000000..1596dff
--- /dev/null
+++ b/src/core/src/tonkadur/wyrd/v1/compiler/util/Fold.java
@@ -0,0 +1,132 @@
+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 Fold
+{
+ /* Utility Class */
+ private Fold () {}
+
+ /* Uses Durstenfeld's shuffling algorithm */
+ public static Instruction generate
+ (
+ final RegisterManager registers,
+ final InstructionManager assembler,
+ final Computation lambda,
+ final Address storage_address,
+ final Address collection_in,
+ final boolean is_foldl
+ )
+ {
+ final List<Computation> params;
+ final List<Instruction> result, while_body;
+ final Register iterator, collection_in_size;
+ final Computation start_point, end_point, condition, increment;
+
+ params = new ArrayList<Computation>();
+ result = new ArrayList<Instruction>();
+ while_body = new ArrayList<Instruction>();
+
+ iterator = registers.reserve(Type.INT, result);
+ collection_in_size = registers.reserve(Type.INT, result);
+
+ if (is_foldl)
+ {
+ end_point = collection_in_size.get_value();
+ start_point = Constant.ZERO;
+ condition = Operation.less_than(iterator.get_value(), end_point);
+ increment = Operation.plus(iterator.get_value(), Constant.ONE);
+ }
+ else
+ {
+ end_point = Constant.ZERO;
+ start_point =
+ Operation.minus(collection_in_size.get_value(), Constant.ONE);
+ condition = Operation.greater_equal_than(iterator.get_value(), end_point);
+ increment = Operation.minus(iterator.get_value(), Constant.ONE);
+ }
+
+
+ result.add
+ (
+ new SetValue
+ (
+ collection_in_size.get_address(),
+ new Size(collection_in)
+ )
+ );
+
+ result.add(new SetValue(iterator.get_address(), start_point));
+
+ params.add(new ValueOf(storage_address));
+ params.add
+ (
+ new ValueOf
+ (
+ new RelativeAddress
+ (
+ collection_in,
+ new Cast(iterator.get_value(), Type.STRING),
+ (
+ (MapType) collection_in.get_target_type()
+ ).get_member_type()
+ )
+ )
+ );
+
+ while_body.add
+ (
+ LambdaEvaluation.generate
+ (
+ registers,
+ assembler,
+ lambda,
+ /* Can't put it in the target collection directly, since that may
+ * be a set.
+ */
+ storage_address,
+ params
+ )
+ );
+
+ while_body.add(new SetValue(iterator.get_address(), increment));
+
+ result.add
+ (
+ While.generate
+ (
+ registers,
+ assembler,
+ condition,
+ assembler.merge(while_body)
+ )
+ );
+
+ registers.release(iterator, result);
+ registers.release(collection_in_size, result);
+
+ return assembler.merge(result);
+ }
+}