| summaryrefslogtreecommitdiff |
diff options
| author | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2020-07-08 00:20:52 +0200 |
|---|---|---|
| committer | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2020-07-08 00:20:52 +0200 |
| commit | 88657c6dba477efeb42dd1b94d7636f5633b38d4 (patch) | |
| tree | 8fe02c41c24d431a2e23825c1ef51d49934d6f7a | |
| parent | 6a30ee067c8ef61193873c2a598e91d524d2e51b (diff) | |
Adds Conditional switch for values.
| -rw-r--r-- | src/core/src/tonkadur/fate/v1/lang/CondValue.java | 138 | ||||
| -rw-r--r-- | src/core/src/tonkadur/fate/v1/lang/IfElseValue.java | 19 | ||||
| -rw-r--r-- | src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 | 3 | ||||
| -rw-r--r-- | src/core/src/tonkadur/fate/v1/parser/FateParser.g4 | 121 | ||||
| -rw-r--r-- | src/core/src/tonkadur/parser/Context.java | 5 |
5 files changed, 268 insertions, 18 deletions
diff --git a/src/core/src/tonkadur/fate/v1/lang/CondValue.java b/src/core/src/tonkadur/fate/v1/lang/CondValue.java new file mode 100644 index 0000000..cb0bf7c --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/CondValue.java @@ -0,0 +1,138 @@ +package tonkadur.fate.v1.lang; + +import java.util.List; +import java.util.Collections; + +import tonkadur.functional.Cons; + +import tonkadur.error.ErrorManager; + +import tonkadur.parser.Origin; + +import tonkadur.fate.v1.lang.meta.ValueNode; + +import tonkadur.fate.v1.error.ConflictingTypeException; +import tonkadur.fate.v1.error.IncomparableTypeException; +import tonkadur.fate.v1.error.InvalidTypeException; + +public class CondValue extends ValueNode +{ + /***************************************************************************/ + /**** MEMBERS **************************************************************/ + /***************************************************************************/ + protected final List<Cons<ValueNode, ValueNode>> branches; + + /***************************************************************************/ + /**** PROTECTED ************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + protected CondValue + ( + final Origin origin, + final Type return_type, + final List<Cons<ValueNode, ValueNode>> branches + ) + { + super(origin, return_type); + + this.branches = branches; + } + + /***************************************************************************/ + /**** PUBLIC ***************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + public static CondValue build + ( + final Origin origin, + final List<Cons<ValueNode, ValueNode>> branches + ) + throws + InvalidTypeException, + ConflictingTypeException, + IncomparableTypeException + { + final Type first_type; + Type hint; + + first_type = branches.get(0).get_cdr().get_type(); + hint = first_type; + + for (final Cons<ValueNode, ValueNode> entry: branches) + { + if (!entry.get_car().get_type().can_be_used_as(Type.BOOLEAN)) + { + ErrorManager.handle + ( + new InvalidTypeException + ( + entry.get_car().get_origin(), + entry.get_car().get_type(), + Collections.singleton(Type.BOOLEAN) + ) + ); + } + + if (entry.get_cdr().get_type().equals(hint)) + { + continue; + } + + ErrorManager.handle + ( + new ConflictingTypeException + ( + entry.get_cdr().get_origin(), + entry.get_cdr().get_type(), + first_type + ) + ); + + hint = (Type) hint.generate_comparable_to(entry.get_cdr().get_type()); + + if (hint.equals(Type.ANY)) + { + ErrorManager.handle + ( + new IncomparableTypeException + ( + entry.get_cdr().get_origin(), + entry.get_cdr().get_type(), + first_type + ) + ); + } + } + + return new CondValue(origin, hint, branches); + } + + /**** Accessors ************************************************************/ + + /**** Misc. ****************************************************************/ + @Override + public String toString () + { + final StringBuilder sb = new StringBuilder(); + + sb.append(origin.toString()); + sb.append("(CondValue"); + sb.append(System.lineSeparator()); + + for (final Cons<ValueNode, ValueNode> entry: branches) + { + sb.append(System.lineSeparator()); + sb.append("Condition:"); + sb.append(System.lineSeparator()); + sb.append(entry.get_car().toString()); + sb.append(System.lineSeparator()); + sb.append("Value:"); + sb.append(entry.get_cdr().toString()); + sb.append(System.lineSeparator()); + } + + sb.append(")"); + + return sb.toString(); + } +} diff --git a/src/core/src/tonkadur/fate/v1/lang/IfElseValue.java b/src/core/src/tonkadur/fate/v1/lang/IfElseValue.java index 960af57..d54e164 100644 --- a/src/core/src/tonkadur/fate/v1/lang/IfElseValue.java +++ b/src/core/src/tonkadur/fate/v1/lang/IfElseValue.java @@ -1,8 +1,5 @@ package tonkadur.fate.v1.lang; -import java.util.Set; -import java.util.Map; -import java.util.HashMap; import java.util.Collections; import tonkadur.error.ErrorManager; @@ -70,7 +67,7 @@ public class IfElseValue extends ValueNode ( new InvalidTypeException ( - origin, + condition.get_origin(), condition.get_type(), Collections.singleton(Type.BOOLEAN) ) @@ -88,7 +85,12 @@ public class IfElseValue extends ValueNode ErrorManager.handle ( - new ConflictingTypeException(origin, if_false_type, if_true_type) + new ConflictingTypeException + ( + if_false.get_origin(), + if_false_type, + if_true_type + ) ); hint = @@ -98,7 +100,12 @@ public class IfElseValue extends ValueNode { ErrorManager.handle ( - new IncomparableTypeException(origin, if_false_type, if_true_type) + new IncomparableTypeException + ( + if_false.get_origin(), + if_false_type, + if_true_type + ) ); } diff --git a/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 b/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 index 4714d8e..6042ebc 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 @@ -43,12 +43,13 @@ GREATER_THAN_KW: L_PAREN ('greater_than'|'>'); IF_ELSE_KW: L_PAREN 'if_else'; IF_KW: L_PAREN 'if'; IMPLIES_KW: L_PAREN ('implies'|'=>'); +INCLUDE_KW: L_PAREN 'include'; IS_MEMBER_KW: L_PAREN 'is_member'; LOWER_EQUAL_THAN_KW: L_PAREN ('lower_equal_than'|'=<'|'<='); LOWER_THAN_KW: L_PAREN ('lower_than'|'<'); MACRO_KW: L_PAREN 'macro'; MINUS_KW: L_PAREN ('minus'|'-'); -NEWLINE_KW: L_PAREN 'newline'; +NEWLINE_KW: L_PAREN 'newline)'; NOT_KW: L_PAREN ('not'|'~'|'!'); ONE_IN_KW: L_PAREN 'one_in'; OR_KW: L_PAREN ('or'|'\\/'); diff --git a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 index eb065bb..12981cb 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 @@ -13,13 +13,17 @@ options import java.util.Map; import java.util.HashMap; + import tonkadur.error.ErrorManager; import tonkadur.functional.Cons; import tonkadur.parser.Context; + import tonkadur.parser.Location; import tonkadur.parser.Origin; + import tonkadur.fate.v1.Utils; + import tonkadur.fate.v1.error.IllegalReferenceNameException; import tonkadur.fate.v1.error.UnknownVariableScopeException; @@ -47,6 +51,7 @@ fate_file [Context context, World world] ( (first_level_fate_instr|general_fate_instr) { + /* TODO */ } WS* )* @@ -58,6 +63,7 @@ fate_file [Context context, World world] general_fate_sequence: (WS* general_fate_instr WS*)* { + /* TODO */ } ; @@ -168,6 +174,8 @@ first_level_fate_instr: | REQUIRE_EXTENSION_KW WS+ WORD WS* R_PAREN { WORLD.add_required_extension(($WORD.text)); + + /* TODO: error report if extension not explicitly enabled. */ } | DECLARE_ALIAS_TYPE_KW WS+ parent=type WS+ new_reference_name WS* R_PAREN @@ -284,14 +292,17 @@ first_level_fate_instr: | ADD_KW WS+ value WS+ value_reference WS* R_PAREN { + /* TODO */ } | REMOVE_ONE_KW WS+ value WS+ value_reference WS* R_PAREN { + /* TODO */ } | REMOVE_ALL_KW WS+ value WS+ value_reference WS* R_PAREN { + /* TODO */ } | DECLARE_EVENT_TYPE_KW WS+ new_reference_name WS+ type_list WS* R_PAREN @@ -319,6 +330,41 @@ first_level_fate_instr: | REQUIRE_KW WS+ WORD WS* R_PAREN { + if (!WORLD.has_loaded_file(($WORD.text))) + { + CONTEXT.push + ( + new Location + ( + CONTEXT.get_current_file(), + ($REQUIRE_KW.getLine()), + ($REQUIRE_KW.getCharPositionInLine()) + ), + ($WORD.text) + ); + + Utils.add_file_content(($WORD.text), CONTEXT, WORLD); + + CONTEXT.pop(); + } + } + + | INCLUDE_KW WS+ WORD WS* R_PAREN + { + CONTEXT.push + ( + new Location + ( + CONTEXT.get_current_file(), + ($INCLUDE_KW.getLine()), + ($INCLUDE_KW.getCharPositionInLine()) + ), + ($WORD.text) + ); + + Utils.add_file_content(($WORD.text), CONTEXT, WORLD); + + CONTEXT.pop(); } | DEFINE_MACRO_KW @@ -331,10 +377,13 @@ first_level_fate_instr: WS* R_PAREN { + /* TODO */ } | EXTENSION_FIRST_LEVEL_KW WORD WS+ general_fate_sequence WS* R_PAREN { + /* TODO */ + /* TODO: no param alternative. */ /* Extension stuff */ System.out.println("Using extension FLI " + ($WORD.text)); @@ -350,52 +399,72 @@ returns [InstructionNode result] : L_PAREN WS+ general_fate_sequence WS* R_PAREN { + /* TODO */ + $result = null; } | CLEAR_KW WS+ value_reference WS* R_PAREN { + /* TODO */ + $result = null; } | SET_KW WS+ value WS+ value_reference WS* R_PAREN { + /* TODO */ + $result = null; } | SET_FIELDS_KW WS+ field_value_list WS* value_reference WS* R_PAREN { + /* TODO */ + $result = null; } | SET_EXPRESSION_KW WS+ value WS+ value_reference WS* R_PAREN { + /* TODO */ + /* that one isn't resolved until the value is referenced */ $result = null; } | EVENT_KW WS+ WORD WS+ value_list WS* R_PAREN { + /* TODO */ + $result = null; } | MACRO_KW WS+ WORD WS+ value_list WS* R_PAREN { + /* TODO */ + $result = null; } | SEQUENCE_KW WS+ WORD WS* R_PAREN { + /* TODO */ + $result = null; } | ASSERT_KW WS+ value WS* R_PAREN { + /* TODO */ + $result = null; } | IF_KW WS+ value WS* general_fate_instr WS* R_PAREN { + /* TODO */ + $result = null; } @@ -405,21 +474,29 @@ returns [InstructionNode result] WS+ general_fate_instr WS* R_PAREN { + /* TODO */ + $result = null; } | COND_KW WS+ instr_cond_list WS* R_PAREN { + /* TODO */ + $result = null; } - | PLAYER_CHOICE_KW WS+ player_choice+ WS* R_PAREN + | PLAYER_CHOICE_KW WS+ (player_choice WS*)+ R_PAREN { + /* TODO */ + $result = null; } | EXTENSION_INSTRUCTION_KW WORD WS+ general_fate_sequence WS* R_PAREN { + /* TODO */ + /* Extension stuff */ System.out.println("Using extension instruction " + ($WORD.text)); $result = null; @@ -427,6 +504,8 @@ returns [InstructionNode result] | text+ { + /* TODO */ + $result = null; } ; @@ -443,50 +522,63 @@ returns [List<Cons<ValueNode,InstructionNode>> result] { $result.add(new Cons(($value.result), ($general_fate_instr.result))); } + WS* )+ { } ; player_choice: - L_PAREN WS* L_PAREN text+ R_PAREN WS+ general_fate_sequence WS* R_PAREN + L_PAREN WS* + L_PAREN WS* text+ WS* R_PAREN WS+ + general_fate_sequence WS* + R_PAREN { + /* TODO */ } | IF_KW WS+ value WS+ player_choice WS* R_PAREN { + /* TODO */ } | IF_ELSE_KW WS+ value WS+ player_choice WS+ player_choice WS* R_PAREN { + /* TODO */ } | COND_KW WS+ player_choice_cond_list WS* R_PAREN { + /* TODO */ } ; player_choice_cond_list: - (L_PAREN WS* value WS+ player_choice WS* R_PAREN)+ + (L_PAREN WS* value WS+ player_choice WS* R_PAREN WS*)+ { + /* TODO */ } ; text: sentence { + /* TODO */ } - | ENABLE_TEXT_PARAMETER_KW WS+ WORD WS+ text+ WS* R_PAREN + | WS* ENABLE_TEXT_PARAMETER_KW WS+ WORD WS+ text+ WS* R_PAREN WS* { + /* TODO */ } - | NEWLINE_KW + | WS* NEWLINE_KW WS* { + /* TODO */ } - | non_text_value + | WS* non_text_value WS* { + /* TODO */ } ; @@ -995,8 +1087,16 @@ returns [ValueNode result] | COND_KW WS+ value_cond_list WS* R_PAREN { - /* TODO */ - $result = null; + $result = + CondValue.build + ( + CONTEXT.get_origin_at + ( + ($COND_KW.getLine()), + ($COND_KW.getCharPositionInLine()) + ), + ($value_cond_list.result) + ); } | boolean_expression @@ -1045,8 +1145,7 @@ returns [ValueNode result] | value_reference { - /* TODO */ - $result = null; + $result = ($value_reference.result); } ; catch [final Throwable e] @@ -1127,7 +1226,7 @@ returns [List<Cons<ValueNode, ValueNode>> result] } : ( - L_PAREN WS* c=value WS+ v=value WS* R_PAREN + L_PAREN WS* c=value WS+ v=value WS* R_PAREN WS* { $result.add(new Cons(($c.result), ($v.result))); } diff --git a/src/core/src/tonkadur/parser/Context.java b/src/core/src/tonkadur/parser/Context.java index f579318..c3278ff 100644 --- a/src/core/src/tonkadur/parser/Context.java +++ b/src/core/src/tonkadur/parser/Context.java @@ -38,6 +38,11 @@ public class Context source.pop(); } + public String get_current_file () + { + return current_file; + } + /**** Utils ****************************************************************/ public Origin get_origin_at (final int line, final int column) { |


