summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2021-08-21 21:48:47 +0200
committerNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2021-08-21 21:48:47 +0200
commit248a0bffd1d96548402c70a5b181e67de59d1e14 (patch)
treefe34cc397e12590abcabc3f19f2e00bceac3d17d /src
parentc44f60829dc93687fe7d904b60d154de58f0492d (diff)
Adds some missing generic computations.
Diffstat (limited to 'src')
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/computation/generic/IfElseValue.java187
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/computation/generic/Newline.java64
-rw-r--r--src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/computation/generic/IfElseValueCompiler.java144
-rw-r--r--src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/computation/generic/NewlineCompiler.java31
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();
+ }
+}