xo-interpreter2 stack: streamline op== impl + utests
This commit is contained in:
parent
6575ab1c11
commit
8743aa44ef
2 changed files with 139 additions and 3 deletions
|
|
@ -43,6 +43,7 @@ namespace xo {
|
||||||
using xo::scm::Variable;
|
using xo::scm::Variable;
|
||||||
using xo::scm::Apply;
|
using xo::scm::Apply;
|
||||||
#endif
|
#endif
|
||||||
|
using xo::mm::AAllocator;
|
||||||
using xo::mm::AGCObject;
|
using xo::mm::AGCObject;
|
||||||
using xo::print::APrintable;
|
using xo::print::APrintable;
|
||||||
using xo::facet::FacetRegistry;
|
using xo::facet::FacetRegistry;
|
||||||
|
|
@ -1185,6 +1186,45 @@ namespace xo {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
// make_builtin_apply_pm2
|
// 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>
|
obj<AExpression>
|
||||||
|
|
@ -1223,9 +1263,16 @@ namespace xo {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case optype::op_equal:
|
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
|
auto pm_obj = (with_facet<AGCObject>::mkobj
|
||||||
(&Primitives::s_equal_gco_gco_pm));
|
(&NumericPrimitives::s_cmpeq_gco_gco_pm));
|
||||||
auto fn_expr = (DConstant::make
|
auto fn_expr = (DConstant::make
|
||||||
(p_psm->expr_alloc(), pm_obj));
|
(p_psm->expr_alloc(), pm_obj));
|
||||||
|
|
||||||
|
|
@ -1240,6 +1287,7 @@ namespace xo {
|
||||||
fn_expr, lhs_, rhs_);
|
fn_expr, lhs_, rhs_);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
case optype::op_not_equal:
|
case optype::op_not_equal:
|
||||||
case optype::op_less:
|
case optype::op_less:
|
||||||
|
|
@ -1250,6 +1298,13 @@ namespace xo {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case optype::op_multiply:
|
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
|
auto pm_obj = (with_facet<AGCObject>::mkobj
|
||||||
(&NumericPrimitives::s_mul_gco_gco_pm));
|
(&NumericPrimitives::s_mul_gco_gco_pm));
|
||||||
|
|
@ -1281,6 +1336,7 @@ namespace xo {
|
||||||
return DApplyExpr::make2(p_psm->expr_alloc(),
|
return DApplyExpr::make2(p_psm->expr_alloc(),
|
||||||
tref, fn_expr, lhs_, rhs_);
|
tref, fn_expr, lhs_, rhs_);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case optype::op_divide:
|
case optype::op_divide:
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
#include <xo/reader2/init_reader2.hpp>
|
#include <xo/reader2/init_reader2.hpp>
|
||||||
#include <xo/expression2/DefineExpr.hpp>
|
#include <xo/expression2/DefineExpr.hpp>
|
||||||
#include <xo/expression2/ApplyExpr.hpp>
|
#include <xo/expression2/ApplyExpr.hpp>
|
||||||
|
#include <xo/expression2/IfElseExpr.hpp>
|
||||||
#include <xo/expression2/VarRef.hpp>
|
#include <xo/expression2/VarRef.hpp>
|
||||||
#include <xo/expression2/Constant.hpp>
|
#include <xo/expression2/Constant.hpp>
|
||||||
#include <xo/procedure2/Primitive_gco_2_gco_gco.hpp>
|
#include <xo/procedure2/Primitive_gco_2_gco_gco.hpp>
|
||||||
|
|
@ -31,6 +32,7 @@ namespace xo {
|
||||||
|
|
||||||
using xo::scm::AExpression;
|
using xo::scm::AExpression;
|
||||||
using xo::scm::DDefineExpr;
|
using xo::scm::DDefineExpr;
|
||||||
|
using xo::scm::DIfElseExpr;
|
||||||
using xo::scm::DApplyExpr;
|
using xo::scm::DApplyExpr;
|
||||||
using xo::scm::DVarRef;
|
using xo::scm::DVarRef;
|
||||||
using xo::scm::DConstant;
|
using xo::scm::DConstant;
|
||||||
|
|
@ -680,7 +682,7 @@ namespace xo {
|
||||||
|
|
||||||
auto pm = obj<AGCObject,DPrimitive_gco_2_gco_gco>::from(fn->value());
|
auto pm = obj<AGCObject,DPrimitive_gco_2_gco_gco>::from(fn->value());
|
||||||
REQUIRE(pm);
|
REQUIRE(pm);
|
||||||
REQUIRE(pm->name() == "_equal");
|
REQUIRE(pm->name() == "_cmpeq");
|
||||||
|
|
||||||
auto lhs = obj<AExpression,DConstant>::from(expr->arg(0));
|
auto lhs = obj<AExpression,DConstant>::from(expr->arg(0));
|
||||||
REQUIRE(lhs);
|
REQUIRE(lhs);
|
||||||
|
|
@ -700,6 +702,84 @@ namespace xo {
|
||||||
log && fixture.log_memory_layout(&log);
|
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]")
|
TEST_CASE("SchematikaParser-interactive-lambda", "[reader2][SchematikaParser]")
|
||||||
{
|
{
|
||||||
const auto & testname = Catch::getResultCapture().getCurrentTestName();
|
const auto & testname = Catch::getResultCapture().getCurrentTestName();
|
||||||
|
|
@ -743,7 +823,7 @@ namespace xo {
|
||||||
log && fixture.log_memory_layout(&log);
|
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();
|
const auto & testname = Catch::getResultCapture().getCurrentTestName();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue