summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/computation/AmbiguousWord.java30
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/computation/generic/Newline.java1
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/meta/VariableFromWord.java112
-rw-r--r--src/core/src/tonkadur/fate/v1/parser/FateParser.g4117
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<String>();
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<String> 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<Cons<Computation, Instruction>> result]
condition = null;
$result = new ArrayList<Cons<Computation, Instruction>>();
- PARSER.enable_restricted_variable_stack_of(pcd);
+ //PARSER.enable_restricted_variable_stack_of(pcd);
}
:
(
@@ -1769,7 +1771,7 @@ returns [List<Cons<Computation, Instruction>> result]
{
condition = ($computation.result);
- PARSER.disable_restricted_stack_of(pcd);
+ // PARSER.disable_restricted_stack_of(pcd);
}
)
|
@@ -1788,7 +1790,7 @@ returns [List<Cons<Computation, Instruction>> 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<Cons<Computation, Instruction>> result]
@init
{
$result = new ArrayList<Cons<Computation, Instruction>>();
- 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<Computation> result]
@init
{
$result = new ArrayList<Computation>();
+ 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));
}
)*