xo-interpreter2: apply sequence now working in interpreter
This commit is contained in:
parent
e71954697c
commit
61d41a2298
8 changed files with 203 additions and 34 deletions
|
|
@ -8,6 +8,8 @@
|
|||
#include "VsmEvalArgsFrame.hpp"
|
||||
#include <xo/expression2/ApplyExpr.hpp>
|
||||
#include <xo/expression2/Constant.hpp>
|
||||
#include <xo/procedure2/RuntimeContext.hpp>
|
||||
#include <xo/procedure2/SimpleRcx.hpp>
|
||||
#include <xo/gc/DX1Collector.hpp>
|
||||
#include <xo/gc/detail/IAllocator_DX1Collector.hpp>
|
||||
#include <xo/printable2/Printable.hpp>
|
||||
|
|
@ -26,9 +28,13 @@ namespace xo {
|
|||
|
||||
namespace scm {
|
||||
|
||||
// NOTE: using heap for {DX1Collector, DSimpleRcx} instances
|
||||
// (though allocation from explictly mmap'd memory)
|
||||
//
|
||||
VirtualSchematikaMachine::VirtualSchematikaMachine(const VsmConfig & config)
|
||||
: config_{config},
|
||||
mm_(box<AAllocator,DX1Collector>(new DX1Collector(config.x1_config_))),
|
||||
rcx_(box<ARuntimeContext,DSimpleRcx>(new DSimpleRcx(mm_.to_op()))),
|
||||
reader_{config.rdr_config_, mm_.to_op()}
|
||||
{}
|
||||
|
||||
|
|
@ -211,21 +217,23 @@ namespace xo {
|
|||
|
||||
// assuming bump allocator:
|
||||
//
|
||||
// DArray VsmApplyFrame VsmEvalArgsFrame
|
||||
// v v v
|
||||
// +----------------------+-------+------+----+--------+-------+------+-------+
|
||||
// | argument expressions | par x | cont | fn | args x | par x | cont | i_arg |
|
||||
// +----------------------+-----|-+------+----+------|-+-----|-+------+-------+
|
||||
// ^ ^ | | |
|
||||
// | \----------------------------------/
|
||||
// \ | /
|
||||
// \-----------------------------------------------/
|
||||
// DArray VsmApplyFrame VsmEvalArgsFrame
|
||||
// v v v
|
||||
// +----------------------+-------+-------+----+--------+-------+-------+-------+
|
||||
// | argument expressions | par x | cont1 | fn | args x | par x | cont2 | i_arg |
|
||||
// +----------------------+-----|-+-------+----+------|-+-----|-+-------+-------+
|
||||
// ^ ^ | | |
|
||||
// | \-----------------------------------/
|
||||
// \ | /
|
||||
// \------------------------------------------------/
|
||||
// /
|
||||
// <---------------------------/
|
||||
//
|
||||
// - VsmEvalArgsFrame: owned by VSM, state for evalargs loop
|
||||
// - VsmApplyFrame: owned by VSM, state for transferring control to called function
|
||||
// - DArray: contains evaluated args; owned by called primitive
|
||||
// - cont2: always c_apply
|
||||
//
|
||||
|
||||
auto apply = obj<AExpression,DApplyExpr>::from(expr_);
|
||||
|
||||
|
|
@ -235,13 +243,13 @@ namespace xo {
|
|||
|
||||
// TODO: check function signature
|
||||
|
||||
auto apply_frame
|
||||
= obj<AGCObject,DVsmApplyFrame>
|
||||
(DVsmApplyFrame::make(mm_.to_op(), stack_, cont_, args));
|
||||
DVsmApplyFrame * apply_frame
|
||||
= DVsmApplyFrame::make(mm_.to_op(), stack_, cont_, args);
|
||||
|
||||
auto evalargs_frame
|
||||
= obj<AGCObject,DVsmEvalArgsFrame>
|
||||
(DVsmEvalArgsFrame::make(mm_.to_op(), apply_frame, VsmInstr::c_apply));
|
||||
(DVsmEvalArgsFrame::make(mm_.to_op(),
|
||||
apply_frame, VsmInstr::c_apply, apply.data()));
|
||||
|
||||
this->stack_ = evalargs_frame;
|
||||
|
||||
|
|
@ -269,13 +277,131 @@ namespace xo {
|
|||
void
|
||||
VirtualSchematikaMachine::_do_apply_op()
|
||||
{
|
||||
// not implemented
|
||||
assert(false);
|
||||
// rcx_ : runtime context
|
||||
// fn_ : function to call
|
||||
// args_ : array of arguments
|
||||
|
||||
// TODO: check argument types
|
||||
|
||||
this->value_ = fn_.apply_nocheck(rcx_.to_op(), args_);
|
||||
this->pc_ = cont_;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
VirtualSchematikaMachine::_do_evalargs_op()
|
||||
{
|
||||
scope log(XO_DEBUG(false));
|
||||
|
||||
if (!value_.is_value()) {
|
||||
// error while evaluating function arg
|
||||
|
||||
log.retroactively_enable();
|
||||
log && log("error in apply -> terminating app");
|
||||
|
||||
this->pc_ = VsmInstr::c_halt;
|
||||
return;
|
||||
}
|
||||
|
||||
// here: nested evaluation succeeded
|
||||
|
||||
// value of one of {fn, arg(i), ..} in fn(arg0 .. arg(n-1))
|
||||
//
|
||||
obj<AGCObject> value = *(value_.value());
|
||||
|
||||
// value_ in [i_arg] value_
|
||||
// . (if i_arg >= 0) . (if i_arg = -1)
|
||||
// . .
|
||||
// DArray . VsmApplyFrame . VsmEvalArgsFrame
|
||||
// v v v v v
|
||||
// +----------------------+-------+-------+----+--------+-------+-------+--------+-------+
|
||||
// | argument expressions | par o | cont1 | fn | args x | par o | cont2 | applyx | i_arg |
|
||||
// +----------------------+-----|-+-------+----+------|-+-----|-+-------+--------+-------+
|
||||
// ^ ^ | | |
|
||||
// | \-----------------------------------/
|
||||
// \ | /
|
||||
// \------------------------------------------------/
|
||||
// /
|
||||
// <---------------------------/
|
||||
//
|
||||
// - VsmEvalArgsFrame: owned by VSM, state for evalargs loop
|
||||
// - VsmApplyFrame: owned by VSM, state for transferring control to called function
|
||||
// - DArray: contains evaluated args; owned by called primitive
|
||||
|
||||
// - i_arg
|
||||
// if -1: value_ register holds function
|
||||
// if >=0: value_ register holds i'th function argument
|
||||
//
|
||||
|
||||
auto evalargs_frame
|
||||
= obj<AGCObject,DVsmEvalArgsFrame>::from(stack_);
|
||||
|
||||
assert(evalargs_frame);
|
||||
|
||||
int32_t i_arg = evalargs_frame->i_arg();
|
||||
|
||||
DVsmApplyFrame * apply_frame = evalargs_frame->parent();
|
||||
|
||||
const DApplyExpr * apply_expr
|
||||
= evalargs_frame->apply_expr();
|
||||
|
||||
if (i_arg == -1) {
|
||||
auto fn = value.to_facet<AProcedure>();
|
||||
|
||||
if (fn) {
|
||||
apply_frame->assign_fn(fn);
|
||||
|
||||
i_arg = evalargs_frame->increment_arg();
|
||||
|
||||
// now i_arg is 0 -> evaluate that argument
|
||||
|
||||
this->expr_ = apply_expr->arg(i_arg);
|
||||
this->pc_ = VsmInstr::c_eval;
|
||||
//this->cont_ = VsmInstra::c_evalargs; // redundant, since preserved
|
||||
|
||||
return;
|
||||
} else {
|
||||
// error - function position must deliver something with AProcedure?
|
||||
// or DClosure, but we'll get to that.
|
||||
|
||||
log.retroactively_enable();
|
||||
log("expected procedure in function position -> terminate");
|
||||
|
||||
assert(false);
|
||||
}
|
||||
} else {
|
||||
DArray * args = apply_frame->args();
|
||||
|
||||
log && log(xtag("i_arg", i_arg), xtag("n_arg", args->size()), xtag("cap", args->capacity()));
|
||||
|
||||
args->push_back(value);
|
||||
|
||||
i_arg = evalargs_frame->increment_arg();
|
||||
|
||||
if (i_arg == static_cast<int32_t>(apply_expr->n_args())) {
|
||||
// all apply-arguments have been evaluated
|
||||
// -> done with VsmEvalArgsFrame
|
||||
//
|
||||
|
||||
this->fn_ = apply_frame->fn();
|
||||
this->args_ = apply_frame->args();
|
||||
|
||||
this->stack_ = apply_frame->parent();
|
||||
this->pc_ = VsmInstr::c_apply;
|
||||
this->cont_ = apply_frame->cont();
|
||||
|
||||
return;
|
||||
|
||||
} else {
|
||||
this->expr_ = apply_expr->arg(i_arg);
|
||||
this->pc_ = VsmInstr::c_eval;
|
||||
//this->cont_ = VsmInstra::c_evalargs; // redundant, since preserved
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// not implemented
|
||||
assert(false);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue