xo-reader2: utest with variable reference. Works !
This commit is contained in:
parent
a737b98853
commit
57f6f9073e
5 changed files with 125 additions and 47 deletions
|
|
@ -27,7 +27,7 @@ namespace xo {
|
||||||
Binding::print(std::ostream & os) const
|
Binding::print(std::ostream & os) const
|
||||||
{
|
{
|
||||||
if (i_link_ == c_link_global) {
|
if (i_link_ == c_link_global) {
|
||||||
os << "{path:global}";
|
os << "{path:global:" << j_slot_ << "}";
|
||||||
} else if (i_link_ == c_link_sentinel) {
|
} else if (i_link_ == c_link_sentinel) {
|
||||||
os << "{path}";
|
os << "{path}";
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,8 @@ namespace xo {
|
||||||
DGlobalSymtab::upsert_variable(obj<AAllocator> mm,
|
DGlobalSymtab::upsert_variable(obj<AAllocator> mm,
|
||||||
DVariable * var)
|
DVariable * var)
|
||||||
{
|
{
|
||||||
|
scope log(XO_DEBUG(true), std::string_view(*var->name()));
|
||||||
|
|
||||||
// It's possible there's already a global variable
|
// It's possible there's already a global variable
|
||||||
// with the same name.
|
// with the same name.
|
||||||
//
|
//
|
||||||
|
|
@ -78,6 +80,8 @@ namespace xo {
|
||||||
DVariable * existing = this->lookup_variable(var->name());
|
DVariable * existing = this->lookup_variable(var->name());
|
||||||
|
|
||||||
if (existing) {
|
if (existing) {
|
||||||
|
log && log("variable with this symbol already exists");
|
||||||
|
|
||||||
if (existing == var) {
|
if (existing == var) {
|
||||||
// impossible, but.. noop, right?
|
// impossible, but.. noop, right?
|
||||||
return;
|
return;
|
||||||
|
|
@ -91,6 +95,8 @@ namespace xo {
|
||||||
//
|
//
|
||||||
(*vars_)[existing->path().j_slot()] = obj<AGCObject,DVariable>(var);
|
(*vars_)[existing->path().j_slot()] = obj<AGCObject,DVariable>(var);
|
||||||
} else {
|
} else {
|
||||||
|
log && log("variable is new");
|
||||||
|
|
||||||
DArray::size_type n = vars_->size();
|
DArray::size_type n = vars_->size();
|
||||||
|
|
||||||
// NOTE: expansion of var_ array here is moot at present (Feb 2026),
|
// NOTE: expansion of var_ array here is moot at present (Feb 2026),
|
||||||
|
|
@ -146,8 +152,7 @@ namespace xo {
|
||||||
{
|
{
|
||||||
assert(sym);
|
assert(sym);
|
||||||
|
|
||||||
scope log(XO_DEBUG(true), "stub");
|
scope log(XO_DEBUG(true), std::string_view(*sym));
|
||||||
log && log(xtag("sym", std::string_view(*sym)));
|
|
||||||
|
|
||||||
auto ix = map_->find(sym);
|
auto ix = map_->find(sym);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
#include "DIfElseSsm.hpp"
|
#include "DIfElseSsm.hpp"
|
||||||
#include "ParenSsm.hpp"
|
#include "ParenSsm.hpp"
|
||||||
#include "ExpectExprSsm.hpp"
|
#include "ExpectExprSsm.hpp"
|
||||||
|
#include "VarRef.hpp"
|
||||||
|
|
||||||
#include <xo/expression2/DConstant.hpp>
|
#include <xo/expression2/DConstant.hpp>
|
||||||
#include <xo/expression2/detail/IExpression_DConstant.hpp>
|
#include <xo/expression2/detail/IExpression_DConstant.hpp>
|
||||||
|
|
@ -204,23 +205,23 @@ namespace xo {
|
||||||
|
|
||||||
void
|
void
|
||||||
DToplevelSeqSsm::on_symbol_token(const Token & tk,
|
DToplevelSeqSsm::on_symbol_token(const Token & tk,
|
||||||
ParserStateMachine * p_psm)
|
ParserStateMachine * p_psm)
|
||||||
{
|
{
|
||||||
switch (seqtype_) {
|
switch (seqtype_) {
|
||||||
case exprseqtype::toplevel_interactive:
|
case exprseqtype::toplevel_interactive:
|
||||||
{
|
{
|
||||||
#ifdef NOT_YET
|
auto varref = obj<AExpression,DVarRef>(p_psm->lookup_varref(tk.text()));
|
||||||
obj<AExpression,DVariable> var = p_psm->lookup_var(tk.text());
|
|
||||||
|
|
||||||
if (var) {
|
if (varref) {
|
||||||
DProgressSsm::start(var, p_psm);
|
DProgressSsm::start(p_psm->parser_alloc(),
|
||||||
|
varref,
|
||||||
|
p_psm);
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
p_psm->unknown_variable_error("DToplevelSeqSsm::on_symbol_token",
|
p_psm->error_unbound_variable("DToplevelSeqSsm",
|
||||||
tk,
|
tk.text());
|
||||||
this->get_expect_str(),
|
return;
|
||||||
p_psm);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case exprseqtype::toplevel_batch:
|
case exprseqtype::toplevel_batch:
|
||||||
|
|
|
||||||
|
|
@ -156,6 +156,16 @@ namespace xo {
|
||||||
{
|
{
|
||||||
scope log(XO_DEBUG(debug_flag_));
|
scope log(XO_DEBUG(debug_flag_));
|
||||||
|
|
||||||
|
const DUniqueString * ustr = stringtable_.lookup(symbolname);
|
||||||
|
|
||||||
|
if (!ustr) {
|
||||||
|
// if we don't already know the symbol,
|
||||||
|
// -> can't be a valid variable reference
|
||||||
|
// (whether global or local)
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// 1. check global symtab
|
// 1. check global symtab
|
||||||
// 2. combine local+global symtab into indept struct
|
// 2. combine local+global symtab into indept struct
|
||||||
|
|
@ -163,52 +173,46 @@ namespace xo {
|
||||||
//
|
//
|
||||||
|
|
||||||
if (local_symtab_) {
|
if (local_symtab_) {
|
||||||
const DUniqueString * ustr = stringtable_.lookup(symbolname);
|
DLocalSymtab * symtab = local_symtab_;
|
||||||
|
|
||||||
if (ustr) {
|
// count #of nested scopes to cross, to reach symbol
|
||||||
DLocalSymtab * symtab = local_symtab_;
|
//
|
||||||
|
int32_t link_count = 0;
|
||||||
|
|
||||||
// count #of nested scopes to cross, to reach symbol
|
while (symtab) {
|
||||||
//
|
Binding b = symtab->lookup_binding(ustr);
|
||||||
int32_t link_count = 0;
|
|
||||||
|
|
||||||
while (symtab) {
|
if (b.is_local()) {
|
||||||
Binding b = symtab->lookup_binding(ustr);
|
assert(b.i_link() == 0);
|
||||||
|
|
||||||
if (b.is_local()) {
|
DVariable * vardef = symtab->lookup_var(b);
|
||||||
assert(b.i_link() == 0);
|
assert(vardef);
|
||||||
|
|
||||||
DVariable * vardef = symtab->lookup_var(b);
|
/** ascii diagram here
|
||||||
assert(vardef);
|
**/
|
||||||
|
|
||||||
|
return DVarRef::make(expr_alloc_,
|
||||||
/** ascii diagram here
|
vardef,
|
||||||
**/
|
link_count);
|
||||||
|
} else {
|
||||||
return DVarRef::make(expr_alloc_,
|
assert(b.is_null());
|
||||||
vardef,
|
|
||||||
link_count);
|
|
||||||
} else {
|
|
||||||
assert(b.is_null());
|
|
||||||
}
|
|
||||||
|
|
||||||
++link_count;
|
|
||||||
symtab = symtab->parent();
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// if we don't already know the symbol,
|
|
||||||
// -> can't be a valid variable reference
|
|
||||||
// (whether global or local)
|
|
||||||
|
|
||||||
return nullptr;
|
++link_count;
|
||||||
|
symtab = symtab->parent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: check global symtab also
|
DVariable * vardef = global_symtab_->lookup_variable(ustr);
|
||||||
|
|
||||||
log.retroactively_enable();
|
if (vardef) {
|
||||||
log("STUB: check global symtab");
|
return DVarRef::make(expr_alloc_,
|
||||||
|
vardef,
|
||||||
|
0 /*link_count -- n/a for globals*/);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// symbol not found
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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/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>
|
||||||
#include <xo/object2/Float.hpp>
|
#include <xo/object2/Float.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::DApplyExpr;
|
using xo::scm::DApplyExpr;
|
||||||
|
using xo::scm::DVarRef;
|
||||||
using xo::scm::DConstant;
|
using xo::scm::DConstant;
|
||||||
|
|
||||||
//using xo::scm::ParserResult;
|
//using xo::scm::ParserResult;
|
||||||
|
|
@ -232,7 +234,7 @@ namespace xo {
|
||||||
{
|
{
|
||||||
const auto & testname = Catch::getResultCapture().getCurrentTestName();
|
const auto & testname = Catch::getResultCapture().getCurrentTestName();
|
||||||
|
|
||||||
constexpr bool c_debug_flag = true;
|
constexpr bool c_debug_flag = false;
|
||||||
scope log(XO_DEBUG(c_debug_flag), xtag("test", testname));
|
scope log(XO_DEBUG(c_debug_flag), xtag("test", testname));
|
||||||
|
|
||||||
ParserFixture fixture(testname, c_debug_flag);
|
ParserFixture fixture(testname, c_debug_flag);
|
||||||
|
|
@ -267,6 +269,72 @@ namespace xo {
|
||||||
log && fixture.log_memory_layout(&log);
|
log && fixture.log_memory_layout(&log);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("SchematikaParser-interactive-def2", "[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 foo : f64 = 3.141593 ;
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
std::vector<Token> tk_v{
|
||||||
|
Token::def_token(),
|
||||||
|
Token::symbol_token("foo"),
|
||||||
|
Token::colon_token(),
|
||||||
|
Token::symbol_token("f64"),
|
||||||
|
Token::singleassign_token(),
|
||||||
|
Token::f64_token("3.141593"),
|
||||||
|
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:
|
||||||
|
*
|
||||||
|
* foo ;
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
std::vector<Token> tk_v{
|
||||||
|
// Token::f64_token("2.0"),
|
||||||
|
// Token::star_token(),
|
||||||
|
Token::symbol_token("foo"),
|
||||||
|
Token::semicolon_token(),
|
||||||
|
};
|
||||||
|
|
||||||
|
utest_tokenizer_loop(&parser, tk_v, c_debug_flag);
|
||||||
|
|
||||||
|
const auto & result = parser.result();
|
||||||
|
{
|
||||||
|
auto expr = obj<AExpression,DVarRef>::from(result.result_expr());
|
||||||
|
REQUIRE(expr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log && fixture.log_memory_layout(&log);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("SchematikaParser-interactive-integer", "[reader2][SchematikaParser]")
|
TEST_CASE("SchematikaParser-interactive-integer", "[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