xo-interpreter2: ifelse expressions working + utest
This commit is contained in:
parent
6ffe3a627d
commit
e7e9d226dd
18 changed files with 508 additions and 7 deletions
|
|
@ -103,6 +103,32 @@ xo_add_genfacetimpl(
|
|||
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
# note: manual target; generated code committed to git
|
||||
xo_add_genfacetimpl(
|
||||
TARGET xo-interpreter2-facetimpl-gcobject-vsmifelsecontframe
|
||||
FACET_PKG xo_gc
|
||||
FACET GCObject
|
||||
REPR VsmIfElseContFrame
|
||||
INPUT idl/IGCObject_DVsmIfElseContFrame.json5
|
||||
OUTPUT_HPP_DIR include/xo/interpreter2
|
||||
OUTPUT_IMPL_SUBDIR ifelse
|
||||
OUTPUT_CPP_DIR src/interpreter2
|
||||
)
|
||||
|
||||
# note: manual target; generated code committed to git
|
||||
xo_add_genfacetimpl(
|
||||
TARGET xo-interpreter2-facetimpl-printable-vsmifelsecontframe
|
||||
FACET_PKG xo_printable2
|
||||
FACET Printable
|
||||
REPR VsmIfElseContFrame
|
||||
INPUT idl/IPrintable_DVsmIfElseContFrame.json5
|
||||
OUTPUT_HPP_DIR include/xo/interpreter2
|
||||
OUTPUT_IMPL_SUBDIR ifelse
|
||||
OUTPUT_CPP_DIR src/interpreter2
|
||||
)
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
# note: manual target; generated code committed to git
|
||||
xo_add_genfacetimpl(
|
||||
TARGET xo-interpreter2-facetimpl-gcobject-vsmseqcontframe
|
||||
|
|
|
|||
15
xo-interpreter2/idl/IGCObject_DVsmIfElseContFrame.json5
Normal file
15
xo-interpreter2/idl/IGCObject_DVsmIfElseContFrame.json5
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
mode: "implementation",
|
||||
includes: [
|
||||
"<xo/gc/GCObject.hpp>",
|
||||
"<xo/alloc2/Allocator.hpp>"
|
||||
],
|
||||
local_types: [ ],
|
||||
namespace1: "xo",
|
||||
namespace2: "scm",
|
||||
facet_idl: "idl/GCObject.json5",
|
||||
brief: "provide AGCObject interface for DVsmIfElseContFrame",
|
||||
using_doxygen: true,
|
||||
repr: "DVsmIfElseContFrame",
|
||||
doc: [ "implement AGCObject for DVsmIfElseContFrame" ],
|
||||
}
|
||||
13
xo-interpreter2/idl/IPrintable_DVsmIfElseContFrame.json5
Normal file
13
xo-interpreter2/idl/IPrintable_DVsmIfElseContFrame.json5
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
mode: "implementation",
|
||||
includes: [ "<xo/printable2/Printable.hpp>",
|
||||
"<xo/printable2/detail/IPrintable_Xfer.hpp>" ],
|
||||
local_types: [ ],
|
||||
namespace1: "xo",
|
||||
namespace2: "scm",
|
||||
facet_idl: "idl/Printable.json5",
|
||||
brief: "provide APrintable interface for DVsmIfElseContFrame",
|
||||
using_doxygen: true,
|
||||
repr: "DVsmIfElseContFrame",
|
||||
doc: [ "implement APrintable for DVsmIfElseContFrame" ],
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
/** @file DVsmIfElseContFrame.hpp
|
||||
*
|
||||
* @author Roland Conybeare, Feb 2026
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "VsmInstr.hpp"
|
||||
#include <xo/expression2/IfElseExpr.hpp>
|
||||
#include <xo/gc/GCObject.hpp>
|
||||
|
||||
namespace xo {
|
||||
namespace scm {
|
||||
/** @brief saved VSM state during evaluation of a SequenceExpr
|
||||
**/
|
||||
class DVsmIfElseContFrame {
|
||||
public:
|
||||
using ACollector = xo::mm::ACollector;
|
||||
using AAllocator = xo::mm::AAllocator;
|
||||
using AGCObject = xo::mm::AGCObject;
|
||||
using ppindentinfo = xo::print::ppindentinfo;
|
||||
|
||||
public:
|
||||
/** @defgroup scm-vsmevalsequenceframe-ctors constructors **/
|
||||
///@{
|
||||
|
||||
DVsmIfElseContFrame(obj<AGCObject> parent,
|
||||
VsmInstr cont,
|
||||
DIfElseExpr * ifelse_expr);
|
||||
|
||||
/** create instance using memory from allocator @p mm **/
|
||||
static DVsmIfElseContFrame * make(obj<AAllocator> mm,
|
||||
obj<AGCObject> parent,
|
||||
VsmInstr cont,
|
||||
DIfElseExpr * ifelse_expr);
|
||||
|
||||
///@}
|
||||
/** @defgroup scm-vsmevalsequenceframe-access-methods access methods **/
|
||||
///@{
|
||||
|
||||
obj<AGCObject> parent() const noexcept { return parent_; }
|
||||
VsmInstr cont() const noexcept { return cont_; }
|
||||
DIfElseExpr * ifelse_expr() const noexcept { return ifelse_expr_; }
|
||||
|
||||
///@}
|
||||
/** @defgroup scm-vsmevalsequenceframe-general-methods general methods **/
|
||||
///@{
|
||||
|
||||
///@}
|
||||
/** @defgroup scm-vsmevalsequenceframe-gcobject-facet gcobject facet **/
|
||||
///@{
|
||||
|
||||
std::size_t shallow_size() const noexcept;
|
||||
DVsmIfElseContFrame * shallow_copy(obj<AAllocator> mm) const noexcept;
|
||||
std::size_t forward_children(obj<ACollector> gc) noexcept;
|
||||
|
||||
///@}
|
||||
/** @defgrouop scm-vsmseqcontframe-printable-facet printable facet **/
|
||||
///@{
|
||||
|
||||
bool pretty(const ppindentinfo & ppii) const noexcept;
|
||||
|
||||
///@}
|
||||
|
||||
private:
|
||||
/** @defgroup scm-vsmevalsequenceframe-members member variables **/
|
||||
///@{
|
||||
|
||||
/** saved VSM stack; restore when this frame consumed **/
|
||||
obj<AGCObject> parent_;
|
||||
/** saved continuation; restore when this frame consumed **/
|
||||
VsmInstr cont_;
|
||||
/** saved expr. evaluate elements of this sequence in order **/
|
||||
DIfElseExpr * ifelse_expr_ = nullptr;
|
||||
|
||||
///@}
|
||||
};
|
||||
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end DVsmIfElseContFrame.hpp */
|
||||
|
|
@ -187,6 +187,11 @@ namespace xo {
|
|||
**/
|
||||
void _do_apply_cont_op();
|
||||
|
||||
/** proceed with if- or else- branch of an if-else expression
|
||||
* after evaluating test condition
|
||||
**/
|
||||
void _do_ifelse_cont_op();
|
||||
|
||||
/** loop continuation after evaluating element of a SequenceExpr **/
|
||||
void _do_seq_cont_op();
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
/** @file VsmIfElseContFrame.hpp
|
||||
*
|
||||
* @author Roland Conybeare, Feb 2026
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "DVsmIfElseContFrame.hpp"
|
||||
#include "ifelse/IGCObject_DVsmIfElseContFrame.hpp"
|
||||
#include "ifelse/IPrintable_DVsmIfElseContFrame.hpp"
|
||||
|
||||
/* end VsmIfElseContFrame.hpp */
|
||||
|
|
@ -13,14 +13,21 @@ namespace xo {
|
|||
public:
|
||||
explicit VsmInstr(vsm_opcode oc) : opcode_{oc} {}
|
||||
|
||||
// instructions
|
||||
|
||||
static VsmInstr c_halt;
|
||||
static VsmInstr c_eval;
|
||||
|
||||
static VsmInstr c_apply;
|
||||
static VsmInstr c_evalargs;
|
||||
/** proceed to continuation after an ApplyExpr **/
|
||||
/** restore VSM state for continuation of an apply expression **/
|
||||
static VsmInstr c_apply_cont;
|
||||
|
||||
/** proceed to branch of if-else expression after evaluating
|
||||
* test condition
|
||||
**/
|
||||
static VsmInstr c_ifelse_cont;
|
||||
|
||||
/** loop to evaluate members of a SequenceExpr **/
|
||||
static VsmInstr c_seq_cont;
|
||||
|
||||
|
|
|
|||
|
|
@ -28,11 +28,14 @@ namespace xo {
|
|||
**/
|
||||
evalargs,
|
||||
|
||||
/** Coda to restore vsm registers (local_env, stack, cont)
|
||||
/** continuation to restore vsm registers (local_env, stack, cont)
|
||||
* after invoking a closure
|
||||
**/
|
||||
apply_cont,
|
||||
|
||||
/** continuation to act on a branch **/
|
||||
ifelse_cont,
|
||||
|
||||
/** Loop over elements of a SequenceExpr **/
|
||||
seq_cont,
|
||||
|
||||
|
|
@ -55,3 +58,4 @@ namespace xo {
|
|||
} /*namespace xo*/
|
||||
|
||||
/* end VsmOpcode.hpp */
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
/** @file IGCObject_DVsmIfElseContFrame.hpp
|
||||
*
|
||||
* Generated automagically from ingredients:
|
||||
* 1. code generator:
|
||||
* [xo-facet/codegen/genfacet]
|
||||
* arguments:
|
||||
* --input [idl/IGCObject_DVsmIfElseContFrame.json5]
|
||||
* 2. jinja2 template for abstract facet .hpp file:
|
||||
* [iface_facet_repr.hpp.j2]
|
||||
* 3. idl for facet methods
|
||||
* [idl/IGCObject_DVsmIfElseContFrame.json5]
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GCObject.hpp"
|
||||
#include <xo/gc/GCObject.hpp>
|
||||
#include <xo/alloc2/Allocator.hpp>
|
||||
#include "DVsmIfElseContFrame.hpp"
|
||||
|
||||
namespace xo { namespace scm { class IGCObject_DVsmIfElseContFrame; } }
|
||||
|
||||
namespace xo {
|
||||
namespace facet {
|
||||
template <>
|
||||
struct FacetImplementation<xo::mm::AGCObject,
|
||||
xo::scm::DVsmIfElseContFrame>
|
||||
{
|
||||
using ImplType = xo::mm::IGCObject_Xfer
|
||||
<xo::scm::DVsmIfElseContFrame,
|
||||
xo::scm::IGCObject_DVsmIfElseContFrame>;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
namespace xo {
|
||||
namespace scm {
|
||||
/** @class IGCObject_DVsmIfElseContFrame
|
||||
**/
|
||||
class IGCObject_DVsmIfElseContFrame {
|
||||
public:
|
||||
/** @defgroup scm-gcobject-dvsmifelsecontframe-type-traits **/
|
||||
///@{
|
||||
using size_type = xo::mm::AGCObject::size_type;
|
||||
using AAllocator = xo::mm::AGCObject::AAllocator;
|
||||
using ACollector = xo::mm::AGCObject::ACollector;
|
||||
using Copaque = xo::mm::AGCObject::Copaque;
|
||||
using Opaque = xo::mm::AGCObject::Opaque;
|
||||
///@}
|
||||
/** @defgroup scm-gcobject-dvsmifelsecontframe-methods **/
|
||||
///@{
|
||||
// const methods
|
||||
/** memory consumption for this instance **/
|
||||
static size_type shallow_size(const DVsmIfElseContFrame & self) noexcept;
|
||||
/** copy instance using allocator **/
|
||||
static Opaque shallow_copy(const DVsmIfElseContFrame & self, obj<AAllocator> mm) noexcept;
|
||||
|
||||
// non-const methods
|
||||
/** during GC: forward immdiate children **/
|
||||
static size_type forward_children(DVsmIfElseContFrame & self, obj<ACollector> gc) noexcept;
|
||||
///@}
|
||||
};
|
||||
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end */
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/** @file IPrintable_DVsmIfElseContFrame.hpp
|
||||
*
|
||||
* Generated automagically from ingredients:
|
||||
* 1. code generator:
|
||||
* [xo-facet/codegen/genfacet]
|
||||
* arguments:
|
||||
* --input [idl/IPrintable_DVsmIfElseContFrame.json5]
|
||||
* 2. jinja2 template for abstract facet .hpp file:
|
||||
* [iface_facet_repr.hpp.j2]
|
||||
* 3. idl for facet methods
|
||||
* [idl/IPrintable_DVsmIfElseContFrame.json5]
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Printable.hpp"
|
||||
#include <xo/printable2/Printable.hpp>
|
||||
#include <xo/printable2/detail/IPrintable_Xfer.hpp>
|
||||
#include "DVsmIfElseContFrame.hpp"
|
||||
|
||||
namespace xo { namespace scm { class IPrintable_DVsmIfElseContFrame; } }
|
||||
|
||||
namespace xo {
|
||||
namespace facet {
|
||||
template <>
|
||||
struct FacetImplementation<xo::print::APrintable,
|
||||
xo::scm::DVsmIfElseContFrame>
|
||||
{
|
||||
using ImplType = xo::print::IPrintable_Xfer
|
||||
<xo::scm::DVsmIfElseContFrame,
|
||||
xo::scm::IPrintable_DVsmIfElseContFrame>;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
namespace xo {
|
||||
namespace scm {
|
||||
/** @class IPrintable_DVsmIfElseContFrame
|
||||
**/
|
||||
class IPrintable_DVsmIfElseContFrame {
|
||||
public:
|
||||
/** @defgroup scm-printable-dvsmifelsecontframe-type-traits **/
|
||||
///@{
|
||||
using ppindentinfo = xo::print::APrintable::ppindentinfo;
|
||||
using Copaque = xo::print::APrintable::Copaque;
|
||||
using Opaque = xo::print::APrintable::Opaque;
|
||||
///@}
|
||||
/** @defgroup scm-printable-dvsmifelsecontframe-methods **/
|
||||
///@{
|
||||
// const methods
|
||||
/** Pretty-printing support for this object.
|
||||
See [xo-indentlog/xo/indentlog/pretty.hpp] **/
|
||||
static bool pretty(const DVsmIfElseContFrame & self, const ppindentinfo & ppii);
|
||||
|
||||
// non-const methods
|
||||
///@}
|
||||
};
|
||||
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end */
|
||||
|
|
@ -20,6 +20,10 @@ set(SELF_SRCS
|
|||
IGCObject_DVsmApplyClosureFrame.cpp
|
||||
IPrintable_DVsmApplyClosureFrame.cpp
|
||||
|
||||
DVsmIfElseContFrame.cpp
|
||||
IGCObject_DVsmIfElseContFrame.cpp
|
||||
IPrintable_DVsmIfElseContFrame.cpp
|
||||
|
||||
DVsmSeqContFrame.cpp
|
||||
IGCObject_DVsmSeqContFrame.cpp
|
||||
IPrintable_DVsmSeqContFrame.cpp
|
||||
|
|
|
|||
66
xo-interpreter2/src/interpreter2/DVsmIfElseContFrame.cpp
Normal file
66
xo-interpreter2/src/interpreter2/DVsmIfElseContFrame.cpp
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/** @file DVsmIfElseContFrame.cpp
|
||||
*
|
||||
* @author Roland Conybeare, Feb 2026
|
||||
**/
|
||||
|
||||
#include "DVsmIfElseContFrame.hpp"
|
||||
|
||||
namespace xo {
|
||||
namespace scm {
|
||||
|
||||
DVsmIfElseContFrame::DVsmIfElseContFrame(obj<AGCObject> parent,
|
||||
VsmInstr cont,
|
||||
DIfElseExpr * ifelse_expr)
|
||||
: parent_{parent},
|
||||
cont_{cont},
|
||||
ifelse_expr_{ifelse_expr}
|
||||
{}
|
||||
|
||||
DVsmIfElseContFrame *
|
||||
DVsmIfElseContFrame::make(obj<AAllocator> mm,
|
||||
obj<AGCObject> parent,
|
||||
VsmInstr cont,
|
||||
DIfElseExpr * seq_expr)
|
||||
{
|
||||
void * mem = mm.alloc_for<DVsmIfElseContFrame>();
|
||||
|
||||
return new (mem) DVsmIfElseContFrame(parent, cont, seq_expr);
|
||||
}
|
||||
|
||||
// gcobject facet
|
||||
|
||||
std::size_t
|
||||
DVsmIfElseContFrame::shallow_size() const noexcept
|
||||
{
|
||||
return sizeof(*this);
|
||||
}
|
||||
|
||||
DVsmIfElseContFrame *
|
||||
DVsmIfElseContFrame::shallow_copy(obj<AAllocator> mm) const noexcept
|
||||
{
|
||||
return mm.std_copy_for<DVsmIfElseContFrame>(this);
|
||||
}
|
||||
|
||||
std::size_t
|
||||
DVsmIfElseContFrame::forward_children(obj<ACollector> gc) noexcept
|
||||
{
|
||||
gc.forward_inplace(&parent_);
|
||||
gc.forward_inplace(&ifelse_expr_);
|
||||
|
||||
return this->shallow_size();
|
||||
}
|
||||
|
||||
// printable facet
|
||||
|
||||
bool
|
||||
DVsmIfElseContFrame::pretty(const ppindentinfo & ppii) const noexcept
|
||||
{
|
||||
return ppii.pps()->pretty_struct(ppii,
|
||||
"DVsmIfElseContFrame",
|
||||
refrtag("cont", cont_));
|
||||
}
|
||||
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end DVsmIfElseContFrame.cpp */
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/** @file IGCObject_DVsmIfElseContFrame.cpp
|
||||
*
|
||||
* Generated automagically from ingredients:
|
||||
* 1. code generator:
|
||||
* [xo-facet/codegen/genfacet]
|
||||
* arguments:
|
||||
* --input [idl/IGCObject_DVsmIfElseContFrame.json5]
|
||||
* 2. jinja2 template for abstract facet .hpp file:
|
||||
* [iface_facet_any.hpp.j2]
|
||||
* 3. idl for facet methods
|
||||
* [idl/IGCObject_DVsmIfElseContFrame.json5]
|
||||
**/
|
||||
|
||||
#include "ifelse/IGCObject_DVsmIfElseContFrame.hpp"
|
||||
|
||||
namespace xo {
|
||||
namespace scm {
|
||||
auto
|
||||
IGCObject_DVsmIfElseContFrame::shallow_size(const DVsmIfElseContFrame & self) noexcept -> size_type
|
||||
{
|
||||
return self.shallow_size();
|
||||
}
|
||||
|
||||
auto
|
||||
IGCObject_DVsmIfElseContFrame::shallow_copy(const DVsmIfElseContFrame & self, obj<AAllocator> mm) noexcept -> Opaque
|
||||
{
|
||||
return self.shallow_copy(mm);
|
||||
}
|
||||
|
||||
auto
|
||||
IGCObject_DVsmIfElseContFrame::forward_children(DVsmIfElseContFrame & self, obj<ACollector> gc) noexcept -> size_type
|
||||
{
|
||||
return self.forward_children(gc);
|
||||
}
|
||||
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end IGCObject_DVsmIfElseContFrame.cpp */
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/** @file IPrintable_DVsmIfElseContFrame.cpp
|
||||
*
|
||||
* Generated automagically from ingredients:
|
||||
* 1. code generator:
|
||||
* [xo-facet/codegen/genfacet]
|
||||
* arguments:
|
||||
* --input [idl/IPrintable_DVsmIfElseContFrame.json5]
|
||||
* 2. jinja2 template for abstract facet .hpp file:
|
||||
* [iface_facet_any.hpp.j2]
|
||||
* 3. idl for facet methods
|
||||
* [idl/IPrintable_DVsmIfElseContFrame.json5]
|
||||
**/
|
||||
|
||||
#include "ifelse/IPrintable_DVsmIfElseContFrame.hpp"
|
||||
|
||||
namespace xo {
|
||||
namespace scm {
|
||||
auto
|
||||
IPrintable_DVsmIfElseContFrame::pretty(const DVsmIfElseContFrame & self, const ppindentinfo & ppii) -> bool
|
||||
{
|
||||
return self.pretty(ppii);
|
||||
}
|
||||
|
||||
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end IPrintable_DVsmIfElseContFrame.cpp */
|
||||
|
|
@ -7,6 +7,7 @@
|
|||
#include "VsmApplyFrame.hpp"
|
||||
#include "VsmEvalArgsFrame.hpp"
|
||||
#include "VsmApplyClosureFrame.hpp"
|
||||
#include "VsmIfElseContFrame.hpp"
|
||||
#include "VsmSeqContFrame.hpp"
|
||||
#include "VsmRcx.hpp"
|
||||
#include "Closure.hpp"
|
||||
|
|
@ -14,6 +15,7 @@
|
|||
#include <xo/expression2/LambdaExpr.hpp>
|
||||
#include <xo/expression2/Constant.hpp>
|
||||
#include <xo/expression2/SequenceExpr.hpp>
|
||||
#include <xo/object2/Boolean.hpp>
|
||||
#include <xo/procedure2/RuntimeContext.hpp>
|
||||
//#include <xo/procedure2/SimpleRcx.hpp>
|
||||
#include <xo/gc/DX1Collector.hpp>
|
||||
|
|
@ -190,6 +192,9 @@ namespace xo {
|
|||
case vsm_opcode::apply_cont:
|
||||
_do_apply_cont_op();
|
||||
break;
|
||||
case vsm_opcode::ifelse_cont:
|
||||
_do_ifelse_cont_op();
|
||||
break;
|
||||
case vsm_opcode::seq_cont:
|
||||
_do_seq_cont_op();
|
||||
break;
|
||||
|
|
@ -388,14 +393,26 @@ namespace xo {
|
|||
void
|
||||
VirtualSchematikaMachine::_do_eval_if_else_op()
|
||||
{
|
||||
// not implemented
|
||||
assert(false);
|
||||
// control:
|
||||
// self -> eval(test) -> ifelse_cont -> eval(when_true)
|
||||
// -> eval(when_false)
|
||||
|
||||
auto ifelse_expr = obj<AExpression,DIfElseExpr>::from(expr_);
|
||||
|
||||
obj<AGCObject,DVsmIfElseContFrame> ifelse_frame
|
||||
(DVsmIfElseContFrame::make(mm_.to_op(),
|
||||
stack_, cont_, ifelse_expr.data()));
|
||||
|
||||
this->stack_ = ifelse_frame;
|
||||
this->cont_ = VsmInstr::c_ifelse_cont;
|
||||
this->expr_ = ifelse_expr->test();
|
||||
this->pc_ = VsmInstr::c_eval;
|
||||
}
|
||||
|
||||
void
|
||||
VirtualSchematikaMachine::_do_eval_sequence_op()
|
||||
{
|
||||
// assuming bump allocator:
|
||||
// stack:
|
||||
//
|
||||
// VsmEvalSequence
|
||||
// v
|
||||
|
|
@ -640,6 +657,50 @@ namespace xo {
|
|||
this->pc_ = frame->cont();
|
||||
}
|
||||
|
||||
void
|
||||
VirtualSchematikaMachine::_do_ifelse_cont_op()
|
||||
{
|
||||
// pre: result of evaluating test condition in value_ register
|
||||
|
||||
auto frame = obj<AGCObject,DVsmIfElseContFrame>::from(stack_);
|
||||
|
||||
assert(frame);
|
||||
assert(value_.is_value());
|
||||
|
||||
auto flag = obj<AGCObject,DBoolean>::from(*value_.value());
|
||||
|
||||
if (flag.data()) {
|
||||
obj<AExpression> next_expr;
|
||||
{
|
||||
if (flag->value()) {
|
||||
// proceed with if-branch
|
||||
next_expr = frame->ifelse_expr()->when_true();
|
||||
} else {
|
||||
// proceed with else-branch
|
||||
next_expr = frame->ifelse_expr()->when_false();
|
||||
}
|
||||
}
|
||||
|
||||
this->stack_ = frame->parent();
|
||||
this->cont_ = frame->cont();
|
||||
this->expr_ = next_expr;
|
||||
this->pc_ = VsmInstr::c_eval;
|
||||
} else {
|
||||
auto error = DRuntimeError::make(mm_.to_op(),
|
||||
"_do_ifelse_cont_op",
|
||||
"expected boolean for test condition");
|
||||
this->value_ = VsmResult(error);
|
||||
|
||||
// for now: halt VSM execution
|
||||
// TODO: some combination of
|
||||
// 1. emit stack trace
|
||||
// 2. go to debugger
|
||||
// 3. have every vsm instruction check inputs for errors
|
||||
|
||||
this->pc_ = VsmInstr::c_halt;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
VirtualSchematikaMachine::_do_seq_cont_op()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ namespace xo {
|
|||
case vsm_opcode::apply: return "apply";
|
||||
case vsm_opcode::evalargs: return "evalargs";
|
||||
case vsm_opcode::apply_cont: return "apply_cont";
|
||||
case vsm_opcode::ifelse_cont: return "ifelse_cont";
|
||||
case vsm_opcode::seq_cont: return "seq_cont";
|
||||
case vsm_opcode::N:
|
||||
break;
|
||||
|
|
@ -39,6 +40,9 @@ namespace xo {
|
|||
VsmInstr
|
||||
VsmInstr::c_apply_cont = VsmInstr(vsm_opcode::apply_cont);
|
||||
|
||||
VsmInstr
|
||||
VsmInstr::c_ifelse_cont = VsmInstr(vsm_opcode::ifelse_cont);
|
||||
|
||||
VsmInstr
|
||||
VsmInstr::c_seq_cont = VsmInstr(vsm_opcode::seq_cont);
|
||||
} /*namespace scm*/
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include "VsmApplyFrame.hpp"
|
||||
#include "VsmEvalArgsFrame.hpp"
|
||||
#include "VsmApplyClosureFrame.hpp"
|
||||
#include "VsmIfElseContFrame.hpp"
|
||||
#include "VsmSeqContFrame.hpp"
|
||||
#include "Primitive_gco_2_gco_gco.hpp"
|
||||
#include "Closure.hpp"
|
||||
|
|
@ -38,6 +39,7 @@ namespace xo {
|
|||
// +- VsmApplyFrame
|
||||
// +- VsmEvalArgsFrame
|
||||
// +- VsmApplyClosureFrame
|
||||
// +- VsmIfElseContFrame
|
||||
// \- VsmSeqContFrame
|
||||
|
||||
FacetRegistry::register_impl<AGCObject, DVsmApplyFrame>();
|
||||
|
|
@ -49,6 +51,9 @@ namespace xo {
|
|||
FacetRegistry::register_impl<AGCObject, DVsmApplyClosureFrame>();
|
||||
FacetRegistry::register_impl<APrintable, DVsmApplyClosureFrame>();
|
||||
|
||||
FacetRegistry::register_impl<AGCObject, DVsmIfElseContFrame>();
|
||||
FacetRegistry::register_impl<APrintable, DVsmIfElseContFrame>();
|
||||
|
||||
FacetRegistry::register_impl<AGCObject, DVsmSeqContFrame>();
|
||||
FacetRegistry::register_impl<APrintable, DVsmSeqContFrame>();
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ namespace xo {
|
|||
using xo::scm::VsmConfig;
|
||||
using xo::scm::VsmResultExt;
|
||||
using xo::scm::DClosure;
|
||||
using xo::scm::DString;
|
||||
using xo::scm::DFloat;
|
||||
using xo::scm::DBoolean;
|
||||
using xo::scm::DInteger;
|
||||
|
|
@ -258,10 +259,10 @@ namespace xo {
|
|||
|
||||
log && log(xtag("res.tseq", res.value()->_typeseq()));
|
||||
|
||||
auto x = obj<AGCObject,DBoolean>::from(*res.value());
|
||||
auto x = obj<AGCObject,DString>::from(*res.value());
|
||||
|
||||
REQUIRE(x);
|
||||
REQUIRE(x.data()->value() == true);
|
||||
REQUIRE(strcmp(x.data()->chars(), "equal") == 0);
|
||||
|
||||
REQUIRE(res.remaining_.size() == 1);
|
||||
REQUIRE(*res.remaining_.lo() == '\n');
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue