| summaryrefslogtreecommitdiff |
diff options
| author | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2020-08-30 02:14:51 +0200 |
|---|---|---|
| committer | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2020-08-30 02:14:51 +0200 |
| commit | 19d1cd96cc2d862869dbb852d663996a1b64bd9d (patch) | |
| tree | e0b7573b4d2a0510acab9ae473fcd1ae6b0e67cf /src | |
| parent | 5eaad6f3ed30cbeae04d46f6984f85c3da015281 (diff) | |
Adds a possible solution to loops in player choices.
Diffstat (limited to 'src')
8 files changed, 245 insertions, 10 deletions
diff --git a/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 b/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 index 7077127..1525d42 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 @@ -82,10 +82,9 @@ REF_KW: L_PAREN (((('ref'('erence'?))|'ptr'|'pointer')(US'to')?)|('address'(US'o REMOVE_ALL_KW: L_PAREN 'remove'US'all' SEP+; REVERSE_KW: L_PAREN 'reverse'(US'list')? SEP+; REMOVE_ONE_KW: L_PAREN 'remove'US'one' SEP+; -REMOVE_AT_KW: L_PAREN ('remove'US('elem'('ent')?US)?'at'|'rm'|'del'|'delete') SEP+; +REMOVE_AT_KW: L_PAREN ('remove'US('elem'('ent')?US)?'at') SEP+; REQUIRE_EXTENSION_KW: L_PAREN 'require'US'extension' SEP+; REQUIRE_KW: L_PAREN 'require' SEP+; -SEQUENCE_KW: L_PAREN 'seq'('uence')? SEP+; SET_FIELDS_KW: L_PAREN 'set'US'fields' SEP+; SET_KW: L_PAREN 'set'(US(('val''ue'?)|('var''iable'?)))? SEP+; LIST_KW: L_PAREN 'list' SEP+; @@ -94,7 +93,6 @@ SWITCH_KW: L_PAREN 'switch' SEP+; TIMES_KW: L_PAREN ('times'|'*') SEP+; TRUE_KW: L_PAREN 'true)'; DONE_KW: L_PAREN 'done)'; -VAL_KW: L_PAREN ('val'|'value') SEP+; VARIABLE_KW: L_PAREN ('variable'|'var') SEP+; VISIT_KW: L_PAREN ('call'|'visit')(US(('seq'('uence'?))|('proc'('edure'?))))? SEP+; CONTINUE_AS_KW: L_PAREN (('continue'US('as'|'to'|'with'))|('jump'(US'to')?)|('go'US'to')|'exec')(US(('seq'('uence'?))|('proc'('edure'?))))? SEP+; diff --git a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 index f122a9a..2c6aeca 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 @@ -1351,6 +1351,105 @@ returns [Instruction result] ($player_choice.result) ); } + + | FOR_EACH_KW + value_reference WS+ new_reference_name + { + final Map<String, Variable> variable_map; + final Variable new_variable; + final Type collection_type; + Type elem_type; + + elem_type = Type.ANY; + + collection_type = ($value_reference.result).get_type(); + + if (collection_type instanceof CollectionType) + { + elem_type = ((CollectionType) collection_type).get_content_type(); + } + else + { + ErrorManager.handle + ( + new InvalidTypeException + ( + CONTEXT.get_origin_at + ( + ($FOR_EACH_KW.getLine()), + ($FOR_EACH_KW.getCharPositionInLine()) + ), + elem_type, + Type.COLLECTION_TYPES + ) + ); + + elem_type = Type.ANY; + } + + + new_variable = + new Variable + ( + CONTEXT.get_origin_at + ( + ($FOR_EACH_KW.getLine()), + ($FOR_EACH_KW.getCharPositionInLine()) + ), + elem_type, + ($new_reference_name.result) + ); + + variable_map = LOCAL_VARIABLES.peekFirst(); + + if (variable_map.containsKey(($new_reference_name.result))) + { + ErrorManager.handle + ( + new DuplicateLocalVariableException + ( + variable_map.get(($new_reference_name.result)), + new_variable + ) + ); + } + else + { + variable_map.put(($new_reference_name.result), new_variable); + } + } + WS+ + { + BREAKABLE_LEVELS++; + HIERARCHICAL_VARIABLES.push(new ArrayList()); + } + player_choice_list + { + BREAKABLE_LEVELS--; + + for (final String s: HIERARCHICAL_VARIABLES.pop()) + { + LOCAL_VARIABLES.peekFirst().remove(s); + } + } + WS* + R_PAREN + { + $result = + new ForEach + ( + CONTEXT.get_origin_at + ( + ($FOR_EACH_KW.getLine()), + ($FOR_EACH_KW.getCharPositionInLine()) + ), + ($value_reference.result), + ($new_reference_name.result), + ($player_choice_list.result) + ); + + variable_map.remove(($new_reference_name.result)); + } ; catch [final Throwable e] { @@ -2757,7 +2856,7 @@ returns [Reference result] ); } - | FIELD_KW value_reference WORD R_PAREN + | FIELD_KW value_reference WS+ WORD WS* R_PAREN { $result = FieldReference.build 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 2c163e7..42df895 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 @@ -24,6 +24,7 @@ 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.Size; +import tonkadur.wyrd.v1.lang.computation.GetLastChoiceIndex; import tonkadur.wyrd.v1.lang.computation.ValueOf; import tonkadur.wyrd.v1.lang.instruction.AddChoice; @@ -1291,9 +1292,12 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor * * Wyrd (add_choice label i0) */ + final List<Instruction> to_next, labels_only; final ComputationCompiler cc; final String start_of_effect, end_of_effect; + to_next = new ArrayList<Instruction>(); + labels_only = new ArrayList<Instruction>(); cc = new ComputationCompiler(compiler); start_of_effect = compiler.assembler().generate_label("<choice#start>"); @@ -1306,7 +1310,7 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor result.add(cc.get_init()); } - result.add + labels_only.add ( new AddChoice ( @@ -1314,13 +1318,62 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor compiler.assembler().get_label_constant(start_of_effect) ) ); + + labels_only.add + ( + new SetPC(compiler.assembler().get_label_constant(end_of_effect)) + ); + + result.add + ( + If.generate + ( + compiler.registers(), + compiler.assembler(), + Operation.equals + ( + compiler.registers().get_choice_number_holder().get_value(), + new Constant(Type.INT, "-2") + ), + compiler.assembler().merge(labels_only) + ) + ); + + to_next.add + ( + new SetValue + ( + compiler.registers().get_choice_number_holder().get_address(), + Operation.plus + ( + compiler.registers().get_choice_number_holder().get_value(), + Constant.ONE + ) + ) + ); + + to_next.add + ( + new SetPC(compiler.assembler().get_label_constant(end_of_effect)) + ); + result.add ( compiler.assembler().mark_after ( - new SetPC + If.generate ( - compiler.assembler().get_label_constant(end_of_effect) + compiler.registers(), + compiler.assembler(), + Operation.not + ( + Operation.equals + ( + compiler.registers().get_choice_number_holder().get_value(), + new GetLastChoiceIndex() + ) + ), + compiler.assembler().merge(to_next) ), start_of_effect ) @@ -1359,13 +1412,29 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor ) throws Throwable { - final String end_of_choices_label; + final String start_of_choices_label, end_of_choices_label; + + start_of_choices_label = + compiler.assembler().generate_label("<ChoicesDefinition>"); end_of_choices_label = compiler.assembler().generate_label("<ChoicesResolved>"); compiler.assembler().push_context_label("choices", end_of_choices_label); + result.add + ( + compiler.assembler().mark_after + ( + new SetValue + ( + compiler.registers().get_choice_number_holder().get_address(), + new Constant(Type.INT, "-2") + ), + start_of_choices_label + ) + ); + /* * Fate: (player_choice_list i0 ... in) * @@ -1386,11 +1455,25 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor compiler.assembler().pop_context_label("choices"); + result.add(new ResolveChoices()); + + result.add + ( + new SetValue + ( + compiler.registers().get_choice_number_holder().get_address(), + new Constant(Type.INT, "0") + ) + ); + result.add ( compiler.assembler().mark_after ( - new ResolveChoices(), + new SetPC + ( + compiler.assembler().get_label_constant(start_of_choices_label) + ), end_of_choices_label ) ); diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/util/registers/RegisterContext.java b/src/core/src/tonkadur/wyrd/v1/compiler/util/registers/RegisterContext.java index 08c71f2..090f596 100644 --- a/src/core/src/tonkadur/wyrd/v1/compiler/util/registers/RegisterContext.java +++ b/src/core/src/tonkadur/wyrd/v1/compiler/util/registers/RegisterContext.java @@ -146,6 +146,7 @@ class RegisterContext public void unbind (final String name) { + release(aliased_registers.get(name)); aliased_registers.remove(name); } diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/util/registers/RegisterManager.java b/src/core/src/tonkadur/wyrd/v1/compiler/util/registers/RegisterManager.java index 2fbad42..8af7754 100644 --- a/src/core/src/tonkadur/wyrd/v1/compiler/util/registers/RegisterManager.java +++ b/src/core/src/tonkadur/wyrd/v1/compiler/util/registers/RegisterManager.java @@ -37,7 +37,7 @@ public class RegisterManager protected final Map<String, StackableRegisterContext> context_by_name; protected final Deque<RegisterContext> context; protected final RegisterContext base_context, parameter_context; - protected final Register next_pc, pc_stack; + protected final Register next_pc, pc_stack, choice_number; protected int created_contexts; public RegisterManager () @@ -45,6 +45,7 @@ public class RegisterManager base_context = new RegisterContext("base context"); parameter_context = new RegisterContext("parameter context", ".param."); next_pc = base_context.reserve(Type.INT); + choice_number = base_context.reserve(Type.INT); pc_stack = base_context.reserve(new MapType(Type.INT)); context_by_name = new HashMap<String, StackableRegisterContext>(); @@ -69,6 +70,11 @@ public class RegisterManager return context_name_prefix + (created_contexts++); } + public Register get_choice_number_holder () + { + return choice_number; + } + public void create_stackable_context (final String context_name) { final StackableRegisterContext result; diff --git a/src/core/src/tonkadur/wyrd/v1/lang/computation/GetLastChoiceIndex.java b/src/core/src/tonkadur/wyrd/v1/lang/computation/GetLastChoiceIndex.java new file mode 100644 index 0000000..8f70687 --- /dev/null +++ b/src/core/src/tonkadur/wyrd/v1/lang/computation/GetLastChoiceIndex.java @@ -0,0 +1,37 @@ +package tonkadur.wyrd.v1.lang.computation; + +import tonkadur.wyrd.v1.lang.type.Type; + +import tonkadur.wyrd.v1.lang.meta.Computation; +import tonkadur.wyrd.v1.lang.meta.ComputationVisitor; + +public class GetLastChoiceIndex extends Computation +{ + /***************************************************************************/ + /**** MEMBERS **************************************************************/ + /***************************************************************************/ + + /***************************************************************************/ + /**** PUBLIC ***************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + public GetLastChoiceIndex () + { + super(Type.INT); + } + + /**** Accessors ************************************************************/ + @Override + public void get_visited_by (final ComputationVisitor cv) + throws Throwable + { + cv.visit_get_last_choice_index(this); + } + + /**** Misc. ****************************************************************/ + @Override + public String toString () + { + return "(GetLastChoiceIndex)"; + } +} diff --git a/src/core/src/tonkadur/wyrd/v1/lang/meta/ComputationVisitor.java b/src/core/src/tonkadur/wyrd/v1/lang/meta/ComputationVisitor.java index fdfdc1b..1d9b2be 100644 --- a/src/core/src/tonkadur/wyrd/v1/lang/meta/ComputationVisitor.java +++ b/src/core/src/tonkadur/wyrd/v1/lang/meta/ComputationVisitor.java @@ -31,6 +31,9 @@ public interface ComputationVisitor public void visit_relative_address (final RelativeAddress n) throws Throwable; + public void visit_get_last_choice_index (final GetLastChoiceIndex n) + throws Throwable; + public void visit_rich_text (final RichText n) throws Throwable; diff --git a/src/json-export/src/tonkadur/jsonexport/ComputationCompiler.java b/src/json-export/src/tonkadur/jsonexport/ComputationCompiler.java index 3210f73..132e658 100644 --- a/src/json-export/src/tonkadur/jsonexport/ComputationCompiler.java +++ b/src/json-export/src/tonkadur/jsonexport/ComputationCompiler.java @@ -116,6 +116,14 @@ public class ComputationCompiler implements ComputationVisitor result.put("category", "newline"); } + public void visit_get_last_choice_index (final GetLastChoiceIndex n) + throws Throwable + { + result = new JSONObject(); + + result.put("category", "last_choice_index"); + } + public void visit_operation (final Operation n) throws Throwable { |


