| summaryrefslogtreecommitdiff | 
diff options
22 files changed, 581 insertions, 181 deletions
| diff --git a/data/examples/monster_battle/in_your_room.fate b/data/examples/monster_battle/in_your_room.fate index 892c680..8f30a00 100644 --- a/data/examples/monster_battle/in_your_room.fate +++ b/data/examples/monster_battle/in_your_room.fate @@ -52,7 +52,7 @@                 Oh! You found something!              )           ) -         (imacro get_item (ref (var potion))) +         (macro get_item (ref (var potion)))        )        (text_effect narrator           No, you don't find anything. @@ -70,7 +70,7 @@     (text_effect narrator        It's a monster-holder! There's a note, too.     ) -   (imacro generate_random_creature (var player.creature)) +   (macro generate_random_creature (var player.creature))     (event pause)     (text_effect note_reading        Hey sleepyhead. I couldn't wake you up for your big day, but lucky you, diff --git a/src/core/src/tonkadur/Main.java b/src/core/src/tonkadur/Main.java index 23666dd..4dabacb 100644 --- a/src/core/src/tonkadur/Main.java +++ b/src/core/src/tonkadur/Main.java @@ -4,8 +4,6 @@ import java.io.IOException;  import tonkadur.parser.Context; -import tonkadur.fate.v1.lang.World; -  import tonkadur.fate.v1.Utils;  public class Main @@ -15,23 +13,42 @@ public class Main     public static void main (final String[] args)     { -      final World world; +      final tonkadur.fate.v1.lang.World fate_world; +      final tonkadur.wyrd.v1.lang.World wyrd_world;        final Context context; -      world = new World(); +      fate_world = new tonkadur.fate.v1.lang.World();        context = Context.build(args[0]);        try        { -         Utils.add_file_content(context.get_current_file(), context, world); +         Utils.add_file_content +         ( +            context.get_current_file(), +            context, +            fate_world +         );           System.out.println("Parsing completed."); -         System.out.println(world.toString()); +         System.out.println(fate_world.toString());        }        catch (final Exception e)        {           System.err.println("Parsing failed."); -         System.err.println(world.toString()); +         System.err.println(fate_world.toString()); +         e.printStackTrace(); +      } + +      try +      { +         wyrd_world = +            tonkadur.wyrd.v1.compiler.fate.v1.Compiler.compile(fate_world); + +         System.out.println("Compilation completed."); +      } +      catch (final Throwable e) +      { +         System.err.println("Compilation failed.");           e.printStackTrace();        }     } diff --git a/src/core/src/tonkadur/fate/v1/lang/computation/IfElseValue.java b/src/core/src/tonkadur/fate/v1/lang/computation/IfElseValue.java index 63adfb6..5288163 100644 --- a/src/core/src/tonkadur/fate/v1/lang/computation/IfElseValue.java +++ b/src/core/src/tonkadur/fate/v1/lang/computation/IfElseValue.java @@ -123,6 +123,22 @@ public class IfElseValue extends Computation     }     /**** Accessors ************************************************************/ + +   public Computation get_condition () +   { +      return condition; +   } + +   public Computation get_if_true () +   { +      return if_true; +   } + +   public Computation get_if_false () +   { +      return if_false; +   } +     @Override     public void get_visited_by (final ComputationVisitor cv)     throws Throwable diff --git a/src/core/src/tonkadur/fate/v1/lang/computation/Operation.java b/src/core/src/tonkadur/fate/v1/lang/computation/Operation.java index dfbfcb3..d67fa1d 100644 --- a/src/core/src/tonkadur/fate/v1/lang/computation/Operation.java +++ b/src/core/src/tonkadur/fate/v1/lang/computation/Operation.java @@ -175,4 +175,14 @@ public class Operation extends Computation     {        cv.visit_operation(this);     } + +   public Operator get_operator () +   { +      return operator; +   } + +   public List<Computation> get_operands () +   { +      return operands; +   }  } diff --git a/src/core/src/tonkadur/fate/v1/lang/computation/RefOperator.java b/src/core/src/tonkadur/fate/v1/lang/computation/RefOperator.java index 49f3ef6..54cdaad 100644 --- a/src/core/src/tonkadur/fate/v1/lang/computation/RefOperator.java +++ b/src/core/src/tonkadur/fate/v1/lang/computation/RefOperator.java @@ -28,8 +28,6 @@ public class RefOperator extends Computation     /***************************************************************************/     /**** PUBLIC ***************************************************************/     /***************************************************************************/ -   /**** Constructors *********************************************************/ -     /**** Accessors ************************************************************/     @Override     public void get_visited_by (final ComputationVisitor cv) @@ -38,6 +36,11 @@ public class RefOperator extends Computation        cv.visit_ref_operator(this);     } +   public Reference get_target () +   { +      return referred; +   } +     /**** Misc. ****************************************************************/     @Override     public String toString () diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/ComputationCompiler.java b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/ComputationCompiler.java index 1cc3af8..52d92bc 100644 --- a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/ComputationCompiler.java +++ b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/ComputationCompiler.java @@ -1,5 +1,6 @@  package tonkadur.wyrd.v1.compiler.fate.v1; +import java.util.Collections;  import java.util.List;  import java.util.ArrayList; @@ -8,8 +9,14 @@ import tonkadur.error.Error;  import tonkadur.wyrd.v1.lang.meta.Computation;  import tonkadur.wyrd.v1.lang.meta.Instruction; -import tonkadur.wyrd.v1.lang.computation.Ref; -import tonkadur.wyrd.v1.lang.computation.ValueOf; +import tonkadur.wyrd.v1.lang.type.Type; + +import tonkadur.wyrd.v1.lang.instruction.SetValue; + +import tonkadur.wyrd.v1.compiler.util.IfElse; + +import tonkadur.wyrd.v1.lang.computation.*; +  import tonkadur.wyrd.v1.lang.World; @@ -17,30 +24,38 @@ public class ComputationCompiler  implements tonkadur.fate.v1.lang.meta.ComputationVisitor  {     protected final Compiler compiler; -   protected final List<Instruction> pre_computation_instructions; -   protected final List<Ref> allocated_variables; -   protected final boolean expect_ref; +   protected final List<Instruction> init_instructions; +   protected final List<Ref> reserved_variables; +   protected boolean instructions_were_generated;     protected Computation result_as_computation;     protected Ref result_as_ref; -   public ComputationCompiler -   ( -      final Compiler compiler, -      final boolean expect_ref -   ) +   public ComputationCompiler (final Compiler compiler)     {        this.compiler = compiler; -      this.expect_ref = expect_ref; -      allocated_variables = new ArrayList<Ref>(); -      pre_computation_instructions = new ArrayList<Instruction>(); +      reserved_variables = new ArrayList<Ref>(); +      init_instructions = new ArrayList<Instruction>();        result_as_ref = null;        result_as_computation = null; +      instructions_were_generated = false; +   } + +   public boolean has_init () +   { +      return !init_instructions.isEmpty();     }     public Instruction get_init ()     { -      return compiler.assembler().merge(pre_computation_instructions); +      instructions_were_generated = true; + +      if (init_instructions.isEmpty()) +      { +         return null; +      } + +      return compiler.assembler().merge(init_instructions);     }     public Computation get_computation () @@ -59,37 +74,52 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor     public Ref get_ref ()     { -      if ((result_as_ref == null) && (result_as_computation != null)) -      { -         generate_ref(); -      } -        return result_as_ref;     } -   protected void generate_ref () +   public void generate_ref ()     { -      final Ref result; +      if ((!instructions_were_generated) && (result_as_ref == null)) +      { +         final Ref result; + +         result = reserve(result_as_computation.get_type()); -      result = -         compiler.anonymous_variables().reserve +         init_instructions.add           ( -            result_as_computation.get_type() +            new SetValue(result, result_as_computation)           ); -      allocated_variables.add(result); -      result_as_ref = result; +         result_as_ref = result; +      }     }     public void release_variables ()     { -      for (final Ref ref: allocated_variables) +      for (final Ref ref: reserved_variables)        {           compiler.anonymous_variables().release(ref);        }     } +   protected void assimilate (final ComputationCompiler cc) +   { +      init_instructions.addAll(cc.init_instructions); +      reserved_variables.addAll(cc.reserved_variables); +   } + +   protected Ref reserve (final Type t) +   { +      final Ref result; + +      result = compiler.anonymous_variables().reserve(t); + +      reserved_variables.add(result); + +      return result; +   } +     @Override     public void visit_at_reference     ( @@ -97,7 +127,27 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor     )     throws Throwable     { -      /* TODO: implement */ +      final ComputationCompiler n_cc; + +      n_cc = new ComputationCompiler(compiler); + +      n.get_parent().get_visited_by(n_cc); + +      assimilate(n_cc); + +      result_as_ref = +         new Ref +         ( +            n_cc.get_computation(), +            TypeCompiler.compile +            ( +               compiler, +               ( +                  (tonkadur.fate.v1.lang.type.RefType) +                     n.get_parent().get_type() +               ).get_referenced_type() +            ) +         );     }     @Override @@ -127,7 +177,12 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor     )     throws Throwable     { -      /* TODO: implement */ +      result_as_computation = +         new Constant +         ( +            TypeCompiler.compile(compiler, n.get_type()), +            n.get_value_as_string() +         );     }     @Override @@ -147,7 +202,28 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor     )     throws Throwable     { -      /* TODO: implement */ +      final ComputationCompiler n_cc; + +      n_cc = new ComputationCompiler(compiler); + +      n.get_parent().get_visited_by(n_cc); + +      assimilate(n_cc); + +      result_as_ref = +         new RelativeRef +         ( +            n_cc.get_ref(), +            new Constant(Type.STRING, n.get_field_name()), +            TypeCompiler.compile +            ( +               compiler, +               ( +                  (tonkadur.fate.v1.lang.type.RefType) +                     n.get_parent().get_type() +               ).get_referenced_type() +            ) +         );     }     @Override @@ -157,7 +233,97 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor     )     throws Throwable     { -      /* TODO: implement */ +      final ComputationCompiler cond_cc, if_true_cc, if_false_cc; + +      cond_cc = new ComputationCompiler(compiler); +      if_true_cc = new ComputationCompiler(compiler); +      if_false_cc = new ComputationCompiler(compiler); + +      n.get_condition().get_visited_by(cond_cc); +      n.get_if_true().get_visited_by(if_true_cc); +      n.get_if_false().get_visited_by(if_false_cc); + +      if (if_true_cc.has_init() || if_false_cc.has_init()) +      { +         /* +          * Unsafe ifelse computation: at least one of the branches needs to +          * use instructions with values *before* the condition has been +          * checked. This results in non-lazy evaluation, and is dangerous: +          * the condition might be a test to ensure that the computations of the +          * chosen branch are legal. In such cases, performing the potentially +          * illegal branch's instructions is likely to result in a runtime error +          * on the interpreter. +          * +          * Instead, we just convert the ifelse into an instruction-based +          * equivalent and store the result in an anonymous variable to be used +          * here. +          */ +         final Ref if_else_result; +         final List<Instruction> if_true_branch; +         final List<Instruction> if_false_branch; + +         if_else_result = reserve(if_true_cc.get_computation().get_type()); + +         if_true_branch = new ArrayList<Instruction>(); +         if_false_branch = new ArrayList<Instruction>(); + +         if (if_true_cc.has_init()) +         { +            if_true_branch.add(if_true_cc.get_init()); +         } + +         if (if_false_cc.has_init()) +         { +            if_false_branch.add(if_false_cc.get_init()); +         } + +         if_true_branch.add +         ( +            new SetValue(if_else_result, if_true_cc.get_computation()) +         ); + +         if_false_branch.add +         ( +            new SetValue(if_else_result, if_false_cc.get_computation()) +         ); + +         if (cond_cc.has_init()) +         { +            init_instructions.add(cond_cc.get_init()); +         } + +         init_instructions.add +         ( +            IfElse.generate +            ( +               compiler.anonymous_variables(), +               compiler.assembler(), +               cond_cc.get_computation(), +               compiler.assembler().merge(if_true_branch), +               compiler.assembler().merge(if_false_branch) +            ) +         ); + +         reserved_variables.addAll(cond_cc.reserved_variables); +         reserved_variables.addAll(if_true_cc.reserved_variables); +         reserved_variables.addAll(if_false_cc.reserved_variables); + +         result_as_computation = new ValueOf(if_else_result); +      } +      else +      { +         assimilate(cond_cc); +         assimilate(if_true_cc); +         assimilate(if_false_cc); + +         result_as_computation = +            new IfElseComputation +            ( +               cond_cc.get_computation(), +               if_true_cc.get_computation(), +               if_false_cc.get_computation() +            ); +      }     }     @Override @@ -187,7 +353,7 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor     )     throws Throwable     { -      /* TODO: implement */ +      result_as_computation = new Newline();     }     @Override @@ -197,7 +363,8 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor     )     throws Throwable     { -      /* TODO: implement */ +      /* TODO */ +      result_as_computation = new Constant(Type.INT, "0");     }     @Override @@ -207,7 +374,28 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor     )     throws Throwable     { -      /* TODO: implement */ +      final List<Computation> content; + +      content = new ArrayList<Computation>(); + +      for +      ( +         final tonkadur.fate.v1.lang.meta.Computation fate_content: +            n.get_content() +      ) +      { +         final ComputationCompiler content_cc; + +         content_cc = new ComputationCompiler(compiler); + +         fate_content.get_visited_by(content_cc); + +         assimilate(content_cc); + +         content.add(content_cc.get_computation()); +      } + +      result_as_computation = new RichText(content);     }     @Override @@ -217,7 +405,7 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor     )     throws Throwable     { -      /* TODO: implement */ +      result_as_ref = compiler.macros().get_parameter_ref(n.get_name());     }     @Override @@ -227,7 +415,15 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor     )     throws Throwable     { -      /* TODO: implement */ +      final ComputationCompiler n_cc; + +      n_cc = new ComputationCompiler(compiler); + +      n.get_target().get_visited_by(n_cc); + +      assimilate(n_cc); + +      result_as_computation = n_cc.result_as_ref;     }     @Override @@ -237,7 +433,40 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor     )     throws Throwable     { -      /* TODO: implement */ +      final ComputationCompiler text_cc; +      final List<Computation> parameters; + +      text_cc = new ComputationCompiler(compiler); +      parameters = new ArrayList<Computation>(); + +      n.get_text().get_visited_by(text_cc); + +      assimilate(text_cc); + +      for +      ( +         final tonkadur.fate.v1.lang.meta.Computation fate_param: +            n.get_parameters() +      ) +      { +         final ComputationCompiler param_cc; + +         param_cc = new ComputationCompiler(compiler); + +         fate_param.get_visited_by(param_cc); + +         assimilate(param_cc); + +         parameters.add(param_cc.get_computation()); +      } + +      result_as_computation = +         new AddRichTextEffect +         ( +            n.get_effect().get_name(), +            parameters, +            Collections.singletonList(text_cc.get_computation()) +         );     }     @Override @@ -247,7 +476,10 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor     )     throws Throwable     { -      /* TODO: implement */ +      n.get_value().get_visited_by(this); + +      result_as_computation = +         new RichText(Collections.singletonList(result_as_computation));     }     @Override @@ -257,6 +489,9 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor     )     throws Throwable     { -      /* TODO: implement */ +      result_as_ref = +         compiler.world().get_variable(n.get_variable().get_name()).get_ref(); + +      result_as_computation = new ValueOf(result_as_ref);     }  } diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/InstructionCompiler.java b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/InstructionCompiler.java index b4038dd..8ed0c87 100644 --- a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/InstructionCompiler.java +++ b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/InstructionCompiler.java @@ -100,17 +100,27 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor        final Type element_type;        final Computation value_of_element, value_of_collection_size; -      element_compiler = new ComputationCompiler(compiler, false); +      element_compiler = new ComputationCompiler(compiler);        ae.get_element().get_visited_by(element_compiler); -      result.add(element_compiler.get_init()); + +      if (element_compiler.has_init()) +      { +         result.add(element_compiler.get_init()); +      } +        element_type = element_compiler.get_computation().get_type();        element = compiler.anonymous_variables().reserve(element_type);        result.add(new SetValue(element, element_compiler.get_computation()));        element_compiler.release_variables(); -      reference_compiler = new ComputationCompiler(compiler, true); +      reference_compiler = new ComputationCompiler(compiler);        ae.get_collection().get_visited_by(reference_compiler); -      result.add(reference_compiler.get_init()); + +      if (reference_compiler.has_init()) +      { +         result.add(reference_compiler.get_init()); +      } +        collection = reference_compiler.get_ref();        element_found = compiler.anonymous_variables().reserve(Type.BOOLEAN); @@ -185,18 +195,26 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor        final Ref collection_as_ref;        final ComputationCompiler element_compiler, reference_compiler; -      element_compiler = new ComputationCompiler(compiler, false); +      element_compiler = new ComputationCompiler(compiler);        ae.get_element().get_visited_by(element_compiler); -      reference_compiler = new ComputationCompiler(compiler, true); +      reference_compiler = new ComputationCompiler(compiler);        ae.get_collection().get_visited_by(reference_compiler);        collection_as_ref = reference_compiler.get_ref(); -      result.add(reference_compiler.get_init()); -      result.add(element_compiler.get_init()); +      if (reference_compiler.has_init()) +      { +         result.add(reference_compiler.get_init()); +      } + +      if (element_compiler.has_init()) +      { +         result.add(element_compiler.get_init()); +      } +        result.add        (           new SetValue @@ -204,13 +222,10 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor              new RelativeRef              (                 collection_as_ref, -               Collections.singletonList +               new Cast                 ( -                  new Cast -                  ( -                     new Size(collection_as_ref), -                     Type.STRING -                  ) +                  new Size(collection_as_ref), +                  Type.STRING                 ),                 element_compiler.get_computation().get_type()              ), @@ -266,11 +281,15 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor         */        final ComputationCompiler cc; -      cc = new ComputationCompiler(compiler, false); +      cc = new ComputationCompiler(compiler);        a.get_condition().get_visited_by(cc); -      result.add(cc.get_init()); +      if (cc.has_init()) +      { +         result.add(cc.get_init()); +      } +        result.add(new Assert(cc.get_computation()));        cc.release_variables(); @@ -288,13 +307,17 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor        final ComputationCompiler reference_compiler;        final Ref collection_ref; -      reference_compiler = new ComputationCompiler(compiler, true); +      reference_compiler = new ComputationCompiler(compiler);        c.get_collection().get_visited_by(reference_compiler);        collection_ref = reference_compiler.get_ref(); -      result.add(reference_compiler.get_init()); +      if (reference_compiler.has_init()) +      { +         result.add(reference_compiler.get_init()); +      } +        result.add        (           Clear.generate @@ -358,11 +381,15 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor           current_else_branch = new ArrayList<Instruction>();           ic = new InstructionCompiler(compiler); -         cc = new ComputationCompiler(compiler, false); +         cc = new ComputationCompiler(compiler);           branch.get_car().get_visited_by(cc); -         previous_else_branch.add(cc.get_init()); +         if (cc.has_init()) +         { +            previous_else_branch.add(cc.get_init()); +         } +           previous_else_branch.add           (              IfElse.generate @@ -401,12 +428,16 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor         */        final ComputationCompiler cc; -      cc = new ComputationCompiler(compiler, false); +      cc = new ComputationCompiler(compiler);        n.get_content().get_visited_by(cc); -      result.add(cc.get_init()); -      result.add(new Display(Collections.singletonList(cc.get_computation()))); +      if (cc.has_init()) +      { +         result.add(cc.get_init()); +      } + +      result.add(new Display(cc.get_computation()));        cc.release_variables();     } @@ -437,11 +468,14 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor        {           final ComputationCompiler cc; -         cc = new ComputationCompiler(compiler, false); +         cc = new ComputationCompiler(compiler);           fate_computation.get_visited_by(cc); -         result.add(cc.get_init()); +         if (cc.has_init()) +         { +            result.add(cc.get_init()); +         }           cc_list.add(cc);           parameters.add(cc.get_computation()); @@ -471,7 +505,7 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor        final InstructionCompiler if_true_ic;        final InstructionCompiler if_false_ic; -      cc = new ComputationCompiler(compiler, false); +      cc = new ComputationCompiler(compiler);        if_true_ic = new InstructionCompiler(compiler);        if_false_ic = new InstructionCompiler(compiler); @@ -479,7 +513,11 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor        n.get_if_true().get_visited_by(if_true_ic);        n.get_if_false().get_visited_by(if_false_ic); -      result.add(cc.get_init()); +      if (cc.has_init()) +      { +         result.add(cc.get_init()); +      } +        result.add        (           IfElse.generate @@ -510,13 +548,17 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor        final ComputationCompiler cc;        final InstructionCompiler if_true_ic; -      cc = new ComputationCompiler(compiler, false); +      cc = new ComputationCompiler(compiler);        if_true_ic = new InstructionCompiler(compiler);        n.get_condition().get_visited_by(cc);        n.get_if_true().get_visited_by(if_true_ic); -      result.add(cc.get_init()); +      if (cc.has_init()) +      { +         result.add(cc.get_init()); +      } +        result.add        (           If.generate @@ -585,11 +627,14 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor        {           final ComputationCompiler cc; -         cc = new ComputationCompiler(compiler, true); +         cc = new ComputationCompiler(compiler);           fate_computation.get_visited_by(cc); -         result.add(cc.get_init()); +         if (cc.has_init()) +         { +            result.add(cc.get_init()); +         }           cc_list.add(cc);           parameters.add(cc.get_ref()); @@ -620,12 +665,15 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor        final ComputationCompiler cc;        final InstructionCompiler ic; -      cc = new ComputationCompiler(compiler, false); +      cc = new ComputationCompiler(compiler);        ic = new InstructionCompiler(compiler);        n.get_text().get_visited_by(cc); -      result.add(cc.get_init()); +      if (cc.has_init()) +      { +         result.add(cc.get_init()); +      }        for        ( @@ -710,8 +758,8 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor        final ComputationCompiler elem_cc, collection_cc;        final Ref elem, collection_size, collection; -      elem_cc = new ComputationCompiler(compiler, false); -      collection_cc = new ComputationCompiler(compiler, true); +      elem_cc = new ComputationCompiler(compiler); +      collection_cc = new ComputationCompiler(compiler);        elem =           compiler.anonymous_variables().reserve @@ -724,8 +772,15 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor        n.get_element().get_visited_by(elem_cc);        n.get_collection().get_visited_by(collection_cc); -      result.add(elem_cc.get_init()); -      result.add(collection_cc.get_init()); +      if (elem_cc.has_init()) +      { +         result.add(elem_cc.get_init()); +      } + +      if (collection_cc.has_init()) +      { +         result.add(collection_cc.get_init()); +      }        collection = collection_cc.get_ref(); @@ -856,8 +911,8 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor        final Ref collection;        final Computation value_of_collection_size; -      elem_cc = new ComputationCompiler(compiler, false); -      collection_cc = new ComputationCompiler(compiler, true); +      elem_cc = new ComputationCompiler(compiler); +      collection_cc = new ComputationCompiler(compiler);        elem =           compiler.anonymous_variables().reserve @@ -872,8 +927,15 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor        n.get_element().get_visited_by(elem_cc);        n.get_collection().get_visited_by(collection_cc); -      result.add(elem_cc.get_init()); -      result.add(collection_cc.get_init()); +      if (elem_cc.has_init()) +      { +         result.add(elem_cc.get_init()); +      } + +      if (collection_cc.has_init()) +      { +         result.add(collection_cc.get_init()); +      }        collection = collection_cc.get_ref(); @@ -985,14 +1047,22 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor         */        final ComputationCompiler value_cc, ref_cc; -      value_cc = new ComputationCompiler(compiler, false); -      ref_cc = new ComputationCompiler(compiler, true); +      value_cc = new ComputationCompiler(compiler); +      ref_cc = new ComputationCompiler(compiler);        n.get_value().get_visited_by(value_cc); -      result.add(value_cc.get_init()); + +      if (value_cc.has_init()) +      { +         result.add(value_cc.get_init()); +      }        n.get_reference().get_visited_by(ref_cc); -      result.add(ref_cc.get_init()); + +      if (ref_cc.has_init()) +      { +         result.add(ref_cc.get_init()); +      }        result.add        ( @@ -1002,4 +1072,15 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor        value_cc.release_variables();        ref_cc.release_variables();     } + +   /* +    * TODO: Be careful about compiling Fate's loop operators: +    *    You can't do: +    *       condition.get_visited_by(ComputationCompiler); +    *       result.add(ComputationCompiler.get_init(); +    *       result.add(While.generate(...)); +    * +    *       The whatever is added in result.add(ComputationCompiler.get_init(); +    *       needs to be re-evaluated at every iteration. +    */  } diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/util/BinarySearch.java b/src/core/src/tonkadur/wyrd/v1/compiler/util/BinarySearch.java index 57580e7..b6e7a4b 100644 --- a/src/core/src/tonkadur/wyrd/v1/compiler/util/BinarySearch.java +++ b/src/core/src/tonkadur/wyrd/v1/compiler/util/BinarySearch.java @@ -170,10 +170,7 @@ public class BinarySearch                 new RelativeRef                 (                    collection, -                  Collections.singletonList -                  ( -                     new Cast(value_of_result_index, Type.STRING) -                  ), +                  new Cast(value_of_result_index, Type.STRING),                    element_type                 )              ) diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/util/Clear.java b/src/core/src/tonkadur/wyrd/v1/compiler/util/Clear.java index 17965ae..d63e8fb 100644 --- a/src/core/src/tonkadur/wyrd/v1/compiler/util/Clear.java +++ b/src/core/src/tonkadur/wyrd/v1/compiler/util/Clear.java @@ -82,10 +82,7 @@ public class Clear              new RelativeRef              (                 collection, -               Collections.singletonList -               ( -                  new Cast(value_of_iterator, Type.STRING) -               ), +               new Cast(value_of_iterator, Type.STRING),                 element_type              )           ) diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/util/InsertAt.java b/src/core/src/tonkadur/wyrd/v1/compiler/util/InsertAt.java index dba37dc..5484e8a 100644 --- a/src/core/src/tonkadur/wyrd/v1/compiler/util/InsertAt.java +++ b/src/core/src/tonkadur/wyrd/v1/compiler/util/InsertAt.java @@ -92,10 +92,7 @@ public class InsertAt              new RelativeRef              (                 collection, -               Collections.singletonList -               ( -                  new Cast(value_of_end, Type.STRING) -               ), +               new Cast(value_of_end, Type.STRING),                 element_type              ),              new ValueOf @@ -103,10 +100,7 @@ public class InsertAt                 new RelativeRef                 (                    collection, -                  Collections.singletonList -                  ( -                     new Cast(value_of_prev, Type.STRING) -                  ), +                  new Cast(value_of_prev, Type.STRING),                    element_type                 )              ) @@ -142,10 +136,7 @@ public class InsertAt              new RelativeRef              (                 collection, -               Collections.singletonList -               ( -                  new Cast(value_of_index, Type.STRING) -               ), +               new Cast(value_of_index, Type.STRING),                 element_type              ),              element diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/util/InstructionManager.java b/src/core/src/tonkadur/wyrd/v1/compiler/util/InstructionManager.java index b3ea40f..74fe200 100644 --- a/src/core/src/tonkadur/wyrd/v1/compiler/util/InstructionManager.java +++ b/src/core/src/tonkadur/wyrd/v1/compiler/util/InstructionManager.java @@ -162,11 +162,15 @@ public class InstructionManager     public Instruction merge (final List<Instruction> instructions)     { -      if (instructions.size() == 0) +      if (instructions.isEmpty())        {           /* Important in case of label on InstructionList */           return NOP.generate(this);        } +      else if (instructions.size() == 1) +      { +         return instructions.get(0); +      }        return new InstructionList(instructions);     } diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/util/IterativeSearch.java b/src/core/src/tonkadur/wyrd/v1/compiler/util/IterativeSearch.java index 1d4c471..dabec5a 100644 --- a/src/core/src/tonkadur/wyrd/v1/compiler/util/IterativeSearch.java +++ b/src/core/src/tonkadur/wyrd/v1/compiler/util/IterativeSearch.java @@ -115,10 +115,7 @@ public class IterativeSearch                       new RelativeRef                       (                          collection, -                        Collections.singletonList -                        ( -                           new Cast(value_of_result_index, Type.STRING) -                        ), +                        new Cast(value_of_result_index, Type.STRING),                          target_type                       )                    ), diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/util/RemoveAllOf.java b/src/core/src/tonkadur/wyrd/v1/compiler/util/RemoveAllOf.java index cba50b5..bd9bb1e 100644 --- a/src/core/src/tonkadur/wyrd/v1/compiler/util/RemoveAllOf.java +++ b/src/core/src/tonkadur/wyrd/v1/compiler/util/RemoveAllOf.java @@ -104,10 +104,7 @@ public class RemoveAllOf           new RelativeRef           (              collection, -            Collections.singletonList -            ( -               new Cast(value_of_index, Type.STRING) -            ), +            new Cast(value_of_index, Type.STRING),              element_type           ); @@ -162,13 +159,10 @@ public class RemoveAllOf              new RelativeRef              (                 collection, -               Collections.singletonList +               new Cast                 ( -                  new Cast -                  ( -                     Operation.plus(value_of_index, value_of_found), -                     Type.STRING -                  ) +                  Operation.plus(value_of_index, value_of_found), +                  Type.STRING                 ),                 element_type              ) @@ -209,13 +203,10 @@ public class RemoveAllOf              new RelativeRef              (                 collection, -               Collections.singletonList +               new Cast                 ( -                  new Cast -                  ( -                     Operation.plus(value_of_end, value_of_found), -                     Type.STRING -                  ) +                  Operation.plus(value_of_end, value_of_found), +                  Type.STRING                 ),                 element_type              ) diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/util/RemoveAt.java b/src/core/src/tonkadur/wyrd/v1/compiler/util/RemoveAt.java index be5a859..050a8c6 100644 --- a/src/core/src/tonkadur/wyrd/v1/compiler/util/RemoveAt.java +++ b/src/core/src/tonkadur/wyrd/v1/compiler/util/RemoveAt.java @@ -80,10 +80,7 @@ public class RemoveAt           new RelativeRef           (              collection, -            Collections.singletonList -            ( -               new Cast(value_of_index, Type.STRING) -            ), +            new Cast(value_of_index, Type.STRING),              element_type           ); @@ -110,10 +107,7 @@ public class RemoveAt                 new RelativeRef                 (                    collection, -                  Collections.singletonList -                  ( -                     new Cast(value_of_next, Type.STRING) -                  ), +                  new Cast(value_of_next, Type.STRING),                    element_type                 )              ) diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/util/While.java b/src/core/src/tonkadur/wyrd/v1/compiler/util/While.java index 1101a4c..c2e7d16 100644 --- a/src/core/src/tonkadur/wyrd/v1/compiler/util/While.java +++ b/src/core/src/tonkadur/wyrd/v1/compiler/util/While.java @@ -68,4 +68,60 @@ public class While        return assembler.merge(result);     } + +   /* +    * Instruction cond_init +    * Computation boolean condition +    * Instruction while_body +    * +    * (mark start_label cond_init) +    * (set .pc (ifelse condition (label if_true_label) (label end_label))) +    * (mark if_true_label while_body) +    * (mark_after end_label (set .pc (label start_label))) +    */ +   public static Instruction generate +   ( +      final AnonymousVariableManager anonymous_variables, +      final InstructionManager assembler, +      final Instruction cond_init, +      final Computation condition, +      final Instruction while_body +   ) +   { +      final String start_label, if_true_label, end_label; +      final List<Instruction> result; + +      start_label = assembler.generate_label("<while#start_label>"); +      if_true_label = assembler.generate_label("<while#if_true_label>"); +      end_label = assembler.generate_label("<while#end_label>"); + +      result = new ArrayList<Instruction>(); + +      result.add(assembler.mark(start_label, cond_init)); + +      result.add +      ( +         new SetPC +         ( +            new IfElseComputation +            ( +               condition, +               assembler.get_label_constant(if_true_label), +               assembler.get_label_constant(end_label) +            ) +         ) +      ); + +      result.add(assembler.mark(if_true_label, while_body)); +      result.add +      ( +         assembler.mark_after +         ( +            new SetPC(assembler.get_label_constant(start_label)), +            end_label +         ) +      ); + +      return assembler.merge(result); +   }  } diff --git a/src/core/src/tonkadur/wyrd/v1/lang/Variable.java b/src/core/src/tonkadur/wyrd/v1/lang/Variable.java index fee6ca4..7117b89 100644 --- a/src/core/src/tonkadur/wyrd/v1/lang/Variable.java +++ b/src/core/src/tonkadur/wyrd/v1/lang/Variable.java @@ -37,11 +37,6 @@ public class Variable     public Ref get_ref ()     { -      return -         new Ref -         ( -            Collections.singletonList(new Constant(Type.STRING, name)), -            type -         ); +      return new Ref(new Constant(Type.STRING, name), type);     }  } diff --git a/src/core/src/tonkadur/wyrd/v1/lang/computation/AddRichTextEffect.java b/src/core/src/tonkadur/wyrd/v1/lang/computation/AddRichTextEffect.java index 318e418..74f967a 100644 --- a/src/core/src/tonkadur/wyrd/v1/lang/computation/AddRichTextEffect.java +++ b/src/core/src/tonkadur/wyrd/v1/lang/computation/AddRichTextEffect.java @@ -1,20 +1,18 @@  package tonkadur.wyrd.v1.lang.computation;  import java.util.List; -import java.util.Map;  import tonkadur.wyrd.v1.lang.type.Type;  import tonkadur.wyrd.v1.lang.meta.Computation; -public class AddRichTextEffect extends Computation +public class AddRichTextEffect extends RichText  {     /***************************************************************************/     /**** MEMBERS **************************************************************/     /***************************************************************************/     protected final String effect_name;     protected final List<Computation> effect_parameters; -   protected final List<Computation> content;     /***************************************************************************/     /**** PUBLIC ***************************************************************/ @@ -27,11 +25,10 @@ public class AddRichTextEffect extends Computation        final List<Computation> content     )     { -      super(Type.RICH_TEXT); +      super(content);        this.effect_name = effect_name;        this.effect_parameters = effect_parameters; -      this.content = content;     }     /**** Accessors ************************************************************/ @@ -44,9 +41,4 @@ public class AddRichTextEffect extends Computation     {        return effect_parameters;     } - -   public List<Computation> get_content () -   { -      return content; -   }  } diff --git a/src/core/src/tonkadur/wyrd/v1/lang/computation/Newline.java b/src/core/src/tonkadur/wyrd/v1/lang/computation/Newline.java index aa561b0..bd3fbe5 100644 --- a/src/core/src/tonkadur/wyrd/v1/lang/computation/Newline.java +++ b/src/core/src/tonkadur/wyrd/v1/lang/computation/Newline.java @@ -1,10 +1,8 @@  package tonkadur.wyrd.v1.lang.computation; -import tonkadur.wyrd.v1.lang.type.Type; +import java.util.ArrayList; -import tonkadur.wyrd.v1.lang.meta.Computation; - -public class Newline extends Computation +public class Newline extends RichText  {     /***************************************************************************/     /**** MEMBERS **************************************************************/ @@ -16,6 +14,6 @@ public class Newline extends Computation     /**** Constructors *********************************************************/     public Newline ()     { -      super(Type.STRING); +      super(new ArrayList());     }  } diff --git a/src/core/src/tonkadur/wyrd/v1/lang/computation/Ref.java b/src/core/src/tonkadur/wyrd/v1/lang/computation/Ref.java index 69aa905..006a2ea 100644 --- a/src/core/src/tonkadur/wyrd/v1/lang/computation/Ref.java +++ b/src/core/src/tonkadur/wyrd/v1/lang/computation/Ref.java @@ -1,7 +1,5 @@  package tonkadur.wyrd.v1.lang.computation; -import java.util.List; -  import tonkadur.wyrd.v1.lang.type.Type;  import tonkadur.wyrd.v1.lang.meta.Computation; @@ -11,25 +9,25 @@ public class Ref extends Computation     /***************************************************************************/     /**** MEMBERS **************************************************************/     /***************************************************************************/ -   protected final List<Computation> accesses; +   protected final Computation address;     protected final Type target_type;     /***************************************************************************/     /**** PUBLIC ***************************************************************/     /***************************************************************************/     /**** Constructors *********************************************************/ -   public Ref (final List<Computation> accesses, final Type target_type) +   public Ref (final Computation address, final Type target_type)     {        super(Type.POINTER); -      this.accesses = accesses; +      this.address = address;        this.target_type = target_type;     }     /**** Accessors ************************************************************/ -   public List<Computation> get_accesses () +   public Computation get_address ()     { -      return accesses; +      return address;     }     public Type get_target_type () diff --git a/src/core/src/tonkadur/wyrd/v1/lang/computation/RelativeRef.java b/src/core/src/tonkadur/wyrd/v1/lang/computation/RelativeRef.java index bc39075..2ab63cc 100644 --- a/src/core/src/tonkadur/wyrd/v1/lang/computation/RelativeRef.java +++ b/src/core/src/tonkadur/wyrd/v1/lang/computation/RelativeRef.java @@ -1,7 +1,5 @@  package tonkadur.wyrd.v1.lang.computation; -import java.util.List; -  import tonkadur.wyrd.v1.lang.type.Type;  import tonkadur.wyrd.v1.lang.meta.Computation; @@ -20,11 +18,11 @@ public class RelativeRef extends Ref     public RelativeRef     (        final Ref parent, -      final List<Computation> accesses, +      final Computation member,        final Type target_type     )     { -      super(accesses, target_type); +      super(member, target_type);        this.parent = parent;     } diff --git a/src/core/src/tonkadur/wyrd/v1/lang/computation/RichText.java b/src/core/src/tonkadur/wyrd/v1/lang/computation/RichText.java new file mode 100644 index 0000000..a82b7ab --- /dev/null +++ b/src/core/src/tonkadur/wyrd/v1/lang/computation/RichText.java @@ -0,0 +1,32 @@ +package tonkadur.wyrd.v1.lang.computation; + +import java.util.List; + +import tonkadur.wyrd.v1.lang.type.Type; + +import tonkadur.wyrd.v1.lang.meta.Computation; + +public class RichText extends Computation +{ +   /***************************************************************************/ +   /**** MEMBERS **************************************************************/ +   /***************************************************************************/ +   protected final List<Computation> content; + +   /***************************************************************************/ +   /**** PUBLIC ***************************************************************/ +   /***************************************************************************/ +   /**** Constructors *********************************************************/ +   public RichText (final List<Computation> content) +   { +      super(Type.RICH_TEXT); + +      this.content = content; +   } + +   /**** Accessors ************************************************************/ +   public List<Computation> get_content () +   { +      return content; +   } +} diff --git a/src/core/src/tonkadur/wyrd/v1/lang/instruction/Display.java b/src/core/src/tonkadur/wyrd/v1/lang/instruction/Display.java index 3cae965..0256416 100644 --- a/src/core/src/tonkadur/wyrd/v1/lang/instruction/Display.java +++ b/src/core/src/tonkadur/wyrd/v1/lang/instruction/Display.java @@ -1,7 +1,5 @@  package tonkadur.wyrd.v1.lang.instruction; -import java.util.List; -  import tonkadur.wyrd.v1.lang.meta.Computation;  import tonkadur.wyrd.v1.lang.meta.Instruction; @@ -10,19 +8,19 @@ public class Display extends Instruction     /***************************************************************************/     /**** MEMBERS **************************************************************/     /***************************************************************************/ -   protected final List<Computation> content; +   protected final Computation content;     /***************************************************************************/     /**** PUBLIC ***************************************************************/     /***************************************************************************/     /**** Constructors *********************************************************/ -   public Display (final List<Computation> content) +   public Display (final Computation content)     {        this.content = content;     }     /**** Accessors ************************************************************/ -   public List<Computation> get_content () +   public Computation get_content ()     {        return content;     } | 


