Skip to content

Commit bb56325

Browse files
committed
Refactored FnArgsDef rules. Fixed issue #224.
1 parent 552c260 commit bb56325

5 files changed

Lines changed: 51 additions & 22 deletions

File tree

spec/inputs/syntax.yue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ invokeA(
392392
v = {
393393
a -1
394394
a(
395-
-1)
395+
-1)
396396
a \
397397
- 1
398398
a-1
@@ -405,7 +405,7 @@ v = {
405405

406406
a ~1
407407
a(
408-
~1)
408+
~1)
409409
a \
410410
~ 1
411411
a~1

spec/inputs/unicode/syntax.yue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ with 对象
376376
变量v = {
377377
变量a -1
378378
变量a(
379-
-1)
379+
-1)
380380
变量a \
381381
- 1
382382
变量a-1
@@ -389,7 +389,7 @@ with 对象
389389

390390
变量a ~1
391391
变量a(
392-
~1)
392+
~1)
393393
变量a \
394394
~ 1
395395
变量a~1

src/yuescript/yue_compiler.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -876,6 +876,10 @@ class YueCompilerImpl {
876876
return false;
877877
}
878878

879+
bool isListComp(Comprehension_t* comp) const {
880+
return comp->items.size() == 2 && ast_is<CompFor_t>(comp->items.back());
881+
}
882+
879883
void markVarLocalConst(const std::string& name) {
880884
auto& scope = _scopes.back();
881885
scope.vars->insert_or_assign(name, VarType::LocalConst);
@@ -1474,7 +1478,7 @@ class YueCompilerImpl {
14741478
if (simpleValue->value.is<TableLit_t>()) {
14751479
return true;
14761480
} else if (auto comp = simpleValue->value.as<Comprehension_t>()) {
1477-
if (comp->items.size() != 2 || !ast_is<CompFor_t>(comp->items.back())) {
1481+
if (!isListComp(comp)) {
14781482
return true;
14791483
}
14801484
}
@@ -1877,7 +1881,7 @@ class YueCompilerImpl {
18771881
case id<Try_t>(): transformTry(static_cast<Try_t*>(value), out, ExpUsage::Common); break;
18781882
case id<Comprehension_t>(): {
18791883
auto comp = static_cast<Comprehension_t*>(value);
1880-
if (comp->items.size() == 2 && ast_is<CompFor_t>(comp->items.back())) {
1884+
if (isListComp(comp)) {
18811885
transformCompCommon(comp, out);
18821886
} else {
18831887
specialSingleValue = false;
@@ -2468,7 +2472,7 @@ class YueCompilerImpl {
24682472
case id<Comprehension_t>(): {
24692473
auto comp = static_cast<Comprehension_t*>(value);
24702474
auto expList = assignment->expList.get();
2471-
if (comp->items.size() == 2 && ast_is<CompFor_t>(comp->items.back())) {
2475+
if (isListComp(comp)) {
24722476
std::string preDefine = getPreDefineLine(assignment);
24732477
transformComprehension(comp, out, ExpUsage::Assignment, expList);
24742478
out.back().insert(0, preDefine);
@@ -2893,7 +2897,7 @@ class YueCompilerImpl {
28932897
if (auto tbA = item->get_by_path<TableLit_t>()) {
28942898
tableItems = &tbA->values.objects();
28952899
} else if (auto tbB = item->get_by_path<Comprehension_t>()) {
2896-
if (tbB->items.size() == 2 && ast_is<CompFor_t>(tbB->items.back())) {
2900+
if (isListComp(tbB)) {
28972901
throw CompileError("invalid destructure value"sv, tbB);
28982902
}
28992903
tableItems = &tbB->items.objects();
@@ -2924,7 +2928,7 @@ class YueCompilerImpl {
29242928
}
29252929
case id<Comprehension_t>(): {
29262930
auto table = static_cast<Comprehension_t*>(node);
2927-
if (table->items.size() == 2 && ast_is<CompFor_t>(table->items.back())) {
2931+
if (isListComp(table)) {
29282932
throw CompileError("invalid destructure value"sv, table);
29292933
}
29302934
tableItems = &table->items.objects();
@@ -3295,7 +3299,7 @@ class YueCompilerImpl {
32953299
if (auto tab = sVal->value.as<TableLit_t>()) {
32963300
destructNode = tab;
32973301
} else if (auto comp = sVal->value.as<Comprehension_t>()) {
3298-
if (comp->items.size() != 2 || !ast_is<CompFor_t>(comp->items.back())) {
3302+
if (!isListComp(comp)) {
32993303
destructNode = comp;
33003304
}
33013305
}
@@ -7422,7 +7426,7 @@ class YueCompilerImpl {
74227426
}
74237427
}
74247428
} else if (auto comp = sval->value.as<Comprehension_t>()) {
7425-
if (comp->items.size() != 2 || !ast_is<CompFor_t>(comp->items.back())) {
7429+
if (!isListComp(comp)) {
74267430
discrete = inExp->new_ptr<ExpList_t>();
74277431
for (ast_node* val : comp->items.objects()) {
74287432
if (auto def = ast_cast<NormalDef_t>(val)) {
@@ -8285,7 +8289,7 @@ class YueCompilerImpl {
82858289

82868290
void transformComprehension(Comprehension_t* comp, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) {
82878291
auto x = comp;
8288-
if (comp->items.size() != 2 || !ast_is<CompFor_t>(comp->items.back())) {
8292+
if (!isListComp(comp)) {
82898293
switch (usage) {
82908294
case ExpUsage::Assignment: {
82918295
auto tableLit = x->new_ptr<TableLit_t>();

src/yuescript/yue_parser.cpp

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,15 @@ class ParserError : public std::logic_error {
5050
} \
5151
} while (false)
5252

53+
#define RaiseErrorI(msg, item) \
54+
do { \
55+
if (reinterpret_cast<State*>(item.user_data)->lax) { \
56+
return -1; \
57+
} else { \
58+
throw ParserError(msg, item.begin); \
59+
} \
60+
} while (false)
61+
5362
// clang-format off
5463
YueParser::YueParser() {
5564
plain_space = *set(" \t");
@@ -316,14 +325,14 @@ YueParser::YueParser() {
316325
for (input_it i = item.begin->m_it; i != item.end->m_it; ++i) {
317326
switch (*i) {
318327
case '\t': indent += 4; break;
319-
default: RaiseError("can not mix the use of tabs and spaces as indents"sv, item); break;
328+
default: RaiseErrorI("can not mix the use of tabs and spaces as indents"sv, item); break;
320329
}
321330
}
322331
} else {
323332
for (input_it i = item.begin->m_it; i != item.end->m_it; ++i) {
324333
switch (*i) {
325334
case ' ': indent++; break;
326-
default: RaiseError("can not mix the use of tabs and spaces as indents"sv, item); break;
335+
default: RaiseErrorI("can not mix the use of tabs and spaces as indents"sv, item); break;
327336
}
328337
}
329338
}
@@ -357,6 +366,12 @@ YueParser::YueParser() {
357366
}
358367
}
359368
State* st = reinterpret_cast<State*>(item.user_data);
369+
if (st->indents.empty()) {
370+
RaiseError("unknown indent level"sv, item);
371+
}
372+
if (st->indents.top() > indent) {
373+
RaiseError("unexpected dedent"sv, item);
374+
}
360375
st->indents.push(indent);
361376
return true;
362377
});
@@ -1014,16 +1029,24 @@ YueParser::YueParser() {
10141029

10151030
FnArgDef = (Variable | SelfItem >> -ExistentialOp) >> -(space >> '`' >> space >> Name) >> -(space >> '=' >> space >> Exp) | TableLit | SimpleTable;
10161031

1017-
check_vararg_position = and_(white >> ')') | white >> -(',' >> white) >> vararg_position_error;
1032+
check_vararg_position = and_(white >> (')' | key("using"))) | white >> -(',' >> white) >> vararg_position_error;
10181033

1019-
FnArgDefList = Seperator >> (
1020-
fn_arg_def_lit_lines >> -(-(space >> ',') >> white >> VarArg >> -(space >> '`' >> space >> Name) >> check_vararg_position) |
1021-
white >> VarArg >> -(space >> '`' >> space >> Name) >> check_vararg_position
1022-
);
1034+
var_arg_def = (
1035+
VarArg |
1036+
+space_break >> push_indent_match >> ensure(space >> VarArg >> -(space >> '`' >> space >> Name), pop_indent)
1037+
) >> check_vararg_position;
1038+
1039+
FnArgDefList = Seperator >>
1040+
-fn_arg_def_list >>
1041+
-(-(space >> ',') >> +space_break >> fn_arg_def_lit_lines) >>
1042+
-(-(space >> ',') >> space >> var_arg_def);
10231043

10241044
OuterVarShadow = key("using") >> space >> (key("nil") | NameList);
10251045

1026-
FnArgsDef = '(' >> *space_break >> -FnArgDefList >> -(white >> OuterVarShadow) >> white >> -(and_(',') >> unexpected_comma_error) >> ')';
1046+
outer_var_shadow_def = OuterVarShadow |
1047+
+space_break >> push_indent_match >> ensure(space >> OuterVarShadow, pop_indent);
1048+
1049+
FnArgsDef = '(' >> space >> -FnArgDefList >> -(space >> outer_var_shadow_def) >> white >> -(and_(',') >> unexpected_comma_error) >> ')';
10271050
FnArrow = expr("->") | "=>";
10281051
FunLit = pl::user(true_(), [](const item_t& item) {
10291052
State* st = reinterpret_cast<State*>(item.user_data);
@@ -1035,11 +1058,11 @@ YueParser::YueParser() {
10351058
) >> space >> FnArrow >> -(space >> Body);
10361059

10371060
MacroName = '$' >> UnicodeName;
1038-
macro_args_def = '(' >> white >> -FnArgDefList >> white >> -(and_(',') >> unexpected_comma_error) >> ')';
1061+
macro_args_def = '(' >> space >> -FnArgDefList >> white >> -(and_(',') >> unexpected_comma_error) >> ')';
10391062
MacroLit = -(macro_args_def >> space) >> "->" >> space >> Body;
10401063
MacroFunc = MacroName >> (Invoke | InvokeArgs);
10411064
Macro = key("macro") >> space >> (
1042-
UnicodeName >> space >> '=' >> space >> (MacroLit | MacroFunc | expected_expression_error) |
1065+
UnicodeName >> space >> '=' >> space >> (MacroLit | MacroFunc | invalid_macro_definition_error) |
10431066
invalid_macro_definition_error
10441067
);
10451068
MacroInPlace = '$' >> space >> "->" >> space >> Body;

src/yuescript/yue_parser.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,8 @@ class YueParser {
280280
NONE_AST_RULE(fn_arg_def_lit_lines);
281281
NONE_AST_RULE(destruct_def);
282282
NONE_AST_RULE(macro_args_def);
283+
NONE_AST_RULE(var_arg_def);
284+
NONE_AST_RULE(outer_var_shadow_def);
283285
NONE_AST_RULE(chain_call);
284286
NONE_AST_RULE(chain_call_list);
285287
NONE_AST_RULE(chain_index_chain);

0 commit comments

Comments
 (0)