From a80f6057d6857f715a89340fdeff629cdb97f085 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=82=A6=E8=A7=A3=E8=AF=B4?= Date: Wed, 12 Feb 2025 11:44:51 +0800 Subject: [PATCH] Optional preprocessor --- blitz/main.cpp | 12 ++++++++---- blitzide/blitzide.aps | Bin 76380 -> 76408 bytes blitzide/blitzide.rc | 2 ++ blitzide/mainframe.cpp | 10 ++++++++++ blitzide/mainframe.h | 1 + blitzide/prefs.cpp | 3 +++ blitzide/prefs.h | 1 + blitzide/resource.h | 3 ++- compiler/parser.cpp | 42 ++++++++++++++++++++--------------------- compiler/parser.h | 10 +++++----- compiler/toker.cpp | 10 ++++++---- compiler/toker.h | 3 ++- debugger/prefs.cpp | 2 ++ debugger/prefs.h | 1 + linker/image_util.cpp | 2 +- 15 files changed, 65 insertions(+), 37 deletions(-) diff --git a/blitz/main.cpp b/blitz/main.cpp index dd6815f9..51ba3b00 100644 --- a/blitz/main.cpp +++ b/blitz/main.cpp @@ -37,7 +37,7 @@ static void showInfo() { } static void showUsage() { - std::cout << "Usage: blitzcc [-h|-q|+q|-c|-d|-k|+k|-nlaa|-v|-o exefile] [sourcefile.bb]" << std::endl; + std::cout << "Usage: blitzcc [-h|-q|+q|-c|-d|-k|+k|-nlaa|-v|-p|-o exefile] [sourcefile.bb]" << std::endl; } static void showHelp() { @@ -51,6 +51,7 @@ static void showHelp() { std::cout << "+k : dump keywords and syntax" << std::endl; std::cout << "-v : version info" << std::endl; std::cout << "-nlaa : disables large address awareness for the output executable" << std::endl; + std::cout << "-p : enabling preprocessor" << std::endl; std::cout << "-o exefile : generate executable" << std::endl; } @@ -136,7 +137,7 @@ int _cdecl main(int argc, char* argv[]) { bool debug = false, quiet = false, veryquiet = false, compileonly = false; bool dumpkeys = false, dumphelp = false, showhelp = false, dumpasm = false; bool versinfo = false; - bool nolaa = false; + bool preprocess = false, nolaa = false; for (int k = 1; k < argc; ++k) { std::string t = argv[k]; @@ -170,6 +171,9 @@ int _cdecl main(int argc, char* argv[]) { else if (t == "-v") { versinfo = true; } + else if (t == "-p") { + preprocess = true; + } else if (t == "-o") { if (out_file.size() || k == argc - 1) usageErr(); out_file = argv[++k]; @@ -246,9 +250,9 @@ int _cdecl main(int argc, char* argv[]) { try { //parse if (!veryquiet) std::cout << "Parsing..." << std::endl; - Toker toker(in_file, in, debug); + Toker toker(in_file, in, debug, preprocess); Parser parser(toker); - prog = parser.parse(in_file, debug); + prog = parser.parse(in_file, debug, preprocess); //semant if (!veryquiet) std::cout << "Generating..." << std::endl; diff --git a/blitzide/blitzide.aps b/blitzide/blitzide.aps index 301997031a1b089f576e4d5c1a0cf6ee67ec13b1..ddf04fd177dea4c5d9ddc2b7851c0d55d704aadb 100644 GIT binary patch delta 550 zcmW-bUr1AN6vxlGyLU7~m@%wvY^&6}88KG(nmtX%W+kY*PS$4hPi$diO|%|-Q0k$l z2#S*&0-t74ZxKJCqQ5>0QUntHk!lb@5MtniL15>04!_^$ob&zu{;VwP8_W95oM*lj zDcKu)bhfDnQ);TGPoocgX`EKu^GU>6I^-P3do<@M^S&xZYw1Pg3+{pbk|ZTeYm#+lEc-O5hT>C$wH??ivgdbqX9Ie(uMnKG`c`}Y+ zBW(cO<~wnW;W|HcG0z`e{Ng{Zu4w?@Iheqhw)Z7ZC$OEX32Z={rxKXO2fQE>E^*z( z8e^Ln1Fz}JtB`R(URmLcOvF9p;yGUxc>KGOKkvezu_2BTUT~!=To*KNX+hZB^vYWD ci3lmbPj~5tdtaax`D=?DJtEC0XZB$DA9MhlqyPW_ delta 539 zcmYk0&1(};6vgkEOoH)?l)_L)JEN^8X%2|4J?RW|12JgyZ$Y_7khGPd=Mi! z4@bm&?h%H?seBJg@VRm|+g_coZGD#&c1)q1H6f_F?g*-~_j+TL<`f4DI|Y3JZ7s zaU!Ppt7gyG@<9A4+dLbC+2Ko~&CQ)kB{fKNC=xcCpdKekG$X|oY4f_u8ZRs2Q^n>V znrD{8{F2R)xZ3gjncfjpy4f84e}`odJ*kR!Rhxa4H6knG`*JdrSHZSbg+06$#}3@) zjW}F9=7ugcZtsF?)K@v#1qUy|9XEnable(true); break; + case ID_PROGRAM_PREPROCESSOR: + ui->SetCheck(prefs.prg_preprocess); ui->Enable(true); + break; case ID_DEBUG: ui->SetCheck(prefs.prg_debug); ui->Enable(true); break; diff --git a/blitzide/mainframe.h b/blitzide/mainframe.h index 7f345b45..ec52c51f 100644 --- a/blitzide/mainframe.h +++ b/blitzide/mainframe.h @@ -48,6 +48,7 @@ class MainFrame : public CFrameWnd,public HelpListener,EditorListener,TabberList afx_msg void programCompile(); afx_msg void programPublish(); afx_msg void programCommandLine(); + afx_msg void programPreprocess(); afx_msg void programDebug(); afx_msg void programNoLAA(); diff --git a/blitzide/prefs.cpp b/blitzide/prefs.cpp index a9f0ecaa..d71897c2 100644 --- a/blitzide/prefs.cpp +++ b/blitzide/prefs.cpp @@ -36,6 +36,7 @@ void Prefs::open() inipp::Ini ini; ini.parse(in); + inipp::get_value(ini.sections["COMPILER"], "Preprocess", prg_preprocess); inipp::get_value(ini.sections["COMPILER"], "Debug", prg_debug); inipp::get_value(ini.sections["COMPILER"], "NoLAA", prg_nolaa); inipp::get_value(ini.sections["COMPILER"], "LastBuild", prg_lastbuild); @@ -108,6 +109,7 @@ void Prefs::close() inipp::Ini ini; auto& compilerSection = ini.sections["COMPILER"]; + compilerSection.insert(std::make_pair("Preprocess", boolToString(prg_preprocess))); compilerSection.insert(std::make_pair("Debug", boolToString(prg_debug))); compilerSection.insert(std::make_pair("NoLAA", boolToString(prg_nolaa))); compilerSection.insert(std::make_pair("LastBuild", prg_lastbuild)); @@ -152,6 +154,7 @@ void Prefs::close() void Prefs::setDefault() { + prg_preprocess = false; prg_debug = true; prg_nolaa = false; diff --git a/blitzide/prefs.h b/blitzide/prefs.h index bb7d8e72..27bea4a3 100644 --- a/blitzide/prefs.h +++ b/blitzide/prefs.h @@ -3,6 +3,7 @@ class Prefs{ public: + bool prg_preprocess; bool prg_debug; bool prg_nolaa; std::string prg_lastbuild; diff --git a/blitzide/resource.h b/blitzide/resource.h index 787f9ca2..6fe584ce 100644 --- a/blitzide/resource.h +++ b/blitzide/resource.h @@ -71,13 +71,14 @@ #define ID_NLAA 40132 #define ID_BACKUP 40133 #define ID_OPENINI 40134 +#define ID_PROGRAM_PREPROCESSOR 40137 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 144 -#define _APS_NEXT_COMMAND_VALUE 40137 +#define _APS_NEXT_COMMAND_VALUE 40138 #define _APS_NEXT_CONTROL_VALUE 1026 #define _APS_NEXT_SYMED_VALUE 101 #endif diff --git a/compiler/parser.cpp b/compiler/parser.cpp index 177ff6ab..8cb89f1b 100644 --- a/compiler/parser.cpp +++ b/compiler/parser.cpp @@ -16,7 +16,7 @@ static bool isTerm(int c) { return c == ':' || c == '\n'; } Parser::Parser(Toker& t) :toker(&t), main_toker(&t) { } -ProgNode* Parser::parse(const std::string& main, bool debug) { +ProgNode* Parser::parse(const std::string& main, bool debug, bool preprocess) { incfile = main; @@ -27,7 +27,7 @@ ProgNode* Parser::parse(const std::string& main, bool debug) { StmtSeqNode* stmts = 0; try { - stmts = parseStmtSeq(STMTS_PROG, debug); + stmts = parseStmtSeq(STMTS_PROG, debug, preprocess); if (toker->curr() != EOF) exp("end-of-file"); } catch (Ex) { @@ -69,13 +69,13 @@ void Parser::parseChar(int c) { toker->next(); } -StmtSeqNode* Parser::parseStmtSeq(int scope, bool debug) { +StmtSeqNode* Parser::parseStmtSeq(int scope, bool debug, bool preprocess) { std::unique_ptr stmts(new StmtSeqNode(incfile)); - parseStmtSeq(stmts.get(), scope, debug); + parseStmtSeq(stmts.get(), scope, debug, preprocess); return stmts.release(); } -void Parser::parseStmtSeq(StmtSeqNode* stmts, int scope, bool debug) { +void Parser::parseStmtSeq(StmtSeqNode* stmts, int scope, bool debug, bool preprocess) { for (;;) { while (toker->curr() == ':' || (scope != STMTS_LINE && toker->curr() == '\n')) toker->next(); @@ -100,14 +100,14 @@ void Parser::parseStmtSeq(StmtSeqNode* stmts, int scope, bool debug) { std::ifstream i_stream(inc); if (!i_stream.good()) ex(MultiLang::unable_open_include_file); - Toker i_toker(inc, i_stream, debug); + Toker i_toker(inc, i_stream, debug, preprocess); std::string t_inc = incfile; incfile = inc; Toker* t_toker = toker; toker = &i_toker; included.insert(incfile); - std::unique_ptr ss(parseStmtSeq(scope, debug)); + std::unique_ptr ss(parseStmtSeq(scope, debug, preprocess)); if (toker->curr() != EOF) exp(MultiLang::end_of_file); result = new IncludeNode(incfile, ss.release()); @@ -159,7 +159,7 @@ void Parser::parseStmtSeq(StmtSeqNode* stmts, int scope, bool debug) { break; case IF: { - toker->next(); result = parseIf(debug); + toker->next(); result = parseIf(debug, preprocess); if (toker->curr() == ENDIF) toker->next(); } break; @@ -167,7 +167,7 @@ void Parser::parseStmtSeq(StmtSeqNode* stmts, int scope, bool debug) { { toker->next(); std::unique_ptr expr(parseExpr(false)); - std::unique_ptr stmts(parseStmtSeq(STMTS_BLOCK, debug)); + std::unique_ptr stmts(parseStmtSeq(STMTS_BLOCK, debug, preprocess)); int pos = toker->pos(); if (toker->curr() != WEND) exp("'Wend'"); toker->next(); @@ -177,7 +177,7 @@ void Parser::parseStmtSeq(StmtSeqNode* stmts, int scope, bool debug) { case REPEAT: { toker->next(); ExprNode* expr = 0; - std::unique_ptr stmts(parseStmtSeq(STMTS_BLOCK, debug)); + std::unique_ptr stmts(parseStmtSeq(STMTS_BLOCK, debug, preprocess)); int curr = toker->curr(); int pos = toker->pos(); if (curr != UNTIL && curr != FOREVER) exp(MultiLang::until_or_forever); @@ -195,13 +195,13 @@ void Parser::parseStmtSeq(StmtSeqNode* stmts, int scope, bool debug) { toker->next(); std::unique_ptr exprs(parseExprSeq()); if (!exprs->size()) exp(MultiLang::expression_sequence); - std::unique_ptr stmts(parseStmtSeq(STMTS_BLOCK, debug)); + std::unique_ptr stmts(parseStmtSeq(STMTS_BLOCK, debug, preprocess)); selNode->push_back(new CaseNode(exprs.release(), stmts.release())); continue; } else if (toker->curr() == DEFAULT) { toker->next(); - std::unique_ptr stmts(parseStmtSeq(STMTS_BLOCK, debug)); + std::unique_ptr stmts(parseStmtSeq(STMTS_BLOCK, debug, preprocess)); if (toker->curr() != ENDSELECT) exp("'End Select'"); selNode->defStmts = stmts.release(); break; @@ -225,7 +225,7 @@ void Parser::parseStmtSeq(StmtSeqNode* stmts, int scope, bool debug) { if (toker->next() == EACH) { toker->next(); std::string ident = parseIdent(); - stmts = std::unique_ptr(parseStmtSeq(STMTS_BLOCK, debug)); + stmts = std::unique_ptr(parseStmtSeq(STMTS_BLOCK, debug, preprocess)); int pos = toker->pos(); if (toker->curr() != NEXT) exp("'Next'"); toker->next(); @@ -241,7 +241,7 @@ void Parser::parseStmtSeq(StmtSeqNode* stmts, int scope, bool debug) { toker->next(); step = std::unique_ptr(parseExpr(false)); } else step = std::unique_ptr(new IntConstNode(1)); - stmts = std::unique_ptr(parseStmtSeq(STMTS_BLOCK, debug)); + stmts = std::unique_ptr(parseStmtSeq(STMTS_BLOCK, debug, preprocess)); int pos = toker->pos(); if (toker->curr() != NEXT) exp("'Next'"); toker->next(); @@ -325,7 +325,7 @@ void Parser::parseStmtSeq(StmtSeqNode* stmts, int scope, bool debug) { break; case FUNCTION: if (scope != STMTS_PROG) ex(MultiLang::function_can_only_appear_in_main); - toker->next(); funcs->push_back(parseFuncDecl(debug)); + toker->next(); funcs->push_back(parseFuncDecl(debug, preprocess)); break; case DIM: do { @@ -461,7 +461,7 @@ DimNode* Parser::parseArrayDecl() { return d; } -DeclNode* Parser::parseFuncDecl(bool debug) { +DeclNode* Parser::parseFuncDecl(bool debug, bool preprocess) { int pos = toker->pos(); std::string ident = parseIdent(); std::string tag = parseTypeTag(); @@ -476,7 +476,7 @@ DeclNode* Parser::parseFuncDecl(bool debug) { if (toker->curr() != ')') exp("')'"); } toker->next(); - std::unique_ptr stmts(parseStmtSeq(STMTS_BLOCK, debug)); + std::unique_ptr stmts(parseStmtSeq(STMTS_BLOCK, debug, preprocess)); if (toker->curr() != ENDFUNCTION) exp("'End Function'"); StmtNode* ret = new ReturnNode(0); ret->pos = toker->pos(); stmts->push_back(ret); toker->next(); @@ -504,7 +504,7 @@ DeclNode* Parser::parseStructDecl() { return d; } -IfNode* Parser::parseIf(bool debug) { +IfNode* Parser::parseIf(bool debug, bool preprocess) { std::unique_ptr expr; std::unique_ptr stmts, elseOpt; @@ -512,19 +512,19 @@ IfNode* Parser::parseIf(bool debug) { if (toker->curr() == THEN) toker->next(); bool blkif = isTerm(toker->curr()); - stmts = std::unique_ptr(parseStmtSeq(blkif ? STMTS_BLOCK : STMTS_LINE, debug)); + stmts = std::unique_ptr(parseStmtSeq(blkif ? STMTS_BLOCK : STMTS_LINE, debug, preprocess)); if (toker->curr() == ELSEIF) { int pos = toker->pos(); toker->next(); - IfNode* ifnode = parseIf(debug); + IfNode* ifnode = parseIf(debug, preprocess); ifnode->pos = pos; elseOpt = std::unique_ptr(new StmtSeqNode(incfile)); elseOpt->push_back(ifnode); } else if (toker->curr() == ELSE) { toker->next(); - elseOpt = std::unique_ptr(parseStmtSeq(blkif ? STMTS_BLOCK : STMTS_LINE, debug)); + elseOpt = std::unique_ptr(parseStmtSeq(blkif ? STMTS_BLOCK : STMTS_LINE, debug, preprocess)); } if (blkif) { if (toker->curr() != ENDIF) exp("'EndIf'"); diff --git a/compiler/parser.h b/compiler/parser.h index ac05d54b..0c8b3305 100644 --- a/compiler/parser.h +++ b/compiler/parser.h @@ -13,7 +13,7 @@ class Parser { Parser(Toker& t); - ProgNode* parse(const std::string& main, bool debug); + ProgNode* parse(const std::string& main, bool debug, bool preprocess); private: std::string incfile; @@ -26,8 +26,8 @@ class Parser { DeclSeqNode* funcs; DeclSeqNode* datas; - StmtSeqNode* parseStmtSeq(int scope, bool debug); - void parseStmtSeq(StmtSeqNode* stmts, int scope, bool debug); + StmtSeqNode* parseStmtSeq(int scope, bool debug, bool preprocess); + void parseStmtSeq(StmtSeqNode* stmts, int scope, bool debug, bool preprocess); void ex(const std::string& s); void exp(const std::string& s); @@ -38,11 +38,11 @@ class Parser { VarNode* parseVar(); VarNode* parseVar(const std::string& ident, const std::string& tag); - IfNode* parseIf(bool debug); + IfNode* parseIf(bool debug, bool preprocess); DeclNode* parseVarDecl(int kind, bool constant); DimNode* parseArrayDecl(); - DeclNode* parseFuncDecl(bool debug); + DeclNode* parseFuncDecl(bool debug, bool preprocess); DeclNode* parseStructDecl(); ExprSeqNode* parseExprSeq(); diff --git a/compiler/toker.cpp b/compiler/toker.cpp index f2813c74..c1c14928 100644 --- a/compiler/toker.cpp +++ b/compiler/toker.cpp @@ -115,10 +115,12 @@ static void makeKeywords() made = true; } -Toker::Toker(const std::string& file, std::istream& in, bool debug) :inc_file(file), in(in), curr_row(-1) +Toker::Toker(const std::string& file, std::istream& in, bool debug, bool preprocess) :inc_file(file), in(in), curr_row(-1), preprocess(preprocess) { - MacroDefines["__DEBUG__"] = debug ? "True" : "False"; - MacroDefines["__VERSION__"] = BASE_VER; + if (preprocess) { + MacroDefines["__DEBUG__"] = debug ? "True" : "False"; + MacroDefines["__VERSION__"] = BASE_VER; + } makeKeywords(); nextline(); } @@ -174,7 +176,7 @@ void Toker::nextline() getline(in, line); line += '\n'; chars_toked += line.size(); - if (!noMacro) { + if (preprocess && !noMacro) { auto now = std::chrono::system_clock::now(); auto in_time_t = std::chrono::system_clock::to_time_t(now); std::stringstream compilerDate; diff --git a/compiler/toker.h b/compiler/toker.h index 13d22dc1..feb896a6 100644 --- a/compiler/toker.h +++ b/compiler/toker.h @@ -35,7 +35,7 @@ extern std::map MacroDefines; // dangerous! class Toker { public: - Toker(const std::string& inc_file, std::istream& in, bool debug); + Toker(const std::string& inc_file, std::istream& in, bool debug, bool preprocess); int pos(); int curr(); @@ -62,6 +62,7 @@ class Toker { std::istream& in; std::string line; std::vector tokes; + bool preprocess; void nextline(); bool isValidIdentifier(const std::string& str); int curr_row, curr_toke; diff --git a/debugger/prefs.cpp b/debugger/prefs.cpp index d1377063..ec7fb83a 100644 --- a/debugger/prefs.cpp +++ b/debugger/prefs.cpp @@ -46,6 +46,7 @@ void Prefs::open() { inipp::Ini ini; ini.parse(in); + inipp::get_value(ini.sections["COMPILER"], "Preprocess", prg_preprocess); inipp::get_value(ini.sections["COMPILER"], "Debug", prg_debug); inipp::get_value(ini.sections["COMPILER"], "NoLAA", prg_nolaa); inipp::get_value(ini.sections["COMPILER"], "LastBuild", prg_lastbuild); @@ -109,6 +110,7 @@ void Prefs::open() { } void Prefs::setDefault() { + prg_preprocess = false; prg_debug = true; prg_nolaa = false; diff --git a/debugger/prefs.h b/debugger/prefs.h index 38f87c89..57b6cb29 100644 --- a/debugger/prefs.h +++ b/debugger/prefs.h @@ -3,6 +3,7 @@ class Prefs { public: + bool prg_preprocess; bool prg_debug; bool prg_nolaa; std::string prg_lastbuild; diff --git a/linker/image_util.cpp b/linker/image_util.cpp index d66bf05d..7c5ba640 100644 --- a/linker/image_util.cpp +++ b/linker/image_util.cpp @@ -315,7 +315,7 @@ bool makeExe(int entry, bool nolaa) { if(!img_file) return false; head->chars |= 0x0002; //executable - if(nolaa == false) head->chars |= 0x0020; //Large Address Aware + if(!nolaa) head->chars |= 0x0020; //Large Address Aware head->chars &= ~0x2000; //not Dll opts->entry = entry; return true;