fix(preprocessor): expression eval & blocks (#190)

This commit is contained in:
Xenxo Espasandín 2024-02-09 16:52:04 +01:00 committed by GitHub
parent 0e6238a6ab
commit b8d2c84ae0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 58 additions and 28 deletions

View File

@ -14,6 +14,7 @@ struct directive
kind type; kind type;
bool skip; bool skip;
bool exec;
}; };
} // namespace xsk::arc } // namespace xsk::arc

View File

@ -14,6 +14,7 @@ struct directive
kind type; kind type;
bool skip; bool skip;
bool exec;
}; };
} // namespace xsk::gsc } // namespace xsk::gsc

View File

@ -258,7 +258,7 @@ auto preprocessor::read_directive(token& tok) -> void
auto preprocessor::read_directive_if(token&) -> void auto preprocessor::read_directive_if(token&) -> void
{ {
auto skip = !evaluate(); auto skip = !evaluate();
indents_.push({ directive::IF, skip }); indents_.push({ directive::IF, skip, !skip });
skip_ += skip ? 1 : 0; skip_ += skip ? 1 : 0;
} }
@ -283,7 +283,7 @@ auto preprocessor::read_directive_ifdef(token&) -> void
skip = !defines_.contains(name); skip = !defines_.contains(name);
} }
indents_.push({ directive::IFDEF, skip }); indents_.push({ directive::IFDEF, skip, !skip });
skip_ += skip ? 1 : 0; skip_ += skip ? 1 : 0;
} }
@ -308,7 +308,7 @@ auto preprocessor::read_directive_ifndef(token&) -> void
skip = defines_.contains(name); skip = defines_.contains(name);
} }
indents_.push({ directive::IFNDEF, skip }); indents_.push({ directive::IFNDEF, skip, !skip });
skip_ += skip ? 1 : 0; skip_ += skip ? 1 : 0;
} }
@ -328,8 +328,8 @@ auto preprocessor::read_directive_elif(token& tok) -> void
throw ppr_error(tok.pos, "#elif after #else"); throw ppr_error(tok.pos, "#elif after #else");
} }
auto skip = !evaluate(); auto skip = !evaluate() || dir.exec;
indents_.push({ directive::ELIF, skip }); indents_.push({ directive::ELIF, skip, !skip || dir.exec });
skip_ += skip ? 1 : 0; skip_ += skip ? 1 : 0;
} }
@ -365,10 +365,10 @@ auto preprocessor::read_directive_elifdef(token& tok) -> void
next = read_token(); next = read_token();
expect(next, token::NEWLINE); expect(next, token::NEWLINE);
skip = !defines_.contains(name); skip = !defines_.contains(name) || dir.exec;
} }
indents_.push({ directive::ELIFDEF, skip }); indents_.push({ directive::ELIFDEF, skip, !skip || dir.exec });
skip_ += skip ? 1 : 0; skip_ += skip ? 1 : 0;
} }
@ -404,10 +404,10 @@ auto preprocessor::read_directive_elifndef(token& tok) -> void
next = read_token(); next = read_token();
expect(next, token::NEWLINE); expect(next, token::NEWLINE);
skip = defines_.contains(name); skip = defines_.contains(name) || dir.exec;
} }
indents_.push({ directive::ELIFNDEF, skip }); indents_.push({ directive::ELIFNDEF, skip, !skip || dir.exec });
skip_ += skip ? 1 : 0; skip_ += skip ? 1 : 0;
} }
@ -430,8 +430,8 @@ auto preprocessor::read_directive_else(token& tok) -> void
throw ppr_error(tok.pos, "#else after #else"); throw ppr_error(tok.pos, "#else after #else");
} }
auto skip = !dir.skip; auto skip = dir.exec;
indents_.push({ directive::ELSE, skip }); indents_.push({ directive::ELSE, skip, dir.exec });
skip_ += skip ? 1 : 0; skip_ += skip ? 1 : 0;
} }
@ -987,7 +987,21 @@ auto preprocessor::evaluate() -> bool
} }
else if (tok.type == token::NAME) else if (tok.type == token::NAME)
{ {
if (tok.data == "defined") if (tok.data == "true")
{
last_def = false;
last_paren = false;
tok.type = token::TRUE;
expr_.push_back(std::move(tok));
}
else if (tok.data == "false")
{
last_def = false;
last_paren = false;
tok.type = token::FALSE;
expr_.push_back(std::move(tok));
}
else if (tok.data == "defined")
{ {
last_def = true; last_def = true;
tok.type = token::DEFINED; tok.type = token::DEFINED;

View File

@ -258,7 +258,7 @@ auto preprocessor::read_directive(token& tok) -> void
auto preprocessor::read_directive_if(token&) -> void auto preprocessor::read_directive_if(token&) -> void
{ {
auto skip = !evaluate(); auto skip = !evaluate();
indents_.push({ directive::IF, skip }); indents_.push({ directive::IF, skip, !skip });
skip_ += skip ? 1 : 0; skip_ += skip ? 1 : 0;
} }
@ -283,7 +283,7 @@ auto preprocessor::read_directive_ifdef(token&) -> void
skip = !defines_.contains(name); skip = !defines_.contains(name);
} }
indents_.push({ directive::IFDEF, skip }); indents_.push({ directive::IFDEF, skip, !skip });
skip_ += skip ? 1 : 0; skip_ += skip ? 1 : 0;
} }
@ -308,7 +308,7 @@ auto preprocessor::read_directive_ifndef(token&) -> void
skip = defines_.contains(name); skip = defines_.contains(name);
} }
indents_.push({ directive::IFNDEF, skip }); indents_.push({ directive::IFNDEF, skip, !skip });
skip_ += skip ? 1 : 0; skip_ += skip ? 1 : 0;
} }
@ -328,8 +328,8 @@ auto preprocessor::read_directive_elif(token& tok) -> void
throw ppr_error(tok.pos, "#elif after #else"); throw ppr_error(tok.pos, "#elif after #else");
} }
auto skip = !evaluate(); auto skip = !evaluate() || dir.exec;
indents_.push({ directive::ELIF, skip }); indents_.push({ directive::ELIF, skip, !skip || dir.exec });
skip_ += skip ? 1 : 0; skip_ += skip ? 1 : 0;
} }
@ -365,10 +365,10 @@ auto preprocessor::read_directive_elifdef(token& tok) -> void
next = read_token(); next = read_token();
expect(next, token::NEWLINE); expect(next, token::NEWLINE);
skip = !defines_.contains(name); skip = !defines_.contains(name) || dir.exec;
} }
indents_.push({ directive::ELIFDEF, skip }); indents_.push({ directive::ELIFDEF, skip, !skip || dir.exec });
skip_ += skip ? 1 : 0; skip_ += skip ? 1 : 0;
} }
@ -404,10 +404,10 @@ auto preprocessor::read_directive_elifndef(token& tok) -> void
next = read_token(); next = read_token();
expect(next, token::NEWLINE); expect(next, token::NEWLINE);
skip = defines_.contains(name); skip = defines_.contains(name) || dir.exec;
} }
indents_.push({ directive::ELIFNDEF, skip }); indents_.push({ directive::ELIFNDEF, skip, !skip || dir.exec });
skip_ += skip ? 1 : 0; skip_ += skip ? 1 : 0;
} }
@ -430,8 +430,8 @@ auto preprocessor::read_directive_else(token& tok) -> void
throw ppr_error(tok.pos, "#else after #else"); throw ppr_error(tok.pos, "#else after #else");
} }
auto skip = !dir.skip; auto skip = dir.exec;
indents_.push({ directive::ELSE, skip }); indents_.push({ directive::ELSE, skip, dir.exec });
skip_ += skip ? 1 : 0; skip_ += skip ? 1 : 0;
} }
@ -970,7 +970,21 @@ auto preprocessor::evaluate() -> bool
} }
else if (tok.type == token::NAME) else if (tok.type == token::NAME)
{ {
if (tok.data == "defined") if (tok.data == "true")
{
last_def = false;
last_paren = false;
tok.type = token::TRUE;
expr_.push_back(std::move(tok));
}
else if (tok.data == "false")
{
last_def = false;
last_paren = false;
tok.type = token::FALSE;
expr_.push_back(std::move(tok));
}
else if (tok.data == "defined")
{ {
last_def = true; last_def = true;
tok.type = token::DEFINED; tok.type = token::DEFINED;
@ -1314,16 +1328,16 @@ auto preprocessor::eval_expr_primary() -> i32
{ {
if (eval_match(token::TRUE)) if (eval_match(token::TRUE))
return 1; return 1;
if (eval_match(token::FALSE)) if (eval_match(token::FALSE))
return 0; return 0;
if (eval_match(token::FLT)) if (eval_match(token::FLT))
return static_cast<i32>(std::stof(eval_prev().data)); return static_cast<i32>(std::stof(eval_prev().data));
if (eval_match(token::INT)) if (eval_match(token::INT))
return static_cast<i32>(std::stoi(eval_prev().data)); return static_cast<i32>(std::stoi(eval_prev().data));
if (eval_match(token::LPAREN)) if (eval_match(token::LPAREN))
{ {
auto val = eval_expr(); auto val = eval_expr();