xo-interpreter2: + nil + cons
This commit is contained in:
parent
cb6df6c0d8
commit
2e1ae9bca3
30 changed files with 213 additions and 11 deletions
|
|
@ -15,6 +15,7 @@
|
|||
#include "VsmRcx.hpp"
|
||||
#include "Closure.hpp"
|
||||
#include <xo/object2/Sequence.hpp>
|
||||
#include <xo/object2/List.hpp>
|
||||
#include <xo/numeric/NumericDispatch.hpp>
|
||||
#include <xo/expression2/DefineExpr.hpp>
|
||||
#include <xo/expression2/ApplyExpr.hpp>
|
||||
|
|
@ -914,7 +915,7 @@ namespace xo {
|
|||
static DPrimitive_gco_0 s_cwd_pm("_cwd",
|
||||
&xfer_cwd);
|
||||
|
||||
// ----- primitive: fn_nth() -----
|
||||
// ----- primitive: nth() -----
|
||||
|
||||
// TODO: seq_gc -> obj<ASequence>
|
||||
// n_gco -> obj<AGCObject,DInteger>
|
||||
|
|
@ -934,6 +935,24 @@ namespace xo {
|
|||
|
||||
static DPrimitive_gco_2_gco_gco s_nth_pm("_nth", &xfer_nth);
|
||||
|
||||
// ----- primitive: cons() -----
|
||||
|
||||
obj<AGCObject>
|
||||
xfer_cons(obj<ARuntimeContext> rcx,
|
||||
obj<AGCObject> car,
|
||||
obj<AGCObject> cdr)
|
||||
{
|
||||
(void)rcx;
|
||||
|
||||
auto cdr_list = obj<AGCObject,DList>::from(cdr);
|
||||
|
||||
return DList::cons(rcx.allocator(),
|
||||
car,
|
||||
cdr_list.data());
|
||||
}
|
||||
|
||||
static DPrimitive_gco_2_gco_gco s_cons_pm("_cons", &xfer_cons);
|
||||
|
||||
// ----- primitive: fn_n_args() -----
|
||||
|
||||
obj<AGCObject>
|
||||
|
|
@ -1038,6 +1057,18 @@ namespace xo {
|
|||
obj<AGCObject,DPrimitive_gco_2_gco_gco>(&s_nth_pm));
|
||||
}
|
||||
|
||||
/* cons */
|
||||
{
|
||||
const DUniqueString * name
|
||||
= reader_.intern_string("cons");
|
||||
|
||||
global_env_->_upsert_value
|
||||
(mm_.to_op(),
|
||||
name,
|
||||
Reflect::require<DPrimitive_gco_2_gco_gco>(),
|
||||
obj<AGCObject,DPrimitive_gco_2_gco_gco>(&s_cons_pm));
|
||||
}
|
||||
|
||||
/* fn_n_args */
|
||||
{
|
||||
const DUniqueString * name
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ namespace xo {
|
|||
using xo::scm::DFloat;
|
||||
using xo::scm::DBoolean;
|
||||
using xo::scm::DInteger;
|
||||
using xo::scm::DRuntimeError;
|
||||
// using xo::scm::DRuntimeError;
|
||||
using xo::mm::AGCObject;
|
||||
using xo::mm::MemorySizeInfo;
|
||||
using xo::mm::AAllocator;
|
||||
|
|
|
|||
|
|
@ -26,11 +26,14 @@ namespace xo {
|
|||
DList(xo::obj<AGCObject> h,
|
||||
DList * r) : head_{h}, rest_{r} {}
|
||||
|
||||
/** sentinel for null list.
|
||||
/** sentinel for null list. Idempotent.
|
||||
* Application code may prefer ListOps::nil()
|
||||
**/
|
||||
static DList * _nil();
|
||||
|
||||
/** like _nil(), but retrn fop wrapper **/
|
||||
static obj<AGCObject,DList> nil();
|
||||
|
||||
/** list with first element @p car,
|
||||
* followed by contents of list @p cdr.
|
||||
* Shares structure with @p cdr
|
||||
|
|
@ -40,6 +43,11 @@ namespace xo {
|
|||
obj<AGCObject> car,
|
||||
DList * cdr);
|
||||
|
||||
/** like @c _cons(mm,car,cdr), but return fop wrapper **/
|
||||
static obj<AGCObject,DList> cons(obj<AAllocator> mm,
|
||||
obj<AGCObject> car,
|
||||
DList * cdr);
|
||||
|
||||
/** DList length is at least 1 **/
|
||||
bool is_empty() const noexcept;
|
||||
/** DList models a finite sequence **/
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ namespace xo {
|
|||
using xo::print::APrintable;
|
||||
using xo::mm::AGCObject;
|
||||
using xo::facet::FacetRegistry;
|
||||
using xo::facet::typeseq;
|
||||
//using xo::facet::typeseq;
|
||||
|
||||
namespace scm {
|
||||
static DList s_null(obj<AGCObject>(), nullptr);
|
||||
|
|
@ -28,6 +28,12 @@ namespace xo {
|
|||
return &s_null;
|
||||
}
|
||||
|
||||
obj<AGCObject,DList>
|
||||
DList::nil()
|
||||
{
|
||||
return obj<AGCObject,DList>(_nil());
|
||||
}
|
||||
|
||||
DList *
|
||||
DList::_cons(obj<AAllocator> mm,
|
||||
obj<AGCObject> car,
|
||||
|
|
@ -38,6 +44,14 @@ namespace xo {
|
|||
return new (mem) DList(car, cdr);
|
||||
}
|
||||
|
||||
obj<AGCObject,DList>
|
||||
DList::cons(obj<AAllocator> mm,
|
||||
obj<AGCObject> car,
|
||||
DList * cdr)
|
||||
{
|
||||
return obj<AGCObject,DList>(_cons(mm, car, cdr));
|
||||
}
|
||||
|
||||
#ifdef OBSOLETE
|
||||
DList *
|
||||
DList::list(obj<AAllocator> mm,
|
||||
|
|
@ -137,8 +151,6 @@ namespace xo {
|
|||
obj<APrintable> elt
|
||||
= FacetRegistry::instance().variant<APrintable, AGCObject>(l->head_);
|
||||
|
||||
|
||||
|
||||
assert(elt.data());
|
||||
|
||||
if (!pps->print_upto(elt))
|
||||
|
|
|
|||
|
|
@ -84,12 +84,18 @@ namespace xo {
|
|||
void on_quote_token(const Token & tk,
|
||||
ParserStateMachine * p_psm);
|
||||
|
||||
/** step state machine for this syntax on incoming boolean literal token @p tkk
|
||||
/** step state machine for this syntax on incoming boolean literal token @p tk
|
||||
* with overall parser state in @p p_psm
|
||||
**/
|
||||
void on_bool_token(const Token & tk,
|
||||
ParserStateMachine * p_psm);
|
||||
|
||||
/** step state machine for this syntax on incoming nil literal token @p tk
|
||||
* with overall parser state in @p p_psm.
|
||||
**/
|
||||
void on_nil_token(const Token & tk,
|
||||
ParserStateMachine * p_psm);
|
||||
|
||||
/** update state for this syntax on incoming f64 token @p tk,
|
||||
* overall parser state in @p p_psm
|
||||
**/
|
||||
|
|
|
|||
|
|
@ -119,6 +119,11 @@ namespace xo {
|
|||
**/
|
||||
void on_bool_token(const Token & tk, ParserStateMachine * p_psm);
|
||||
|
||||
/** update state for this syntax on incoming nil token @p tk,
|
||||
* overall parser state in @p p_psm
|
||||
**/
|
||||
void on_nil_token(const Token & tk, ParserStateMachine * p_psm);
|
||||
|
||||
/** update state for this syntax on incoming leftparen token @p tk,
|
||||
* overall parser state in @p p_psm
|
||||
**/
|
||||
|
|
|
|||
|
|
@ -171,6 +171,7 @@ namespace xo {
|
|||
case tokentype::tk_slash:
|
||||
case tokentype::tk_cmpeq:
|
||||
case tokentype::tk_cmpne:
|
||||
case tokentype::tk_nil:
|
||||
case tokentype::tk_type:
|
||||
case tokentype::tk_lambda:
|
||||
case tokentype::tk_let:
|
||||
|
|
|
|||
|
|
@ -546,6 +546,7 @@ namespace xo {
|
|||
case tokentype::tk_slash:
|
||||
case tokentype::tk_cmpeq:
|
||||
case tokentype::tk_cmpne:
|
||||
case tokentype::tk_nil:
|
||||
case tokentype::tk_type:
|
||||
case tokentype::tk_lambda:
|
||||
case tokentype::tk_then:
|
||||
|
|
|
|||
|
|
@ -150,6 +150,7 @@ namespace xo {
|
|||
case tokentype::tk_slash:
|
||||
case tokentype::tk_cmpeq:
|
||||
case tokentype::tk_cmpne:
|
||||
case tokentype::tk_nil:
|
||||
case tokentype::tk_type:
|
||||
case tokentype::tk_lambda:
|
||||
case tokentype::tk_then:
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include <xo/object2/Boolean.hpp>
|
||||
#include <xo/object2/Integer.hpp>
|
||||
#include <xo/object2/Float.hpp>
|
||||
#include <xo/object2/List.hpp>
|
||||
#include <xo/stringtable2/String.hpp>
|
||||
#include <xo/alloc2/GCObject.hpp>
|
||||
#include <xo/facet/facet_implementation.hpp>
|
||||
|
|
@ -155,6 +156,10 @@ namespace xo {
|
|||
this->on_bool_token(tk, p_psm);
|
||||
return;
|
||||
|
||||
case tokentype::tk_nil:
|
||||
this->on_nil_token(tk, p_psm);
|
||||
return;
|
||||
|
||||
case tokentype::tk_if:
|
||||
this->on_if_token(tk, p_psm);
|
||||
return;
|
||||
|
|
@ -372,6 +377,23 @@ namespace xo {
|
|||
p_psm);
|
||||
}
|
||||
|
||||
void
|
||||
DExpectExprSsm::on_nil_token(const Token & tk,
|
||||
ParserStateMachine * p_psm)
|
||||
{
|
||||
(void)tk;
|
||||
|
||||
auto nil = DList::nil();
|
||||
auto expr = DConstant::make(p_psm->expr_alloc(), nil);
|
||||
|
||||
// DProgressSsm responsible for resolving cases like
|
||||
// nil ++ nil;
|
||||
|
||||
DProgressSsm::start(p_psm->parser_alloc(),
|
||||
expr,
|
||||
p_psm);
|
||||
}
|
||||
|
||||
void
|
||||
DExpectExprSsm::on_f64_token(const Token & tk,
|
||||
ParserStateMachine * p_psm)
|
||||
|
|
|
|||
|
|
@ -135,6 +135,7 @@ namespace xo {
|
|||
case tokentype::tk_slash:
|
||||
case tokentype::tk_cmpeq:
|
||||
case tokentype::tk_cmpne:
|
||||
case tokentype::tk_nil:
|
||||
case tokentype::tk_type:
|
||||
case tokentype::tk_then:
|
||||
case tokentype::tk_else:
|
||||
|
|
|
|||
|
|
@ -165,6 +165,7 @@ namespace xo {
|
|||
case tokentype::tk_slash:
|
||||
case tokentype::tk_cmpeq:
|
||||
case tokentype::tk_cmpne:
|
||||
case tokentype::tk_nil:
|
||||
case tokentype::tk_type:
|
||||
case tokentype::tk_then:
|
||||
case tokentype::tk_else:
|
||||
|
|
|
|||
|
|
@ -127,6 +127,7 @@ namespace xo {
|
|||
case tokentype::tk_slash:
|
||||
case tokentype::tk_cmpeq:
|
||||
case tokentype::tk_cmpne:
|
||||
case tokentype::tk_nil:
|
||||
case tokentype::tk_type:
|
||||
case tokentype::tk_lambda:
|
||||
case tokentype::tk_then:
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ namespace xo {
|
|||
case tokentype::tk_slash:
|
||||
case tokentype::tk_cmpeq:
|
||||
case tokentype::tk_cmpne:
|
||||
case tokentype::tk_nil:
|
||||
case tokentype::tk_type:
|
||||
case tokentype::tk_then:
|
||||
case tokentype::tk_else:
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ namespace xo {
|
|||
case tokentype::tk_slash:
|
||||
case tokentype::tk_cmpeq:
|
||||
case tokentype::tk_cmpne:
|
||||
case tokentype::tk_nil:
|
||||
case tokentype::tk_type:
|
||||
case tokentype::tk_then:
|
||||
case tokentype::tk_else:
|
||||
|
|
|
|||
|
|
@ -140,6 +140,7 @@ namespace xo {
|
|||
case tokentype::tk_slash:
|
||||
case tokentype::tk_cmpeq:
|
||||
case tokentype::tk_cmpne:
|
||||
case tokentype::tk_nil:
|
||||
case tokentype::tk_type:
|
||||
case tokentype::tk_then:
|
||||
case tokentype::tk_else:
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ namespace xo {
|
|||
case tokentype::tk_slash:
|
||||
case tokentype::tk_cmpeq:
|
||||
case tokentype::tk_cmpne:
|
||||
case tokentype::tk_nil:
|
||||
case tokentype::tk_type:
|
||||
case tokentype::tk_lambda:
|
||||
case tokentype::tk_then:
|
||||
|
|
|
|||
|
|
@ -107,6 +107,7 @@ namespace xo {
|
|||
case tokentype::tk_slash:
|
||||
case tokentype::tk_cmpeq:
|
||||
case tokentype::tk_cmpne:
|
||||
case tokentype::tk_nil:
|
||||
case tokentype::tk_type:
|
||||
case tokentype::tk_lambda:
|
||||
case tokentype::tk_then:
|
||||
|
|
|
|||
|
|
@ -186,6 +186,7 @@ namespace xo {
|
|||
case tokentype::tk_slash:
|
||||
case tokentype::tk_cmpeq:
|
||||
case tokentype::tk_cmpne:
|
||||
case tokentype::tk_nil:
|
||||
case tokentype::tk_type:
|
||||
case tokentype::tk_lambda:
|
||||
case tokentype::tk_let:
|
||||
|
|
|
|||
|
|
@ -163,6 +163,7 @@ namespace xo {
|
|||
case tokentype::tk_slash:
|
||||
case tokentype::tk_cmpeq:
|
||||
case tokentype::tk_cmpne:
|
||||
case tokentype::tk_nil:
|
||||
case tokentype::tk_type:
|
||||
case tokentype::tk_then:
|
||||
case tokentype::tk_else:
|
||||
|
|
|
|||
|
|
@ -132,6 +132,7 @@ namespace xo {
|
|||
case tokentype::tk_slash:
|
||||
case tokentype::tk_cmpeq:
|
||||
case tokentype::tk_cmpne:
|
||||
case tokentype::tk_nil:
|
||||
case tokentype::tk_type:
|
||||
case tokentype::tk_lambda:
|
||||
case tokentype::tk_then:
|
||||
|
|
|
|||
|
|
@ -309,6 +309,7 @@ namespace xo {
|
|||
this->on_operator_token(tk, p_psm);
|
||||
return;
|
||||
|
||||
case tokentype::tk_nil:
|
||||
case tokentype::tk_type:
|
||||
case tokentype::tk_lambda:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -133,6 +133,7 @@ namespace xo {
|
|||
case tokentype::tk_slash:
|
||||
case tokentype::tk_cmpeq:
|
||||
case tokentype::tk_cmpne:
|
||||
case tokentype::tk_nil:
|
||||
case tokentype::tk_type:
|
||||
case tokentype::tk_lambda:
|
||||
case tokentype::tk_then:
|
||||
|
|
|
|||
|
|
@ -114,6 +114,7 @@ namespace xo {
|
|||
case tokentype::tk_slash:
|
||||
case tokentype::tk_cmpeq:
|
||||
case tokentype::tk_cmpne:
|
||||
case tokentype::tk_nil:
|
||||
case tokentype::tk_type:
|
||||
case tokentype::tk_lambda:
|
||||
case tokentype::tk_let:
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include <xo/expression2/Constant.hpp>
|
||||
#include <xo/stringtable2/String.hpp>
|
||||
#include <xo/object2/List.hpp>
|
||||
#include <xo/object2/Float.hpp>
|
||||
#include <xo/object2/Integer.hpp>
|
||||
#include <xo/object2/Boolean.hpp>
|
||||
|
|
@ -152,6 +153,10 @@ namespace xo {
|
|||
this->on_bool_token(tk, p_psm);
|
||||
return;
|
||||
|
||||
case tokentype::tk_nil:
|
||||
this->on_nil_token(tk, p_psm);
|
||||
return;
|
||||
|
||||
case tokentype::tk_leftparen:
|
||||
this->on_leftparen_token(tk, p_psm);
|
||||
return;
|
||||
|
|
@ -378,7 +383,7 @@ namespace xo {
|
|||
break;
|
||||
}
|
||||
|
||||
Super::on_token(tk, p_psm);
|
||||
Super::illegal_token(tk, p_psm);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -404,7 +409,32 @@ namespace xo {
|
|||
break;
|
||||
}
|
||||
|
||||
Super::on_token(tk, p_psm);
|
||||
Super::illegal_token(tk, p_psm);
|
||||
}
|
||||
|
||||
void
|
||||
DToplevelSeqSsm::on_nil_token(const Token & tk,
|
||||
ParserStateMachine * p_psm)
|
||||
{
|
||||
switch (seqtype_) {
|
||||
case exprseqtype::toplevel_interactive:
|
||||
{
|
||||
auto dvalue = DList::nil();
|
||||
auto expr = DConstant::make(p_psm->expr_alloc(), dvalue);
|
||||
|
||||
DProgressSsm::start(p_psm->parser_alloc(),
|
||||
expr,
|
||||
p_psm);
|
||||
return;
|
||||
}
|
||||
case exprseqtype::toplevel_batch:
|
||||
break;
|
||||
case exprseqtype::N:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
Super::illegal_token(tk, p_psm);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -431,7 +461,7 @@ namespace xo {
|
|||
break;
|
||||
}
|
||||
|
||||
Super::on_token(tk, p_psm);
|
||||
Super::illegal_token(tk, p_psm);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -454,7 +484,7 @@ namespace xo {
|
|||
break;
|
||||
}
|
||||
|
||||
Super::on_token(tk, p_psm);
|
||||
Super::illegal_token(tk, p_psm);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#include <xo/expression2/VarRef.hpp>
|
||||
#include <xo/expression2/Constant.hpp>
|
||||
#include <xo/procedure2/Primitive_gco_2_gco_gco.hpp>
|
||||
#include <xo/object2/List.hpp>
|
||||
#include <xo/object2/Float.hpp>
|
||||
#include <xo/object2/Integer.hpp>
|
||||
#include <xo/stringtable2/String.hpp>
|
||||
|
|
@ -41,6 +42,7 @@ namespace xo {
|
|||
using xo::scm::Token;
|
||||
using xo::mm::AGCObject;
|
||||
using xo::scm::DPrimitive_gco_2_gco_gco;
|
||||
using xo::scm::DList;
|
||||
using xo::scm::DString;
|
||||
using xo::scm::DFloat;
|
||||
using xo::scm::DInteger;
|
||||
|
|
@ -603,6 +605,67 @@ namespace xo {
|
|||
log && fixture.log_memory_layout(&log);
|
||||
}
|
||||
|
||||
TEST_CASE("SchematikaParser-interactive-nil", "[reader2][SchematikaParser]")
|
||||
{
|
||||
const auto & testname = Catch::getResultCapture().getCurrentTestName();
|
||||
|
||||
constexpr bool c_debug_flag = false;
|
||||
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:
|
||||
*
|
||||
* nil ;
|
||||
*
|
||||
**/
|
||||
|
||||
{
|
||||
auto & result = parser.on_token(Token::nil_token());
|
||||
|
||||
log && log("after nil token:");
|
||||
log && log(xtag("parser", &parser));
|
||||
log && log(xtag("result", result));
|
||||
|
||||
REQUIRE(parser.has_incomplete_expr() == true);
|
||||
REQUIRE(!result.is_error());
|
||||
REQUIRE(result.is_incomplete());
|
||||
}
|
||||
|
||||
{
|
||||
auto & result = parser.on_token(Token::semicolon_token());
|
||||
|
||||
log && log("after semicolon token:");
|
||||
log && log(xtag("parser", &parser));
|
||||
log && log(xtag("result", result));
|
||||
|
||||
REQUIRE(parser.has_incomplete_expr() == false);
|
||||
REQUIRE(!result.is_error());
|
||||
REQUIRE(result.is_expression());
|
||||
REQUIRE(result.result_expr());
|
||||
|
||||
auto expr = obj<AExpression,DConstant>::from(result.result_expr());
|
||||
REQUIRE(expr);
|
||||
|
||||
REQUIRE(expr->value());
|
||||
|
||||
auto value_list = obj<AGCObject,DList>::from(expr->value());
|
||||
|
||||
REQUIRE(value_list);
|
||||
|
||||
REQUIRE(value_list->is_empty());
|
||||
}
|
||||
|
||||
//REQUIRE(result.is_error());
|
||||
//// illegal input on token
|
||||
//REQUIRE(result.error_description());
|
||||
|
||||
log && fixture.log_memory_layout(&log);
|
||||
}
|
||||
|
||||
TEST_CASE("SchematikaParser-interactive-arith", "[reader2][SchematikaParser]")
|
||||
{
|
||||
const auto & testname = Catch::getResultCapture().getCurrentTestName();
|
||||
|
|
|
|||
|
|
@ -134,6 +134,8 @@ namespace xo {
|
|||
/** token for @c "==" **/
|
||||
static Token cmpeq_token() { return Token(tokentype::tk_cmpeq); }
|
||||
|
||||
/** token representing keyword @c nil **/
|
||||
static Token nil_token() { return Token(tokentype::tk_nil); }
|
||||
/** token representing keyword @c type **/
|
||||
static Token type() { return Token(tokentype::tk_type); }
|
||||
/** token representing keyword @c def **/
|
||||
|
|
|
|||
|
|
@ -140,6 +140,9 @@ namespace xo {
|
|||
/** operator @c '!=' **/
|
||||
tk_cmpne,
|
||||
|
||||
/** keyword @c 'nil' **/
|
||||
tk_nil,
|
||||
|
||||
/** keyword @c 'type' **/
|
||||
tk_type,
|
||||
|
||||
|
|
|
|||
|
|
@ -587,6 +587,8 @@ namespace xo {
|
|||
if ((tk_text == "true") || (tk_text == "false")) {
|
||||
tk_type = tokentype::tk_bool;
|
||||
keep_text = true;
|
||||
} else if (tk_text == "nil") {
|
||||
tk_type = tokentype::tk_nil;
|
||||
} else if (tk_text == "type") {
|
||||
tk_type = tokentype::tk_type;
|
||||
} else if (tk_text == "def") {
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ namespace xo {
|
|||
CASE(tk_cmpeq);
|
||||
CASE(tk_cmpne);
|
||||
|
||||
CASE(tk_nil);
|
||||
CASE(tk_type);
|
||||
CASE(tk_def);
|
||||
CASE(tk_deftype);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue