From 2a3e50752ade96c3b5d6b1103937bef0f6b31157 Mon Sep 17 00:00:00 2001 From: Li Jin Date: Wed, 7 Jun 2023 09:42:50 +0800 Subject: add new syntax of in-expression. --- src/.clang-format | 39 +++++---- src/yuescript/ast.hpp | 3 +- src/yuescript/yue_ast.h | 138 ++++++++++++++++-------------- src/yuescript/yue_compiler.cpp | 188 ++++++++++++++++++++++++++++++++++++++--- src/yuescript/yue_parser.cpp | 21 +++-- src/yuescript/yue_parser.h | 10 ++- 6 files changed, 289 insertions(+), 110 deletions(-) (limited to 'src') diff --git a/src/.clang-format b/src/.clang-format index 5d305ae..6b3ad7b 100644 --- a/src/.clang-format +++ b/src/.clang-format @@ -1,17 +1,24 @@ -# Format Style Options - Created with Clang Power Tools ---- -BasedOnStyle: WebKit -AllowShortCaseLabelsOnASingleLine: true -AllowShortIfStatementsOnASingleLine: WithoutElse -AllowShortLoopsOnASingleLine: true -BreakBeforeBraces: Attach -Cpp11BracedListStyle: true -IndentCaseLabels: true -NamespaceIndentation: None -SpaceBeforeCpp11BracedList: false -TabWidth: 4 -AlignEscapedNewlines: DontAlign -AlwaysBreakBeforeMultilineStrings: true -FixNamespaceComments: true +# Format Style Options - Created with Clang Power Tools +--- +BasedOnStyle: WebKit +AllowShortCaseLabelsOnASingleLine: true +AllowShortIfStatementsOnASingleLine: WithoutElse +AllowShortLoopsOnASingleLine: true +BreakBeforeBraces: Attach +Cpp11BracedListStyle: true +IndentCaseLabels: true +NamespaceIndentation: None +SpaceBeforeCpp11BracedList: false +TabWidth: 4 +AlignEscapedNewlines: DontAlign +AlwaysBreakBeforeMultilineStrings: true +FixNamespaceComments: true UseTab: Always -... +AlignOperands: AlignAfterOperator +AllowShortLambdasOnASingleLine: Empty +LambdaBodyIndentation: Signature +AlignAfterOpenBracket: DontAlign +ContinuationIndentWidth: 4 +ObjCBlockIndentWidth: 4 +ConstructorInitializerIndentWidth: 4 +... diff --git a/src/yuescript/ast.hpp b/src/yuescript/ast.hpp index 3443c7f..c6da312 100644 --- a/src/yuescript/ast.hpp +++ b/src/yuescript/ast.hpp @@ -21,6 +21,8 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND namespace parserlib { +using namespace std::string_view_literals; + class ast_node; template class ast_ptr; @@ -50,7 +52,6 @@ struct Counter<0> { enum { value = Counter<__LINE__ - 1>::value + 1 }; \ } -class ast_node; template constexpr typename std::enable_if::value, int>::type id(); diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h index 65008fb..acb7221 100644 --- a/src/yuescript/yue_ast.h +++ b/src/yuescript/yue_ast.h @@ -11,16 +11,17 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include "yuescript/ast.hpp" namespace parserlib { -using namespace std::string_view_literals; #define AST_LEAF(type) \ COUNTER_INC; \ + namespace yue { \ class type##_t : public ast_node { \ public: \ virtual int getId() const override { return COUNTER_READ; } #define AST_NODE(type) \ COUNTER_INC; \ + namespace yue { \ class type##_t : public ast_container { \ public: \ virtual int getId() const override { return COUNTER_READ; } @@ -34,11 +35,49 @@ using namespace std::string_view_literals; virtual const std::string_view getName() const override { return name; } \ } \ ; \ + } \ template <> \ - constexpr int id() { return COUNTER_READ; } + constexpr int id() { return COUNTER_READ; } // clang-format off +namespace yue { +class ExpListLow_t; +class TableBlock_t; +class Attrib_t; +class SimpleTable_t; +class TableLit_t; +class Assign_t; +class Exp_t; +class VariablePair_t; +class NormalPair_t; +class MetaVariablePair_t; +class MetaNormalPair_t; +class FnArgsDef_t; +class ChainValue_t; +class ExistentialOp_t; +class Block_t; +class Statement_t; +class Body_t; +class AssignableNameList_t; +class StarExp_t; +class CompInner_t; +class AssignableChain_t; +class UnaryExp_t; +class Parens_t; +class MacroName_t; +class String_t; +class ConstValue_t; +class ClassDecl_t; +class UnaryValue_t; +class FunLit_t; +class DefaultValue_t; +class InvokeArgs_t; +class TableBlockIndent_t; +class Macro_t; +class In_t; +} // namespace yue + AST_LEAF(Num) AST_END(Num, "num"sv) @@ -101,10 +140,6 @@ AST_NODE(NameList) AST_MEMBER(NameList, &sep, &names) AST_END(NameList, "name_list"sv) -class ExpListLow_t; -class TableBlock_t; -class Attrib_t; - AST_NODE(LocalValues) ast_ptr nameList; ast_sel valueList; @@ -126,10 +161,6 @@ AST_END(ConstAttrib, "const"sv) AST_LEAF(CloseAttrib) AST_END(CloseAttrib, "close"sv) -class SimpleTable_t; -class TableLit_t; -class Assign_t; - AST_NODE(LocalAttrib) ast_sel attrib; ast_ptr sep; @@ -152,8 +183,6 @@ AST_NODE(ImportLiteral) AST_MEMBER(ImportLiteral, &sep, &inners) AST_END(ImportLiteral, "import_literal"sv) -class Exp_t; - AST_NODE(ImportFrom) ast_ptr sep; ast_sel_list names; @@ -161,8 +190,6 @@ AST_NODE(ImportFrom) AST_MEMBER(ImportFrom, &sep, &names, &exp) AST_END(ImportFrom, "import_from"sv) -class MacroName_t; - AST_NODE(MacroNamePair) ast_ptr key; ast_ptr value; @@ -172,11 +199,6 @@ AST_END(MacroNamePair, "macro_name_pair"sv) AST_LEAF(ImportAllMacro) AST_END(ImportAllMacro, "import_all_macro"sv) -class VariablePair_t; -class NormalPair_t; -class MetaVariablePair_t; -class MetaNormalPair_t; - AST_NODE(ImportTabLit) ast_ptr sep; ast_sel_list items; @@ -209,13 +231,9 @@ AST_NODE(ShortTabAppending) AST_MEMBER(ShortTabAppending, &assign) AST_END(ShortTabAppending, "short_table_appending"sv) -class FnArgsDef_t; - AST_LEAF(FnArrowBack) AST_END(FnArrowBack, "fn_arrow_back"sv) -class ChainValue_t; - AST_NODE(Backcall) ast_ptr argsDef; ast_ptr arrow; @@ -235,19 +253,12 @@ AST_NODE(ExpList) AST_MEMBER(ExpList, &sep, &exprs) AST_END(ExpList, "exp_list"sv) -class TableBlock_t; - AST_NODE(Return) bool allowBlockMacroReturn = false; ast_sel valueList; AST_MEMBER(Return, &valueList) AST_END(Return, "return"sv) -class ExistentialOp_t; -class Assign_t; -class Block_t; -class Statement_t; - AST_NODE(With) ast_ptr eop; ast_ptr valueList; @@ -263,9 +274,9 @@ AST_NODE(SwitchList) AST_END(SwitchList, "switch_list"sv) AST_NODE(SwitchCase) - ast_ptr valueList; + ast_sel condition; ast_sel body; - AST_MEMBER(SwitchCase, &valueList, &body) + AST_MEMBER(SwitchCase, &condition, &body) AST_END(SwitchCase, "switch_case"sv) AST_NODE(Switch) @@ -306,8 +317,6 @@ AST_NODE(While) AST_MEMBER(While, &type, &condition, &body) AST_END(While, "while"sv) -class Body_t; - AST_NODE(Repeat) ast_ptr body; ast_ptr condition; @@ -328,9 +337,6 @@ AST_NODE(For) AST_MEMBER(For, &varName, &startValue, &stopValue, &stepValue, &body) AST_END(For, "for"sv) -class AssignableNameList_t; -class StarExp_t; - AST_NODE(ForEach) ast_ptr nameList; ast_sel loopValue; @@ -355,8 +361,6 @@ AST_NODE(Try) AST_MEMBER(Try, &func, &catchBlock) AST_END(Try, "try"sv) -class CompInner_t; - AST_NODE(Comprehension) ast_sel value; ast_ptr forLoop; @@ -400,8 +404,6 @@ AST_NODE(CompInner) AST_MEMBER(CompInner, &sep, &items) AST_END(CompInner, "comp_inner"sv) -class TableBlock_t; - AST_NODE(Assign) ast_ptr sep; ast_sel_list values; @@ -423,15 +425,40 @@ AST_END(BinaryOperator, "binary_op"sv) AST_LEAF(UnaryOperator) AST_END(UnaryOperator, "unary_op"sv) -class AssignableChain_t; +AST_LEAF(InRangeOpen) +AST_END(InRangeOpen, "in_range_open"sv) + +AST_LEAF(InRangeClose) +AST_END(InRangeClose, "in_range_close"sv) + +AST_LEAF(NotIn) +AST_END(NotIn, "not_in"sv) + +AST_NODE(InRange) + ast_sel open; + ast_ptr openValue; + ast_ptr closeValue; + ast_sel close; + AST_MEMBER(InRange, &open, &openValue, &closeValue, &close) +AST_END(InRange, "in_range"sv) + +AST_NODE(InDiscrete) + ast_ptr sep; + ast_list values; + AST_MEMBER(InDiscrete, &sep, &values) +AST_END(InDiscrete, "in_discrete"sv) + +AST_NODE(In) + ast_ptr not_; + ast_sel item; + AST_MEMBER(In, ¬_, &item) +AST_END(In, "in"sv) AST_NODE(Assignable) ast_sel item; AST_MEMBER(Assignable, &item) AST_END(Assignable, "assignable"sv) -class UnaryExp_t; - AST_NODE(ExpOpValue) ast_ptr op; ast_list pipeExprs; @@ -446,9 +473,6 @@ AST_NODE(Exp) AST_MEMBER(Exp, &sep, &pipeExprs, &opValues, &nilCoalesed) AST_END(Exp, "exp"sv) -class Parens_t; -class MacroName_t; - AST_NODE(Callable) ast_sel item; AST_MEMBER(Callable, &item) @@ -465,8 +489,6 @@ AST_NODE(VariablePairDef) AST_MEMBER(VariablePairDef, &pair, &defVal) AST_END(VariablePairDef, "variable_pair_def"sv) -class String_t; - AST_NODE(NormalPair) ast_sel key; ast_sel value; @@ -515,11 +537,6 @@ AST_NODE(SimpleTable) AST_MEMBER(SimpleTable, &sep, &pairs) AST_END(SimpleTable, "simple_table"sv) -class ConstValue_t; -class ClassDecl_t; -class UnaryValue_t; -class FunLit_t; - AST_NODE(SimpleValue) ast_sel startValue; ast_sel stopValue; @@ -614,8 +629,6 @@ AST_END(ExistentialOp, "existential_op"sv) AST_LEAF(TableAppendingOp) AST_END(TableAppendingOp, "table_appending_op"sv) -class InvokeArgs_t; - AST_NODE(ChainValue) ast_ptr sep; ast_sel_list items; @@ -641,8 +654,6 @@ AST_NODE(SpreadExp) AST_MEMBER(SpreadExp, &exp) AST_END(SpreadExp, "spread_exp"sv) -class TableBlockIndent_t; - AST_NODE(TableLit) ast_ptr sep; ast_sel_list def; ast_sel target; @@ -799,7 +808,8 @@ AST_END(UnaryValue, "unary_value"sv) AST_NODE(UnaryExp) ast_list ops; ast_list expos; - AST_MEMBER(UnaryExp, &ops, &expos) + ast_ptr inExp; + AST_MEMBER(UnaryExp, &ops, &expos, &inExp) AST_END(UnaryExp, "unary_exp"sv) AST_NODE(ExpListAssign) @@ -869,8 +879,6 @@ AST_NODE(Statement) AST_MEMBER(Statement, &sep, &comments, &content, &appendix, &needSep) AST_END(Statement, "statement"sv) -class Block_t; - AST_NODE(Body) ast_sel content; AST_MEMBER(Body, &content) diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index e0ff9e9..98d19a7 100644 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp @@ -72,7 +72,7 @@ static std::unordered_set Metamethods = { "close"s // Lua 5.4 }; -const std::string_view version = "0.16.8"sv; +const std::string_view version = "0.17.0"sv; const std::string_view extension = "yue"sv; class CompileError : public std::logic_error { @@ -761,7 +761,7 @@ private: } case id(): { auto unary = static_cast(item); - if (unary->expos.size() == 1) { + if (unary->expos.size() == 1 && !unary->inExp) { return unary; } return nullptr; @@ -774,7 +774,7 @@ private: BREAK_IF(!exp->opValues.empty()); BREAK_IF(exp->pipeExprs.size() != 1); auto unary = static_cast(exp->pipeExprs.back()); - BREAK_IF(unary->expos.size() != 1); + BREAK_IF(unary->expos.size() != 1 || unary->inExp); return unary; BLOCK_END return nullptr; @@ -1028,9 +1028,12 @@ private: } std::string singleVariableFrom(ast_node* expList, bool accessing) { - if (!ast_is(expList)) return Empty; + if (!ast_is(expList)) return Empty; BLOCK_START - auto value = singleValueFrom(expList); + auto value = ast_cast(expList); + if (!value) { + value = singleValueFrom(expList); + } BREAK_IF(!value); auto chainValue = value->item.as(); BREAK_IF(!chainValue); @@ -1157,6 +1160,24 @@ private: return false; } + UnaryExp_t* unaryGeneratingAnonFunc(Exp_t* exp) { + if (!exp) return nullptr; + BLOCK_START + BREAK_IF(exp->nilCoalesed); + BREAK_IF(!exp->opValues.empty()); + BREAK_IF(exp->pipeExprs.size() != 1); + auto unary = static_cast(exp->pipeExprs.back()); + BREAK_IF(unary->expos.size() != 1); + BREAK_IF(!unary->inExp); + auto value = static_cast(unary->expos.back()); + auto varName = singleVariableFrom(value, false); + if (varName.empty() || !isLocal(varName)) { + return unary; + } + BLOCK_END + return nullptr; + } + void pushFunctionScope() { _enableReturn.push(true); _enableBreakLoop.push(false); @@ -1971,6 +1992,12 @@ private: auto expList = assignment->expList.get(); transformNilCoalesedExp(exp, out, ExpUsage::Assignment, expList); return; + } else if (auto unary = unaryGeneratingAnonFunc(exp)) { + std::string preDefine = getPreDefineLine(assignment); + auto expList = assignment->expList.get(); + transformUnaryExp(unary, out, ExpUsage::Assignment, expList); + out.back().insert(0, preDefine); + return; } auto singleVal = singleValueFrom(exp); BREAK_IF(!singleVal); @@ -3134,7 +3161,7 @@ private: void transform_pipe_exp(const node_container& values, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { if (values.size() == 1 && usage == ExpUsage::Closure) { - transform_unary_exp(static_cast(values.front()), out); + transformUnaryExp(static_cast(values.front()), out, ExpUsage::Closure); } else { auto x = values.front(); auto arg = newExp(static_cast(x), x); @@ -3404,7 +3431,7 @@ private: void transformSimpleValue(SimpleValue_t* simpleValue, str_list& out) { auto value = simpleValue->value.get(); switch (value->getId()) { - case id(): transform_const_value(static_cast(value), out); break; + case id(): transformConstValue(static_cast(value), out); break; case id(): transformIf(static_cast(value), out, ExpUsage::Closure); break; case id(): transformSwitch(static_cast(value), out, ExpUsage::Closure); break; case id(): transformWithClosure(static_cast(value), out); break; @@ -3414,7 +3441,7 @@ private: case id(): transformWhileClosure(static_cast(value), out); break; case id(): transformDo(static_cast(value), out, ExpUsage::Closure); break; case id(): transformTry(static_cast(value), out, ExpUsage::Closure); break; - case id(): transform_unary_value(static_cast(value), out); break; + case id(): transformUnaryValue(static_cast(value), out); break; case id(): transformTblComprehension(static_cast(value), out, ExpUsage::Closure); break; case id(): transformTableLit(static_cast(value), out); break; case id(): transformComprehension(static_cast(value), out, ExpUsage::Closure); break; @@ -4050,6 +4077,9 @@ private: } else if (isPureNilCoalesed(exp)) { transformNilCoalesedExp(exp, out, ExpUsage::Return); return; + } else if (auto unary = unaryGeneratingAnonFunc(exp)) { + transformUnaryExp(unary, out, ExpUsage::Return); + return; } } if (auto singleValue = singleValueFrom(valueList)) { @@ -5363,7 +5393,7 @@ private: out.push_back('(' + join(temp, ", "sv) + ')'); } - void transform_unary_value(UnaryValue_t* unary_value, str_list& out) { + void transformUnaryValue(UnaryValue_t* unary_value, str_list& out) { str_list temp; for (auto _op : unary_value->ops.objects()) { std::string op = _parser.toString(_op); @@ -5376,7 +5406,124 @@ private: out.push_back(join(temp)); } - void transform_unary_exp(UnaryExp_t* unary_exp, str_list& out) { + void transformUnaryExp(UnaryExp_t* unary_exp, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { + auto x = unary_exp; + if (unary_exp->inExp) { + std::string varName; + if (unary_exp->ops.empty() && unary_exp->expos.size() == 1) { + auto value = static_cast(unary_exp->expos.back()); + varName = singleVariableFrom(value, false); + if (!isLocal(varName)) { + varName.clear(); + } + } + if (varName.empty()) { + str_list temp; + if (usage == ExpUsage::Closure) { + pushFunctionScope(); + pushAnonVarArg(); + pushScope(); + } else if (usage == ExpUsage::Assignment) { + temp.push_back(indent() + "do"s + nll(x)); + pushScope(); + } + auto newUnaryExp = x->new_ptr(); + newUnaryExp->ops.dup(unary_exp->ops); + newUnaryExp->expos.dup(unary_exp->expos); + auto exp = newExp(newUnaryExp, x); + auto newVar = getUnusedName("_val_"sv); + auto assignExp = toAst(newVar, x); + auto assignment = assignmentFrom(assignExp, exp, x); + transformAssignment(assignment, temp); + if (auto range = unary_exp->inExp->item.as()) { + str_list tmp; + transformExp(range->openValue, tmp, ExpUsage::Closure); + transformExp(range->closeValue, tmp, ExpUsage::Closure); + if (usage == ExpUsage::Assignment) { + str_list tmpList; + transformExp(static_cast(assignList->exprs.front()), tmpList, ExpUsage::Closure); + _buf << indent() << tmpList.back() << " = "sv; + } else { + _buf << indent() << "return "sv; + } + if (unary_exp->inExp->not_) { + _buf << "not ("sv; + } + _buf << tmp.front() << (range->open.is() ? " < "sv : " <= "sv) << newVar << " and "sv << newVar << (range->close.is() ? " < "sv : " <= "sv) << tmp.back(); + if (unary_exp->inExp->not_) { + _buf << ")"sv; + } + _buf << nll(x); + temp.push_back(clearBuf()); + } else { + auto discrete = unary_exp->inExp->item.to(); + str_list tmp; + for (auto exp : discrete->values.objects()) { + transformExp(static_cast(exp), tmp, ExpUsage::Closure); + } + _buf << indent() << "return "sv; + if (unary_exp->inExp->not_) { + _buf << "not ("sv; + } + for (const auto& exp : tmp) { + _buf << exp << " == "sv << newVar; + if (exp != tmp.back()) { + _buf << " or "sv; + } + } + if (unary_exp->inExp->not_) { + _buf << ")"sv; + } + _buf << nll(x); + temp.push_back(clearBuf()); + } + if (usage == ExpUsage::Closure) { + temp.push_front(anonFuncStart() + nll(x)); + popScope(); + temp.push_back(indent() + anonFuncEnd()); + out.push_back(join(temp)); + popAnonVarArg(); + popFunctionScope(); + } else if (usage == ExpUsage::Assignment) { + popScope(); + temp.push_back(indent() + "end"s + nll(x)); + out.push_back(join(temp)); + } else { + out.push_back(join(temp)); + } + } else { + if (auto range = unary_exp->inExp->item.as()) { + str_list tmp; + transformExp(range->openValue, tmp, ExpUsage::Closure); + transformExp(range->closeValue, tmp, ExpUsage::Closure); + if (unary_exp->inExp->not_) { + _buf << "not "sv; + } + _buf << '(' << tmp.front() << (range->open.is() ? " < "sv : " <= "sv) << varName << " and "sv << varName << (range->close.is() ? " < "sv : " <= "sv) << tmp.back(); + _buf << ')'; + out.push_back(clearBuf()); + } else { + auto discrete = unary_exp->inExp->item.to(); + str_list tmp; + for (auto exp : discrete->values.objects()) { + transformExp(static_cast(exp), tmp, ExpUsage::Closure); + } + if (unary_exp->inExp->not_) { + _buf << "not "sv; + } + _buf << '('; + for (const auto& exp : tmp) { + _buf << exp << " == "sv << varName; + if (exp != tmp.back()) { + _buf << " or "sv; + } + } + _buf << ')'; + out.push_back(clearBuf()); + } + } + return; + } if (unary_exp->ops.empty() && unary_exp->expos.size() == 1) { transformValue(static_cast(unary_exp->expos.back()), out); return; @@ -7322,7 +7469,7 @@ private: out.push_back(join(temp)); } - void transform_const_value(ConstValue_t* const_value, str_list& out) { + void transformConstValue(ConstValue_t* const_value, str_list& out) { out.push_back(_parser.toString(const_value)); } @@ -8216,7 +8363,20 @@ private: std::string tabCheckVar; for (auto branch_ : branches) { auto branch = static_cast(branch_); - if (auto value = singleValueFrom(branch->valueList); + if (auto inExp = branch->condition.as()) { + auto unary = branch->new_ptr(); + unary->expos.push_back(toAst(objVar, branch)); + unary->inExp.set(inExp); + transformUnaryExp(unary, temp, ExpUsage::Closure); + temp.back() = indent() + (firstBranch ? "if "s : "elseif "s) + temp.back() + " then"s + nll(branch); + pushScope(); + transform_plain_body(branch->body, temp, usage, assignList); + popScope(); + firstBranch = false; + continue; + } + auto valueList = branch->condition.to(); + if (auto value = singleValueFrom(valueList); value && (value->item.is() || value->getByPath())) { if (!firstBranch) { temp.push_back(indent() + "else"s + nll(branch)); @@ -8245,7 +8405,7 @@ private: } temp.back().append(indent() + "if "s + tabCheckVar + " then"s + nll(branch)); pushScope(); - auto assignment = assignmentFrom(static_cast(branch->valueList->exprs.front()), toAst(objVar, branch), branch); + auto assignment = assignmentFrom(static_cast(valueList->exprs.front()), toAst(objVar, branch), branch); auto info = extractDestructureInfo(assignment, true, false); transformAssignment(assignment, temp, true); str_list conds; @@ -8283,7 +8443,7 @@ private: temp.push_back(indent() + (firstBranch ? "if"s : "elseif"s)); firstBranch = false; str_list tmp; - const auto& exprs = branch->valueList->exprs.objects(); + const auto& exprs = valueList->exprs.objects(); for (auto exp_ : exprs) { auto exp = static_cast(exp_); transformExp(exp, tmp, ExpUsage::Closure); diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index dffdbe1..f383275 100644 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp @@ -317,7 +317,7 @@ YueParser::YueParser() { with_exp = ExpList >> -(space >> Assign); With = key("with") >> -ExistentialOp >> space >> disable_do_chain_arg_table_block_rule(with_exp) >> space >> body_with("do"); - SwitchCase = key("when") >> disable_chain_rule(disable_arg_table_block_rule(SwitchList)) >> space >> body_with("then"); + SwitchCase = key("when") >> (disable_chain_rule(disable_arg_table_block_rule(SwitchList)) | space >> In) >> space >> body_with("then"); switch_else = key("else") >> space >> body; switch_block = @@ -454,12 +454,19 @@ YueParser::YueParser() { expo_value = exponential_operator >> *space_break >> space >> Value; expo_exp = Value >> *(space >> expo_value); + InRangeOpen = true_(); + InRangeClose = true_(); + NotIn = true_(); + InRange = ('(' >> InRangeOpen | '[' >> InRangeClose) >> space >> Exp >> space >> ',' >> space >> Exp >> space >> (')' >> InRangeOpen | ']' >> InRangeClose); + InDiscrete = '{' >> Seperator >> space >> Exp >> *(space >> ',' >> space >> Exp) >> space >> '}'; + In = -(key("not") >> NotIn >> space) >> key("in") >> space >> (InRange | InDiscrete); + UnaryOperator = '-' >> not_(set(">=") | space_one) | '#' | '~' >> not_('=' | space_one) | key("not"); - UnaryExp = *(UnaryOperator >> space) >> expo_exp; + UnaryExp = *(UnaryOperator >> space) >> expo_exp >> -(space >> In); pipe_operator = "|>"; pipe_value = pipe_operator >> *space_break >> space >> UnaryExp; @@ -916,7 +923,7 @@ ParseInfo YueParser::parse(std::string_view codes, rule& r) { error_list errors; try { State state; - res.node.set(pl::parse(*(res.codes), r, errors, &state)); + res.node.set(::yue::parse(*(res.codes), r, errors, &state)); if (state.exportCount > 0) { res.moduleName = std::move(state.moduleName); res.exportDefault = state.exportDefault; @@ -952,14 +959,6 @@ std::string YueParser::toString(input::iterator begin, input::iterator end) { return _converter.to_bytes(std::wstring(begin, end)); } -input YueParser::encode(std::string_view codes) { - return _converter.from_bytes(&codes.front(), &codes.back() + 1); -} - -std::string YueParser::decode(const input& codes) { - return _converter.to_bytes(codes); -} - namespace Utils { void replace(std::string& str, std::string_view from, std::string_view to) { size_t start_pos = 0; diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h index 3be50a7..d4f66eb 100644 --- a/src/yuescript/yue_parser.h +++ b/src/yuescript/yue_parser.h @@ -25,6 +25,7 @@ namespace yue { using namespace std::string_view_literals; using namespace std::string_literals; using namespace parserlib; +using namespace parserlib::yue; struct ParseInfo { struct Error { @@ -86,9 +87,6 @@ public: std::string toString(ast_node* node); std::string toString(input::iterator begin, input::iterator end); - input encode(std::string_view input); - std::string decode(const input& input); - protected: ParseInfo parse(std::string_view codes, rule& r); @@ -378,6 +376,12 @@ private: AST_RULE(ConstValue) AST_RULE(UnaryValue) AST_RULE(UnaryExp) + AST_RULE(InRangeOpen) + AST_RULE(InRangeClose) + AST_RULE(NotIn) + AST_RULE(InRange) + AST_RULE(InDiscrete) + AST_RULE(In) AST_RULE(ExpListAssign) AST_RULE(IfLine) AST_RULE(WhileLine) -- cgit v1.2.3-55-g6feb