xo-interpreter2 stack: streamline op== impl + utests
This commit is contained in:
parent
4cab102ff2
commit
788363dd4c
20 changed files with 302 additions and 21 deletions
|
|
@ -185,6 +185,14 @@ namespace xo {
|
|||
if (expr_pr)
|
||||
log && log(xtag("expr", expr_pr));
|
||||
|
||||
if (value_.value()) {
|
||||
auto value_pr = const_cast<obj<AGCObject> *>(value_.value())->to_facet<APrintable>();
|
||||
if (value_pr)
|
||||
log && log(xtag("value", value_pr));
|
||||
} else {
|
||||
log && log("value not present or tk error");
|
||||
}
|
||||
|
||||
auto stack_pr = stack_.to_facet<APrintable>();
|
||||
if (stack_pr)
|
||||
log && log(xtag("stack", stack_pr));
|
||||
|
|
|
|||
|
|
@ -490,7 +490,7 @@ namespace xo {
|
|||
log && vsm_fixture.log_memory_layout(&log);
|
||||
}
|
||||
|
||||
TEST_CASE("VirtualSchematikaMachine-fact0", "[interpreter2][VSM]")
|
||||
TEST_CASE("VirtualSchematikaMachine-if2", "[interpreter2][VSM]")
|
||||
{
|
||||
const auto & testname = Catch::getResultCapture().getCurrentTestName();
|
||||
|
||||
|
|
@ -504,6 +504,53 @@ namespace xo {
|
|||
|
||||
vsm.begin_interactive_session();
|
||||
|
||||
span_type input = span_type::from_cstr("def n = 4; if (n == 4) then n * 3 else n * 5;");
|
||||
|
||||
for (int i_expr = 0; i_expr < 2; ++i_expr) {
|
||||
log && log(xtag("input", input));
|
||||
|
||||
VsmResultExt res
|
||||
= vsm.read_eval_print(input, eof_flag);
|
||||
|
||||
REQUIRE(res.is_value());
|
||||
REQUIRE(res.value());
|
||||
|
||||
log && log(xtag("res.tseq", res.value()->_typeseq()),
|
||||
xtag("res.type", TypeRegistry::id2name(res.value()->_typeseq())));
|
||||
|
||||
if (i_expr == 0) {
|
||||
auto x = obj<AGCObject,DUniqueString>::from(*res.value());
|
||||
REQUIRE(x);
|
||||
REQUIRE(strcmp(x->chars(), "n") == 0);
|
||||
input = res.remaining_;
|
||||
} else if (i_expr == 1) {
|
||||
auto x = obj<AGCObject,DInteger>::from(*res.value());
|
||||
REQUIRE(x);
|
||||
REQUIRE(x->value() == 12);
|
||||
|
||||
REQUIRE(res.remaining_.size() == 1);
|
||||
REQUIRE(*res.remaining_.lo() == '\n');
|
||||
input = res.remaining_;
|
||||
}
|
||||
}
|
||||
|
||||
log && vsm_fixture.log_memory_layout(&log);
|
||||
}
|
||||
|
||||
TEST_CASE("VirtualSchematikaMachine-fact0", "[interpreter2][VSM]")
|
||||
{
|
||||
const auto & testname = Catch::getResultCapture().getCurrentTestName();
|
||||
|
||||
bool c_debug_flag = false;
|
||||
scope log(XO_DEBUG(c_debug_flag), xtag("test", testname));
|
||||
|
||||
VsmFixture vsm_fixture(testname, c_debug_flag);
|
||||
auto & vsm = vsm_fixture.vsm_;
|
||||
|
||||
bool eof_flag = true;
|
||||
|
||||
vsm.begin_interactive_session();
|
||||
|
||||
span_type input = span_type::from_cstr("def fact = lambda (n) { if (n == 0) then 1 else n * fact(n - 1) }; fact(4);");
|
||||
|
||||
for (int i_expr = 0; i_expr < 2; ++i_expr) {
|
||||
|
|
|
|||
|
|
@ -27,6 +27,9 @@ namespace xo {
|
|||
DFloat * x, DInteger * y);
|
||||
static obj<AGCObject> subtract(obj<ARuntimeContext> rcx,
|
||||
DFloat * x, DInteger * y);
|
||||
|
||||
static obj<AGCObject> cmp_equal(obj<ARuntimeContext> rcx,
|
||||
DFloat * x, DInteger * y);
|
||||
};
|
||||
|
||||
class IntegerFloatOps {
|
||||
|
|
@ -42,6 +45,9 @@ namespace xo {
|
|||
DInteger * x, DFloat * y);
|
||||
static obj<AGCObject> subtract(obj<ARuntimeContext> rcx,
|
||||
DInteger * x, DFloat * y);
|
||||
|
||||
static obj<AGCObject> cmp_equal(obj<ARuntimeContext> rcx,
|
||||
DInteger * x, DFloat * y);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@ namespace xo {
|
|||
DFloat * x, DFloat * y);
|
||||
static obj<AGCObject> subtract(obj<ARuntimeContext> rcx,
|
||||
DFloat * x, DFloat * y);
|
||||
|
||||
static obj<AGCObject> cmp_equal(obj<ARuntimeContext> rcx,
|
||||
DFloat * x, DFloat * y);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,9 @@ namespace xo {
|
|||
static obj<AGCObject> subtract(obj<ARuntimeContext> rcx,
|
||||
DInteger * x, DInteger * y);
|
||||
|
||||
static obj<AGCObject> cmp_equal(obj<ARuntimeContext> rcx,
|
||||
DInteger * x, DInteger * y);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,6 +82,11 @@ namespace xo {
|
|||
obj<AGCObject> x,
|
||||
obj<AGCObject> y);
|
||||
|
||||
/** compare two numeric values for equality **/
|
||||
static obj<AGCObject> cmp_equal(obj<ARuntimeContext> rcx,
|
||||
obj<AGCObject> x,
|
||||
obj<AGCObject> y);
|
||||
|
||||
/** report memory use for owned arenas to @p visitor **/
|
||||
void visit_pools(const MemorySizeVisitor & visitor);
|
||||
|
||||
|
|
@ -94,7 +99,8 @@ namespace xo {
|
|||
void register_impl(typename NumericOps<DRepr1, DRepr2>::BinaryOp_Impl mul_fn,
|
||||
typename NumericOps<DRepr1, DRepr2>::BinaryOp_Impl div_fn,
|
||||
typename NumericOps<DRepr1, DRepr2>::BinaryOp_Impl add_fn,
|
||||
typename NumericOps<DRepr1, DRepr2>::BinaryOp_Impl sub_fn) {
|
||||
typename NumericOps<DRepr1, DRepr2>::BinaryOp_Impl sub_fn,
|
||||
typename NumericOps<DRepr1, DRepr2>::BinaryOp_Impl cmpeq_fn) {
|
||||
|
||||
KeyType key(typeseq::id<DRepr1>().seqno(),
|
||||
typeseq::id<DRepr2>().seqno());
|
||||
|
|
@ -104,7 +110,8 @@ namespace xo {
|
|||
= NumericOps<DRepr1, DRepr2>::make(mul_fn,
|
||||
div_fn,
|
||||
add_fn,
|
||||
sub_fn);
|
||||
sub_fn,
|
||||
cmpeq_fn);
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -25,13 +25,18 @@ namespace xo {
|
|||
explicit AnonymizedNumericOps(BinaryOp multiply,
|
||||
BinaryOp divide,
|
||||
BinaryOp add,
|
||||
BinaryOp subtract)
|
||||
: multiply_{multiply}, divide_{divide}, add_{add}, subtract_{subtract} {}
|
||||
BinaryOp subtract,
|
||||
BinaryOp cmpeq)
|
||||
: multiply_{multiply}, divide_{divide}, add_{add}, subtract_{subtract},
|
||||
cmpeq_{cmpeq} {}
|
||||
|
||||
BinaryOp multiply_ = nullptr;
|
||||
BinaryOp divide_ = nullptr;
|
||||
BinaryOp add_ = nullptr;
|
||||
BinaryOp subtract_ = nullptr;
|
||||
|
||||
/** compare numerics for equality **/
|
||||
BinaryOp cmpeq_ = nullptr;
|
||||
};
|
||||
|
||||
template <typename DRepr1, typename DRepr2>
|
||||
|
|
@ -46,11 +51,13 @@ namespace xo {
|
|||
static AnonymizedNumericOps make(BinaryOp_Impl multiply,
|
||||
BinaryOp_Impl divide,
|
||||
BinaryOp_Impl add,
|
||||
BinaryOp_Impl subtract) {
|
||||
BinaryOp_Impl subtract,
|
||||
BinaryOp_Impl cmpeq) {
|
||||
return AnonymizedNumericOps(reinterpret_cast<BinaryOp_Anon>(multiply),
|
||||
reinterpret_cast<BinaryOp_Anon>(divide),
|
||||
reinterpret_cast<BinaryOp_Anon>(add),
|
||||
reinterpret_cast<BinaryOp_Anon>(subtract));
|
||||
reinterpret_cast<BinaryOp_Anon>(subtract),
|
||||
reinterpret_cast<BinaryOp_Anon>(cmpeq));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,9 @@ namespace xo {
|
|||
static DPrimitive_gco_2_gco_gco s_add_gco_gco_pm;
|
||||
/** polymorphic (in both arguments) subtract **/
|
||||
static DPrimitive_gco_2_gco_gco s_sub_gco_gco_pm;
|
||||
|
||||
/** polymorphic (in both arguments) compare (==) **/
|
||||
static DPrimitive_gco_2_gco_gco s_cmpeq_gco_gco_pm;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include "FloatIntegerOps.hpp"
|
||||
#include "float/INumeric_DFloat.hpp"
|
||||
#include <xo/object2/Boolean.hpp>
|
||||
|
||||
namespace xo {
|
||||
using xo::mm::AGCObject;
|
||||
|
|
@ -41,6 +42,14 @@ namespace xo {
|
|||
return DFloat::box<AGCObject>(rcx.allocator(), x->value() - y->value());
|
||||
}
|
||||
|
||||
obj<AGCObject>
|
||||
FloatIntegerOps::cmp_equal(obj<ARuntimeContext> rcx,
|
||||
DFloat * x, DInteger * y)
|
||||
{
|
||||
return DBoolean::box<AGCObject>(rcx.allocator(),
|
||||
x->value() == DFloat::value_type(y->value()));
|
||||
}
|
||||
|
||||
// ----- Integer op Float -----
|
||||
|
||||
obj<AGCObject>
|
||||
|
|
@ -71,6 +80,14 @@ namespace xo {
|
|||
return DFloat::box<AGCObject>(rcx.allocator(), x->value() - y->value());
|
||||
}
|
||||
|
||||
obj<AGCObject>
|
||||
IntegerFloatOps::cmp_equal(obj<ARuntimeContext> rcx,
|
||||
DInteger * x, DFloat * y)
|
||||
{
|
||||
return DFloat::box<AGCObject>(rcx.allocator(),
|
||||
DFloat::value_type(x->value() == y->value()));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include "FloatOps.hpp"
|
||||
#include "float/INumeric_DFloat.hpp"
|
||||
#include <xo/object2/Boolean.hpp>
|
||||
|
||||
namespace xo {
|
||||
using xo::mm::AGCObject;
|
||||
|
|
@ -39,6 +40,13 @@ namespace xo {
|
|||
return DFloat::box<AGCObject>(rcx.allocator(), x->value() - y->value());
|
||||
}
|
||||
|
||||
obj<AGCObject>
|
||||
FloatOps::cmp_equal(obj<ARuntimeContext> rcx,
|
||||
DFloat * x, DFloat * y)
|
||||
{
|
||||
return DBoolean::box<AGCObject>(rcx.allocator(), x->value() == y->value());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,10 @@
|
|||
|
||||
#include "IntegerOps.hpp"
|
||||
#include "integer/INumeric_DInteger.hpp"
|
||||
#include <xo/object2/Boolean.hpp>
|
||||
|
||||
namespace xo {
|
||||
using xo::scm::DBoolean;
|
||||
using xo::mm::AGCObject;
|
||||
|
||||
namespace scm {
|
||||
|
|
@ -39,6 +41,13 @@ namespace xo {
|
|||
return DInteger::box<AGCObject>(rcx.allocator(), x->value() - y->value());
|
||||
}
|
||||
|
||||
obj<AGCObject>
|
||||
IntegerOps::cmp_equal(obj<ARuntimeContext> rcx,
|
||||
DInteger * x, DInteger * y)
|
||||
{
|
||||
return DBoolean::box<AGCObject>(rcx.allocator(), x->value() == y->value());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -81,6 +81,22 @@ namespace xo {
|
|||
return (*target_fn)(rcx, x.data(), y.data());
|
||||
}
|
||||
|
||||
obj<AGCObject>
|
||||
NumericDispatch::cmp_equal(obj<ARuntimeContext> rcx,
|
||||
obj<AGCObject> x,
|
||||
obj<AGCObject> y)
|
||||
{
|
||||
KeyType key(x._typeseq(), y._typeseq());
|
||||
|
||||
auto target_fn
|
||||
= NumericDispatch::instance().dispatch_[key].cmpeq_;
|
||||
|
||||
if (!target_fn)
|
||||
assert(false);
|
||||
|
||||
return (*target_fn)(rcx, x.data(), y.data());
|
||||
}
|
||||
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,10 @@ namespace xo {
|
|||
NumericPrimitives::s_sub_gco_gco_pm("_sub",
|
||||
&NumericDispatch::subtract);
|
||||
|
||||
DPrimitive_gco_2_gco_gco
|
||||
NumericPrimitives::s_cmpeq_gco_gco_pm("_cmpeq",
|
||||
&NumericDispatch::cmp_equal);
|
||||
|
||||
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
|
|
|||
|
|
@ -38,25 +38,29 @@ namespace xo {
|
|||
(&FloatOps::multiply,
|
||||
&FloatOps::divide,
|
||||
&FloatOps::add,
|
||||
&FloatOps::subtract);
|
||||
&FloatOps::subtract,
|
||||
&FloatOps::cmp_equal);
|
||||
|
||||
NumericDispatch::instance().register_impl<DFloat, DInteger>
|
||||
(&FloatIntegerOps::multiply,
|
||||
&FloatIntegerOps::divide,
|
||||
&FloatIntegerOps::add,
|
||||
&FloatIntegerOps::subtract);
|
||||
&FloatIntegerOps::subtract,
|
||||
&FloatIntegerOps::cmp_equal);
|
||||
|
||||
NumericDispatch::instance().register_impl<DInteger, DFloat>
|
||||
(&IntegerFloatOps::multiply,
|
||||
&IntegerFloatOps::divide,
|
||||
&IntegerFloatOps::add,
|
||||
&IntegerFloatOps::subtract);
|
||||
&IntegerFloatOps::subtract,
|
||||
&IntegerFloatOps::cmp_equal);
|
||||
|
||||
NumericDispatch::instance().register_impl<DInteger, DInteger>
|
||||
(&IntegerOps::multiply,
|
||||
&IntegerOps::divide,
|
||||
&IntegerOps::add,
|
||||
&IntegerOps::subtract);
|
||||
&IntegerOps::subtract,
|
||||
&IntegerOps::cmp_equal);
|
||||
|
||||
log && log(xtag("ANumeric.tseq", typeseq::id<ANumeric>()));
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ namespace xo {
|
|||
bool
|
||||
DBoolean::pretty(const ppindentinfo & ppii) const
|
||||
{
|
||||
return ppdetail_atomic<bool>::print_pretty
|
||||
return ppdetail_atomic<const char *>::print_pretty
|
||||
(ppii,
|
||||
(value_ ? "true" : "false"));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include "RuntimeError.hpp"
|
||||
|
||||
namespace xo {
|
||||
using xo::print::APrintable;
|
||||
using xo::mm::AGCObject;
|
||||
using xo::facet::typeseq;
|
||||
|
||||
|
|
@ -89,12 +90,14 @@ namespace xo {
|
|||
bool
|
||||
DRuntimeError::pretty(const ppindentinfo & ppii) const
|
||||
{
|
||||
return ppii.pps()->pretty_struct(ppii,
|
||||
"DRuntimeError");
|
||||
return ppii.pps()->pretty_struct
|
||||
(ppii,
|
||||
"DRuntimeError",
|
||||
refrtag("src", obj<APrintable,DString>(src_function_)),
|
||||
refrtag("err", obj<APrintable,DString>(error_descr_)));
|
||||
}
|
||||
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end DRuntimeError.cpp */
|
||||
|
||||
|
|
|
|||
|
|
@ -29,13 +29,13 @@ namespace xo {
|
|||
* so we can dispatch on vector, matrix, function types
|
||||
**/
|
||||
static DPrimitive_gco_2_gco_gco s_sub_gco_gco_pm;
|
||||
#endif
|
||||
|
||||
/** polymorphic equality comparison
|
||||
*
|
||||
* TODO: this will want to move to x-numeric/
|
||||
**/
|
||||
static DPrimitive_gco_2_gco_gco s_equal_gco_gco_pm;
|
||||
#endif
|
||||
|
||||
#ifdef NOT_YET
|
||||
static Primitive_f64_1_f64 s_neg_f64_pm;
|
||||
|
|
|
|||
|
|
@ -159,7 +159,6 @@ namespace xo {
|
|||
xtag("y.tseq", y_tseq)));
|
||||
return obj<AGCObject>();
|
||||
}
|
||||
#endif
|
||||
|
||||
obj<AGCObject>
|
||||
equal_gco_gco(obj<ARuntimeContext> rcx,
|
||||
|
|
@ -219,6 +218,7 @@ namespace xo {
|
|||
xtag("y.tseq", y_tseq)));
|
||||
return obj<AGCObject>();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef NOT_YET
|
||||
double
|
||||
|
|
@ -263,10 +263,10 @@ namespace xo {
|
|||
|
||||
DPrimitive_gco_2_gco_gco
|
||||
Primitives::s_sub_gco_gco_pm("_sub", &sub_gco_gco);
|
||||
#endif
|
||||
|
||||
DPrimitive_gco_2_gco_gco
|
||||
Primitives::s_equal_gco_gco_pm("_equal", &equal_gco_gco);
|
||||
#endif
|
||||
|
||||
#ifdef NOT_YET
|
||||
Primitive_f64_1_f64
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ namespace xo {
|
|||
using xo::scm::Variable;
|
||||
using xo::scm::Apply;
|
||||
#endif
|
||||
using xo::mm::AAllocator;
|
||||
using xo::mm::AGCObject;
|
||||
using xo::print::APrintable;
|
||||
using xo::facet::FacetRegistry;
|
||||
|
|
@ -1185,6 +1186,45 @@ namespace xo {
|
|||
|
||||
namespace {
|
||||
// make_builtin_apply_pm2
|
||||
|
||||
// helper function for making apply expression that invokes
|
||||
// a binary primitive. Use for numeric operators:
|
||||
// {*, /, +, -, ==}
|
||||
//
|
||||
obj<AExpression>
|
||||
assemble_numeric_expr_aux(obj<AAllocator> expr_alloc,
|
||||
const TypeRef::prefix_type & prefix,
|
||||
DPrimitive_gco_2_gco_gco * p_gco_pm,
|
||||
obj<AExpression> lhs,
|
||||
obj<AExpression> rhs)
|
||||
{
|
||||
auto pm_obj = with_facet<AGCObject>::mkobj(p_gco_pm);
|
||||
auto fn_expr = DConstant::make(expr_alloc, pm_obj);
|
||||
|
||||
/* note:
|
||||
* 1. don't assume we know lhs_ / rhs_ value types yet.
|
||||
* perhaps have expression like
|
||||
* f(..) * g(..)
|
||||
* where f is the function that contains current ssm.
|
||||
*
|
||||
* 2. consequence: we need representation for
|
||||
* polymorphic multiply on unknown numeric arguments.
|
||||
*
|
||||
* 3. TypeRef::dwim(..) is a placeholder.
|
||||
* Plan to later provide abstract interpreter
|
||||
* (ie compiler pass :) to drive type inference/unification
|
||||
*
|
||||
* 4. Alternatively could supply type-annotation syntax
|
||||
* so human can assist inference; context here is we want
|
||||
* to automate the boring stuff
|
||||
*/
|
||||
|
||||
TypeRef tref = TypeRef::dwim(prefix, nullptr);
|
||||
|
||||
return DApplyExpr::make2(expr_alloc,
|
||||
tref, fn_expr, lhs, rhs);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
obj<AExpression>
|
||||
|
|
@ -1223,9 +1263,16 @@ namespace xo {
|
|||
break;
|
||||
|
||||
case optype::op_equal:
|
||||
return assemble_numeric_expr_aux
|
||||
(p_psm->expr_alloc(),
|
||||
TypeRef::prefix_type::from_chars("_cmpeq_gco"),
|
||||
&NumericPrimitives::s_cmpeq_gco_gco_pm,
|
||||
lhs_, rhs_);
|
||||
|
||||
#ifdef OBSOLETE
|
||||
{
|
||||
auto pm_obj = (with_facet<AGCObject>::mkobj
|
||||
(&Primitives::s_equal_gco_gco_pm));
|
||||
(&NumericPrimitives::s_cmpeq_gco_gco_pm));
|
||||
auto fn_expr = (DConstant::make
|
||||
(p_psm->expr_alloc(), pm_obj));
|
||||
|
||||
|
|
@ -1240,6 +1287,7 @@ namespace xo {
|
|||
fn_expr, lhs_, rhs_);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case optype::op_not_equal:
|
||||
case optype::op_less:
|
||||
|
|
@ -1250,6 +1298,13 @@ namespace xo {
|
|||
break;
|
||||
|
||||
case optype::op_multiply:
|
||||
return assemble_numeric_expr_aux
|
||||
(p_psm->expr_alloc(),
|
||||
TypeRef::prefix_type::from_chars("_mul_gco"),
|
||||
&NumericPrimitives::s_mul_gco_gco_pm,
|
||||
lhs_, rhs_);
|
||||
|
||||
#ifdef OBSOLETE
|
||||
{
|
||||
auto pm_obj = (with_facet<AGCObject>::mkobj
|
||||
(&NumericPrimitives::s_mul_gco_gco_pm));
|
||||
|
|
@ -1281,6 +1336,7 @@ namespace xo {
|
|||
return DApplyExpr::make2(p_psm->expr_alloc(),
|
||||
tref, fn_expr, lhs_, rhs_);
|
||||
}
|
||||
#endif
|
||||
|
||||
break;
|
||||
case optype::op_divide:
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include <xo/reader2/init_reader2.hpp>
|
||||
#include <xo/expression2/DefineExpr.hpp>
|
||||
#include <xo/expression2/ApplyExpr.hpp>
|
||||
#include <xo/expression2/IfElseExpr.hpp>
|
||||
#include <xo/expression2/VarRef.hpp>
|
||||
#include <xo/expression2/Constant.hpp>
|
||||
#include <xo/procedure2/Primitive_gco_2_gco_gco.hpp>
|
||||
|
|
@ -31,6 +32,7 @@ namespace xo {
|
|||
|
||||
using xo::scm::AExpression;
|
||||
using xo::scm::DDefineExpr;
|
||||
using xo::scm::DIfElseExpr;
|
||||
using xo::scm::DApplyExpr;
|
||||
using xo::scm::DVarRef;
|
||||
using xo::scm::DConstant;
|
||||
|
|
@ -680,7 +682,7 @@ namespace xo {
|
|||
|
||||
auto pm = obj<AGCObject,DPrimitive_gco_2_gco_gco>::from(fn->value());
|
||||
REQUIRE(pm);
|
||||
REQUIRE(pm->name() == "_equal");
|
||||
REQUIRE(pm->name() == "_cmpeq");
|
||||
|
||||
auto lhs = obj<AExpression,DConstant>::from(expr->arg(0));
|
||||
REQUIRE(lhs);
|
||||
|
|
@ -700,6 +702,84 @@ namespace xo {
|
|||
log && fixture.log_memory_layout(&log);
|
||||
}
|
||||
|
||||
TEST_CASE("SchematikaParser-interactive-if1", "[reader2][SchematikaParser]")
|
||||
{
|
||||
const auto & testname = Catch::getResultCapture().getCurrentTestName();
|
||||
|
||||
constexpr bool c_debug_flag = true;
|
||||
scope log(XO_DEBUG(c_debug_flag),
|
||||
xtag("test", testname));
|
||||
|
||||
ParserFixture fixture(testname, c_debug_flag);
|
||||
auto & parser = *(fixture.parser_);
|
||||
|
||||
parser.begin_interactive_session();
|
||||
|
||||
{
|
||||
/** Walkthrough parsing input equivalent to:
|
||||
*
|
||||
* def n = 4 ;
|
||||
* ^ ^ ^ ^ ^
|
||||
* 0 1 2 3 4
|
||||
**/
|
||||
|
||||
std::vector<Token> tk_v{
|
||||
/* [0] */ Token::def_token(),
|
||||
/* [1] */ Token::symbol_token("n"),
|
||||
/* [2] */ Token::singleassign_token(),
|
||||
/* [3] */ Token::i64_token("4"),
|
||||
/* [4] */ Token::semicolon_token()
|
||||
};
|
||||
|
||||
utest_tokenizer_loop(&parser, tk_v, c_debug_flag);
|
||||
}
|
||||
|
||||
{
|
||||
const auto & result = parser.result();
|
||||
|
||||
auto expr = obj<AExpression,DDefineExpr>::from(result.result_expr());
|
||||
REQUIRE(expr);
|
||||
}
|
||||
|
||||
{
|
||||
parser.reset_result();
|
||||
|
||||
/** Walkthrough parsing input equivalent to:
|
||||
*
|
||||
* if (n == 4) then 1 else n * 5 ;
|
||||
* ^ ^^ ^ ^^ ^ ^ ^ ^ ^ ^ ^
|
||||
* 0 1| 3 4| 6 7 8 9 a b c
|
||||
* 2 5
|
||||
**/
|
||||
|
||||
std::vector<Token> tk_v{
|
||||
/* [0] */ Token::if_token(),
|
||||
/* [1] */ Token::leftparen_token(),
|
||||
/* [2] */ Token::symbol_token("n"),
|
||||
/* [3] */ Token::cmpeq_token(),
|
||||
/* [4] */ Token::i64_token("4"),
|
||||
/* [5] */ Token::rightparen_token(),
|
||||
/* [6] */ Token::then_token(),
|
||||
/* [7] */ Token::i64_token("1"),
|
||||
/* [8] */ Token::else_token(),
|
||||
/* [9] */ Token::symbol_token("n"),
|
||||
/* [a] */ Token::star_token(),
|
||||
/* [b] */ Token::i64_token("5"),
|
||||
/* [c] */ Token::semicolon_token()
|
||||
};
|
||||
|
||||
utest_tokenizer_loop(&parser, tk_v, c_debug_flag);
|
||||
}
|
||||
|
||||
const auto & result = parser.result();
|
||||
{
|
||||
auto expr = obj<AExpression,DIfElseExpr>::from(result.result_expr());
|
||||
REQUIRE(expr);
|
||||
}
|
||||
|
||||
log && fixture.log_memory_layout(&log);
|
||||
}
|
||||
|
||||
TEST_CASE("SchematikaParser-interactive-lambda", "[reader2][SchematikaParser]")
|
||||
{
|
||||
const auto & testname = Catch::getResultCapture().getCurrentTestName();
|
||||
|
|
@ -743,7 +823,7 @@ namespace xo {
|
|||
log && fixture.log_memory_layout(&log);
|
||||
}
|
||||
|
||||
TEST_CASE("SchematikaParser-interactive-if", "[reader2][SchematikaParser]")
|
||||
TEST_CASE("SchematikaParser-interactive-if2", "[reader2][SchematikaParser]")
|
||||
{
|
||||
const auto & testname = Catch::getResultCapture().getCurrentTestName();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue