summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/ComputationCompiler.java106
-rw-r--r--src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/InstructionCompiler.java53
-rw-r--r--src/core/src/tonkadur/wyrd/v1/compiler/util/registers/RegisterManager.java182
-rw-r--r--src/core/src/tonkadur/wyrd/v1/compiler/util/registers/StackableRegisterContext.java45
4 files changed, 356 insertions, 30 deletions
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 7d92f21..bbdb47c 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
@@ -1333,7 +1333,49 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor
)
throws Throwable
{
- /* TODO */
+ final String out_label, in_label;
+ final List<Register> parameters;
+ final Register result_holder;
+ final String context_name;
+
+ out_label = compiler.assembler().generate_label("<lambda_expr#out>");
+ in_label = compiler.assembler().generate_label("<lambda_expr#in>");
+
+ parameters = new ArrayList<Register>();
+
+ context_name = compiler.registers().create_stackable_context_name();
+
+ compiler.registers().create_stackable_context(context_name);
+
+ compiler.registers().push_context(context_name);
+
+ result_holder =
+ compiler.registers().reserve
+ (
+ new PointerType
+ (
+ TypeCompiler.compile
+ (
+ compiler,
+ n.get_lambda_function().get_type()
+ )
+ )
+ );
+
+ parameters.add(result_holder);
+
+ for (final
+ compiler.registers().read_parameters(parameters);
+ /* create new context */
+ /* push context */
+
+ /* (mark_after (setpc (label out)) (label in)) */
+ /* cc = compile lambda_expression */
+ /* (set result = cc.get_result())
+ /* (mark_after (merge (exit_instr)) (label out)) */
+ /* pop context */
+
+ /* result = (label in) */
}
@Override
@@ -1343,7 +1385,67 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor
)
throws Throwable
{
- /* TODO */
+ final ComputationCompiler target_line_cc;
+ final List<Computation> parameters;
+ final Register result;
+ final String return_to_label;
+
+ target_line_cc = new ComputationCompiler();
+
+ return_to_label =
+ compiler.assembler().generate_label("<lambda_eval#return_to>");
+
+ n.get_lambda_function_reference().get_visited_by(target_line_cc);
+
+ assimilate(target_line_cc);
+
+ result =
+ compiler.registers().reserve
+ (
+ TypeCompiler.compile(compiler, n.get_type())
+ );
+
+ parameters.add(result.get_address());
+
+ for
+ (
+ final tonkadur.fate.v1.lang.meta.Computation param: n.get_parameters()
+ )
+ {
+ final ComputationCompiler cc;
+
+ cc = new ComputationCompiler(compiler);
+
+ param.get_visited_by(cc);
+
+ assimilate(cc);
+
+ parameters.add(cc.get_computation());
+ }
+
+ init_instructions.addAll
+ (
+ compiler.registers().store_parameters(parameters);
+ );
+
+ init_instructions.add
+ (
+ compiler.assembler().mark_after
+ (
+ compiler.assembler().merge
+ (
+ compiler.registers().get_visit_context_instructions
+ (
+ target_line_cc.get_computation(),
+ return_to_label
+ )
+ ),
+ return_to_label
+ )
+ );
+
+ result_as_address = result.get_address();
+ result_as_computation = result.get_value();
}
@Override
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 6b9e6b9..2459f2a 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
@@ -233,7 +233,11 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor
)
throws Throwable
{
- /* TODO */
+ final Register r;
+
+ r = compiler.registers().reserve(n.get_type());
+
+ compiler.registers().bind(r, n.get_name());
}
@Override
@@ -1205,7 +1209,20 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor
)
throws Throwable
{
- /* TODO */
+ result.add
+ (
+ compiler.assembler().merge
+ (
+ compiler.registers().get_finalize_context_instructions()
+ )
+ );
+ result.add
+ (
+ compiler.assembler().merge
+ (
+ compiler.registers().get_leave_context_instructions()
+ )
+ );
}
@Override
@@ -1646,6 +1663,10 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor
throws Throwable
{
/* TODO */
+ /* ... handle parameters ... */
+
+ /* init target seq */
+ /* enter target seq */
}
@Override
@@ -1655,19 +1676,23 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor
)
throws Throwable
{
- /*
- * Fate: (sequence_call string)
- * Wyrd: (set_pc <label string>)
- */
- compiler.assembler().add_fixed_name_label(n.get_sequence_name());
+ /* TODO */
+ final String sequence_name;
- result.add
- (
- new SetPC
- (
- compiler.assembler().get_label_constant(n.get_sequence_name())
- )
- );
+ sequence_name = n.get_sequence_name();
+
+ /* ... handle parameters ... */
+
+ if (compiler.registers().get_current_context_name().equals(sequence_name))
+ {
+ /* Special case, we morph into it. */
+ }
+ else
+ {
+ /* init target seq */
+ /* finalize current seq */
+ /* jump to current seq */
+ }
}
@Override
diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/util/registers/RegisterManager.java b/src/core/src/tonkadur/wyrd/v1/compiler/util/registers/RegisterManager.java
index 88f3eeb..6dd9401 100644
--- a/src/core/src/tonkadur/wyrd/v1/compiler/util/registers/RegisterManager.java
+++ b/src/core/src/tonkadur/wyrd/v1/compiler/util/registers/RegisterManager.java
@@ -27,12 +27,16 @@ public class RegisterManager
protected static final String context_name_prefix = ".context.";
protected final Map<String, StackableRegisterContext> context_by_name;
protected final Deque<RegisterContext> context;
- protected final RegisterContext base_context;
+ protected final RegisterContext base_context, parameter_context;
+ protected final Register next_pc, pc_stack;
protected int created_contexts;
public RegisterManager ()
{
base_context = new RegisterContext("base context");
+ parameter_context = new RegisterContext("parameter context", ".param.");
+ next_pc = base_context.reserve(Type.INT);
+ pc_stack = base_context.reserve(new MapType(Type.INT));
context_by_name = new HashMap<String, StackableRegisterContext>();
context = new ArrayDeque<RegisterContext>();
@@ -70,6 +74,30 @@ public class RegisterManager
context_by_name.put(context_name, result);
}
+ public void push_context (final String context_name)
+ {
+ final StackableRegisterContext target;
+
+ target = context_by_name.get(context_name);
+
+ if (target == null)
+ {
+ System.err.println
+ (
+ "[P] Cannot push unknown context '"
+ + context
+ + "'."
+ );
+ }
+
+ context.push(target);
+ }
+
+ public void pop_context ()
+ {
+ context.pop();
+ }
+
public Register register (final Type t, final String name)
{
return context.peekFirst().reserve(t, name);
@@ -99,20 +127,104 @@ public class RegisterManager
return result;
}
- public List<Instruction> get_enter_context_instructions
+ public List<Instruction> get_visit_context_instructions
+ (
+ final Computation enter_at,
+ final Computation leave_to
+ )
+ {
+ final List<Instruction> result;
+
+ result = new ArrayList<Instruction>();
+
+ result.add
+ (
+ new SetValue
+ (
+ new RelativeAddress
+ (
+ pc_stack.get_address(),
+ new Size(pc_stack.get_address()),
+ Type.INT
+ ),
+ leave_to
+ )
+ );
+
+ result.add(new SetPC(enter_at));
+
+ return result;
+ }
+
+ public List<Instruction> get_jump_to_context_instructions
(
- final String context_name
+ final Computation enter_at
)
{
- return context_by_name.get(context_name).get_enter_instructions();
+ final List<Instruction> result;
+
+ result = new ArrayList<Instruction>();
+
+ result.add(new SetPC(enter_at));
+
+ return result;
+ }
+
+ public List<Instruction> get_initialize_context_instructions
+ (
+ final String context_name,
+ final List<Computation> parameters
+ )
+ {
+ return
+ context_by_name.get(context_name).get_initialize_instructions
+ (
+ parameters
+ );
}
- public List<Instruction> get_leave_context_instructions
+ public List<Instruction> get_morph_into_context_instructions
(
- final String context_name
+ final List<Computation> parameters
)
{
- return context_by_name.get(context_name).get_leave_instructions();
+ return context.peekFirst().get_morph_into_instructions(parameters);
+ }
+
+ public String get_current_context_name ()
+ {
+ return context.peekFirst().get_name();
+ }
+
+ public List<Instruction> get_leave_context_instructions ()
+ {
+ final Address return_to_address;
+ final List<Instruction> result;
+
+ return_to_address =
+ new RelativeAddress
+ (
+ pc_stack.get_address(),
+ new Size(pc_stack.get_address()),
+ Type.INT
+ );
+
+ result = new ArrayList<Instruction>();
+
+ result.add
+ (
+ new SetValue(next_pc.get_address(), new ValueOf(return_to_address))
+ );
+
+ result.add(new Remove(return_to_address));
+ result.add(new SetPC(next.pc.get_value()));
+
+ return result;
+ }
+
+ public List<Instruction> get_finalize_context_instructions ()
+ {
+ return context.peekFirst().get_finalize_instructions();
}
public Collection<DictType> get_context_structure_types ()
@@ -133,4 +245,60 @@ public class RegisterManager
{
return base_context.get_all_registers();
}
+
+ public List<Instruction> store_parameters (final List<Computation> params)
+ {
+ final List<Register> used_registers;
+ final List<Instruction> result;
+
+ used_registers = new ArrayList<Register>();
+ result = new ArrayList<Instruction>();
+
+ for (final Computation p: params)
+ {
+ final Register r;
+
+ r = parameters_context.reserve(p.get_type());
+
+ result.add(new SetValue(r.get_address(), p));
+
+ used_registers.add(r);
+ }
+
+ for (final Register r: used_registers)
+ {
+ /* Side-channel attack to pass parameters, because it's convenient. */
+ r.set_is_in_use(false);
+ }
+
+ return result;
+ }
+
+ public List<Instruction> read_parameters (final List<Register> params)
+ {
+ final List<Register> used_registers;
+ final List<Instruction> result;
+
+ used_registers = new ArrayList<Register>();
+ result = new ArrayList<Instruction>();
+
+ for (final Register p: params)
+ {
+ final Register r;
+
+ r = parameters_context.reserve(p.get_type());
+
+ result.add(new SetValue(p.get_address(), r.get_value()));
+
+ used_registers.add(r);
+ }
+
+ for (final Register r: used_registers)
+ {
+ /* Side-channel attack to pass parameters, because it's convenient. */
+ r.set_is_in_use(false);
+ }
+
+ return result;
+ }
}
diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/util/registers/StackableRegisterContext.java b/src/core/src/tonkadur/wyrd/v1/compiler/util/registers/StackableRegisterContext.java
index e8f79a8..d099e8e 100644
--- a/src/core/src/tonkadur/wyrd/v1/compiler/util/registers/StackableRegisterContext.java
+++ b/src/core/src/tonkadur/wyrd/v1/compiler/util/registers/StackableRegisterContext.java
@@ -27,10 +27,12 @@ import tonkadur.wyrd.v1.lang.type.DictType;
class StackableRegisterContext extends RegisterContext
{
protected final Map<String, Type> context_structure_fields;
+ protected final RegisterContext base_context;
protected final DictType context_structure;
protected final Register context_stack_level;
protected final Register context_stacks;
- protected final Address current_context_address;
+ protected final Address current_context_address_holder;
+ protected final Computation current_context_address;
public StackableRegisterContext
(
@@ -40,6 +42,8 @@ class StackableRegisterContext extends RegisterContext
{
super(context_name);
+ this.base_context = base_context;
+
context_structure_fields = new HashMap<String, Type>();
context_structure = new DictType(context_name, context_structure_fields);
@@ -51,13 +55,15 @@ class StackableRegisterContext extends RegisterContext
new MapType(new PointerType(context_structure))
);
- current_context_address =
+ current_context_address_holder =
new RelativeAddress
(
context_stacks.get_address(),
new Cast(context_stack_level.get_value(), Type.STRING),
new PointerType(context_structure)
);
+
+ current_context_address = new ValueOf(current_context_address_holder);
}
@Override
@@ -67,7 +73,8 @@ class StackableRegisterContext extends RegisterContext
if (context_structure.get_fields().get(name) != null)
{
- System.err.println
+ ;
+ System.err.println
(
"[P] Duplicate register '"
+ name
@@ -93,16 +100,40 @@ class StackableRegisterContext extends RegisterContext
);
}
- public List<Instruction> get_enter_instructions ()
+ public List<Instruction> get_initialize_instructions ()
{
/* TODO */
return new ArrayList<>();
}
- public List<Instruction> get_leave_instructions ()
+ public List<Instruction> get_finalize_instructions ()
{
- /* TODO */
- return new ArrayList<>();
+ final List<Instruction> result;
+
+ result = new ArrayList<Instruction>();
+
+ result.add(new Remove(current_context_address));
+ result.add(new Remove(current_context_address_holder));
+
+ result.add
+ (
+ new SetValue
+ (
+ context_stack_level.get_address(),
+ Operation.minus(context_stack_level.get_value(), Constant.ONE)
+ )
+ );
+
+ result.add
+ (
+ new SetValue
+ (
+ context_stack_level.get_address(),
+ Operation.minus(context_stack_level.get_value(), Constant.ONE)
+ )
+ );
+
+ return result;
}
public DictType get_structure_type ()