diff options
Diffstat (limited to 'source/20-codegen-compiler/main.cpp')
-rw-r--r-- | source/20-codegen-compiler/main.cpp | 183 |
1 files changed, 93 insertions, 90 deletions
diff --git a/source/20-codegen-compiler/main.cpp b/source/20-codegen-compiler/main.cpp index c393fb0..2068962 100644 --- a/source/20-codegen-compiler/main.cpp +++ b/source/20-codegen-compiler/main.cpp @@ -534,6 +534,10 @@ struct NamespaceStackframe { }; struct ParserState { + // TODO +}; + +struct ParserOutput { CodegenModel model; CodegenOutput headerOutput; CodegenOutput sourceOutput; @@ -563,7 +567,7 @@ struct ParserState { int currentEnumBraceDepth = -1; }; -void HandleDirectiveEnum(AppState& as, ParserState& ps, CodegenLexer& lexer) { +void HandleDirectiveEnum(AppState& as, ParserOutput& ps, CodegenLexer& lexer) { // Consume the directive ++lexer.idx; @@ -614,10 +618,13 @@ void HandleDirectiveEnum(AppState& as, ParserState& ps, CodegenLexer& lexer) { ps.currentEnum->generating = true; } -void HandleInputFile(AppState& as, std::string_view filenameStem, std::string_view source) { - CodegenLexer lexer; - lexer.InitializeFrom(source); +CodegenLexer LexInputFile(AppState& as, std::string_view source) { + CodegenLexer result; + result.InitializeFrom(source); + return result; +} +void ParseInputFileAndGenerate(AppState& as, CodegenLexer& /*lexingState*/ ls, std::string_view filenameStem) { #if CODEGEN_DEBUG_PRINT printf("BEGIN tokens\n"); for (auto& token : lexer.tokens) { @@ -642,21 +649,23 @@ void HandleInputFile(AppState& as, std::string_view filenameStem, std::string_vi sourceFile.header = true; sourceFile.reprocessing = true; - ParserState ps; + // TODO move lexedTokens and consumption related functions to ParserState struct + + ParserOutput po; { INPLACE_FMT(hpp, "%.*s.gh.inl", PRINTF_STRING_VIEW(filenameStem)); INPLACE_FMT(cpp, "%.*s.gs.inl", PRINTF_STRING_VIEW(filenameStem)); - Utils::ProduceGeneratedHeader(hpp, ps.headerOutput, cpp, ps.sourceOutput); + Utils::ProduceGeneratedHeader(hpp, po.headerOutput, cpp, po.sourceOutput); } - auto& tokens = lexer.tokens; - auto& idx = lexer.idx; - while (lexer.idx < lexer.tokens.size()) { - auto& token = lexer.Current(); + auto& tokens = ls.tokens; + auto& idx = ls.idx; + while (ls.idx < ls.tokens.size()) { + auto& token = ls.Current(); bool incrementTokenIdx = true; - // Reamalgamate token type and single char tokens; + // Reamalgamate token type and single char tokens int tokenKey; if (token.type == CLEX_ext_single_char) { tokenKey = token.text[0]; @@ -690,8 +699,8 @@ void HandleInputFile(AppState& as, std::string_view filenameStem, std::string_vi break; } - ps.currentNamespace = ps.model.AddNamespace(DeclNamespace{ - .container = ps.currentNamespace, + po.currentNamespace = po.model.AddNamespace(DeclNamespace{ + .container = po.currentNamespace, .name = tokens[idx].text, }); @@ -706,9 +715,9 @@ void HandleInputFile(AppState& as, std::string_view filenameStem, std::string_vi } } - ps.nsStack.push_back(NamespaceStackframe{ - .ns = ps.currentNamespace, - .depth = ps.currentBraceDepth, + po.nsStack.push_back(NamespaceStackframe{ + .ns = po.currentNamespace, + .depth = po.currentBraceDepth, }); goto endCaseCLEX_id; @@ -729,19 +738,19 @@ void HandleInputFile(AppState& as, std::string_view filenameStem, std::string_vi DEBUG_PRINTF("[DEBUG] found struct named %s\n", idenTok.text.c_str()); auto& name = idenTok.text; - auto fullname = Utils::MakeFullName(name, ps.currentNamespace); + auto fullname = Utils::MakeFullName(name, po.currentNamespace); DeclStruct structDecl; structDecl.sourceFile = &sourceFile; - structDecl.container = ps.currentNamespace; + structDecl.container = po.currentNamespace; structDecl.name = name; // Consume the identifier token ++idx; - if (lexer.TryConsumeSingleCharToken(':')) { + if (ls.TryConsumeSingleCharToken(':')) { while (true) { // Public, protected, etc. - TryConsumeAnyKeyword(lexer); + TryConsumeAnyKeyword(ls); auto& idenTok = tokens[idx]; if (idenTok.type != CLEX_id) { @@ -750,8 +759,8 @@ void HandleInputFile(AppState& as, std::string_view filenameStem, std::string_vi } // TODO support namespace qualified names - auto baseClassFullname = Utils::MakeFullName(idenTok.text, ps.currentNamespace); - auto baseClassDecl = ps.model.FindStruct(baseClassFullname); + auto baseClassFullname = Utils::MakeFullName(idenTok.text, po.currentNamespace); + auto baseClassDecl = po.model.FindStruct(baseClassFullname); if (baseClassDecl) { // We silently ignore a non-existent base class, because they may reside in a file that we didn't scan structDecl.baseClasses.push_back(baseClassDecl); @@ -760,11 +769,11 @@ void HandleInputFile(AppState& as, std::string_view filenameStem, std::string_vi // Consume the identifier token ++idx; - if (lexer.TryConsumeSingleCharToken('{')) { + if (ls.TryConsumeSingleCharToken('{')) { // End of base class list --idx; // Give the '{' token back to the main loop break; - } else if (!lexer.TryConsumeSingleCharToken(',')) { + } else if (!ls.TryConsumeSingleCharToken(',')) { // If the list didn't end, we expect a comma (then followed by more entries) printf("[ERROR] invalid syntax for class inheritance list\n"); goto endCase; @@ -778,9 +787,9 @@ void HandleInputFile(AppState& as, std::string_view filenameStem, std::string_vi { // Get a pointer to the decl inside CodegenInput's storage - auto decl = ps.model.AddStruct(std::move(fullname), std::move(structDecl)); - ps.currentStruct = decl; - ps.currentStructBraceDepth = ps.currentBraceDepth; + auto decl = po.model.AddStruct(std::move(fullname), std::move(structDecl)); + po.currentStruct = decl; + po.currentStructBraceDepth = po.currentBraceDepth; } endCase: @@ -804,17 +813,17 @@ void HandleInputFile(AppState& as, std::string_view filenameStem, std::string_vi } auto& name = tokens[idx].text; - auto fullname = Utils::MakeFullName(name, ps.currentNamespace); + auto fullname = Utils::MakeFullName(name, po.currentNamespace); DeclEnum enumDecl; enumDecl.sourceFile = &sourceFile; - enumDecl.container = ps.currentNamespace; + enumDecl.container = po.currentNamespace; enumDecl.underlyingType = EUT_Int32; // TODO enumDecl.underlyingTypeStr = "int"; enumDecl.name = name; // Temporarily bind the pointers to local variable, HandleDirectiveEnum() and other functions expect these to the set - ps.currentEnum = &enumDecl; - ps.currentEnumBraceDepth = ps.currentBraceDepth; + po.currentEnum = &enumDecl; + po.currentEnumBraceDepth = po.currentBraceDepth; // Consume the enum name identifier ++idx; @@ -827,7 +836,7 @@ void HandleInputFile(AppState& as, std::string_view filenameStem, std::string_vi case CLEX_id: { if (token.text == "BRUSSEL_ENUM") { // Consume the argument list and skip advancing index: this function already consumed all the tokens about BRUSSEL_ENUM - HandleDirectiveEnum(as, ps, lexer); + HandleDirectiveEnum(as, po, ls); continue; } else { auto& vec = enumDecl.elements; @@ -866,19 +875,19 @@ void HandleInputFile(AppState& as, std::string_view filenameStem, std::string_vi ++idx; } - if (ps.currentEnum->generating) { - GenerateForEnum(ps.headerOutput, ps.sourceOutput, *ps.currentEnum); + if (po.currentEnum->generating) { + GenerateForEnum(po.headerOutput, po.sourceOutput, *po.currentEnum); } { - auto decl = ps.model.AddEnum(std::move(fullname), std::move(enumDecl)); - ps.currentEnum = decl; - ps.currentEnumBraceDepth = ps.currentBraceDepth; + auto decl = po.model.AddEnum(std::move(fullname), std::move(enumDecl)); + po.currentEnum = decl; + po.currentEnumBraceDepth = po.currentBraceDepth; } // NOTE: we parse the whole enum at once (above code), the enum ends right here after the closing brace '}' - ps.currentEnum = nullptr; - ps.currentEnumBraceDepth = -1; + po.currentEnum = nullptr; + po.currentEnumBraceDepth = -1; goto endCaseCLEX_id; } @@ -907,15 +916,15 @@ void HandleInputFile(AppState& as, std::string_view filenameStem, std::string_vi ++idx; incrementTokenIdx = false; - if (!ps.currentStruct) { + if (!po.currentStruct) { printf("[ERROR] BRUSSEL_CLASS must be used within a class or struct\n"); break; } // Always-on option - ps.currentStruct->generating = true; + po.currentStruct->generating = true; - auto argList = TryConsumeDirectiveArgumentList(lexer); + auto argList = TryConsumeDirectiveArgumentList(ls); auto& lut = RSTR_LUT(StructMetaGenOptions); for (auto& arg : argList) { if (arg.empty()) { @@ -927,7 +936,7 @@ void HandleInputFile(AppState& as, std::string_view filenameStem, std::string_vi auto iter = lut.find(optionDirective); if (iter == lut.end()) continue; switch (iter->second) { - case SMGO_InheritanceHiearchy: ps.currentStruct->generatingInheritanceHiearchy = true; break; + case SMGO_InheritanceHiearchy: po.currentStruct->generatingInheritanceHiearchy = true; break; case SMGO_COUNT: break; } } @@ -940,15 +949,15 @@ void HandleInputFile(AppState& as, std::string_view filenameStem, std::string_vi ++idx; incrementTokenIdx = false; - if (!ps.currentStruct || - !ps.currentStruct->generating) + if (!po.currentStruct || + !po.currentStruct->generating) { printf("[ERROR] BRUSSEL_PROPERTY must be used within a class or struct, that has the BRUSSEL_CLASS directive\n"); break; } - auto argList = TryConsumeDirectiveArgumentList(lexer); - auto declOpt = TryConsumeMemberVariable(lexer); + auto argList = TryConsumeDirectiveArgumentList(ls); + auto declOpt = TryConsumeMemberVariable(ls); if (!declOpt.has_value()) { printf("[ERROR] a member variable must immediately follow a BRUSSEL_PROPERTY\n"); break; @@ -1009,7 +1018,7 @@ void HandleInputFile(AppState& as, std::string_view filenameStem, std::string_vi } } - ps.currentStruct->memberVariables.push_back(std::move(decl)); + po.currentStruct->memberVariables.push_back(std::move(decl)); goto endCaseCLEX_id; } @@ -1031,50 +1040,50 @@ void HandleInputFile(AppState& as, std::string_view filenameStem, std::string_vi } break; case '{': { - ps.currentBraceDepth++; - if (ps.currentBraceDepth < 0) { + po.currentBraceDepth++; + if (po.currentBraceDepth < 0) { printf("[WARNING] unbalanced brace\n"); } } break; case '}': { - ps.currentBraceDepth--; - if (ps.currentBraceDepth < 0) { + po.currentBraceDepth--; + if (po.currentBraceDepth < 0) { printf("[WARNING] unbalanced brace\n"); } - if (!ps.nsStack.empty()) { - auto& ns = ps.nsStack.back(); - if (ns.depth == ps.currentBraceDepth) { - ps.nsStack.pop_back(); + if (!po.nsStack.empty()) { + auto& ns = po.nsStack.back(); + if (ns.depth == po.currentBraceDepth) { + po.nsStack.pop_back(); - if (!ps.nsStack.empty()) { - ps.currentNamespace = ps.nsStack.back().ns; + if (!po.nsStack.empty()) { + po.currentNamespace = po.nsStack.back().ns; } else { - ps.currentNamespace = nullptr; + po.currentNamespace = nullptr; } } } - if (ps.currentStruct && ps.currentBraceDepth == ps.currentStructBraceDepth) { + if (po.currentStruct && po.currentBraceDepth == po.currentStructBraceDepth) { // Exit struct - if (ps.currentStruct->generating) { - GenerateForClassMetadata(ps.headerOutput, ps.sourceOutput, *ps.currentStruct); + if (po.currentStruct->generating) { + GenerateForClassMetadata(po.headerOutput, po.sourceOutput, *po.currentStruct); } - if (ps.currentStruct->generatingInheritanceHiearchy) { + if (po.currentStruct->generatingInheritanceHiearchy) { // NOTE: this option is transitive to all child classes (as long as they have the basic annotation) // TODO } - ps.currentStruct = nullptr; - ps.currentStructBraceDepth = -1; + po.currentStruct = nullptr; + po.currentStructBraceDepth = -1; } - if (ps.currentEnum && ps.currentBraceDepth == ps.currentEnumBraceDepth) { + if (po.currentEnum && po.currentBraceDepth == po.currentEnumBraceDepth) { // Exit enum - ps.currentEnum = nullptr; - ps.currentEnumBraceDepth = -1; + po.currentEnum = nullptr; + po.currentEnumBraceDepth = -1; } } break; } @@ -1084,23 +1093,29 @@ void HandleInputFile(AppState& as, std::string_view filenameStem, std::string_vi } } - if (ps.currentBraceDepth != 0) { + if (po.currentBraceDepth != 0) { printf("[WARNING] unbalanced brace at end of file\n"); } INPLACE_FMT(generatedHeaderInlName, "%.*s/%.*s.gh.inl", PRINTF_STRING_VIEW(as.outputDir), PRINTF_STRING_VIEW(filenameStem)); - Utils::WriteOutputFile(ps.headerOutput, generatedHeaderInlName); + Utils::WriteOutputFile(po.headerOutput, generatedHeaderInlName); INPLACE_FMT(generatedSourceInlName, "%.*s/%.*s.gs.inl", PRINTF_STRING_VIEW(as.outputDir), PRINTF_STRING_VIEW(filenameStem)); - Utils::WriteOutputFile(ps.sourceOutput, generatedSourceInlName); + Utils::WriteOutputFile(po.sourceOutput, generatedSourceInlName); INPLACE_FMT(generatedCppName, "%.*s/%.*s.g.cpp", PRINTF_STRING_VIEW(as.outputDir), PRINTF_STRING_VIEW(filenameStem)); - Utils::WriteOutputFile(ps.standaloneSourceOutput, generatedCppName); + Utils::WriteOutputFile(po.standaloneSourceOutput, generatedCppName); if (as.modelArchive) { as.modelArchive->DeleteDeclsRelatedToFile(filenameStem); - as.modelArchive->Store(ps.model); + as.modelArchive->Store(po.model); } } +void HandleInputFile(AppState& as, const fs::path& path) { + auto filenameStem = path.stem().string(); + auto lexingState = LexInputFile(as, Utils::ReadFileAsString(path)); + ParseInputFileAndGenerate(as, lexingState, filenameStem); +} + enum InputOpcode { IOP_ProcessSingleFile, IOP_ProcessRecursively, @@ -1112,11 +1127,7 @@ void HandleArgument(AppState& as, InputOpcode opcode, std::string_view operand) switch (opcode) { case IOP_ProcessSingleFile: { DEBUG_PRINTF("Processing single file %.*s\n", PRINTF_STRING_VIEW(operand)); - - fs::path path(operand); - auto filenameStem = path.stem().string(); - auto source = Utils::ReadFileAsString(path); - HandleInputFile(as, filenameStem, source); + HandleInputFile(as, fs::path(operand)); } break; case IOP_ProcessRecursively: { @@ -1129,19 +1140,15 @@ void HandleArgument(AppState& as, InputOpcode opcode, std::string_view operand) } auto& path = item.path(); - auto pathExt = path.extension(); - auto pathStem = path.stem(); - if (pathExt != ".h" && + if (auto pathExt = path.extension(); + pathExt != ".h" && pathExt != ".hpp") { continue; } DEBUG_PRINTF("Processing subfile %s\n", path.string().c_str()); - - auto filenameStem = pathStem.string(); - auto source = Utils::ReadFileAsString(path); - HandleInputFile(as, filenameStem, source); + HandleInputFile(as, path); } } break; @@ -1163,11 +1170,7 @@ void HandleArgument(AppState& as, InputOpcode opcode, std::string_view operand) line.pop_back(); DEBUG_PRINTF("Processing file in list %.*s\n", line.c_str()); - - fs::path path(line); - auto filenameStem = path.stem().string(); - auto source = Utils::ReadFileAsString(path); - HandleInputFile(as, filenameStem, source); + HandleInputFile(as, fs::path(line)); } } break; |