xo-reader2 stack: top-level lambda w/ apply parses
This commit is contained in:
parent
4cd4328f07
commit
ca1370570b
46 changed files with 329 additions and 191 deletions
|
|
@ -101,13 +101,15 @@
|
|||
],
|
||||
},
|
||||
{
|
||||
name: "on_parsed_expression_with_semicolon",
|
||||
doc: ["update state machine for incoming parsed expression @p expr followed by semicolon"],
|
||||
name: "on_parsed_expression_with_token",
|
||||
doc: ["update state machine @p p_psm for incoming parsed expression @p expr followed by token @p tk"],
|
||||
return_type: "void",
|
||||
args: [
|
||||
{type: "obj<AExpression>", name: "expr"},
|
||||
{type: "const Token &", name: "tk"},
|
||||
{type: "ParserStateMachine *", name: "p_psm"},
|
||||
],
|
||||
},
|
||||
],
|
||||
router_facet_explicit_content: [ ],
|
||||
}
|
||||
|
|
|
|||
|
|
@ -176,11 +176,12 @@ namespace xo {
|
|||
ParserStateMachine * p_psm);
|
||||
|
||||
/** update state for this syntax after parsing an expression @p expr
|
||||
* followed by semicolon,
|
||||
* overall parser state in @p p_psm
|
||||
* followed by token @p tk,
|
||||
* with overall parser state in @p p_psm
|
||||
**/
|
||||
void on_parsed_expression_with_semicolon(obj<AExpression> expr,
|
||||
ParserStateMachine * p_psm);
|
||||
void on_parsed_expression_with_token(obj<AExpression> expr,
|
||||
const Token & tk,
|
||||
ParserStateMachine * p_psm);
|
||||
|
||||
///@}
|
||||
/** @defgroup scm-define-printable-facet printable facet methods **/
|
||||
|
|
|
|||
|
|
@ -113,11 +113,12 @@ namespace xo {
|
|||
ParserStateMachine * p_psm);
|
||||
|
||||
/** update state for this syntax after parsing an expression @p expr
|
||||
* followed by semicolon,
|
||||
* followed by token @p tk
|
||||
* overall parser state in @p p_psm
|
||||
**/
|
||||
void on_parsed_expression_with_semicolon(obj<AExpression> expr,
|
||||
ParserStateMachine * p_psm);
|
||||
void on_parsed_expression_with_token(obj<AExpression> expr,
|
||||
const Token & tk,
|
||||
ParserStateMachine * p_psm);
|
||||
|
||||
///@}
|
||||
/** @defgroup scm-define-printable-facet printable facet methods **/
|
||||
|
|
|
|||
|
|
@ -120,10 +120,12 @@ namespace xo {
|
|||
void on_parsed_expression(obj<AExpression> expr, ParserStateMachine * p_psm);
|
||||
|
||||
/** update state for this syntax on parsed expression @p expr
|
||||
* followed by semicolon from nested ssm.
|
||||
* followed by token @p tk from nested ssm.
|
||||
* overall parser state in @p p_psm
|
||||
**/
|
||||
void on_parsed_expression_with_semicolon(obj<AExpression> expr, ParserStateMachine * p_psm);
|
||||
void on_parsed_expression_with_token(obj<AExpression> expr,
|
||||
const Token & tk,
|
||||
ParserStateMachine * p_psm);
|
||||
|
||||
///@}
|
||||
/** @defgroup scm-exprseq-printable-facet printable facet methods **/
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ namespace xo {
|
|||
**/
|
||||
class DIfElseSsm : public DSyntaxStateMachine<DIfElseSsm> {
|
||||
public:
|
||||
using Super = DSyntaxStateMachine<DIfElseExpr>;
|
||||
using Super = DSyntaxStateMachine<DIfElseSsm>;
|
||||
using AAllocator = xo::mm::AAllocator;
|
||||
using DArena = xo::mm::DArena;
|
||||
using TypeDescr = xo::reflect::TypeDescr;
|
||||
|
|
@ -154,8 +154,9 @@ namespace xo {
|
|||
* followed by semicolon,
|
||||
* with overall parser state in @p p_psm.
|
||||
**/
|
||||
void on_parsed_expression_with_semicolon(obj<AExpression> expr,
|
||||
ParserStateMachine * p_psm);
|
||||
void on_parsed_expression_with_token(obj<AExpression> expr,
|
||||
const Token & tk,
|
||||
ParserStateMachine * p_psm);
|
||||
|
||||
///@}
|
||||
/** @defgroup scm-ifelsessm-printable-facet printable facet methods **/
|
||||
|
|
|
|||
|
|
@ -150,8 +150,9 @@ namespace xo {
|
|||
/** update this ssm when nested parser
|
||||
* emits expression @p expr
|
||||
**/
|
||||
void on_parsed_expression_with_semicolon(obj<AExpression> expr,
|
||||
ParserStateMachine * p_psm);
|
||||
void on_parsed_expression_with_token(obj<AExpression> expr,
|
||||
const Token & tk,
|
||||
ParserStateMachine * p_psm);
|
||||
|
||||
#ifdef NOT_YET
|
||||
virtual const char * get_expect_str() const override;
|
||||
|
|
|
|||
|
|
@ -168,8 +168,9 @@ namespace xo {
|
|||
ParserStateMachine * p_psm);
|
||||
void on_rightbrace_token(const Token & tk,
|
||||
ParserStateMachine * p_psm);
|
||||
void on_parsed_expression_with_semicolon(obj<AExpression> expr,
|
||||
ParserStateMachine * p_psm);
|
||||
void on_parsed_expression_with_token(obj<AExpression> expr,
|
||||
const Token & tk,
|
||||
ParserStateMachine * p_psm);
|
||||
|
||||
///@}
|
||||
/** @defgroup scm-progressssm-printable-facet printable facet methods **/
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ namespace xo {
|
|||
|
||||
class DSequenceSsm : public DSyntaxStateMachine<DSequenceSsm> {
|
||||
public:
|
||||
using Super = DSyntaxStateMachine<DSequenceSsm>;
|
||||
//using Sequence = xo::scm::Sequence;
|
||||
//using Lambda = xo::scm::Lambda;
|
||||
using AAllocator = xo::mm::AAllocator;
|
||||
|
|
@ -78,6 +79,13 @@ namespace xo {
|
|||
void on_parsed_expression(obj<AExpression> expr,
|
||||
ParserStateMachine * p_psm);
|
||||
|
||||
/** consume expression @p expr produced by nested ssm followed by token @p tk;
|
||||
* overall parser state in @p p_psm
|
||||
**/
|
||||
void on_parsed_expression_with_token(obj<AExpression> expr,
|
||||
const Token & tk,
|
||||
ParserStateMachine * p_psm);
|
||||
|
||||
///@}
|
||||
/** @defgroup scm-sequencessm-printable-facet printable facet **/
|
||||
///@{
|
||||
|
|
|
|||
|
|
@ -114,8 +114,9 @@ namespace xo {
|
|||
|
||||
/** Default implementation for required SyntaxStateMachine facet method
|
||||
**/
|
||||
void on_parsed_expression_with_semicolon(obj<AExpression> expr,
|
||||
ParserStateMachine * p_psm)
|
||||
void on_parsed_expression_with_token(obj<AExpression> expr,
|
||||
const Token & tk,
|
||||
ParserStateMachine * p_psm)
|
||||
{
|
||||
// starting with c++23 can use "this auto&& self" instead
|
||||
Derived & self = static_cast<Derived&>(*this);
|
||||
|
|
@ -124,9 +125,10 @@ namespace xo {
|
|||
// since the semicolon isn't relevant to problem with syntax
|
||||
//
|
||||
|
||||
p_psm->illegal_parsed_expression(Derived::ssm_classname(),
|
||||
expr,
|
||||
self.get_expect_str());
|
||||
p_psm->illegal_parsed_expression_with_token(Derived::ssm_classname(),
|
||||
expr,
|
||||
tk,
|
||||
self.get_expect_str());
|
||||
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include <xo/expression2/DGlobalSymtab.hpp>
|
||||
#include <xo/expression2/DLocalSymtab.hpp>
|
||||
#include <xo/expression2/DVariable.hpp>
|
||||
#include <xo/expression2/VarRef.hpp>
|
||||
#include <xo/expression2/StringTable.hpp>
|
||||
#include <xo/tokenizer2/Token.hpp>
|
||||
#include <xo/object2/DArray.hpp>
|
||||
|
|
@ -89,8 +90,8 @@ namespace xo {
|
|||
/** get unique (within stringtable) string, beginning with @p prefix **/
|
||||
const DUniqueString * gensym(std::string_view prefix);
|
||||
|
||||
/** get variable defn for @p symbolname, or else nullptr **/
|
||||
Binding lookup_binding(std::string_view symbolname);
|
||||
/** get variable reference for @p symbolname in current context, or else nullptr **/
|
||||
DVarRef * lookup_varref(std::string_view symbolname);
|
||||
|
||||
/** push nested local symtab while parsing the body of a lambda expression;
|
||||
* restore previous symtab at the end of lambda-expression definition.
|
||||
|
|
@ -141,17 +142,6 @@ namespace xo {
|
|||
**/
|
||||
void on_parsed_expression(obj<AExpression> expr);
|
||||
|
||||
/** update state to respond to parsed expression @p expr
|
||||
* (from nested parsing state), with trailing semicolon.
|
||||
*
|
||||
* Need to distinguish cases like:
|
||||
* 6 // ; allowed
|
||||
* f(6 // ) allowed ; forbidden
|
||||
* 6 + // ) forbidden ; forbidden
|
||||
*
|
||||
**/
|
||||
void on_parsed_expression_with_semicolon(obj<AExpression> expr);
|
||||
|
||||
/** update state to respond to parsed expression @p expr
|
||||
* (from nested parsing state), with trailing token @p tk.
|
||||
*
|
||||
|
|
@ -232,6 +222,16 @@ namespace xo {
|
|||
obj<AExpression>,
|
||||
std::string_view expect_str);
|
||||
|
||||
/** report illegal parsed expression @p expr from nested ssm @p ssm_name,
|
||||
* presented with immediately-following input token @p tk
|
||||
* Introducing as placeholder; not clear if this will be reachable
|
||||
* in full parser
|
||||
**/
|
||||
void illegal_parsed_expression_with_token(std::string_view ssm_name,
|
||||
obj<AExpression> expr,
|
||||
const Token & tk,
|
||||
std::string_view expect_str);
|
||||
|
||||
/** report error - no binding for variable @p sym
|
||||
**/
|
||||
void error_unbound_variable(std::string_view ssm_name,
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ public:
|
|||
// const methods
|
||||
/** RTTI: unique id# for actual runtime data representation **/
|
||||
virtual typeseq _typeseq() const noexcept = 0;
|
||||
/** destroy instance @p d; calls c++ dtor only for actual runtime type; does not recover memory **/
|
||||
virtual void _drop(Opaque d) const noexcept = 0;
|
||||
/** identify a type of syntax state machine **/
|
||||
virtual syntaxstatetype ssm_type(Copaque data) const noexcept = 0;
|
||||
/** text describing expected/allowed input to this ssm in current state **/
|
||||
|
|
@ -69,8 +71,8 @@ public:
|
|||
virtual void on_parsed_formal_arglist(Opaque data, DArray * arglist, ParserStateMachine * p_psm) = 0;
|
||||
/** update state machine for incoming parsed expression @p expr **/
|
||||
virtual void on_parsed_expression(Opaque data, obj<AExpression> expr, ParserStateMachine * p_psm) = 0;
|
||||
/** update state machine for incoming parsed expression @p expr followed by semicolon **/
|
||||
virtual void on_parsed_expression_with_semicolon(Opaque data, obj<AExpression> expr, ParserStateMachine * p_psm) = 0;
|
||||
/** update state machine @p p_psm for incoming parsed expression @p expr followed by token @p tk **/
|
||||
virtual void on_parsed_expression_with_token(Opaque data, obj<AExpression> expr, const Token & tk, ParserStateMachine * p_psm) = 0;
|
||||
///@}
|
||||
}; /*ASyntaxStateMachine*/
|
||||
|
||||
|
|
|
|||
|
|
@ -54,8 +54,11 @@ namespace scm {
|
|||
|
||||
// from ASyntaxStateMachine
|
||||
|
||||
// const methods
|
||||
// builtin methods
|
||||
typeseq _typeseq() const noexcept override { return s_typeseq; }
|
||||
[[noreturn]] void _drop(Opaque) const noexcept override { _fatal(); }
|
||||
|
||||
// const methods
|
||||
[[noreturn]] syntaxstatetype ssm_type(Copaque) const noexcept override { _fatal(); }
|
||||
[[noreturn]] std::string_view get_expect_str(Copaque) const noexcept override { _fatal(); }
|
||||
|
||||
|
|
@ -66,7 +69,7 @@ namespace scm {
|
|||
[[noreturn]] void on_parsed_formal(Opaque, const DUniqueString *, TypeDescr, ParserStateMachine *) override;
|
||||
[[noreturn]] void on_parsed_formal_arglist(Opaque, DArray *, ParserStateMachine *) override;
|
||||
[[noreturn]] void on_parsed_expression(Opaque, obj<AExpression>, ParserStateMachine *) override;
|
||||
[[noreturn]] void on_parsed_expression_with_semicolon(Opaque, obj<AExpression>, ParserStateMachine *) override;
|
||||
[[noreturn]] void on_parsed_expression_with_token(Opaque, obj<AExpression>, const Token &, ParserStateMachine *) override;
|
||||
|
||||
///@}
|
||||
|
||||
|
|
|
|||
|
|
@ -66,8 +66,8 @@ namespace xo {
|
|||
static void on_parsed_formal_arglist(DDefineSsm & self, DArray * arglist, ParserStateMachine * p_psm);
|
||||
/** update state machine for incoming parsed expression @p expr **/
|
||||
static void on_parsed_expression(DDefineSsm & self, obj<AExpression> expr, ParserStateMachine * p_psm);
|
||||
/** update state machine for incoming parsed expression @p expr followed by semicolon **/
|
||||
static void on_parsed_expression_with_semicolon(DDefineSsm & self, obj<AExpression> expr, ParserStateMachine * p_psm);
|
||||
/** update state machine @p p_psm for incoming parsed expression @p expr followed by token @p tk **/
|
||||
static void on_parsed_expression_with_token(DDefineSsm & self, obj<AExpression> expr, const Token & tk, ParserStateMachine * p_psm);
|
||||
///@}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -66,8 +66,8 @@ namespace xo {
|
|||
static void on_parsed_formal_arglist(DExpectExprSsm & self, DArray * arglist, ParserStateMachine * p_psm);
|
||||
/** update state machine for incoming parsed expression @p expr **/
|
||||
static void on_parsed_expression(DExpectExprSsm & self, obj<AExpression> expr, ParserStateMachine * p_psm);
|
||||
/** update state machine for incoming parsed expression @p expr followed by semicolon **/
|
||||
static void on_parsed_expression_with_semicolon(DExpectExprSsm & self, obj<AExpression> expr, ParserStateMachine * p_psm);
|
||||
/** update state machine @p p_psm for incoming parsed expression @p expr followed by token @p tk **/
|
||||
static void on_parsed_expression_with_token(DExpectExprSsm & self, obj<AExpression> expr, const Token & tk, ParserStateMachine * p_psm);
|
||||
///@}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -66,8 +66,8 @@ namespace xo {
|
|||
static void on_parsed_formal_arglist(DExpectFormalArgSsm & self, DArray * arglist, ParserStateMachine * p_psm);
|
||||
/** update state machine for incoming parsed expression @p expr **/
|
||||
static void on_parsed_expression(DExpectFormalArgSsm & self, obj<AExpression> expr, ParserStateMachine * p_psm);
|
||||
/** update state machine for incoming parsed expression @p expr followed by semicolon **/
|
||||
static void on_parsed_expression_with_semicolon(DExpectFormalArgSsm & self, obj<AExpression> expr, ParserStateMachine * p_psm);
|
||||
/** update state machine @p p_psm for incoming parsed expression @p expr followed by token @p tk **/
|
||||
static void on_parsed_expression_with_token(DExpectFormalArgSsm & self, obj<AExpression> expr, const Token & tk, ParserStateMachine * p_psm);
|
||||
///@}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -66,8 +66,8 @@ namespace xo {
|
|||
static void on_parsed_formal_arglist(DExpectFormalArglistSsm & self, DArray * arglist, ParserStateMachine * p_psm);
|
||||
/** update state machine for incoming parsed expression @p expr **/
|
||||
static void on_parsed_expression(DExpectFormalArglistSsm & self, obj<AExpression> expr, ParserStateMachine * p_psm);
|
||||
/** update state machine for incoming parsed expression @p expr followed by semicolon **/
|
||||
static void on_parsed_expression_with_semicolon(DExpectFormalArglistSsm & self, obj<AExpression> expr, ParserStateMachine * p_psm);
|
||||
/** update state machine @p p_psm for incoming parsed expression @p expr followed by token @p tk **/
|
||||
static void on_parsed_expression_with_token(DExpectFormalArglistSsm & self, obj<AExpression> expr, const Token & tk, ParserStateMachine * p_psm);
|
||||
///@}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -66,8 +66,8 @@ namespace xo {
|
|||
static void on_parsed_formal_arglist(DExpectSymbolSsm & self, DArray * arglist, ParserStateMachine * p_psm);
|
||||
/** update state machine for incoming parsed expression @p expr **/
|
||||
static void on_parsed_expression(DExpectSymbolSsm & self, obj<AExpression> expr, ParserStateMachine * p_psm);
|
||||
/** update state machine for incoming parsed expression @p expr followed by semicolon **/
|
||||
static void on_parsed_expression_with_semicolon(DExpectSymbolSsm & self, obj<AExpression> expr, ParserStateMachine * p_psm);
|
||||
/** update state machine @p p_psm for incoming parsed expression @p expr followed by token @p tk **/
|
||||
static void on_parsed_expression_with_token(DExpectSymbolSsm & self, obj<AExpression> expr, const Token & tk, ParserStateMachine * p_psm);
|
||||
///@}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -66,8 +66,8 @@ namespace xo {
|
|||
static void on_parsed_formal_arglist(DExpectTypeSsm & self, DArray * arglist, ParserStateMachine * p_psm);
|
||||
/** update state machine for incoming parsed expression @p expr **/
|
||||
static void on_parsed_expression(DExpectTypeSsm & self, obj<AExpression> expr, ParserStateMachine * p_psm);
|
||||
/** update state machine for incoming parsed expression @p expr followed by semicolon **/
|
||||
static void on_parsed_expression_with_semicolon(DExpectTypeSsm & self, obj<AExpression> expr, ParserStateMachine * p_psm);
|
||||
/** update state machine @p p_psm for incoming parsed expression @p expr followed by token @p tk **/
|
||||
static void on_parsed_expression_with_token(DExpectTypeSsm & self, obj<AExpression> expr, const Token & tk, ParserStateMachine * p_psm);
|
||||
///@}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -66,8 +66,8 @@ namespace xo {
|
|||
static void on_parsed_formal_arglist(DExprSeqState & self, DArray * arglist, ParserStateMachine * p_psm);
|
||||
/** update state machine for incoming parsed expression @p expr **/
|
||||
static void on_parsed_expression(DExprSeqState & self, obj<AExpression> expr, ParserStateMachine * p_psm);
|
||||
/** update state machine for incoming parsed expression @p expr followed by semicolon **/
|
||||
static void on_parsed_expression_with_semicolon(DExprSeqState & self, obj<AExpression> expr, ParserStateMachine * p_psm);
|
||||
/** update state machine @p p_psm for incoming parsed expression @p expr followed by token @p tk **/
|
||||
static void on_parsed_expression_with_token(DExprSeqState & self, obj<AExpression> expr, const Token & tk, ParserStateMachine * p_psm);
|
||||
///@}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -66,8 +66,8 @@ namespace xo {
|
|||
static void on_parsed_formal_arglist(DIfElseSsm & self, DArray * arglist, ParserStateMachine * p_psm);
|
||||
/** update state machine for incoming parsed expression @p expr **/
|
||||
static void on_parsed_expression(DIfElseSsm & self, obj<AExpression> expr, ParserStateMachine * p_psm);
|
||||
/** update state machine for incoming parsed expression @p expr followed by semicolon **/
|
||||
static void on_parsed_expression_with_semicolon(DIfElseSsm & self, obj<AExpression> expr, ParserStateMachine * p_psm);
|
||||
/** update state machine @p p_psm for incoming parsed expression @p expr followed by token @p tk **/
|
||||
static void on_parsed_expression_with_token(DIfElseSsm & self, obj<AExpression> expr, const Token & tk, ParserStateMachine * p_psm);
|
||||
///@}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -66,8 +66,8 @@ namespace xo {
|
|||
static void on_parsed_formal_arglist(DLambdaSsm & self, DArray * arglist, ParserStateMachine * p_psm);
|
||||
/** update state machine for incoming parsed expression @p expr **/
|
||||
static void on_parsed_expression(DLambdaSsm & self, obj<AExpression> expr, ParserStateMachine * p_psm);
|
||||
/** update state machine for incoming parsed expression @p expr followed by semicolon **/
|
||||
static void on_parsed_expression_with_semicolon(DLambdaSsm & self, obj<AExpression> expr, ParserStateMachine * p_psm);
|
||||
/** update state machine @p p_psm for incoming parsed expression @p expr followed by token @p tk **/
|
||||
static void on_parsed_expression_with_token(DLambdaSsm & self, obj<AExpression> expr, const Token & tk, ParserStateMachine * p_psm);
|
||||
///@}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -66,8 +66,8 @@ namespace xo {
|
|||
static void on_parsed_formal_arglist(DProgressSsm & self, DArray * arglist, ParserStateMachine * p_psm);
|
||||
/** update state machine for incoming parsed expression @p expr **/
|
||||
static void on_parsed_expression(DProgressSsm & self, obj<AExpression> expr, ParserStateMachine * p_psm);
|
||||
/** update state machine for incoming parsed expression @p expr followed by semicolon **/
|
||||
static void on_parsed_expression_with_semicolon(DProgressSsm & self, obj<AExpression> expr, ParserStateMachine * p_psm);
|
||||
/** update state machine @p p_psm for incoming parsed expression @p expr followed by token @p tk **/
|
||||
static void on_parsed_expression_with_token(DProgressSsm & self, obj<AExpression> expr, const Token & tk, ParserStateMachine * p_psm);
|
||||
///@}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -66,8 +66,8 @@ namespace xo {
|
|||
static void on_parsed_formal_arglist(DSequenceSsm & self, DArray * arglist, ParserStateMachine * p_psm);
|
||||
/** update state machine for incoming parsed expression @p expr **/
|
||||
static void on_parsed_expression(DSequenceSsm & self, obj<AExpression> expr, ParserStateMachine * p_psm);
|
||||
/** update state machine for incoming parsed expression @p expr followed by semicolon **/
|
||||
static void on_parsed_expression_with_semicolon(DSequenceSsm & self, obj<AExpression> expr, ParserStateMachine * p_psm);
|
||||
/** update state machine @p p_psm for incoming parsed expression @p expr followed by token @p tk **/
|
||||
static void on_parsed_expression_with_token(DSequenceSsm & self, obj<AExpression> expr, const Token & tk, ParserStateMachine * p_psm);
|
||||
///@}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -42,8 +42,11 @@ namespace scm {
|
|||
|
||||
// from ASyntaxStateMachine
|
||||
|
||||
// const methods
|
||||
// builtin methods
|
||||
typeseq _typeseq() const noexcept override { return s_typeseq; }
|
||||
void _drop(Opaque d) const noexcept override { _dcast(d).~DRepr(); }
|
||||
|
||||
// const methods
|
||||
syntaxstatetype ssm_type(Copaque data) const noexcept override {
|
||||
return I::ssm_type(_dcast(data));
|
||||
}
|
||||
|
|
@ -70,8 +73,8 @@ namespace scm {
|
|||
void on_parsed_expression(Opaque data, obj<AExpression> expr, ParserStateMachine * p_psm) override {
|
||||
return I::on_parsed_expression(_dcast(data), expr, p_psm);
|
||||
}
|
||||
void on_parsed_expression_with_semicolon(Opaque data, obj<AExpression> expr, ParserStateMachine * p_psm) override {
|
||||
return I::on_parsed_expression_with_semicolon(_dcast(data), expr, p_psm);
|
||||
void on_parsed_expression_with_token(Opaque data, obj<AExpression> expr, const Token & tk, ParserStateMachine * p_psm) override {
|
||||
return I::on_parsed_expression_with_token(_dcast(data), expr, tk, p_psm);
|
||||
}
|
||||
|
||||
///@}
|
||||
|
|
|
|||
|
|
@ -46,8 +46,13 @@ public:
|
|||
/** @defgroup scm-syntaxstatemachine-router-methods **/
|
||||
///@{
|
||||
|
||||
// const methods
|
||||
// explicit injected content
|
||||
|
||||
// builtin methods
|
||||
typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); }
|
||||
void _drop() const noexcept { O::iface()->_drop(O::data()); }
|
||||
|
||||
// const methods
|
||||
syntaxstatetype ssm_type() const noexcept {
|
||||
return O::iface()->ssm_type(O::data());
|
||||
}
|
||||
|
|
@ -74,8 +79,8 @@ public:
|
|||
void on_parsed_expression(obj<AExpression> expr, ParserStateMachine * p_psm) {
|
||||
return O::iface()->on_parsed_expression(O::data(), expr, p_psm);
|
||||
}
|
||||
void on_parsed_expression_with_semicolon(obj<AExpression> expr, ParserStateMachine * p_psm) {
|
||||
return O::iface()->on_parsed_expression_with_semicolon(O::data(), expr, p_psm);
|
||||
void on_parsed_expression_with_token(obj<AExpression> expr, const Token & tk, ParserStateMachine * p_psm) {
|
||||
return O::iface()->on_parsed_expression_with_token(O::data(), expr, tk, p_psm);
|
||||
}
|
||||
|
||||
///@}
|
||||
|
|
|
|||
|
|
@ -626,7 +626,7 @@ namespace xo {
|
|||
{
|
||||
if (defstate_ == defexprstatetype::def_6) {
|
||||
p_psm->pop_ssm();
|
||||
p_psm->on_parsed_expression_with_semicolon(def_expr_);
|
||||
p_psm->on_parsed_expression_with_token(def_expr_, tk);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -649,11 +649,28 @@ namespace xo {
|
|||
}
|
||||
|
||||
void
|
||||
DDefineSsm::on_parsed_expression_with_semicolon(obj<AExpression> expr,
|
||||
ParserStateMachine * p_psm)
|
||||
DDefineSsm::on_parsed_expression_with_token(obj<AExpression> expr,
|
||||
const Token & tk,
|
||||
ParserStateMachine * p_psm)
|
||||
{
|
||||
this->on_parsed_expression(expr, p_psm);
|
||||
this->on_semicolon_token(Token::semicolon_token(), p_psm);
|
||||
/* must end with semicolon */
|
||||
|
||||
if (tk.tk_type() == tokentype::tk_semicolon) {
|
||||
if (defstate_ == defexprstatetype::def_5)
|
||||
{
|
||||
this->defstate_ = defexprstatetype::def_6;
|
||||
|
||||
def_expr_.data()->assign_rhs(expr);
|
||||
|
||||
// completes this definition syntax
|
||||
this->on_semicolon_token(tk, p_psm);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// error in all other cases
|
||||
Super::on_parsed_expression_with_token(expr, tk, p_psm);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ namespace xo {
|
|||
|
||||
log && log(xtag("tk", tk));
|
||||
|
||||
const DVariable * var = p_psm->lookup_variable(tk.text());
|
||||
DVarRef * var = p_psm->lookup_varref(tk.text());
|
||||
|
||||
if (!var) {
|
||||
p_psm->error_unbound_variable(ssm_classname(),
|
||||
|
|
@ -210,7 +210,7 @@ namespace xo {
|
|||
//
|
||||
|
||||
DProgressSsm::start(p_psm->parser_alloc(),
|
||||
obj<AExpression,DVariable>(const_cast<DVariable *>(var)),
|
||||
obj<AExpression,DVarRef>(var),
|
||||
p_psm);
|
||||
}
|
||||
|
||||
|
|
@ -388,14 +388,15 @@ namespace xo {
|
|||
}
|
||||
|
||||
void
|
||||
DExpectExprSsm::on_parsed_expression_with_semicolon(obj<AExpression> expr,
|
||||
ParserStateMachine * p_psm)
|
||||
DExpectExprSsm::on_parsed_expression_with_token(obj<AExpression> expr,
|
||||
const Token & tk,
|
||||
ParserStateMachine * p_psm)
|
||||
{
|
||||
// expression (reported by nested ProgressSsm)
|
||||
// completes this DExpectExprSsm's assignment
|
||||
|
||||
p_psm->pop_ssm();
|
||||
p_psm->on_parsed_expression_with_semicolon(expr);
|
||||
p_psm->on_parsed_expression_with_token(expr, tk);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -167,7 +167,10 @@ namespace xo {
|
|||
case tokentype::tk_dot:
|
||||
case tokentype::tk_comma:
|
||||
case tokentype::tk_colon:
|
||||
break;
|
||||
case tokentype::tk_semicolon:
|
||||
assert(false);
|
||||
break;
|
||||
case tokentype::tk_doublecolon:
|
||||
case tokentype::tk_singleassign:
|
||||
case tokentype::tk_assign:
|
||||
|
|
@ -396,10 +399,16 @@ namespace xo {
|
|||
}
|
||||
|
||||
void
|
||||
DExprSeqState::on_parsed_expression_with_semicolon(obj<AExpression> expr,
|
||||
ParserStateMachine * p_psm)
|
||||
DExprSeqState::on_parsed_expression_with_token(obj<AExpression> expr,
|
||||
const Token & tk,
|
||||
ParserStateMachine * p_psm)
|
||||
{
|
||||
p_psm->capture_result("DExprSeqState::on_parsed_expression_with_semicolon", expr);
|
||||
if (tk.tk_type() == tokentype::tk_semicolon) {
|
||||
p_psm->capture_result("DExprSeqState::on_parsed_expression_with_token", expr);
|
||||
return;
|
||||
}
|
||||
|
||||
Super::on_parsed_expression_with_token(expr, tk, p_psm);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -150,13 +150,15 @@ namespace xo {
|
|||
case tokentype::tk_else:
|
||||
this->on_else_token(tk, p_psm);
|
||||
return;
|
||||
case tokentype::tk_semicolon:
|
||||
this->on_semicolon_token(tk, p_psm);
|
||||
return;
|
||||
case tokentype::tk_colon:
|
||||
case tokentype::tk_singleassign:
|
||||
case tokentype::tk_string:
|
||||
case tokentype::tk_f64:
|
||||
case tokentype::tk_i64:
|
||||
case tokentype::tk_bool:
|
||||
case tokentype::tk_semicolon:
|
||||
case tokentype::tk_invalid:
|
||||
case tokentype::tk_leftparen:
|
||||
case tokentype::tk_rightparen:
|
||||
|
|
@ -405,13 +407,25 @@ namespace xo {
|
|||
}
|
||||
|
||||
void
|
||||
DIfElseSsm::on_parsed_expression_with_semicolon(obj<AExpression> expr,
|
||||
ParserStateMachine * p_psm)
|
||||
DIfElseSsm::on_parsed_expression_with_token(obj<AExpression> expr,
|
||||
const Token & tk,
|
||||
ParserStateMachine * p_psm)
|
||||
{
|
||||
scope log(XO_DEBUG(p_psm->debug_flag()));
|
||||
|
||||
this->on_parsed_expression(expr, p_psm);
|
||||
this->on_semicolon_token(Token::semicolon_token(), p_psm);
|
||||
// TODO: may consider allowing if-else to terminate on other particular tokens
|
||||
// e.g. ')'
|
||||
|
||||
if ((tk.tk_type() == tokentype::tk_then)
|
||||
|| (tk.tk_type() == tokentype::tk_else)
|
||||
|| (tk.tk_type() == tokentype::tk_semicolon))
|
||||
{
|
||||
this->on_parsed_expression(expr, p_psm);
|
||||
this->on_token(tk, p_psm);
|
||||
return;
|
||||
}
|
||||
|
||||
Super::on_parsed_expression_with_token(expr, tk, p_psm);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -364,10 +364,11 @@ namespace xo {
|
|||
}
|
||||
|
||||
void
|
||||
DLambdaSsm::on_parsed_expression_with_semicolon(obj<AExpression> expr,
|
||||
ParserStateMachine * p_psm)
|
||||
DLambdaSsm::on_parsed_expression_with_token(obj<AExpression> expr,
|
||||
const Token & tk,
|
||||
ParserStateMachine * p_psm)
|
||||
{
|
||||
Super::on_parsed_expression_with_semicolon(expr, p_psm);
|
||||
Super::on_parsed_expression_with_token(expr, tk, p_psm);
|
||||
}
|
||||
|
||||
#ifdef NOT_YET
|
||||
|
|
|
|||
|
|
@ -319,10 +319,7 @@ namespace xo {
|
|||
obj<AExpression> expr = this->assemble_expr(p_psm);
|
||||
|
||||
p_psm->pop_ssm(); // completes self
|
||||
|
||||
// TODO: perhaps need to generalize on_parsed_expression_with_semicolon() ..?
|
||||
p_psm->on_parsed_expression(expr);
|
||||
p_psm->on_token(tk);
|
||||
p_psm->on_parsed_expression_with_token(expr, tk);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -458,25 +455,7 @@ namespace xo {
|
|||
}
|
||||
|
||||
p_psm->pop_ssm();
|
||||
p_psm->on_parsed_expression_with_semicolon(expr);
|
||||
|
||||
/* control here on input like:
|
||||
* (1.234;
|
||||
*
|
||||
* a. '(' sets up stack [lparen_0:expect_rhs_expression]
|
||||
* (see exprstate::on_leftparen())
|
||||
* b. 1.234 pushes (in case operators) [lparen_0:expect_rhs_expression:expr_progress]
|
||||
* (see exprstate::on_f64())
|
||||
* c. semicolon completes expr_progress [lparen_0:expect_rhs_expression]
|
||||
* deliver expresssion to expect_rhs_expression.on_expr_with_semicolon()
|
||||
* (see exprstate::on_expr_with_semicolon())
|
||||
* d. expr_rhs_expression forwards expression to [lparen_0]
|
||||
* e. lparen_0 would advance to [lparen_1], but rejects semicolon
|
||||
*/
|
||||
|
||||
#ifdef OBSOLETE
|
||||
Super::on_token(tk, p_psm);
|
||||
#endif
|
||||
p_psm->on_parsed_expression_with_token(expr, tk);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -489,11 +468,15 @@ namespace xo {
|
|||
|
||||
obj<AExpression> expr = this->assemble_expr(p_psm);
|
||||
|
||||
{
|
||||
if (expr) {
|
||||
obj<APrintable> expr_pr
|
||||
= FacetRegistry::instance().variant<APrintable,AExpression>(expr);
|
||||
= FacetRegistry::instance().try_variant<APrintable,AExpression>(expr);
|
||||
assert(expr_pr);
|
||||
log && log(xtag("expr", expr_pr));
|
||||
} else {
|
||||
// illegal token if assemble failed
|
||||
Super::on_token(tk, p_psm);
|
||||
return;
|
||||
}
|
||||
|
||||
p_psm->pop_ssm();
|
||||
|
|
@ -501,15 +484,19 @@ namespace xo {
|
|||
}
|
||||
|
||||
void
|
||||
DProgressSsm::on_parsed_expression_with_semicolon(obj<AExpression> expr,
|
||||
ParserStateMachine * p_psm)
|
||||
DProgressSsm::on_parsed_expression_with_token(obj<AExpression> expr,
|
||||
const Token & tk,
|
||||
ParserStateMachine * p_psm)
|
||||
{
|
||||
scope log(XO_DEBUG(p_psm->debug_flag()),
|
||||
xtag("expr", expr));
|
||||
|
||||
if (op_type_ == optype::invalid) {
|
||||
// e.g. control here on input like
|
||||
// x : = 4 4
|
||||
|
||||
p_psm->illegal_parsed_expression
|
||||
("DProgressSsm::on_parsed_expression_with_semicolon",
|
||||
("DProgressSsm::on_parsed_expression_with_token",
|
||||
expr,
|
||||
this->get_expect_str());
|
||||
return;
|
||||
|
|
@ -521,7 +508,7 @@ namespace xo {
|
|||
|
||||
if (expr2) {
|
||||
p_psm->pop_ssm();
|
||||
p_psm->on_parsed_expression_with_semicolon(expr2);
|
||||
p_psm->on_parsed_expression_with_token(expr2, tk);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -147,10 +147,8 @@ namespace xo {
|
|||
{
|
||||
scope log(XO_DEBUG(p_psm->debug_flag()));
|
||||
|
||||
// TODO: stream inserter that sets up pretty-printing.
|
||||
// Or integrate with indentlog.
|
||||
// Maybe trouble is that indentlog doesn't #include Printable ?
|
||||
//
|
||||
// TODO: switch to printable facet
|
||||
|
||||
log && log(xtag("expr", expr));
|
||||
|
||||
#ifdef NOT_YET
|
||||
|
|
@ -206,8 +204,31 @@ namespace xo {
|
|||
}
|
||||
#endif
|
||||
|
||||
this->seq_expr_->push_back(p_psm->expr_alloc(),
|
||||
expr);
|
||||
this->seq_expr_->push_back(p_psm->expr_alloc(), expr);
|
||||
}
|
||||
|
||||
void
|
||||
DSequenceSsm::on_parsed_expression_with_token(obj<AExpression> expr,
|
||||
const Token & tk,
|
||||
ParserStateMachine * p_psm)
|
||||
{
|
||||
scope log(XO_DEBUG(p_psm->debug_flag()));
|
||||
|
||||
if (tk.tk_type() == tokentype::tk_semicolon) {
|
||||
// keep sequence on stack, consuming semicolon
|
||||
|
||||
this->seq_expr_->push_back(p_psm->expr_alloc(),
|
||||
expr);
|
||||
return;
|
||||
} else if (tk.tk_type() == tokentype::tk_rightbrace) {
|
||||
// rightbrace ends sequence
|
||||
|
||||
this->seq_expr_->push_back(p_psm->expr_alloc(), expr);
|
||||
this->on_rightbrace_token(tk, p_psm);
|
||||
return;
|
||||
}
|
||||
|
||||
Super::on_parsed_expression_with_token(expr, tk, p_psm);
|
||||
}
|
||||
|
||||
#ifdef NOT_YET
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ ISyntaxStateMachine_Any::on_parsed_expression(Opaque, obj<AExpression>, ParserSt
|
|||
}
|
||||
|
||||
auto
|
||||
ISyntaxStateMachine_Any::on_parsed_expression_with_semicolon(Opaque, obj<AExpression>, ParserStateMachine *) -> void
|
||||
ISyntaxStateMachine_Any::on_parsed_expression_with_token(Opaque, obj<AExpression>, const Token &, ParserStateMachine *) -> void
|
||||
{
|
||||
_fatal();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,9 +58,9 @@ namespace xo {
|
|||
self.on_parsed_expression(expr, p_psm);
|
||||
}
|
||||
auto
|
||||
ISyntaxStateMachine_DDefineSsm::on_parsed_expression_with_semicolon(DDefineSsm & self, obj<AExpression> expr, ParserStateMachine * p_psm) -> void
|
||||
ISyntaxStateMachine_DDefineSsm::on_parsed_expression_with_token(DDefineSsm & self, obj<AExpression> expr, const Token & tk, ParserStateMachine * p_psm) -> void
|
||||
{
|
||||
self.on_parsed_expression_with_semicolon(expr, p_psm);
|
||||
self.on_parsed_expression_with_token(expr, tk, p_psm);
|
||||
}
|
||||
|
||||
} /*namespace scm*/
|
||||
|
|
|
|||
|
|
@ -58,9 +58,9 @@ namespace xo {
|
|||
self.on_parsed_expression(expr, p_psm);
|
||||
}
|
||||
auto
|
||||
ISyntaxStateMachine_DExpectExprSsm::on_parsed_expression_with_semicolon(DExpectExprSsm & self, obj<AExpression> expr, ParserStateMachine * p_psm) -> void
|
||||
ISyntaxStateMachine_DExpectExprSsm::on_parsed_expression_with_token(DExpectExprSsm & self, obj<AExpression> expr, const Token & tk, ParserStateMachine * p_psm) -> void
|
||||
{
|
||||
self.on_parsed_expression_with_semicolon(expr, p_psm);
|
||||
self.on_parsed_expression_with_token(expr, tk, p_psm);
|
||||
}
|
||||
|
||||
} /*namespace scm*/
|
||||
|
|
|
|||
|
|
@ -58,9 +58,9 @@ namespace xo {
|
|||
self.on_parsed_expression(expr, p_psm);
|
||||
}
|
||||
auto
|
||||
ISyntaxStateMachine_DExpectFormalArgSsm::on_parsed_expression_with_semicolon(DExpectFormalArgSsm & self, obj<AExpression> expr, ParserStateMachine * p_psm) -> void
|
||||
ISyntaxStateMachine_DExpectFormalArgSsm::on_parsed_expression_with_token(DExpectFormalArgSsm & self, obj<AExpression> expr, const Token & tk, ParserStateMachine * p_psm) -> void
|
||||
{
|
||||
self.on_parsed_expression_with_semicolon(expr, p_psm);
|
||||
self.on_parsed_expression_with_token(expr, tk, p_psm);
|
||||
}
|
||||
|
||||
} /*namespace scm*/
|
||||
|
|
|
|||
|
|
@ -58,9 +58,9 @@ namespace xo {
|
|||
self.on_parsed_expression(expr, p_psm);
|
||||
}
|
||||
auto
|
||||
ISyntaxStateMachine_DExpectFormalArglistSsm::on_parsed_expression_with_semicolon(DExpectFormalArglistSsm & self, obj<AExpression> expr, ParserStateMachine * p_psm) -> void
|
||||
ISyntaxStateMachine_DExpectFormalArglistSsm::on_parsed_expression_with_token(DExpectFormalArglistSsm & self, obj<AExpression> expr, const Token & tk, ParserStateMachine * p_psm) -> void
|
||||
{
|
||||
self.on_parsed_expression_with_semicolon(expr, p_psm);
|
||||
self.on_parsed_expression_with_token(expr, tk, p_psm);
|
||||
}
|
||||
|
||||
} /*namespace scm*/
|
||||
|
|
|
|||
|
|
@ -58,9 +58,9 @@ namespace xo {
|
|||
self.on_parsed_expression(expr, p_psm);
|
||||
}
|
||||
auto
|
||||
ISyntaxStateMachine_DExpectSymbolSsm::on_parsed_expression_with_semicolon(DExpectSymbolSsm & self, obj<AExpression> expr, ParserStateMachine * p_psm) -> void
|
||||
ISyntaxStateMachine_DExpectSymbolSsm::on_parsed_expression_with_token(DExpectSymbolSsm & self, obj<AExpression> expr, const Token & tk, ParserStateMachine * p_psm) -> void
|
||||
{
|
||||
self.on_parsed_expression_with_semicolon(expr, p_psm);
|
||||
self.on_parsed_expression_with_token(expr, tk, p_psm);
|
||||
}
|
||||
|
||||
} /*namespace scm*/
|
||||
|
|
|
|||
|
|
@ -58,9 +58,9 @@ namespace xo {
|
|||
self.on_parsed_expression(expr, p_psm);
|
||||
}
|
||||
auto
|
||||
ISyntaxStateMachine_DExpectTypeSsm::on_parsed_expression_with_semicolon(DExpectTypeSsm & self, obj<AExpression> expr, ParserStateMachine * p_psm) -> void
|
||||
ISyntaxStateMachine_DExpectTypeSsm::on_parsed_expression_with_token(DExpectTypeSsm & self, obj<AExpression> expr, const Token & tk, ParserStateMachine * p_psm) -> void
|
||||
{
|
||||
self.on_parsed_expression_with_semicolon(expr, p_psm);
|
||||
self.on_parsed_expression_with_token(expr, tk, p_psm);
|
||||
}
|
||||
|
||||
} /*namespace scm*/
|
||||
|
|
|
|||
|
|
@ -58,9 +58,9 @@ namespace xo {
|
|||
self.on_parsed_expression(expr, p_psm);
|
||||
}
|
||||
auto
|
||||
ISyntaxStateMachine_DExprSeqState::on_parsed_expression_with_semicolon(DExprSeqState & self, obj<AExpression> expr, ParserStateMachine * p_psm) -> void
|
||||
ISyntaxStateMachine_DExprSeqState::on_parsed_expression_with_token(DExprSeqState & self, obj<AExpression> expr, const Token & tk, ParserStateMachine * p_psm) -> void
|
||||
{
|
||||
self.on_parsed_expression_with_semicolon(expr, p_psm);
|
||||
self.on_parsed_expression_with_token(expr, tk, p_psm);
|
||||
}
|
||||
|
||||
} /*namespace scm*/
|
||||
|
|
|
|||
|
|
@ -58,9 +58,9 @@ namespace xo {
|
|||
self.on_parsed_expression(expr, p_psm);
|
||||
}
|
||||
auto
|
||||
ISyntaxStateMachine_DIfElseSsm::on_parsed_expression_with_semicolon(DIfElseSsm & self, obj<AExpression> expr, ParserStateMachine * p_psm) -> void
|
||||
ISyntaxStateMachine_DIfElseSsm::on_parsed_expression_with_token(DIfElseSsm & self, obj<AExpression> expr, const Token & tk, ParserStateMachine * p_psm) -> void
|
||||
{
|
||||
self.on_parsed_expression_with_semicolon(expr, p_psm);
|
||||
self.on_parsed_expression_with_token(expr, tk, p_psm);
|
||||
}
|
||||
|
||||
} /*namespace scm*/
|
||||
|
|
|
|||
|
|
@ -58,9 +58,9 @@ namespace xo {
|
|||
self.on_parsed_expression(expr, p_psm);
|
||||
}
|
||||
auto
|
||||
ISyntaxStateMachine_DLambdaSsm::on_parsed_expression_with_semicolon(DLambdaSsm & self, obj<AExpression> expr, ParserStateMachine * p_psm) -> void
|
||||
ISyntaxStateMachine_DLambdaSsm::on_parsed_expression_with_token(DLambdaSsm & self, obj<AExpression> expr, const Token & tk, ParserStateMachine * p_psm) -> void
|
||||
{
|
||||
self.on_parsed_expression_with_semicolon(expr, p_psm);
|
||||
self.on_parsed_expression_with_token(expr, tk, p_psm);
|
||||
}
|
||||
|
||||
} /*namespace scm*/
|
||||
|
|
|
|||
|
|
@ -58,9 +58,9 @@ namespace xo {
|
|||
self.on_parsed_expression(expr, p_psm);
|
||||
}
|
||||
auto
|
||||
ISyntaxStateMachine_DProgressSsm::on_parsed_expression_with_semicolon(DProgressSsm & self, obj<AExpression> expr, ParserStateMachine * p_psm) -> void
|
||||
ISyntaxStateMachine_DProgressSsm::on_parsed_expression_with_token(DProgressSsm & self, obj<AExpression> expr, const Token & tk, ParserStateMachine * p_psm) -> void
|
||||
{
|
||||
self.on_parsed_expression_with_semicolon(expr, p_psm);
|
||||
self.on_parsed_expression_with_token(expr, tk, p_psm);
|
||||
}
|
||||
|
||||
} /*namespace scm*/
|
||||
|
|
|
|||
|
|
@ -58,9 +58,9 @@ namespace xo {
|
|||
self.on_parsed_expression(expr, p_psm);
|
||||
}
|
||||
auto
|
||||
ISyntaxStateMachine_DSequenceSsm::on_parsed_expression_with_semicolon(DSequenceSsm & self, obj<AExpression> expr, ParserStateMachine * p_psm) -> void
|
||||
ISyntaxStateMachine_DSequenceSsm::on_parsed_expression_with_token(DSequenceSsm & self, obj<AExpression> expr, const Token & tk, ParserStateMachine * p_psm) -> void
|
||||
{
|
||||
self.on_parsed_expression_with_semicolon(expr, p_psm);
|
||||
self.on_parsed_expression_with_token(expr, tk, p_psm);
|
||||
}
|
||||
|
||||
} /*namespace scm*/
|
||||
|
|
|
|||
|
|
@ -107,38 +107,57 @@ namespace xo {
|
|||
return stringtable_.gensym(str);
|
||||
}
|
||||
|
||||
Binding
|
||||
ParserStateMachine::lookup_binding(std::string_view symbolname)
|
||||
DVarRef *
|
||||
ParserStateMachine::lookup_varref(std::string_view symbolname)
|
||||
{
|
||||
scope log(XO_DEBUG(debug_flag_));
|
||||
|
||||
if (!local_symtab_)
|
||||
return Binding::null();
|
||||
|
||||
const DUniqueString * ustr = stringtable_.lookup(symbolname);
|
||||
|
||||
if (!ustr) {
|
||||
// if not in string table, then can't be a variable either
|
||||
return Binding::null();
|
||||
}
|
||||
|
||||
DLocalSymtab * symtab = local_symtab_;
|
||||
|
||||
// count #of nested scopes to cross, to reach symbol
|
||||
// TODO:
|
||||
// 1. check global symtab
|
||||
// 2. combine local+global symtab into indept struct
|
||||
// 3. move lookup_varref implementation there.
|
||||
//
|
||||
int32_t link_count = 0;
|
||||
|
||||
while (symtab) {
|
||||
Binding b = symtab->lookup_binding(ustr);
|
||||
if (local_symtab_) {
|
||||
const DUniqueString * ustr = stringtable_.lookup(symbolname);
|
||||
|
||||
if (b.is_local()) {
|
||||
assert(b.i_link() == 0);
|
||||
if (ustr) {
|
||||
DLocalSymtab * symtab = local_symtab_;
|
||||
|
||||
return Binding(link_count, b.j_slot());
|
||||
// count #of nested scopes to cross, to reach symbol
|
||||
//
|
||||
int32_t link_count = 0;
|
||||
|
||||
while (symtab) {
|
||||
Binding b = symtab->lookup_binding(ustr);
|
||||
|
||||
if (b.is_local()) {
|
||||
assert(b.i_link() == 0);
|
||||
|
||||
DVariable * vardef = symtab->lookup_var(b);
|
||||
assert(vardef);
|
||||
|
||||
|
||||
/** ascii diagram here
|
||||
**/
|
||||
|
||||
return DVarRef::make(expr_alloc_,
|
||||
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
|
||||
|
|
@ -146,7 +165,7 @@ namespace xo {
|
|||
log.retroactively_enable();
|
||||
log("STUB: check global symtab");
|
||||
|
||||
return Binding::null();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -239,16 +258,6 @@ namespace xo {
|
|||
this->top_ssm().on_parsed_expression(expr, this);
|
||||
}
|
||||
|
||||
void
|
||||
ParserStateMachine::on_parsed_expression_with_semicolon(obj<AExpression> expr)
|
||||
{
|
||||
scope log(XO_DEBUG(debug_flag_), xtag("expr", expr));
|
||||
|
||||
assert(stack_);
|
||||
|
||||
this->top_ssm().on_parsed_expression_with_semicolon(expr, this);
|
||||
}
|
||||
|
||||
void
|
||||
ParserStateMachine::on_parsed_expression_with_token(obj<AExpression> expr,
|
||||
const Token & tk)
|
||||
|
|
@ -257,11 +266,7 @@ namespace xo {
|
|||
|
||||
assert(stack_);
|
||||
|
||||
this->top_ssm().on_parsed_expression(expr, this);
|
||||
|
||||
assert(stack_);
|
||||
|
||||
this->top_ssm().on_token(tk, this);
|
||||
this->top_ssm().on_parsed_expression_with_token(expr, tk, this);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -443,6 +448,39 @@ namespace xo {
|
|||
this->capture_error(ssm_name, errmsg);
|
||||
}
|
||||
|
||||
void
|
||||
ParserStateMachine::illegal_parsed_expression_with_token(std::string_view ssm_name,
|
||||
obj<AExpression> expr,
|
||||
const Token & tk,
|
||||
std::string_view expect_str)
|
||||
{
|
||||
// TODO:
|
||||
// - want to write error message using DArena
|
||||
// - need something like log_streambuf and/or tostr() that's arena-aware
|
||||
|
||||
obj<APrintable> expr_pr
|
||||
= FacetRegistry::instance().variant<APrintable,AExpression>(expr);
|
||||
assert(expr_pr);
|
||||
|
||||
/** TODO
|
||||
* problem here: we have pretty() support for obj<AExpression>,
|
||||
* but not "ordinary printing" support. So expression doesn't get printed
|
||||
**/
|
||||
auto errmsg_string = tostr("Unexpected expression",
|
||||
xtag("expr", expr_pr),
|
||||
xtag("tk", tk),
|
||||
xtag("expecting", expect_str),
|
||||
xtag("ssm", ssm_name),
|
||||
xtag("via", "ParserStateMachine::illegal_parsed_expression"));
|
||||
|
||||
assert(expr_alloc_);
|
||||
|
||||
auto errmsg = DString::from_view(expr_alloc_,
|
||||
std::string_view(errmsg_string));
|
||||
|
||||
this->capture_error(ssm_name, errmsg);
|
||||
}
|
||||
|
||||
void
|
||||
ParserStateMachine::error_unbound_variable(std::string_view ssm_name,
|
||||
std::string_view sym)
|
||||
|
|
|
|||
|
|
@ -976,11 +976,34 @@ namespace xo {
|
|||
REQUIRE(result.is_incomplete());
|
||||
}
|
||||
|
||||
#ifdef NOPE
|
||||
{
|
||||
auto & result = parser.on_token(Token::star_token());
|
||||
|
||||
log && log("after star(*) 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::symbol_token("x"));
|
||||
|
||||
log && log("after symbol(x) 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::rightbrace_token());
|
||||
|
||||
log && log("after rightbrace token:");
|
||||
log && log("after rightbrace(}) token:");
|
||||
log && log(xtag("parser", &parser));
|
||||
log && log(xtag("result", result));
|
||||
|
||||
|
|
@ -990,11 +1013,6 @@ namespace xo {
|
|||
REQUIRE(result.result_expr());
|
||||
}
|
||||
|
||||
//REQUIRE(result.is_error());
|
||||
//// illegal input on token
|
||||
//REQUIRE(result.error_description());
|
||||
#endif
|
||||
REQUIRE(false);
|
||||
}
|
||||
} /*namespace ut*/
|
||||
} /*namespace xo*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue