| summaryrefslogtreecommitdiff | 
diff options
| author | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2021-08-21 21:48:47 +0200 | 
|---|---|---|
| committer | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2021-08-21 21:48:47 +0200 | 
| commit | 248a0bffd1d96548402c70a5b181e67de59d1e14 (patch) | |
| tree | fe34cc397e12590abcabc3f19f2e00bceac3d17d /src/core | |
| parent | c44f60829dc93687fe7d904b60d154de58f0492d (diff) | |
Adds some missing generic computations.
Diffstat (limited to 'src/core')
4 files changed, 426 insertions, 0 deletions
| diff --git a/src/core/src/tonkadur/fate/v1/lang/computation/generic/IfElseValue.java b/src/core/src/tonkadur/fate/v1/lang/computation/generic/IfElseValue.java new file mode 100644 index 0000000..7555849 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/computation/generic/IfElseValue.java @@ -0,0 +1,187 @@ +package tonkadur.fate.v1.lang.computation.generic; + +import java.util.Collection; +import java.util.List; +import java.util.ArrayList; + +import tonkadur.parser.Origin; +import tonkadur.parser.ParsingError; + +import tonkadur.fate.v1.lang.type.Type; +import tonkadur.fate.v1.lang.type.FutureType; + +import tonkadur.fate.v1.lang.meta.ComputationVisitor; +import tonkadur.fate.v1.lang.meta.Computation; +import tonkadur.fate.v1.lang.meta.RecurrentChecks; + +import tonkadur.fate.v1.lang.computation.GenericComputation; + +public class IfElseValue extends GenericComputation +{ +   public static Collection<String> get_aliases () +   { +      final Collection<String> aliases; + +      aliases = new ArrayList<String>(); + +      aliases.add("ifelse"); +      aliases.add("if_else"); +      aliases.add("ifElse"); + +      return aliases; +   } + +   public static GenericComputation build +   ( +      final Origin origin, +      final String alias, +      final List<Computation> call_parameters +   ) +   throws Throwable +   { +      if (call_parameters.size() != 3) +      { +         // TODO: Error. +         System.err.println("Wrong number of params at " + origin.toString()); + +         return null; +      } + +      return +         build +         ( +            origin, +            call_parameters.get(0), +            call_parameters.get(1), +            call_parameters.get(2) +         ); +   } + +   /***************************************************************************/ +   /**** MEMBERS **************************************************************/ +   /***************************************************************************/ +   protected final Computation condition; +   protected final Computation if_true; +   protected final Computation if_false; + +   /***************************************************************************/ +   /**** PROTECTED ************************************************************/ +   /***************************************************************************/ +   /**** Constructors *********************************************************/ +   protected IfElseValue +   ( +      final Origin origin, +      final Type return_type, +      final Computation condition, +      final Computation if_true, +      final Computation if_false +   ) +   { +      super(origin, return_type); + +      this.condition = condition; +      this.if_true = if_true; +      this.if_false = if_false; +   } + +   /***************************************************************************/ +   /**** PUBLIC ***************************************************************/ +   /***************************************************************************/ +   /**** Constructors *********************************************************/ +   public static IfElseValue build +   ( +      final Origin origin, +      final Computation condition, +      final Computation if_true, +      final Computation if_false +   ) +   throws ParsingError +   { +      condition.expect_non_string(); + +      RecurrentChecks.assert_can_be_used_as(condition, Type.BOOL); + +      return +         new IfElseValue +         ( +            origin, +            new FutureType(origin), +            condition, +            if_true, +            if_false +         ); +   } + +   /**** Accessors ************************************************************/ +   @Override +   public void expect_non_string () +   throws ParsingError +   { +      if_true.expect_non_string(); +      if_false.expect_non_string(); + +      ((FutureType) get_type()).resolve_to +      ( +         RecurrentChecks.assert_can_be_used_as(if_false, if_true.get_type()) +      ); +   } + +   @Override +   public void expect_string () +   throws ParsingError +   { +      if_true.expect_string(); +      if_false.expect_string(); + +      ((FutureType) get_type()).resolve_to +      ( +         RecurrentChecks.assert_can_be_used_as(if_false, if_true.get_type()) +      ); +   } + +   public Computation get_condition () +   { +      return condition; +   } + +   public Computation get_if_true () +   { +      return if_true; +   } + +   public Computation get_if_false () +   { +      return if_false; +   } + +   /**** Misc. ****************************************************************/ +   @Override +   public String toString () +   { +      final StringBuilder sb = new StringBuilder(); + +      sb.append("(IfElseValue"); +      sb.append(System.lineSeparator()); +      sb.append(System.lineSeparator()); + +      sb.append("Condition:"); +      sb.append(System.lineSeparator()); +      sb.append(condition.toString()); + +      sb.append(System.lineSeparator()); +      sb.append(System.lineSeparator()); +      sb.append("If true:"); +      sb.append(System.lineSeparator()); +      sb.append(if_true.toString()); + +      sb.append(System.lineSeparator()); +      sb.append(System.lineSeparator()); +      sb.append("If false:"); +      sb.append(System.lineSeparator()); +      sb.append(if_false.toString()); + +      sb.append(")"); + +      return sb.toString(); +   } +} diff --git a/src/core/src/tonkadur/fate/v1/lang/computation/generic/Newline.java b/src/core/src/tonkadur/fate/v1/lang/computation/generic/Newline.java new file mode 100644 index 0000000..664b864 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/computation/generic/Newline.java @@ -0,0 +1,64 @@ +package tonkadur.fate.v1.lang.computation.generic; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import tonkadur.parser.Origin; + +import tonkadur.fate.v1.lang.meta.ComputationVisitor; +import tonkadur.fate.v1.lang.meta.Computation; + +import tonkadur.fate.v1.lang.type.Type; + +import tonkadur.fate.v1.lang.computation.GenericComputation; + +public class Newline extends GenericComputation +{ +   public static Collection<String> get_aliases () +   { +      final Collection<String> aliases; + +      aliases = new ArrayList<String>(); + +      aliases.add("newline"); + +      return aliases; +   } + +   public static GenericComputation build +   ( +      final Origin origin, +      final String alias, +      final List<Computation> call_parameters +   ) +   throws Throwable +   { +      if (call_parameters.size() != 0) +      { +         // TODO: Error. +         System.err.println("Wrong number of params at " + origin.toString()); + +         return null; +      } + +      return new Newline(origin); +   } + +   /***************************************************************************/ +   /**** PUBLIC ***************************************************************/ +   /***************************************************************************/ +   /**** Constructors *********************************************************/ +   public Newline (final Origin origin) +   { +      super(origin, Type.TEXT); +   } + + +   /**** Misc. ****************************************************************/ +   @Override +   public String toString () +   { +      return "(Newline)"; +   } +} diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/computation/generic/IfElseValueCompiler.java b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/computation/generic/IfElseValueCompiler.java new file mode 100644 index 0000000..c6d6d2e --- /dev/null +++ b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/computation/generic/IfElseValueCompiler.java @@ -0,0 +1,144 @@ +package tonkadur.wyrd.v1.compiler.fate.v1.computation.generic; + +import java.util.List; +import java.util.ArrayList; + +import tonkadur.fate.v1.lang.computation.generic.IfElseValue; + +import tonkadur.wyrd.v1.compiler.fate.v1.Compiler; +import tonkadur.wyrd.v1.compiler.fate.v1.ComputationCompiler; + +import tonkadur.wyrd.v1.compiler.fate.v1.computation.GenericComputationCompiler; + +import tonkadur.wyrd.v1.lang.computation.IfElseComputation; + +import tonkadur.wyrd.v1.lang.Register; + +import tonkadur.wyrd.v1.lang.meta.Instruction; + +import tonkadur.wyrd.v1.lang.instruction.SetValue; + +public class IfElseValueCompiler +extends GenericComputationCompiler +{ +   public static Class get_target_class () +   { +      return IfElseValue.class; +   } + +   public IfElseValueCompiler (final Compiler compiler) +   { +      super(compiler); +   } + +   public void compile +   ( +      final tonkadur.fate.v1.lang.computation.GenericComputation computation +   ) +   throws Throwable +   { +      final IfElseValue source; +      final ComputationCompiler cond_cc, if_true_cc, if_false_cc; + +      source = (IfElseValue) computation; + +      cond_cc = new ComputationCompiler(compiler); +      if_true_cc = new ComputationCompiler(compiler); +      if_false_cc = new ComputationCompiler(compiler); + +      source.get_condition().get_visited_by(cond_cc); +      source.get_if_true().get_visited_by(if_true_cc); +      source.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 register to be used +          * here. +          */ +         final Register 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.get_address(), +               if_true_cc.get_computation() +            ) +         ); + +         if_false_branch.add +         ( +            new SetValue +            ( +               if_else_result.get_address(), +               if_false_cc.get_computation() +            ) +         ); + +         if (cond_cc.has_init()) +         { +            init_instructions.add(cond_cc.get_init()); +         } + +         init_instructions.add +         ( +            tonkadur.wyrd.v1.compiler.util.IfElse.generate +            ( +               compiler.registers(), +               compiler.assembler(), +               cond_cc.get_computation(), +               compiler.assembler().merge(if_true_branch), +               compiler.assembler().merge(if_false_branch) +            ) +         ); + +         assimilate_reserved_registers(cond_cc); +         assimilate_reserved_registers(if_true_cc); +         assimilate_reserved_registers(if_false_cc); + +         result_as_computation = if_else_result.get_value(); +         result_as_address = if_else_result.get_address(); +      } +      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() +            ); +      } +   } +} diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/computation/generic/NewlineCompiler.java b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/computation/generic/NewlineCompiler.java new file mode 100644 index 0000000..d5ce82d --- /dev/null +++ b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/computation/generic/NewlineCompiler.java @@ -0,0 +1,31 @@ +package tonkadur.wyrd.v1.compiler.fate.v1.computation.generic; + +import tonkadur.fate.v1.lang.computation.generic.Newline; + +import tonkadur.wyrd.v1.compiler.fate.v1.Compiler; +import tonkadur.wyrd.v1.compiler.fate.v1.ComputationCompiler; + +import tonkadur.wyrd.v1.compiler.fate.v1.computation.GenericComputationCompiler; + +public class NewlineCompiler +extends GenericComputationCompiler +{ +   public static Class get_target_class () +   { +      return Newline.class; +   } + +   public NewlineCompiler (final Compiler compiler) +   { +      super(compiler); +   } + +   public void compile +   ( +      final tonkadur.fate.v1.lang.computation.GenericComputation _computation +   ) +   throws Throwable +   { +      result_as_computation = new tonkadur.wyrd.v1.lang.computation.Newline(); +   } +} | 


