summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/computation/Default.java49
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/computation/New.java1
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/meta/ComputationVisitor.java3
-rw-r--r--src/core/src/tonkadur/fate/v1/parser/FateLexer.g41
-rw-r--r--src/core/src/tonkadur/fate/v1/parser/FateParser.g414
-rw-r--r--src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/ComputationCompiler.java98
-rw-r--r--src/core/src/tonkadur/wyrd/v1/compiler/util/AddElementsOf.java111
-rw-r--r--src/core/src/tonkadur/wyrd/v1/compiler/util/FilterLambda.java162
8 files changed, 436 insertions, 3 deletions
diff --git a/src/core/src/tonkadur/fate/v1/lang/computation/Default.java b/src/core/src/tonkadur/fate/v1/lang/computation/Default.java
new file mode 100644
index 0000000..5315b25
--- /dev/null
+++ b/src/core/src/tonkadur/fate/v1/lang/computation/Default.java
@@ -0,0 +1,49 @@
+package tonkadur.fate.v1.lang.computation;
+
+import tonkadur.parser.Origin;
+
+import tonkadur.fate.v1.lang.type.PointerType;
+import tonkadur.fate.v1.lang.type.Type;
+
+import tonkadur.fate.v1.lang.meta.ComputationVisitor;
+import tonkadur.fate.v1.lang.meta.Computation;
+
+public class Default extends Computation
+{
+ /***************************************************************************/
+ /**** MEMBERS **************************************************************/
+ /***************************************************************************/
+
+ /***************************************************************************/
+ /**** PROTECTED ************************************************************/
+ /***************************************************************************/
+ /**** Constructors *********************************************************/
+ public Default (final Origin origin, final Type t)
+ {
+ super(origin, t);
+ }
+
+ /***************************************************************************/
+ /**** PUBLIC ***************************************************************/
+ /***************************************************************************/
+ /**** Accessors ************************************************************/
+ @Override
+ public void get_visited_by (final ComputationVisitor cv)
+ throws Throwable
+ {
+ cv.visit_default(this);
+ }
+
+ /**** Misc. ****************************************************************/
+ @Override
+ public String toString ()
+ {
+ final StringBuilder sb = new StringBuilder();
+
+ sb.append("(Default ");
+ sb.append(type.get_name());
+ sb.append(") ");
+
+ return sb.toString();
+ }
+}
diff --git a/src/core/src/tonkadur/fate/v1/lang/computation/New.java b/src/core/src/tonkadur/fate/v1/lang/computation/New.java
index 4f036af..000d74a 100644
--- a/src/core/src/tonkadur/fate/v1/lang/computation/New.java
+++ b/src/core/src/tonkadur/fate/v1/lang/computation/New.java
@@ -47,7 +47,6 @@ public class New extends Computation
{
final StringBuilder sb = new StringBuilder();
- sb.append(origin.toString());
sb.append("(New ");
sb.append(target_type.get_name());
sb.append(") ");
diff --git a/src/core/src/tonkadur/fate/v1/lang/meta/ComputationVisitor.java b/src/core/src/tonkadur/fate/v1/lang/meta/ComputationVisitor.java
index 1042abc..fd1ed34 100644
--- a/src/core/src/tonkadur/fate/v1/lang/meta/ComputationVisitor.java
+++ b/src/core/src/tonkadur/fate/v1/lang/meta/ComputationVisitor.java
@@ -22,6 +22,9 @@ public interface ComputationVisitor
public void visit_fold (final Fold n)
throws Throwable;
+ public void visit_default (final Default n)
+ throws Throwable;
+
public void visit_cond_value (final CondValue n)
throws Throwable;
diff --git a/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 b/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4
index 91ce261..b8d0bc7 100644
--- a/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4
+++ b/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4
@@ -41,6 +41,7 @@ DECLARE_EVENT_TYPE_KW: L_PAREN ('declare'|'define'|'def')US'event'(US'type')? SE
DECLARE_TEXT_EFFECT_KW: L_PAREN ('declare'|'define'|'def')US'text'US'effect' SEP+;
DECLARE_VARIABLE_KW: L_PAREN 'global' SEP+;
LOCAL_KW: L_PAREN 'local' SEP+;
+DEFAULT_KW: L_PAREN 'default' SEP+;
DEFINE_SEQUENCE_KW: L_PAREN ('declare'|'define'|'def')US(('seq'('uence')?)|('proc'('edure'?))) SEP+;
DIVIDE_KW: L_PAREN ('divide'|'/'|'div') SEP+;
DO_WHILE_KW: L_PAREN ('do'US'while') SEP+;
diff --git a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4
index ab623a8..108813e 100644
--- a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4
+++ b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4
@@ -3103,6 +3103,20 @@ returns [Computation result]
);
}
+ | DEFAULT_KW type WS* R_PAREN
+ {
+ $result =
+ new Default
+ (
+ CONTEXT.get_origin_at
+ (
+ ($DEFAULT_KW.getLine()),
+ ($DEFAULT_KW.getCharPositionInLine())
+ ),
+ ($type.result)
+ );
+ }
+
| COND_KW value_cond_list WS* R_PAREN
{
$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 d3347c8..3d48b52 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
@@ -23,10 +23,12 @@ 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.AddElementsOf;
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.FilterLambda;
import tonkadur.wyrd.v1.compiler.util.Shuffle;
import tonkadur.wyrd.v1.compiler.util.RemoveAt;
import tonkadur.wyrd.v1.compiler.util.InsertAt;
@@ -1316,6 +1318,21 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor
}
@Override
+ public void visit_default
+ (
+ final tonkadur.fate.v1.lang.computation.Default n
+ )
+ throws Throwable
+ {
+ final Register r;
+
+ r = reserve(TypeCompiler.compile(compiler, n.get_type()));
+
+ init_instructions.add(new Initialize(r.get_address()));
+ }
+
+
+ @Override
public void visit_access
(
final tonkadur.fate.v1.lang.computation.Access n
@@ -2095,7 +2112,50 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor
)
throws Throwable
{
- /* TODO */
+ final ComputationCompiler collection_in_cc, collection_cc;
+ final Register result;
+
+ result = reserve(TypeCompiler.compile(compiler, n.get_type()));
+
+ result_as_address = result.get_address();
+ result_as_computation = result.get_value();
+
+ collection_cc = new ComputationCompiler(compiler);
+
+ n.get_target_collection().get_visited_by(collection_cc);
+
+ if (collection_cc.has_init())
+ {
+ init_instructions.add(collection_cc.get_init());
+ }
+
+ init_instructions.add
+ (
+ new SetValue(result_as_address, collection_cc.get_computation())
+ );
+
+ collection_cc.release_registers(init_instructions);
+
+ collection_in_cc = new ComputationCompiler(compiler);
+
+ n.get_source_collection().get_visited_by(collection_in_cc);
+
+ assimilate(collection_in_cc);
+
+ init_instructions.add
+ (
+ AddElementsOf.generate
+ (
+ compiler.registers(),
+ compiler.assembler(),
+ collection_in_cc.get_address(),
+ result_as_address,
+ (
+ (tonkadur.fate.v1.lang.type.CollectionType)
+ n.get_target_collection().get_type()
+ ).is_set()
+ )
+ );
}
@Override
@@ -2638,7 +2698,41 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor
)
throws Throwable
{
- /* TODO */
+ final ComputationCompiler lambda_cc, in_collection_cc;
+ final Register result;
+
+ result = reserve(TypeCompiler.compile(compiler, n.get_type()));
+
+ result_as_address = result.get_address();
+ result_as_computation = result.get_value();
+
+ 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());
+ }
+
+ in_collection_cc.release_registers(init_instructions);
+
+ init_instructions.add
+ (
+ FilterLambda.generate
+ (
+ compiler.registers(),
+ compiler.assembler(),
+ lambda_cc.get_computation(),
+ result_as_address
+ )
+ );
}
@Override
diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/util/AddElementsOf.java b/src/core/src/tonkadur/wyrd/v1/compiler/util/AddElementsOf.java
new file mode 100644
index 0000000..af979a8
--- /dev/null
+++ b/src/core/src/tonkadur/wyrd/v1/compiler/util/AddElementsOf.java
@@ -0,0 +1,111 @@
+package tonkadur.wyrd.v1.compiler.util;
+
+import java.util.List;
+import java.util.ArrayList;
+
+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 AddElementsOf
+{
+ /* Utility Class */
+ private AddElementsOf () {}
+
+ /* Uses Durstenfeld's shuffling algorithm */
+ public static Instruction generate
+ (
+ final RegisterManager registers,
+ final InstructionManager assembler,
+ final Address collection_in,
+ final Address collection,
+ final boolean to_set
+ )
+ {
+ final List<Instruction> result, while_body;
+ final Register iterator, collection_in_size;
+
+ result = new ArrayList<Instruction>();
+ while_body = new ArrayList<Instruction>();
+
+ iterator = registers.reserve(Type.INT, result);
+ collection_in_size = registers.reserve(Type.INT, result);
+
+ result.add(new SetValue(iterator.get_address(), Constant.ZERO));
+ result.add
+ (
+ new SetValue
+ (
+ collection_in_size.get_address(),
+ new Size(collection_in)
+ )
+ );
+
+ while_body.add
+ (
+ AddElement.generate
+ (
+ registers,
+ assembler,
+ new ValueOf
+ (
+ new RelativeAddress
+ (
+ collection_in,
+ new Cast(iterator.get_value(), Type.STRING),
+ (
+ (MapType) collection_in.get_target_type()
+ ).get_member_type()
+ )
+ ),
+ collection,
+ to_set
+ )
+ );
+
+ 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_in_size.get_value()
+ ),
+ assembler.merge(while_body)
+ )
+ );
+
+ registers.release(iterator, result);
+ registers.release(collection_in_size, result);
+
+ return assembler.merge(result);
+ }
+}
diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/util/FilterLambda.java b/src/core/src/tonkadur/wyrd/v1/compiler/util/FilterLambda.java
new file mode 100644
index 0000000..8757fe7
--- /dev/null
+++ b/src/core/src/tonkadur/wyrd/v1/compiler/util/FilterLambda.java
@@ -0,0 +1,162 @@
+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 FilterLambda
+{
+ /* Utility Class */
+ private FilterLambda () {}
+
+ /* Uses Durstenfeld's shuffling algorithm */
+ public static Instruction generate
+ (
+ final RegisterManager registers,
+ final InstructionManager assembler,
+ final Computation lambda,
+ final Address collection
+ )
+ {
+ final List<Computation> params;
+ final List<Instruction> result, while_body, remove_instructions;
+ final Register iterator, index_storage, collection_size, storage;
+
+ params = new ArrayList<Computation>();
+ 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);
+
+ result.add(new SetValue(iterator.get_address(), Constant.ZERO));
+ result.add
+ (
+ new SetValue(collection_size.get_address(), new Size(collection))
+ );
+
+ params.add
+ (
+ new ValueOf
+ (
+ new RelativeAddress
+ (
+ collection,
+ new Cast(iterator.get_value(), Type.STRING),
+ ((MapType) collection.get_target_type()).get_member_type()
+ )
+ )
+ );
+
+ 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
+ )
+ );
+
+ 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(),
+ 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);
+ }
+}