fix(preprocessor): expression eval & blocks (#190)
This commit is contained in:
parent
0e6238a6ab
commit
b8d2c84ae0
@ -14,6 +14,7 @@ struct directive
|
|||||||
|
|
||||||
kind type;
|
kind type;
|
||||||
bool skip;
|
bool skip;
|
||||||
|
bool exec;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace xsk::arc
|
} // namespace xsk::arc
|
||||||
|
@ -14,6 +14,7 @@ struct directive
|
|||||||
|
|
||||||
kind type;
|
kind type;
|
||||||
bool skip;
|
bool skip;
|
||||||
|
bool exec;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace xsk::gsc
|
} // namespace xsk::gsc
|
||||||
|
@ -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;
|
||||||
|
@ -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();
|
||||||
|
Loading…
Reference in New Issue
Block a user