| summaryrefslogtreecommitdiff | 
diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/src/tonkadur/fate/v1/lang/CondValue.java | 138 | ||||
| -rw-r--r-- | src/core/src/tonkadur/fate/v1/lang/IfElseValue.java | 19 | ||||
| -rw-r--r-- | src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 | 3 | ||||
| -rw-r--r-- | src/core/src/tonkadur/fate/v1/parser/FateParser.g4 | 121 | ||||
| -rw-r--r-- | src/core/src/tonkadur/parser/Context.java | 5 | 
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)     { | 


