From b8d2c84ae0d96704148538b15695ea3edc60994d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xenxo=20Espasand=C3=ADn?= Date: Fri, 9 Feb 2024 16:52:04 +0100 Subject: [PATCH] fix(preprocessor): expression eval & blocks (#190) --- include/xsk/arc/common/directive.hpp | 1 + include/xsk/gsc/common/directive.hpp | 1 + src/arc/preprocessor.cpp | 38 +++++++++++++++-------- src/gsc/preprocessor.cpp | 46 ++++++++++++++++++---------- 4 files changed, 58 insertions(+), 28 deletions(-) diff --git a/include/xsk/arc/common/directive.hpp b/include/xsk/arc/common/directive.hpp index 0f5d72ae..7a675f35 100644 --- a/include/xsk/arc/common/directive.hpp +++ b/include/xsk/arc/common/directive.hpp @@ -14,6 +14,7 @@ struct directive kind type; bool skip; + bool exec; }; } // namespace xsk::arc diff --git a/include/xsk/gsc/common/directive.hpp b/include/xsk/gsc/common/directive.hpp index 1535ec37..699f387f 100644 --- a/include/xsk/gsc/common/directive.hpp +++ b/include/xsk/gsc/common/directive.hpp @@ -14,6 +14,7 @@ struct directive kind type; bool skip; + bool exec; }; } // namespace xsk::gsc diff --git a/src/arc/preprocessor.cpp b/src/arc/preprocessor.cpp index 394b9174..9db17a27 100644 --- a/src/arc/preprocessor.cpp +++ b/src/arc/preprocessor.cpp @@ -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; diff --git a/src/gsc/preprocessor.cpp b/src/gsc/preprocessor.cpp index abb09040..d084367e 100644 --- a/src/gsc/preprocessor.cpp +++ b/src/gsc/preprocessor.cpp @@ -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(std::stof(eval_prev().data)); - + if (eval_match(token::INT)) return static_cast(std::stoi(eval_prev().data)); - + if (eval_match(token::LPAREN)) { auto val = eval_expr();