| summaryrefslogtreecommitdiff |
diff options
6 files changed, 257 insertions, 31 deletions
diff --git a/src/core/src/tonkadur/fate/v1/error/IncompatibleTypeException.java b/src/core/src/tonkadur/fate/v1/error/IncompatibleTypeException.java index b79f293..d1827d3 100644 --- a/src/core/src/tonkadur/fate/v1/error/IncompatibleTypeException.java +++ b/src/core/src/tonkadur/fate/v1/error/IncompatibleTypeException.java @@ -14,6 +14,7 @@ public class IncompatibleTypeException extends ParsingError /***************************************************************************/ protected final Type given_type; protected final Type expected_type; + protected final Type hint; /***************************************************************************/ /**** PUBLIC ***************************************************************/ @@ -34,6 +35,27 @@ public class IncompatibleTypeException extends ParsingError this.given_type = given_type; this.expected_type = expected_type; + this.hint = null; + } + + public IncompatibleTypeException + ( + final Origin call_origin, + final Type given_type, + final Type expected_type, + final Type hint + ) + { + super + ( + ErrorLevel.ERROR, + ErrorCategory.INCOMPATIBLE, + call_origin + ); + + this.given_type = given_type; + this.expected_type = expected_type; + this.hint = hint; } @Override @@ -53,6 +75,13 @@ public class IncompatibleTypeException extends ParsingError sb.append(expected_type.toString()); sb.append("')."); + if (hint != null) + { + sb.append(System.lineSeparator()); + sb.append("Recommended compatible type: "); + sb.append(hint.get_name()); + } + return sb.toString(); } } diff --git a/src/core/src/tonkadur/fate/v1/lang/Cast.java b/src/core/src/tonkadur/fate/v1/lang/Cast.java new file mode 100644 index 0000000..482d203 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/Cast.java @@ -0,0 +1,170 @@ +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; + +import tonkadur.parser.Origin; + +import tonkadur.fate.v1.lang.meta.ValueNode; + +import tonkadur.fate.v1.error.IncompatibleTypeException; +import tonkadur.fate.v1.error.IncomparableTypeException; + +public class Cast extends ValueNode +{ + protected static final Map<Type,Set<Type>> allowed_type_changes; + + static + { + allowed_type_changes = new HashMap<Type,Set<Type>>(); + + allowed_type_changes.put + ( + Type.INT, + Type.NUMBER_TYPES + ); + + allowed_type_changes.put + ( + Type.FLOAT, + Type.NUMBER_TYPES + ); + + allowed_type_changes.put + ( + Type.DICT, + Collections.emptySet() + ); + + allowed_type_changes.put + ( + Type.SET, + Collections.emptySet() + ); + + allowed_type_changes.put + ( + Type.LIST, + Collections.emptySet() + ); + + allowed_type_changes.put + ( + Type.BOOLEAN, + Collections.emptySet() + ); + + allowed_type_changes.put + ( + Type.ANY, + Collections.singleton(Type.ANY) + ); + + allowed_type_changes.put + ( + Type.STRING, + Type.COLLECTION_COMPATIBLE_TYPES + ); + } + /***************************************************************************/ + /**** MEMBERS **************************************************************/ + /***************************************************************************/ + protected final ValueNode value; + + /***************************************************************************/ + /**** PROTECTED ************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + protected Cast + ( + final Origin origin, + final Type to, + final ValueNode value + ) + { + super(origin, to); + this.value = value; + } + + /***************************************************************************/ + /**** PUBLIC ***************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + public static Cast build + ( + final Origin origin, + final Type to, + final ValueNode value + ) + throws + IncompatibleTypeException, + IncomparableTypeException + { + final Type hint; + + if + ( + (value.get_type().can_be_used_as(to)) + || + ( + (to.is_base_type()) + && + ( + allowed_type_changes.get(to).contains + ( + value.get_type().get_true_type() + ) + ) + ) + ) + { + return new Cast(origin, to, value); + } + + hint = (Type) value.get_type().generate_comparable_to(to); + + if (hint.equals(Type.ANY)) + { + ErrorManager.handle + ( + new IncompatibleTypeException(origin, value.get_type(), to) + ); + + ErrorManager.handle + ( + new IncomparableTypeException(origin, value.get_type(), to) + ); + } + else + { + ErrorManager.handle + ( + new IncompatibleTypeException(origin, value.get_type(), to, hint) + ); + } + + return new Cast(origin, hint, value); + } + + /**** Accessors ************************************************************/ + + /**** Misc. ****************************************************************/ + @Override + public String toString () + { + final StringBuilder sb = new StringBuilder(); + + sb.append(origin.toString()); + sb.append("(Cast ("); + sb.append(type.get_name()); + sb.append(") "); + sb.append(value.toString()); + sb.append(")"); + + return sb.toString(); + } +} diff --git a/src/core/src/tonkadur/fate/v1/lang/Operation.java b/src/core/src/tonkadur/fate/v1/lang/Operation.java index 4b05a68..d7efc6c 100644 --- a/src/core/src/tonkadur/fate/v1/lang/Operation.java +++ b/src/core/src/tonkadur/fate/v1/lang/Operation.java @@ -7,7 +7,7 @@ import tonkadur.error.ErrorManager; import tonkadur.parser.Origin; -import tonkadur.fate.v1.error.ConflictingTypeException; +//import tonkadur.fate.v1.error.ConflictingTypeException; import tonkadur.fate.v1.error.IncomparableTypeException; import tonkadur.fate.v1.error.IncompatibleTypeException; import tonkadur.fate.v1.error.InvalidArityException; @@ -41,7 +41,7 @@ public class Operation extends ValueNode final List<ValueNode> operands ) throws - ConflictingTypeException, + //ConflictingTypeException, IncomparableTypeException, IncompatibleTypeException, InvalidArityException, @@ -101,6 +101,8 @@ public class Operation extends ValueNode ); } + /* + if (computed_type.equals(operand_type)) { continue; @@ -116,6 +118,8 @@ public class Operation extends ValueNode ) ); + */ + if (operand_type.can_be_used_as(computed_type)) { continue; diff --git a/src/core/src/tonkadur/fate/v1/lang/meta/DeclarationCollection.java b/src/core/src/tonkadur/fate/v1/lang/meta/DeclarationCollection.java index 81767e9..376befe 100644 --- a/src/core/src/tonkadur/fate/v1/lang/meta/DeclarationCollection.java +++ b/src/core/src/tonkadur/fate/v1/lang/meta/DeclarationCollection.java @@ -160,7 +160,7 @@ public class DeclarationCollection <Declared extends DeclaredEntity> System.exit(-1); } - if (new_version.equals(value_on_missing)) + if (hint.equals(value_on_missing)) { ErrorManager.handle ( diff --git a/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 b/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 index 6f03d0c..4240c1b 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 @@ -13,7 +13,6 @@ L_PAREN: WS* '('; R_PAREN: WS* ')'; ADD_KW: L_PAREN 'add' WS*; -ADD_TO_ENUM_TYPE_KW: L_PAREN 'add_to_enum_type' WS*; ADD_VARIABLE_ATTRIBUTE_KW: L_PAREN 'add_variable_attribute' WS*; AND_KW: L_PAREN ('and'|'/\\') WS*; ASSERT_KW: L_PAREN 'assert' WS*; @@ -23,7 +22,6 @@ COND_KW: L_PAREN 'cond' WS*; COUNT_KW: L_PAREN 'count' WS*; DECLARE_ALIAS_TYPE_KW: L_PAREN 'declare_subtype' WS*; DECLARE_DICT_TYPE_KW: L_PAREN 'declare_dict_type' WS*; -DECLARE_ENUM_TYPE_KW: L_PAREN 'declare_enum_type' WS*; DECLARE_EVENT_TYPE_KW: L_PAREN 'declare_event_type' WS*; DECLARE_TEXT_EFFECT: L_PAREN 'declare_text_effect' WS*; DECLARE_TEXT_EFFECT_KW: L_PAREN 'declare_text_effect' WS*; @@ -36,6 +34,8 @@ EQUALS_KW: L_PAREN ('equals'|'='|'==') WS*; EVENT_KW: L_PAREN 'event' WS*; FALSE_KW: L_PAREN 'false)'; FATE_VERSION_KW: L_PAREN 'fate_version' WS*; +GET_KW: L_PAREN 'get' WS*; +SET_FIELD_KW: L_PAREN 'set_field' WS*; GREATER_EQUAL_THAN_KW: L_PAREN ('greater_equal_than'|'>=') WS*; GREATER_THAN_KW: L_PAREN ('greater_than'|'>') WS*; IF_ELSE_KW: L_PAREN 'if_else' WS*; @@ -57,6 +57,7 @@ POWER_KW: L_PAREN ('power'|'^'|'**') WS*; RANDOM_KW: L_PAREN ('random'|'rand') WS*; REMOVE_ALL_KW: L_PAREN 'remove_all' WS*; REMOVE_ONE_KW: L_PAREN 'remove_one' WS*; +REQUIRE_EXTENSION_KW: L_PAREN 'require_extension' WS*; REQUIRE_KW: L_PAREN 'require' WS*; SEQUENCE_KW: L_PAREN 'sequence' WS*; SET_EXPRESSION_KW: L_PAREN 'set_expression' WS*; diff --git a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 index ccc46db..2585948 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 @@ -117,6 +117,10 @@ first_level_fate_instr: { } + | REQUIRE_EXTENSION_KW name=WORD R_PAREN + { + } + | DECLARE_ALIAS_TYPE_KW parent=WORD WS+ name=WORD R_PAREN { final Origin start_origin, parent_origin; @@ -147,15 +151,19 @@ first_level_fate_instr: { } - | DECLARE_ENUM_TYPE_KW name=WORD R_PAREN + | ADD_KW value WS+ value_reference R_PAREN { } - | DECLARE_EVENT_TYPE_KW name=WORD WS+ word_list R_PAREN + | REMOVE_ONE_KW value WS+ value_reference R_PAREN + { + } + + | REMOVE_ALL_KW value WS+ value_reference R_PAREN { } - | ADD_TO_ENUM_TYPE_KW entry=WORD WS+ name=WORD R_PAREN + | DECLARE_EVENT_TYPE_KW name=WORD WS+ word_list R_PAREN { } @@ -188,8 +196,13 @@ general_fate_instr: { } + | SET_FIELD_KW WORD WS+ value WS+ value_reference R_PAREN + { + } + | SET_EXPRESSION_KW value WS+ value_reference R_PAREN { + /* that one isn't resolved until the value is referenced */ } | EVENT_KW WORD WS+ value_list R_PAREN @@ -609,20 +622,6 @@ catch [final Throwable e] throw new ParseCancellationException(e); } -bag_expression: - | ADD_KW value WS+ value_reference R_PAREN - { - } - - | REMOVE_ONE_KW value WS+ value_reference R_PAREN - { - } - - | REMOVE_ALL_KW value WS+ value_reference R_PAREN - { - } -; - value returns [ValueNode result] : @@ -677,24 +676,43 @@ returns [ValueNode result] $result = ($math_expression.result); } - | CAST_KW WORD WORD value R_PAREN + | CAST_KW WORD value R_PAREN { - /* TODO */ - $result = null; - } + final Origin target_type_origin; + final Type target_type; - | value_reference - { - /* TODO */ - $result = null; + target_type_origin = + CONTEXT.get_origin_at + ( + ($WORD.getLine()), + ($WORD.getCharPositionInLine()) + ); + + target_type = WORLD.types().get(target_type_origin, ($WORD.text)); + + $result = + Cast.build + ( + CONTEXT.get_origin_at + ( + ($WORD.getLine()), + ($WORD.getCharPositionInLine()) + ), + target_type, + ($value.result) + ); } - | SET_KW value WS+ value_reference R_PAREN + | value_reference { /* TODO */ $result = null; } ; +catch [final Throwable e] +{ + throw new ParseCancellationException(e); +} value_reference: VARIABLE_KW WORD R_PAREN @@ -704,6 +722,10 @@ value_reference: | PARAMETER_KW WORD R_PAREN { } + + | GET_KW value_reference R_PAREN + { + } ; value_cond_list: |


