summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2020-07-08 00:20:52 +0200
committerNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2020-07-08 00:20:52 +0200
commit88657c6dba477efeb42dd1b94d7636f5633b38d4 (patch)
tree8fe02c41c24d431a2e23825c1ef51d49934d6f7a
parent6a30ee067c8ef61193873c2a598e91d524d2e51b (diff)
Adds Conditional switch for values.
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/CondValue.java138
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/IfElseValue.java19
-rw-r--r--src/core/src/tonkadur/fate/v1/parser/FateLexer.g43
-rw-r--r--src/core/src/tonkadur/fate/v1/parser/FateParser.g4121
-rw-r--r--src/core/src/tonkadur/parser/Context.java5
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)
{