mirror of
https://github.com/yhirose/cpp-peglib.git
synced 2025-01-23 05:35:29 +00:00
Interpolated string support.
This commit is contained in:
parent
8d2aeabb32
commit
456ce928ea
@ -20,6 +20,7 @@ struct Eval
|
|||||||
case Identifier: return eval_identifier(ast, env);
|
case Identifier: return eval_identifier(ast, env);
|
||||||
case Number: return eval_number(ast, env);
|
case Number: return eval_number(ast, env);
|
||||||
case Boolean: return eval_bool(ast, env);
|
case Boolean: return eval_bool(ast, env);
|
||||||
|
case InterpolatedString: return eval_interpolated_string(ast, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ast.is_token) {
|
if (ast.is_token) {
|
||||||
@ -174,6 +175,15 @@ private:
|
|||||||
return Value(ast.token == "true");
|
return Value(ast.token == "true");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static Value eval_interpolated_string(const Ast& ast, Env& env) {
|
||||||
|
string s;
|
||||||
|
for (auto node: ast.nodes) {
|
||||||
|
const auto& val = eval(*node, env);
|
||||||
|
s += val.str();
|
||||||
|
}
|
||||||
|
return Value(s);
|
||||||
|
};
|
||||||
|
|
||||||
static Value dereference_identirier(Env& env, const string& var) {
|
static Value dereference_identirier(Env& env, const string& var) {
|
||||||
if (!env.has(var)) {
|
if (!env.has(var)) {
|
||||||
string msg = "undefined variable '" + var + "'...";
|
string msg = "undefined variable '" + var + "'...";
|
||||||
|
@ -61,6 +61,19 @@ struct Value
|
|||||||
throw std::runtime_error("type error.");
|
throw std::runtime_error("type error.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string str() const {
|
||||||
|
switch (type) {
|
||||||
|
case Undefined: return "undefined";
|
||||||
|
case Bool: return to_bool() ? "true" : "false";
|
||||||
|
case Long: return std::to_string(to_long()); break;
|
||||||
|
case String: return to_string();
|
||||||
|
//case Function: return "[function]";
|
||||||
|
//case Array: return "[array]";
|
||||||
|
default: throw std::logic_error("invalid internal condition.");
|
||||||
|
}
|
||||||
|
// NOTREACHED
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream& out(std::ostream& os) const {
|
std::ostream& out(std::ostream& os) const {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Undefined: os << "undefined"; break;
|
case Undefined: os << "undefined"; break;
|
||||||
@ -181,7 +194,7 @@ struct Env
|
|||||||
auto func_pretty_print = Value::FunctionValue {
|
auto func_pretty_print = Value::FunctionValue {
|
||||||
{ "arg" },
|
{ "arg" },
|
||||||
[](Env& env) {
|
[](Env& env) {
|
||||||
std::cout << env.get("arg") << std::endl;
|
std::cout << env.get("arg").str() << std::endl;
|
||||||
return Value();
|
return Value();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -20,7 +20,7 @@ static auto g_grammar = R"(
|
|||||||
PRIMARY <- CONDITION (CONDITION_OPERATOR CONDITION)?
|
PRIMARY <- CONDITION (CONDITION_OPERATOR CONDITION)?
|
||||||
CONDITION <- TERM (TERM_OPERATOR TERM)*
|
CONDITION <- TERM (TERM_OPERATOR TERM)*
|
||||||
TERM <- FACTOR (FACTOR_OPERATOR FACTOR)*
|
TERM <- FACTOR (FACTOR_OPERATOR FACTOR)*
|
||||||
FACTOR <- WHILE / IF / FUNCTION / FUNCTION_CALL / NUMBER / BOOLEAN / STRING / IDENTIFIER / '(' _ EXPRESSION ')' _
|
FACTOR <- WHILE / IF / FUNCTION / FUNCTION_CALL / NUMBER / BOOLEAN / STRING / INTERPOLATED_STRING / IDENTIFIER / '(' _ EXPRESSION ')' _
|
||||||
|
|
||||||
BLOCK <- '{' _ STATEMENTS '}' _
|
BLOCK <- '{' _ STATEMENTS '}' _
|
||||||
|
|
||||||
@ -33,6 +33,9 @@ static auto g_grammar = R"(
|
|||||||
BOOLEAN <- < ('true' / 'false') > _
|
BOOLEAN <- < ('true' / 'false') > _
|
||||||
STRING <- ['] < (!['] .)* > ['] _
|
STRING <- ['] < (!['] .)* > ['] _
|
||||||
|
|
||||||
|
INTERPOLATED_STRING <- '"' ('{' _ EXPRESSION '}' / INTERPOLATED_CONTENT)* '"' _
|
||||||
|
INTERPOLATED_CONTENT <- (!["{] .) (!["{] .)*
|
||||||
|
|
||||||
~_ <- (Space / EndOfLine / Comment)*
|
~_ <- (Space / EndOfLine / Comment)*
|
||||||
Space <- ' ' / '\t'
|
Space <- ' ' / '\t'
|
||||||
EndOfLine <- '\r\n' / '\n' / '\r'
|
EndOfLine <- '\r\n' / '\n' / '\r'
|
||||||
@ -76,6 +79,8 @@ peglib::peg& get_parser()
|
|||||||
.ast_token("BOOLEAN", Boolean)
|
.ast_token("BOOLEAN", Boolean)
|
||||||
.ast_token("STRING")
|
.ast_token("STRING")
|
||||||
.ast_token("IDENTIFIER", Identifier)
|
.ast_token("IDENTIFIER", Identifier)
|
||||||
|
.ast_node("INTERPOLATED_STRING", InterpolatedString)
|
||||||
|
.ast_token("INTERPOLATED_CONTENT")
|
||||||
.ast_end();
|
.ast_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,8 @@
|
|||||||
enum AstType
|
enum AstType
|
||||||
{
|
{
|
||||||
Statements, While, If, FunctionCall, Assignment, Condition, BinExpresion,
|
Statements, While, If, FunctionCall, Assignment, Condition, BinExpresion,
|
||||||
Identifier, Number, Boolean, Function
|
Identifier, InterpolatedString,
|
||||||
|
Number, Boolean, Function
|
||||||
};
|
};
|
||||||
|
|
||||||
peglib::peg& get_parser();
|
peglib::peg& get_parser();
|
||||||
|
Loading…
Reference in New Issue
Block a user