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;
bool skip;
bool exec;
};
} // namespace xsk::arc

View File

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

View File

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