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 30199703..ddf04fd1 100644 Binary files a/blitzide/blitzide.aps and b/blitzide/blitzide.aps differ diff --git a/blitzide/blitzide.rc b/blitzide/blitzide.rc index 68ac0ffa..1c10357f 100644 --- a/blitzide/blitzide.rc +++ b/blitzide/blitzide.rc @@ -13,6 +13,7 @@ #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// +// Ó¢Óï(ÃÀ¹ú) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US @@ -104,6 +105,7 @@ BEGIN MENUITEM "Create &Executable...", ID_PUBLISH MENUITEM SEPARATOR MENUITEM "&Program Command Line...", ID_COMMANDLINE + MENUITEM "Preprocessor?", ID_PROGRAM_PREPROCESSOR MENUITEM "&Debug Enabled?", ID_DEBUG MENUITEM "&Not Large Address Aware?", ID_NLAA END diff --git a/blitzide/mainframe.cpp b/blitzide/mainframe.cpp index 2705f39e..4bceac07 100644 --- a/blitzide/mainframe.cpp +++ b/blitzide/mainframe.cpp @@ -48,6 +48,7 @@ BEGIN_MESSAGE_MAP(MainFrame, CFrameWnd) ON_COMMAND(ID_COMPILE, programCompile) ON_COMMAND(ID_PUBLISH, programPublish) ON_COMMAND(ID_COMMANDLINE, programCommandLine) + ON_COMMAND(ID_PROGRAM_PREPROCESSOR, programPreprocess) ON_COMMAND(ID_DEBUG, programDebug) ON_COMMAND(ID_NLAA, programNoLAA) @@ -76,6 +77,7 @@ BEGIN_MESSAGE_MAP(MainFrame, CFrameWnd) ON_UPDATE_COMMAND_UI(ID_COMPILE, updateCmdUI) ON_UPDATE_COMMAND_UI(ID_PUBLISH, updateCmdUI) ON_UPDATE_COMMAND_UI(ID_COMMANDLINE, updateCmdUI) + ON_UPDATE_COMMAND_UI(ID_PROGRAM_PREPROCESSOR, updateCmdUI) ON_UPDATE_COMMAND_UI(ID_DEBUG, updateCmdUI) ON_UPDATE_COMMAND_UI(ID_NLAA, updateCmdUI) ON_UPDATE_COMMAND_UI(ID_HOME, updateCmdUI) @@ -692,6 +694,7 @@ void MainFrame::build(bool exec, bool publish) { std::string opts = " "; + if (prefs.prg_preprocess) opts += "-p "; if (prefs.prg_debug) opts += "-d "; if (prefs.prg_nolaa) opts += "-nlaa "; @@ -795,6 +798,10 @@ void MainFrame::programCommandLine() { d.DoModal(); } +void MainFrame::programPreprocess() { + prefs.prg_preprocess = !prefs.prg_preprocess; +} + void MainFrame::programDebug() { prefs.prg_debug = !prefs.prg_debug; } @@ -879,6 +886,9 @@ void MainFrame::updateCmdUI(CCmdUI* ui) { case ID_NEW:case ID_OPEN:case ID_HOME: ui->Enable(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;