From 9c2d55d7e8576c909ffa94f210c682117cb61a59 Mon Sep 17 00:00:00 2001 From: Nathanael Sensfelder Date: Thu, 28 Oct 2021 22:28:20 +0200 Subject: trims spaces around (newline), pre-resolve variables in AmbiguousWord, removes nearly all pcd checks in player_choice --- .../fate/v1/lang/computation/AmbiguousWord.java | 30 ++++-- .../fate/v1/lang/computation/generic/Newline.java | 1 + .../fate/v1/lang/meta/VariableFromWord.java | 112 ++++++++++++++++++++ src/core/src/tonkadur/fate/v1/parser/FateParser.g4 | 117 ++++++++++++++------- 4 files changed, 218 insertions(+), 42 deletions(-) diff --git a/src/core/src/tonkadur/fate/v1/lang/computation/AmbiguousWord.java b/src/core/src/tonkadur/fate/v1/lang/computation/AmbiguousWord.java index 624d61b..e33ffe3 100644 --- a/src/core/src/tonkadur/fate/v1/lang/computation/AmbiguousWord.java +++ b/src/core/src/tonkadur/fate/v1/lang/computation/AmbiguousWord.java @@ -19,6 +19,7 @@ public class AmbiguousWord extends Computation /***************************************************************************/ protected final ParserData parser; protected final String as_string; + protected final Computation as_variable; protected Computation result; protected void assert_is_resolved () @@ -40,13 +41,15 @@ public class AmbiguousWord extends Computation ( final ParserData parser, final Origin origin, - final String as_string + final String as_string, + final Computation as_variable ) { super(origin, new FutureType(origin)); this.parser = parser; this.as_string = as_string; + this.as_variable = as_variable; result = null; } @@ -79,15 +82,30 @@ public class AmbiguousWord extends Computation @Override public void expect_non_string () { - try + if (as_variable != null) { - result = VariableFromWord.generate(parser, get_origin(), as_string); + result = as_variable; } - catch (final Throwable t) + else { - t.printStackTrace(); + System.err.println + ( + "[P] Somehow, the variable '" + + as_string + + "' was an ambiguous word that wasn't a variable when it was used." + + get_origin().toString() + ); + + try + { + result = VariableFromWord.generate(parser, get_origin(), as_string); + } + catch (final Throwable t) + { + t.printStackTrace(); - System.exit(-1); + System.exit(-1); + } } ((FutureType) type).resolve_to(result.get_type()); diff --git a/src/core/src/tonkadur/fate/v1/lang/computation/generic/Newline.java b/src/core/src/tonkadur/fate/v1/lang/computation/generic/Newline.java index e135cd2..76b030e 100644 --- a/src/core/src/tonkadur/fate/v1/lang/computation/generic/Newline.java +++ b/src/core/src/tonkadur/fate/v1/lang/computation/generic/Newline.java @@ -26,6 +26,7 @@ public class Newline extends GenericComputation aliases = new ArrayList(); aliases.add("newline"); + aliases.add("n"); return aliases; } diff --git a/src/core/src/tonkadur/fate/v1/lang/meta/VariableFromWord.java b/src/core/src/tonkadur/fate/v1/lang/meta/VariableFromWord.java index 813cef4..b6c88d5 100644 --- a/src/core/src/tonkadur/fate/v1/lang/meta/VariableFromWord.java +++ b/src/core/src/tonkadur/fate/v1/lang/meta/VariableFromWord.java @@ -137,4 +137,116 @@ public class VariableFromWord return result; } + + public static Computation attempt + ( + final ParserData parser, + final Origin origin, + final String word + ) + throws Throwable + { + final String[] subrefs; + Computation result; + Variable target_var; + + subrefs = word.split("\\."); + + if (subrefs.length == 0) + { + // 'word' is made only of '.' characters. + return null; + } + + target_var = parser.maybe_get_local_variable(subrefs[0]); + + if (target_var == null) + { + target_var = parser.get_world().variables().get_or_null(subrefs[0]); + } + + if (target_var == null) + { + return null; + } + + result = new VariableReference(origin, target_var); + + /* TODO don't rely on the other classes to generate the subrefs. */ + if (subrefs.length > 1) + { + Type t; + final List subrefs_list; + + subrefs_list = new ArrayList(Arrays.asList(subrefs)); + + subrefs_list.remove(0); + + for (final String subref: subrefs_list) + { + t = result.get_type(); + + while (t instanceof PointerType) + { + t = ((PointerType) t).get_referenced_type(); + + result = + AtReference.build + ( + origin.with_hint(subref), + "at", + Collections.singletonList(result) + ); + } + + if (t instanceof CollectionType) + { + result = + Access.build + ( + origin.with_hint(subref), + "collection:access", + Arrays.asList + ( + new Computation[] + { + Constant.build(origin.with_hint(subref), subref), + result + } + ) + ); + } + else if (t instanceof StructType) + { + result = + FieldAccess.build + ( + origin.with_hint(subref), + result, + Collections.singletonList(subref) + ); + } + else + { + ErrorManager.handle + ( + new BasicParsingError + ( + ErrorLevel.ERROR, + ErrorCategory.INVALID_USE, + origin.with_hint(subref), + ( + "Attempting to access a subreference from a value of" + + " type " + + t.toString() + + ", despite this type not being useable in this way." + ) + ) + ); + } + } + } + + return result; + } } diff --git a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 index c8eba75..e4132d2 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 @@ -50,6 +50,8 @@ options import tonkadur.fate.v1.lang.computation.generic.ExtraComputation; import tonkadur.fate.v1.lang.computation.generic.UserComputation; + import tonkadur.fate.v1.lang.computation.generic.Newline; + import tonkadur.fate.v1.lang.instruction.generic.SetValue; import tonkadur.fate.v1.lang.instruction.generic.ExtraInstruction; import tonkadur.fate.v1.lang.instruction.generic.UserInstruction; @@ -1443,12 +1445,12 @@ returns [Instruction result] TEXT_OPTION_KW L_PAREN WS* { - PARSER.enable_restricted_variable_stack_of(pcd); + //PARSER.enable_restricted_variable_stack_of(pcd); } paragraph WS* R_PAREN WS* { - PARSER.disable_restricted_stack_of(pcd); + //PARSER.disable_restricted_stack_of(pcd); PARSER.increase_local_variables_hierarchy(); } maybe_instruction_list WS* @@ -1471,11 +1473,11 @@ returns [Instruction result] | EVENT_OPTION_KW { - PARSER.enable_restricted_variable_stack_of(pcd); + //PARSER.enable_restricted_variable_stack_of(pcd); } L_PAREN WS* word maybe_computation_list WS* R_PAREN WS* { - PARSER.disable_restricted_stack_of(pcd); + //PARSER.disable_restricted_stack_of(pcd); PARSER.increase_local_variables_hierarchy(); } maybe_instruction_list WS* @@ -1521,11 +1523,11 @@ returns [Instruction result] | IF_KW { - PARSER.enable_restricted_variable_stack_of(pcd); + // PARSER.enable_restricted_variable_stack_of(pcd); } computation WS* { - PARSER.disable_restricted_stack_of(pcd); + // PARSER.disable_restricted_stack_of(pcd); } player_choice_list[pcd] WS* R_PAREN @@ -1545,11 +1547,11 @@ returns [Instruction result] | IF_ELSE_KW { - PARSER.enable_restricted_variable_stack_of(pcd); + // PARSER.enable_restricted_variable_stack_of(pcd); } computation WS* { - PARSER.disable_restricted_stack_of(pcd); + // PARSER.disable_restricted_stack_of(pcd); } if_true=player_choice[pcd] WS* if_false=player_choice[pcd] WS* @@ -1585,11 +1587,11 @@ returns [Instruction result] | SWITCH_KW { - PARSER.enable_restricted_variable_stack_of(pcd); + //PARSER.enable_restricted_variable_stack_of(pcd); } computation WS* { - PARSER.disable_restricted_stack_of(pcd); + //PARSER.disable_restricted_stack_of(pcd); } player_choice_switch_list[pcd] WS+ player_choice[pcd] WS* @@ -1612,8 +1614,8 @@ returns [Instruction result] | FOR_KW l0=L_PAREN { - PARSER.enable_restricted_variable_stack_of(pcd); - PARSER.increase_local_variables_hierarchy(); + //PARSER.enable_restricted_variable_stack_of(pcd); + //PARSER.increase_local_variables_hierarchy(); pcd.increase_variable_names_hierarchy(); } choice_for_variable_list[pcd] WS* @@ -1623,15 +1625,15 @@ returns [Instruction result] choice_for_update_variable_list[pcd] WS* R_PAREN WS* { - PARSER.disable_restricted_stack_of(pcd); + //PARSER.disable_restricted_stack_of(pcd); } player_choice_list[pcd] WS* R_PAREN { pcd.decrease_variable_names_hierarchy(); - PARSER.enable_restricted_variable_stack_of(pcd); - PARSER.decrease_local_variables_hierarchy(); - PARSER.disable_restricted_stack_of(pcd); + //PARSER.enable_restricted_variable_stack_of(pcd); + //PARSER.decrease_local_variables_hierarchy(); + //PARSER.disable_restricted_stack_of(pcd); $result = For.build @@ -1666,7 +1668,7 @@ returns [Instruction result] | FOR_EACH_KW { - PARSER.enable_restricted_variable_stack_of(pcd); + //PARSER.enable_restricted_variable_stack_of(pcd); PARSER.increase_local_variables_hierarchy(); } computation WS+ @@ -1722,15 +1724,15 @@ returns [Instruction result] ); PARSER.add_local_variable(new_variable); - PARSER.disable_restricted_stack_of(pcd); + //PARSER.disable_restricted_stack_of(pcd); } WS+ player_choice_list[pcd] WS* R_PAREN { - PARSER.enable_restricted_variable_stack_of(pcd); + //PARSER.enable_restricted_variable_stack_of(pcd); PARSER.decrease_local_variables_hierarchy(); - PARSER.disable_restricted_stack_of(pcd); + //PARSER.disable_restricted_stack_of(pcd); $result = ForEach.build ( @@ -1759,7 +1761,7 @@ returns [List> result] condition = null; $result = new ArrayList>(); - PARSER.enable_restricted_variable_stack_of(pcd); + //PARSER.enable_restricted_variable_stack_of(pcd); } : ( @@ -1769,7 +1771,7 @@ returns [List> result] { condition = ($computation.result); - PARSER.disable_restricted_stack_of(pcd); + // PARSER.disable_restricted_stack_of(pcd); } ) | @@ -1788,7 +1790,7 @@ returns [List> result] ($something_else.text).substring(1).trim() ); - PARSER.disable_restricted_stack_of(pcd); + // PARSER.disable_restricted_stack_of(pcd); } ) ) @@ -1811,14 +1813,14 @@ returns [List> result] @init { $result = new ArrayList>(); - PARSER.enable_restricted_variable_stack_of(pcd); + //PARSER.enable_restricted_variable_stack_of(pcd); } : ( L_PAREN WS* computation { - PARSER.disable_restricted_stack_of(pcd); + // PARSER.disable_restricted_stack_of(pcd); } WS* player_choice[pcd] WS* R_PAREN @@ -2394,7 +2396,14 @@ returns [Computation result] } else { - $result = new AmbiguousWord(PARSER, ($word.origin), ($word.result)); + $result = + new AmbiguousWord + ( + PARSER, + ($word.origin), + ($word.result), + VariableFromWord.attempt(PARSER, ($word.origin), ($word.result)) + ); } } @@ -2810,31 +2819,67 @@ returns [List result] @init { $result = new ArrayList(); + boolean follows_newline, just_added_space; + + just_added_space = false; } : computation { + + if (($computation.result) instanceof Newline) + { + follows_newline = true; + } + else + { + follows_newline = false; + } + + just_added_space = false; + ($result).add(($computation.result)); } ( (WS+ { - ($result).add - ( - Constant.build_string + if (!follows_newline) + { + ($result).add ( - PARSER.get_origin_at + Constant.build_string ( - ($WS.getLine()), - ($WS.getCharPositionInLine()) - ), - " " - ) - ); + PARSER.get_origin_at + ( + ($WS.getLine()), + ($WS.getCharPositionInLine()) + ), + " " + ) + ); + + just_added_space = true; + } } )* computation { + if (($computation.result) instanceof Newline) + { + follows_newline = true; + + if (just_added_space) + { + ($result).remove(($result).size() - 1); + } + } + else + { + follows_newline = false; + } + + just_added_space = false; + ($result).add(($computation.result)); } )* -- cgit v1.2.3-70-g09d2