From e0950d875e683b0f0e84925b12cf2de9108a2fda Mon Sep 17 00:00:00 2001 From: Nathanael Sensfelder Date: Thu, 17 Sep 2020 21:10:22 +0200 Subject: ... --- .../tonkadur/fate/v1/lang/computation/Default.java | 49 +++++++ .../src/tonkadur/fate/v1/lang/computation/New.java | 1 - .../fate/v1/lang/meta/ComputationVisitor.java | 3 + src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 | 1 + src/core/src/tonkadur/fate/v1/parser/FateParser.g4 | 14 ++ .../v1/compiler/fate/v1/ComputationCompiler.java | 98 ++++++++++++- .../wyrd/v1/compiler/util/AddElementsOf.java | 111 ++++++++++++++ .../wyrd/v1/compiler/util/FilterLambda.java | 162 +++++++++++++++++++++ 8 files changed, 436 insertions(+), 3 deletions(-) create mode 100644 src/core/src/tonkadur/fate/v1/lang/computation/Default.java create mode 100644 src/core/src/tonkadur/wyrd/v1/compiler/util/AddElementsOf.java create mode 100644 src/core/src/tonkadur/wyrd/v1/compiler/util/FilterLambda.java 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; @@ -1315,6 +1317,21 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor new New(TypeCompiler.compile(compiler, n.get_target_type())); } + @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 ( @@ -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 result, while_body; + final Register iterator, collection_in_size; + + result = new ArrayList(); + while_body = new ArrayList(); + + 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 params; + final List result, while_body, remove_instructions; + final Register iterator, index_storage, collection_size, storage; + + params = new ArrayList(); + result = new ArrayList(); + while_body = new ArrayList(); + remove_instructions = new ArrayList(); + + 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); + } +} -- cgit v1.2.3-70-g09d2