| summaryrefslogtreecommitdiff | 
diff options
Diffstat (limited to 'src')
21 files changed, 653 insertions, 150 deletions
| diff --git a/src/core/src/tonkadur/Main.java b/src/core/src/tonkadur/Main.java index c8f8f1b..382dab6 100644 --- a/src/core/src/tonkadur/Main.java +++ b/src/core/src/tonkadur/Main.java @@ -2,6 +2,8 @@ package tonkadur;  import java.io.IOException; +import tonkadur.parser.Context; +  import tonkadur.fate.v1.lang.World;  import tonkadur.fate.v1.Utils; @@ -15,9 +17,14 @@ public class Main     throws IOException     {        final World world; +      final Context context;        world = new World(); +      context = new Context(args[0]); + +      Utils.add_file_content(args[0], context, world); -      Utils.add_file_content(args[0], world); +      System.out.println("Parsing completed."); +      System.out.println(world.toString());     }  } diff --git a/src/core/src/tonkadur/fate/v1/Utils.java b/src/core/src/tonkadur/fate/v1/Utils.java index 562adee..1049e0d 100644 --- a/src/core/src/tonkadur/fate/v1/Utils.java +++ b/src/core/src/tonkadur/fate/v1/Utils.java @@ -5,6 +5,8 @@ import java.io.IOException;  import org.antlr.v4.runtime.CharStreams;  import org.antlr.v4.runtime.CommonTokenStream; +import tonkadur.parser.Context; +  import tonkadur.fate.v1.parser.FateLexer;  import tonkadur.fate.v1.parser.FateParser; @@ -18,6 +20,7 @@ public class Utils     public static void add_file_content     (        final String filename, +      final Context context,        final World world     )     throws IOException @@ -30,6 +33,13 @@ public class Utils        tokens = new CommonTokenStream(lexer);        parser = new FateParser(tokens); -      parser.fate_file(world); +      parser.fate_file(context, world); + +      world.add_loaded_file(filename); + +      if (parser.getNumberOfSyntaxErrors() > 0) +      { +         throw new IOException("There were syntaxic errors in" + filename); +      }     }  } diff --git a/src/core/src/tonkadur/fate/v1/error/ConflictingDeclarationException.java b/src/core/src/tonkadur/fate/v1/error/ConflictingDeclarationException.java index 34e1a98..fdd93b8 100644 --- a/src/core/src/tonkadur/fate/v1/error/ConflictingDeclarationException.java +++ b/src/core/src/tonkadur/fate/v1/error/ConflictingDeclarationException.java @@ -40,9 +40,12 @@ public class ConflictingDeclarationException extends ParsingError     {        final StringBuilder sb = new StringBuilder(); -      sb.append(origin.get_context().toString()); +      sb.append(origin.toString()); +      sb.append(" ");        sb.append(error_category.toString()); -      sb.append(" Declaration for "); +      sb.append(System.lineSeparator()); + +      sb.append("Declaration for ");        sb.append(original_declaration.get_type_name());        sb.append(" '");        sb.append(original_declaration.get_name()); diff --git a/src/core/src/tonkadur/fate/v1/error/ConflictingTypeException.java b/src/core/src/tonkadur/fate/v1/error/ConflictingTypeException.java index 3cf287e..f084ea9 100644 --- a/src/core/src/tonkadur/fate/v1/error/ConflictingTypeException.java +++ b/src/core/src/tonkadur/fate/v1/error/ConflictingTypeException.java @@ -41,9 +41,12 @@ public class ConflictingTypeException extends ParsingError     {        final StringBuilder sb = new StringBuilder(); -      sb.append(origin.get_context().toString()); +      sb.append(origin.toString()); +      sb.append(" ");        sb.append(error_category.toString()); -      sb.append(" Resulting type '"); +      sb.append(System.lineSeparator()); + +      sb.append("Resulting type '");        sb.append(given_type.get_name());        sb.append("' ");        sb.append(" conflicts with the expected one ('"); diff --git a/src/core/src/tonkadur/fate/v1/error/DuplicateDeclarationException.java b/src/core/src/tonkadur/fate/v1/error/DuplicateDeclarationException.java index eb42aba..5e0b5d0 100644 --- a/src/core/src/tonkadur/fate/v1/error/DuplicateDeclarationException.java +++ b/src/core/src/tonkadur/fate/v1/error/DuplicateDeclarationException.java @@ -32,9 +32,12 @@ public class DuplicateDeclarationException extends ParsingError     {        final StringBuilder sb = new StringBuilder(); -      sb.append(origin.get_context().toString()); +      sb.append(origin.toString()); +      sb.append(" ");        sb.append(error_category.toString()); -      sb.append(" Declaration for "); +      sb.append(System.lineSeparator()); + +      sb.append("Declaration for ");        sb.append(original_declaration.get_type_name());        sb.append(" '");        sb.append(original_declaration.get_name()); diff --git a/src/core/src/tonkadur/fate/v1/error/IncomparableDeclarationException.java b/src/core/src/tonkadur/fate/v1/error/IncomparableDeclarationException.java index c5dfc94..d4968ce 100644 --- a/src/core/src/tonkadur/fate/v1/error/IncomparableDeclarationException.java +++ b/src/core/src/tonkadur/fate/v1/error/IncomparableDeclarationException.java @@ -40,9 +40,12 @@ public class IncomparableDeclarationException extends ParsingError     {        final StringBuilder sb = new StringBuilder(); -      sb.append(origin.get_context().toString()); +      sb.append(origin.toString()); +      sb.append(" ");        sb.append(error_category.toString()); -      sb.append(" Declaration for "); +      sb.append(System.lineSeparator()); + +      sb.append("Declaration for ");        sb.append(original_declaration.get_type_name());        sb.append(" '");        sb.append(original_declaration.get_name()); diff --git a/src/core/src/tonkadur/fate/v1/error/IncomparableTypeException.java b/src/core/src/tonkadur/fate/v1/error/IncomparableTypeException.java index 19ae9d6..b3fa548 100644 --- a/src/core/src/tonkadur/fate/v1/error/IncomparableTypeException.java +++ b/src/core/src/tonkadur/fate/v1/error/IncomparableTypeException.java @@ -41,9 +41,12 @@ public class IncomparableTypeException extends ParsingError     {        final StringBuilder sb = new StringBuilder(); -      sb.append(origin.get_context().toString()); +      sb.append(origin.toString()); +      sb.append(" ");        sb.append(error_category.toString()); -      sb.append(" Resulting type '"); +      sb.append(System.lineSeparator()); + +      sb.append("Resulting type '");        sb.append(given_type.toString());        sb.append("' ");        sb.append(" is incomparable with the expected one ('"); diff --git a/src/core/src/tonkadur/fate/v1/error/IncompatibleDeclarationException.java b/src/core/src/tonkadur/fate/v1/error/IncompatibleDeclarationException.java index ce8792a..8e46283 100644 --- a/src/core/src/tonkadur/fate/v1/error/IncompatibleDeclarationException.java +++ b/src/core/src/tonkadur/fate/v1/error/IncompatibleDeclarationException.java @@ -61,9 +61,12 @@ public class IncompatibleDeclarationException extends ParsingError     {        final StringBuilder sb = new StringBuilder(); -      sb.append(origin.get_context().toString()); +      sb.append(origin.toString()); +      sb.append(" ");        sb.append(error_category.toString()); -      sb.append(" Declaration for "); +      sb.append(System.lineSeparator()); + +      sb.append("Declaration for ");        sb.append(original_declaration.get_type_name());        sb.append(" '");        sb.append(original_declaration.get_name()); diff --git a/src/core/src/tonkadur/fate/v1/error/IncompatibleTypeException.java b/src/core/src/tonkadur/fate/v1/error/IncompatibleTypeException.java index da05cb9..b79f293 100644 --- a/src/core/src/tonkadur/fate/v1/error/IncompatibleTypeException.java +++ b/src/core/src/tonkadur/fate/v1/error/IncompatibleTypeException.java @@ -41,9 +41,12 @@ public class IncompatibleTypeException extends ParsingError     {        final StringBuilder sb = new StringBuilder(); -      sb.append(origin.get_context().toString()); +      sb.append(origin.toString()); +      sb.append(" ");        sb.append(error_category.toString()); -      sb.append(" Resulting type '"); +      sb.append(System.lineSeparator()); + +      sb.append("Resulting type '");        sb.append(given_type.toString());        sb.append("' ");        sb.append(" is incompatible with the expected one ('"); diff --git a/src/core/src/tonkadur/fate/v1/error/InvalidArityException.java b/src/core/src/tonkadur/fate/v1/error/InvalidArityException.java index 578ce60..f4f8205 100644 --- a/src/core/src/tonkadur/fate/v1/error/InvalidArityException.java +++ b/src/core/src/tonkadur/fate/v1/error/InvalidArityException.java @@ -10,7 +10,8 @@ public class InvalidArityException extends ParsingError     /***************************************************************************/     /**** MEMBERS **************************************************************/     /***************************************************************************/ -   protected final int arity; +   protected final int min_arity; +   protected final int max_arity;     protected final int arguments_count;     /***************************************************************************/ @@ -20,7 +21,8 @@ public class InvalidArityException extends ParsingError     (        final Origin call_origin,        final int arguments_count, -      final int arity +      final int min_arity, +      final int max_arity     )     {        super @@ -31,7 +33,8 @@ public class InvalidArityException extends ParsingError        );        this.arguments_count = arguments_count; -      this.arity = arity; +      this.min_arity = min_arity; +      this.max_arity = max_arity;     }     @Override @@ -39,10 +42,20 @@ public class InvalidArityException extends ParsingError     {        final StringBuilder sb = new StringBuilder(); -      sb.append(origin.get_context().toString()); +      sb.append(origin.toString()); +      sb.append(" ");        sb.append(error_category.toString()); -      sb.append(" This supports a maximum or a minimum of "); -      sb.append(arity); +      sb.append(System.lineSeparator()); + +      sb.append("This supports a minimum of "); +      sb.append(min_arity); + +      if (max_arity > 0) +      { +         sb.append(" and a maximum of "); +         sb.append(max_arity); +      } +        sb.append(" parameter(s), but was given ");        sb.append(arguments_count);        sb.append(" of them."); diff --git a/src/core/src/tonkadur/fate/v1/error/InvalidTypeException.java b/src/core/src/tonkadur/fate/v1/error/InvalidTypeException.java index 6a62edd..eb9d158 100644 --- a/src/core/src/tonkadur/fate/v1/error/InvalidTypeException.java +++ b/src/core/src/tonkadur/fate/v1/error/InvalidTypeException.java @@ -43,9 +43,12 @@ public class InvalidTypeException extends ParsingError     {        final StringBuilder sb = new StringBuilder(); -      sb.append(origin.get_context().toString()); +      sb.append(origin.toString()); +      sb.append(" ");        sb.append(error_category.toString()); -      sb.append(" Type '"); +      sb.append(System.lineSeparator()); + +      sb.append("Type '");        sb.append(given_type.toString());        sb.append("' ");        sb.append(" is not useable here. The following base types are allowed:"); @@ -54,7 +57,7 @@ public class InvalidTypeException extends ParsingError        {           sb.append(System.lineSeparator());           sb.append("- "); -         sb.append(allowed_types.toString()); +         sb.append(allowed_type.toString());        }        return sb.toString(); diff --git a/src/core/src/tonkadur/fate/v1/error/MissingDeclarationException.java b/src/core/src/tonkadur/fate/v1/error/MissingDeclarationException.java index c4cb08f..57c2932 100644 --- a/src/core/src/tonkadur/fate/v1/error/MissingDeclarationException.java +++ b/src/core/src/tonkadur/fate/v1/error/MissingDeclarationException.java @@ -33,9 +33,12 @@ public class MissingDeclarationException extends ParsingError     {        final StringBuilder sb = new StringBuilder(); -      sb.append(origin.get_context().toString()); +      sb.append(origin.toString()); +      sb.append(" ");        sb.append(error_category.toString()); -      sb.append(" Unknown "); +      sb.append(System.lineSeparator()); + +      sb.append("Unknown ");        sb.append(type_name);        sb.append(" '");        sb.append(name); diff --git a/src/core/src/tonkadur/fate/v1/error/UnknownDictionaryFieldException.java b/src/core/src/tonkadur/fate/v1/error/UnknownDictionaryFieldException.java index a624fb8..dd3e67d 100644 --- a/src/core/src/tonkadur/fate/v1/error/UnknownDictionaryFieldException.java +++ b/src/core/src/tonkadur/fate/v1/error/UnknownDictionaryFieldException.java @@ -38,9 +38,12 @@ public class UnknownDictionaryFieldException extends ParsingError     {        final StringBuilder sb = new StringBuilder(); -      sb.append(origin.get_context().toString()); +      sb.append(origin.toString()); +      sb.append(" ");        sb.append(error_category.toString()); -      sb.append(" Unknown field '"); +      sb.append(System.lineSeparator()); + +      sb.append("Unknown field '");        sb.append(field_name);        sb.append("' for dictionary type '");        sb.append(dict.get_name()); diff --git a/src/core/src/tonkadur/fate/v1/lang/Constant.java b/src/core/src/tonkadur/fate/v1/lang/Constant.java index 7123b26..9c13b1f 100644 --- a/src/core/src/tonkadur/fate/v1/lang/Constant.java +++ b/src/core/src/tonkadur/fate/v1/lang/Constant.java @@ -31,7 +31,16 @@ public class Constant extends ValueNode     /**** PUBLIC ***************************************************************/     /***************************************************************************/     /**** Constructors *********************************************************/ -   public Constant build (final Origin origin, final String as_string) +   public static Constant build_boolean +   ( +      final Origin origin, +      final boolean value +   ) +   { +      return new Constant(origin, Type.BOOLEAN, value ? "true" : "false"); +   } + +   public static Constant build (final Origin origin, final String as_string)     {        try        { @@ -55,17 +64,6 @@ public class Constant extends ValueNode           /* That's fine, we're just testing... */        } -      try -      { -         Boolean.valueOf(as_string); - -         return new Constant(origin, Type.BOOLEAN, as_string); -      } -      catch (final NumberFormatException nfe) -      { -         /* That's fine, we're just testing... */ -      } -        return new Constant(origin, Type.STRING, as_string);     } diff --git a/src/core/src/tonkadur/fate/v1/lang/Operation.java b/src/core/src/tonkadur/fate/v1/lang/Operation.java index b193f5b..4b05a68 100644 --- a/src/core/src/tonkadur/fate/v1/lang/Operation.java +++ b/src/core/src/tonkadur/fate/v1/lang/Operation.java @@ -34,7 +34,7 @@ public class Operation extends ValueNode        this.operands = operands;     } -   public Operation build +   public static Operation build     (        final Origin origin,        final Operator operator, @@ -48,21 +48,35 @@ public class Operation extends ValueNode        InvalidTypeException     {        final Collection<Type> allowed_base_types; -      final int operator_arity; +      final int operator_max_arity; +      final int operator_min_arity; +      final int operands_size;        Type computed_type, previous_computed_type;        allowed_base_types = operator.get_allowed_base_types(); -      operator_arity = operator.get_arity(); +      operator_max_arity = operator.get_maximum_arity(); +      operator_min_arity = operator.get_minimum_arity(); +      operands_size = operands.size();        if        ( -         (operator_arity != 0) -         && (operator_arity < operands.size()) +         (operands_size < operator_min_arity) +         || +         ( +            (operator_max_arity != 0) +            && (operator_max_arity < operands_size) +         )        )        {           ErrorManager.handle           ( -            new InvalidArityException(origin, operands.size(), operator_arity) +            new InvalidArityException +            ( +               origin, +               operands_size, +               operator_min_arity, +               operator_max_arity +            )           );        } diff --git a/src/core/src/tonkadur/fate/v1/lang/Operator.java b/src/core/src/tonkadur/fate/v1/lang/Operator.java index 9e2e522..84681d7 100644 --- a/src/core/src/tonkadur/fate/v1/lang/Operator.java +++ b/src/core/src/tonkadur/fate/v1/lang/Operator.java @@ -5,38 +5,44 @@ import java.util.Set;  public enum Operator  { -   PLUS("+", 0, Type.NUMBER_TYPES, null), -   MINUS("-", 0, Type.NUMBER_TYPES, null), -   TIMES("*", 0, Type.NUMBER_TYPES, null), -   DIVIDED("/", 0, Type.NUMBER_TYPES, null), -   POWER("^", 2, Type.NUMBER_TYPES, null), -   RANDOM("rand", 2, Collections.singleton(Type.INT), null), +   PLUS("+", 2, 0, Type.NUMBER_TYPES, null), +   MINUS("-", 2, 0, Type.NUMBER_TYPES, null), +   TIMES("*", 2, 0, Type.NUMBER_TYPES, null), +   DIVIDE("/", 2, 2, Type.NUMBER_TYPES, null), +   POWER("^", 2, 2, Type.NUMBER_TYPES, null), +   RANDOM("rand", 2, 2, Collections.singleton(Type.INT), null), -   AND("and", 0, Collections.singleton(Type.BOOLEAN), null), -   OR("or", 0, Collections.singleton(Type.BOOLEAN), null), -   NOT("not", 1, Collections.singleton(Type.BOOLEAN), null), -   IMPLIES("implies", 1, Collections.singleton(Type.BOOLEAN), null), +   AND("and", 2, 0, Collections.singleton(Type.BOOLEAN), null), +   OR("or", 2, 0, Collections.singleton(Type.BOOLEAN), null), +   NOT("not", 1, 1, Collections.singleton(Type.BOOLEAN), null), +   IMPLIES("implies", 2, 2, Collections.singleton(Type.BOOLEAN), null), +   ONE_IN("one_in", 1, 0, Collections.singleton(Type.BOOLEAN), null), -   LOWER_THAN("<", 2, Type.NUMBER_TYPES, Type.BOOLEAN), -   LOWER_EQUAL_THAN("=<", 2, Type.NUMBER_TYPES, Type.BOOLEAN), -   GREATER_EQUAL_THAN(">=", 2, Type.NUMBER_TYPES, Type.BOOLEAN), -   GREATER_THAN(">", 2, Type.NUMBER_TYPES, Type.BOOLEAN); +   EQUALS("equals", 2, 0, Type.COLLECTION_COMPATIBLE_TYPES, Type.BOOLEAN), + +   LOWER_THAN("<", 2, 2, Type.NUMBER_TYPES, Type.BOOLEAN), +   LOWER_EQUAL_THAN("=<", 2, 2, Type.NUMBER_TYPES, Type.BOOLEAN), +   GREATER_EQUAL_THAN(">=", 2, 2, Type.NUMBER_TYPES, Type.BOOLEAN), +   GREATER_THAN(">", 2, 2, Type.NUMBER_TYPES, Type.BOOLEAN);     final private String name; -   final private int arity; +   final private int min_arity; +   final private int max_arity;     final private Set<Type> valid_input_types;     final private Type output_type_transform;     private Operator     (        final String name, -      final int arity, +      final int min_arity, +      final int max_arity,        final Set<Type> valid_input_types,        final Type output_type_transform     )     {        this.name = name; -      this.arity = arity; +      this.min_arity = min_arity; +      this.max_arity = max_arity;        this.valid_input_types = valid_input_types;        this.output_type_transform = output_type_transform; @@ -47,9 +53,14 @@ public enum Operator        return valid_input_types;     } -   public int get_arity () +   public int get_minimum_arity () +   { +      return min_arity; +   } + +   public int get_maximum_arity ()     { -      return arity; +      return max_arity;     }     public Type transform_type (final Type in) diff --git a/src/core/src/tonkadur/fate/v1/lang/World.java b/src/core/src/tonkadur/fate/v1/lang/World.java index 5db6d16..43feb5f 100644 --- a/src/core/src/tonkadur/fate/v1/lang/World.java +++ b/src/core/src/tonkadur/fate/v1/lang/World.java @@ -72,6 +72,41 @@ public class World     }     /**** Misc. ****************************************************************/ +   @Override +   public String toString () +   { +      final StringBuilder sb = new StringBuilder(); + +      sb.append("(World"); +      sb.append(System.lineSeparator()); +      sb.append(System.lineSeparator()); +      sb.append("Loaded files: "); +      sb.append(System.lineSeparator()); + +      for (final String filename: loaded_files) +      { +         sb.append("- "); +         sb.append(filename); +         sb.append(System.lineSeparator()); +      } + +      sb.append(System.lineSeparator()); +      sb.append("Events: "); +      sb.append(System.lineSeparator()); +      sb.append(event_collection.toString()); +      sb.append(System.lineSeparator()); +      sb.append(System.lineSeparator()); + +      sb.append("Types: "); +      sb.append(System.lineSeparator()); +      sb.append(type_collection.toString()); +      sb.append(System.lineSeparator()); +      sb.append(System.lineSeparator()); + +      sb.append(")"); + +      return sb.toString(); +   }     /***************************************************************************/     /**** PROTECTED ************************************************************/ 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 04bbfa9..81767e9 100644 --- a/src/core/src/tonkadur/fate/v1/lang/meta/DeclarationCollection.java +++ b/src/core/src/tonkadur/fate/v1/lang/meta/DeclarationCollection.java @@ -80,6 +80,27 @@ public class DeclarationCollection <Declared extends DeclaredEntity>        return result;     } +   /**** Misc. ****************************************************************/ +   public String toString () +   { +      final StringBuilder sb = new StringBuilder(); + +      sb.append("Default Value: "); +      sb.append(value_on_missing.toString()); +      sb.append(System.lineSeparator()); + +      for (final Map.Entry<String, Declared> entry: collection.entrySet()) +      { +         sb.append("- "); +         sb.append(entry.getKey()); +         sb.append(": "); +         sb.append(entry.getValue().toString()); +         sb.append(System.lineSeparator()); +      } + +      return sb.toString(); +   } +     /***************************************************************************/     /**** PROTECTED ************************************************************/     /***************************************************************************/ diff --git a/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 b/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 index 3671a4f..6f03d0c 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 @@ -15,54 +15,56 @@ 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*; +AND_KW: L_PAREN ('and'|'/\\') WS*;  ASSERT_KW: L_PAREN 'assert' WS*; +CAST_KW: L_PAREN 'cast' WS*;  CLEAR_KW: L_PAREN 'clear' WS*;  COND_KW: L_PAREN 'cond' WS*;  COUNT_KW: L_PAREN 'count' WS*; -DECLARE_ALIAS_TYPE_KW: L_PAREN 'declare_alias_type' 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*;  DECLARE_VARIABLE_KW: L_PAREN 'declare_variable' WS*;  DEFINE_MACRO_KW: L_PAREN 'define_macro' WS*;  DEFINE_SEQUENCE_KW: L_PAREN 'define_sequence' WS*; -DIVIDE_KW: L_PAREN 'divide' WS*; +DIVIDE_KW: L_PAREN ('divide'|'/') WS*;  ENABLE_TEXT_PARAMETER_KW: L_PAREN 'enable_text_parameter' WS*; -EQUALS_KW: L_PAREN 'equals' WS*; +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*; -GREATER_EQUAL_THAN_KW: L_PAREN 'greater_equal_than' WS*; -GREATER_THAN_KW: L_PAREN 'greater_than' 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*;  IF_KW: L_PAREN 'if' WS*; -IMPLIES_KW: L_PAREN 'implies' WS*; +IMPLIES_KW: L_PAREN ('implies'|'=>') WS*;  IS_MEMBER_KW: L_PAREN 'is_member' WS*; -LOWER_EQUAL_THAN_KW: L_PAREN 'lower_equal_than' WS*; -LOWER_THAN_KW: L_PAREN 'lower_than' WS*; +LOWER_EQUAL_THAN_KW: L_PAREN ('lower_equal_than'|'=<'|'<=') WS*; +LOWER_THAN_KW: L_PAREN ('lower_than'|'<') WS*;  MACRO_KW: L_PAREN 'macro' WS*; -MINUS_KW: L_PAREN 'minus' WS*; +MINUS_KW: L_PAREN ('minus'|'-') WS*;  NEWLINE_KW: L_PAREN 'newline' WS*; -NOT_KW: L_PAREN 'not' WS*; +NOT_KW: L_PAREN ('not'|'~'|'!') WS*;  ONE_IN_KW: L_PAREN 'one_in' WS*; -OR_KW: L_PAREN 'or' WS*; +OR_KW: L_PAREN ('or'|'\\/') WS*;  PARAMETER_KW: L_PAREN 'parameter' WS*; -PLUS_KW: L_PAREN 'plus' WS*; -POWER_KW: L_PAREN 'power' WS*; -RANDOM_KW: L_PAREN 'random' WS*; -DECLARE_TEXT_EFFECT_KW: L_PAREN 'declare_text_effect' WS*;  PLAYER_CHOICE_KW: L_PAREN 'player_choice' WS*; -CAST_KW: L_PAREN 'cast' WS*; +PLUS_KW: L_PAREN ('plus'|'+') WS*; +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_KW: L_PAREN 'require' WS*;  SEQUENCE_KW: L_PAREN 'sequence' WS*;  SET_EXPRESSION_KW: L_PAREN 'set_expression' WS*;  SET_KW: L_PAREN 'set' WS*; -TIMES_KW: L_PAREN 'times' WS*; +TIMES_KW: L_PAREN ('times'|'*') WS*; +TRUE_KW: L_PAREN 'true)';  VARIABLE_KW: L_PAREN 'variable' WS*; -WORD: (~([\t\r\n()])|'\\)'|'\\(')+; +WORD: (~([ \t\r\n()])|'\\)'|'\\(')+;  COMMENT: WS* ';' .*? '\n' -> channel(HIDDEN); diff --git a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 index 273722f..ccc46db 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 @@ -9,19 +9,32 @@ options  {     package tonkadur.fate.v1.parser; -   import tonkadur.fate.v1.lang.World; +   import tonkadur.error.Error; + +   import tonkadur.parser.Context; +   import tonkadur.parser.Origin; + +   import tonkadur.fate.v1.lang.*; +   import tonkadur.fate.v1.lang.meta.*;  }  @members  { -   /* of the class */ +   Context CONTEXT; +   World WORLD;  }  /******************************************************************************/  /******************************************************************************/  /******************************************************************************/ -fate_file [World world]: -   WS* FATE_VERSION_KW WORD L_PAREN WS* +fate_file [Context context, World world] +   @init +   { +      CONTEXT = context; +      WORLD = world; +   } +   : +   WS* FATE_VERSION_KW WORD R_PAREN WS*     (        (first_level_fate_instr|general_fate_instr)        { @@ -40,24 +53,94 @@ general_fate_sequence:  ;  first_level_fate_instr: -   DEFINE_SEQUENCE_KW WORD WS+ general_fate_sequence R_PAREN +   DEFINE_SEQUENCE_KW WORD WS+ first_node=general_fate_sequence R_PAREN +   { +   /* +      world.sequences().add +      ( +         CONTEXT.get_origin_at +         ( +            ($DEFINE_SEQUENCE_KW.getLine()), +            ($DEFINE_SEQUENCE_KW.getCharPositionInLine()) +         ), +         ($WORD.text), +         //(first_node.result) +      ); +   */ +   } + +   | DECLARE_VARIABLE_KW scope=WORD WS+ type=WORD WS+ name=WORD R_PAREN +   { +   /* +      final Origin start_origin, scope_origin, type_origin; +      final VariableScope variable_scope; +      final Type variable_type; +      final Variable new_variable; + +      start_origin = +         CONTEXT.get_origin_at +         ( +            ($DECLARE_VARIABLE_KW.getLine()), +            ($DECLARE_VARIABLE_KW.getCharPositionInLine()) +         ); + +      scope_origin = +         CONTEXT.get_origin_at +         ( +            ($scope.getLine()), +            ($scope.getCharPositionInLine()) +         ); + +      type_origin = +         CONTEXT.get_origin_at +         ( +            ($type.getLine()), +            ($type.getCharPositionInLine()) +         ); + +      variable_scope = VariableScope.value_of(scope_origin, ($scope.text)); +      variable_type = WORLD.types().get(($type.text)); +      new_variable = +         new Variable +         ( +            start_origin, +            variable_scope, +            variable_type, +            ($name.text) +         ); + +      WORLD.variables().add(new_variable); +   */ +   } + +   | DECLARE_TEXT_EFFECT_KW params=word_list name=WORD R_PAREN     {     } -   | DECLARE_VARIABLE_KW range=WORD WS+ type=WORD WS+ name=WORD R_PAREN +   | DECLARE_ALIAS_TYPE_KW parent=WORD WS+ name=WORD R_PAREN     { -   } +      final Origin start_origin, parent_origin; +      final Type parent_type; +      final Type new_type; -   | DECLARE_TEXT_EFFECT_KW range=WORD R_PAREN -   { -   } +      start_origin = +         CONTEXT.get_origin_at +         ( +            ($DECLARE_ALIAS_TYPE_KW.getLine()), +            ($DECLARE_ALIAS_TYPE_KW.getCharPositionInLine()) +         ); -   | ADD_VARIABLE_ATTRIBUTE_KW WORD WS+ WORD R_PAREN -   { -   } +      parent_origin = +         CONTEXT.get_origin_at +         ( +            ($parent.getLine()), +            ($parent.getCharPositionInLine()) +         ); -   | DECLARE_ALIAS_TYPE_KW parent=WORD WS+ name=WORD R_PAREN -   { +      parent_type = WORLD.types().get(parent_origin, ($parent.text)); +      new_type = new Type(start_origin, parent_type, ($name.text)); + +      WORLD.types().add(new_type);     }     | DECLARE_DICT_TYPE_KW name=WORD typed_param_list R_PAREN @@ -87,9 +170,13 @@ first_level_fate_instr:     {     }  ; +catch [final Throwable e] +{ +   throw new ParseCancellationException(e); +}  general_fate_instr: -   L_PAREN general_fate_sequence R_PAREN +   L_PAREN WS+ general_fate_sequence R_PAREN     {     } @@ -228,81 +315,299 @@ typed_param_list:  /******************************************************************************/  /**** VALUES ******************************************************************/  /******************************************************************************/ -boolean_expression: -   AND_KW value_list R_PAREN -   { +boolean_expression +returns [ValueNode result]: +   TRUE_KW +   { +      $result = +         Constant.build_boolean +         ( +            CONTEXT.get_origin_at +            ( +               ($TRUE_KW.getLine()), +               ($TRUE_KW.getCharPositionInLine()) +            ), +            true +         ); +   } + +   | FALSE_KW +   { +      $result = +         Constant.build_boolean +         ( +            CONTEXT.get_origin_at +            ( +               ($FALSE_KW.getLine()), +               ($FALSE_KW.getCharPositionInLine()) +            ), +            false +         ); +   } + +   | AND_KW value_list R_PAREN +   { +      $result = +         Operation.build +         ( +            CONTEXT.get_origin_at +            ( +               ($AND_KW.getLine()), +               ($AND_KW.getCharPositionInLine()) +            ), +            Operator.AND, +            ($value_list.result) +         );     }     | OR_KW value_list R_PAREN     { +      $result = +         Operation.build +         ( +            CONTEXT.get_origin_at +            ( +               ($OR_KW.getLine()), +               ($OR_KW.getCharPositionInLine()) +            ), +            Operator.OR, +            ($value_list.result) +         );     }     | ONE_IN_KW value_list R_PAREN     { -   } - -   | NOT_KW value R_PAREN -   { -   } - -   | IMPLIES_KW value WS+ value R_PAREN -   { -   } - -   | LOWER_THAN_KW value WS+ value R_PAREN -   { -   } - -   | LOWER_EQUAL_THAN_KW value WS+ value R_PAREN -   { -   } - -   | EQUALS_KW value WS+ value R_PAREN -   { -   } - -   | GREATER_EQUAL_THAN_KW value WS+ value R_PAREN -   { -   } - -   | GREATER_THAN_KW value WS+ value R_PAREN -   { +      $result = +         Operation.build +         ( +            CONTEXT.get_origin_at +            ( +               ($ONE_IN_KW.getLine()), +               ($ONE_IN_KW.getCharPositionInLine()) +            ), +            Operator.ONE_IN, +            ($value_list.result) +         ); +   } + +   | NOT_KW value_list R_PAREN +   { +      $result = +         Operation.build +         ( +            CONTEXT.get_origin_at +            ( +               ($NOT_KW.getLine()), +               ($NOT_KW.getCharPositionInLine()) +            ), +            Operator.NOT, +            ($value_list.result) +         ); +   } + +   | IMPLIES_KW value_list R_PAREN +   { +      $result = +         Operation.build +         ( +            CONTEXT.get_origin_at +            ( +               ($IMPLIES_KW.getLine()), +               ($IMPLIES_KW.getCharPositionInLine()) +            ), +            Operator.IMPLIES, +            ($value_list.result) +         ); +   } + +   | LOWER_THAN_KW value_list R_PAREN +   { +      $result = +         Operation.build +         ( +            CONTEXT.get_origin_at +            ( +               ($LOWER_THAN_KW.getLine()), +               ($LOWER_THAN_KW.getCharPositionInLine()) +            ), +            Operator.LOWER_THAN, +            ($value_list.result) +         ); +   } + +   | LOWER_EQUAL_THAN_KW value_list R_PAREN +   { +      $result = +         Operation.build +         ( +            CONTEXT.get_origin_at +            ( +               ($LOWER_EQUAL_THAN_KW.getLine()), +               ($LOWER_EQUAL_THAN_KW.getCharPositionInLine()) +            ), +            Operator.LOWER_EQUAL_THAN, +            ($value_list.result) +         ); +   } + +   | EQUALS_KW value_list R_PAREN +   { +      $result = +         Operation.build +         ( +            CONTEXT.get_origin_at +            ( +               ($EQUALS_KW.getLine()), +               ($EQUALS_KW.getCharPositionInLine()) +            ), +            Operator.EQUALS, +            ($value_list.result) +         ); +   } + +   | GREATER_EQUAL_THAN_KW value_list R_PAREN +   { +      $result = +         Operation.build +         ( +            CONTEXT.get_origin_at +            ( +               ($GREATER_EQUAL_THAN_KW.getLine()), +               ($GREATER_EQUAL_THAN_KW.getCharPositionInLine()) +            ), +            Operator.GREATER_EQUAL_THAN, +            ($value_list.result) +         ); +   } + +   | GREATER_THAN_KW value_list R_PAREN +   { +      $result = +         Operation.build +         ( +            CONTEXT.get_origin_at +            ( +               ($GREATER_THAN_KW.getLine()), +               ($GREATER_THAN_KW.getCharPositionInLine()) +            ), +            Operator.GREATER_THAN, +            ($value_list.result) +         );     }     | IS_MEMBER_KW value WS+ value_reference R_PAREN     { +      /* TODO */ +      $result = null;     }  ; +catch [final Throwable e] +{ +   throw new ParseCancellationException(e); +} -math_expression: +math_expression +returns [ValueNode result]:     PLUS_KW value_list R_PAREN     { +      $result = +         Operation.build +         ( +            CONTEXT.get_origin_at +            ( +               ($PLUS_KW.getLine()), +               ($PLUS_KW.getCharPositionInLine()) +            ), +            Operator.PLUS, +            ($value_list.result) +         );     }     | MINUS_KW value_list R_PAREN     { +      $result = +         Operation.build +         ( +            CONTEXT.get_origin_at +            ( +               ($MINUS_KW.getLine()), +               ($MINUS_KW.getCharPositionInLine()) +            ), +            Operator.MINUS, +            ($value_list.result) +         );     }     | TIMES_KW value_list R_PAREN     { -   } - -   | DIVIDE_KW value WS+ value R_PAREN -   { -   } - -   | POWER_KW value WS+ value R_PAREN -   { -   } - -   | RANDOM_KW value WS+ value R_PAREN -   { +      $result = +         Operation.build +         ( +            CONTEXT.get_origin_at +            ( +               ($TIMES_KW.getLine()), +               ($TIMES_KW.getCharPositionInLine()) +            ), +            Operator.TIMES, +            ($value_list.result) +         ); +   } + +   | DIVIDE_KW value_list R_PAREN +   { +      $result = +         Operation.build +         ( +            CONTEXT.get_origin_at +            ( +               ($DIVIDE_KW.getLine()), +               ($DIVIDE_KW.getCharPositionInLine()) +            ), +            Operator.DIVIDE, +            ($value_list.result) +         ); +   } + +   | POWER_KW value_list R_PAREN +   { +      $result = +         Operation.build +         ( +            CONTEXT.get_origin_at +            ( +               ($POWER_KW.getLine()), +               ($POWER_KW.getCharPositionInLine()) +            ), +            Operator.POWER, +            ($value_list.result) +         ); +   } + +   | RANDOM_KW value_list R_PAREN +   { +      $result = +         Operation.build +         ( +            CONTEXT.get_origin_at +            ( +               ($RANDOM_KW.getLine()), +               ($RANDOM_KW.getCharPositionInLine()) +            ), +            Operator.RANDOM, +            ($value_list.result) +         );     }     | COUNT_KW value WS+ value_reference R_PAREN     { +      /* TODO */ +      $result= null;     }  ; +catch [final Throwable e] +{ +   throw new ParseCancellationException(e); +}  bag_expression:     | ADD_KW value WS+ value_reference R_PAREN @@ -318,47 +623,76 @@ bag_expression:     }  ; -value: +value +returns [ValueNode result] +:     WORD     { +      $result = +         Constant.build +         ( +            CONTEXT.get_origin_at +            ( +               ($WORD.getLine()), +               ($WORD.getCharPositionInLine()) +            ), +            ($WORD.text) +         );     } -   | L_PAREN WS* sentence R_PAREN +   | L_PAREN WS+ sentence R_PAREN     { +      /* TODO */ +      $result = null;     }     | non_text_value     { +      $result = ($non_text_value.result);     }  ; -non_text_value: +non_text_value +returns [ValueNode result] +:     IF_ELSE_KW value WS+ value WS+ value R_PAREN     { +      /* TODO */ +      $result = null;     }     | COND_KW value_cond_list R_PAREN     { +      /* TODO */ +      $result = null;     }     | boolean_expression     { +      $result = ($boolean_expression.result);     }     | math_expression     { +      $result = ($math_expression.result);     }     | CAST_KW WORD WORD value R_PAREN     { +      /* TODO */ +      $result = null;     }     | value_reference     { +      /* TODO */ +      $result = null;     }     | SET_KW value WS+ value_reference R_PAREN     { +      /* TODO */ +      $result = null;     }  ; @@ -378,8 +712,25 @@ value_cond_list:     }  ; -value_list: -   value* (WS+ value)* +value_list +returns [List<ValueNode> result] +@init +{ +   $result = new ArrayList<ValueNode>(); +} +: +   ( +      value +      { +         ($result).add(($value.result)); +      } +   )* +   (WS+ +      value +      { +         ($result).add(($value.result)); +      } +   )*     {     }  ; diff --git a/src/core/src/tonkadur/parser/Origin.java b/src/core/src/tonkadur/parser/Origin.java index 9fa7939..f6f2d29 100644 --- a/src/core/src/tonkadur/parser/Origin.java +++ b/src/core/src/tonkadur/parser/Origin.java @@ -30,4 +30,15 @@ public class Origin     {        return location;     } + +   @Override +   public String toString() +   { +      final StringBuilder sb = new StringBuilder(); + +      sb.append(context.toString()); +      sb.append(location.toString()); + +      return sb.toString(); +   }  } | 


