From c7812ccf43bbce83a15f6282b7d3903f19376bc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Sat, 12 Jul 2025 22:20:32 +0900 Subject: [PATCH 01/28] Addes statement raw function --- .vscode/launch.json | 2 +- samples/test.brc | 10 +++- src/Compiler/ModuleBuilder.cpp | 53 ++++++++++++++++++- src/Compiler/ModuleBuilder.h | 7 +++ src/Parser/Statement/Statement.h | 1 + src/Parser/Statement/StatementRawFunction.cpp | 12 +++++ src/Parser/Statement/StatementRawFunction.h | 14 +++++ 7 files changed, 96 insertions(+), 3 deletions(-) create mode 100644 src/Parser/Statement/StatementRawFunction.cpp create mode 100644 src/Parser/Statement/StatementRawFunction.h diff --git a/.vscode/launch.json b/.vscode/launch.json index 5574805..4b91f3e 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -6,7 +6,7 @@ "type": "lldb-dap", "request": "launch", "program": "${command:cmake.launchTargetPath}", - "args": ["-v", "${workspaceFolder}/samples/hello.brc"], + "args": ["-v", "${workspaceFolder}/samples/test.brc"], "cwd": "${workspaceFolder}", "internalConsoleOptions": "openOnSessionStart", } diff --git a/samples/test.brc b/samples/test.brc index f71b061..b9222ca 100644 --- a/samples/test.brc +++ b/samples/test.brc @@ -1,5 +1,7 @@ @extern putchar fun: character sint32 -> sint32 +// ./build/brb samples/test.brc -S -x86-asm-syntax=intel + /* User type name data @@ -18,8 +20,14 @@ i u32 <- 0, rep text[i] != 0: // text data <- "Hello world!" +/*addStuff asm<+r, r>: num1 u32, num2 u32 -> u32 + add $1, $0 +;*/ + main fun -> sint32 - text data <- "Hello string!\n" + //text data <- "Hello string!\n" + abc sint32 <- 0 + //addStuff() ret 0 ; \ No newline at end of file diff --git a/src/Compiler/ModuleBuilder.cpp b/src/Compiler/ModuleBuilder.cpp index 4e1aaa1..dcb14c2 100644 --- a/src/Compiler/ModuleBuilder.cpp +++ b/src/Compiler/ModuleBuilder.cpp @@ -14,6 +14,7 @@ #include "Parser/Expression/ExpressionBlock.h" #include "Parser/Statement/StatementFunction.h" +#include "Parser/Statement/StatementRawFunction.h" #include "Parser/Statement/StatementVariable.h" #include "Parser/Statement/StatementAssignment.h" #include "Parser/Statement/StatementReturn.h" @@ -54,6 +55,9 @@ void ModuleBuilder::buildStatement(shared_ptr statement) { case StatementKind::FUNCTION: buildFunctionDeclaration(dynamic_pointer_cast(statement)); break; + case StatementKind::RAW_FUNCTION: + buildRawFunction(dynamic_pointer_cast(statement)); + break; case StatementKind::VARIABLE: buildVarDeclaration(dynamic_pointer_cast(statement)); break; @@ -126,6 +130,29 @@ void ModuleBuilder::buildFunctionDeclaration(shared_ptr state markError(0, 0, errorMessage); } +void ModuleBuilder::buildRawFunction(shared_ptr statement) { + llvm::FunctionType *funType = llvm::FunctionType::get(llvm::Type::getVoidTy(*context), nullptr, false); + llvm::InlineAsm *rawFun = llvm::InlineAsm::get(funType, statement->getRawSource(), "", false, false, llvm::InlineAsm::AsmDialect::AD_Intel); + if (!setRawFun(statement->getName(), rawFun)) + return; + + /*int res; + int a = 42; + int b = 13; + + vector types; + types.push_back(typeSint32); + types.push_back(typeSint32); + llvm::FunctionType *asmType = llvm::FunctionType::get(typeSint32, types, false); + llvm::InlineAsm *asmm = llvm::InlineAsm::get(asmType, "add $0, $1", "+{ebx},i", false, false, llvm::InlineAsm::AsmDialect::AD_Intel); + + vectorargValues; + argValues.push_back(llvm::ConstantInt::get(typeSint32, 5, true)); + argValues.push_back(llvm::ConstantInt::get(typeSint32, 4, true)); + + llvm::Value *valu = builder->CreateCall(asmm, llvm::ArrayRef(argValues));*/ +} + void ModuleBuilder::buildVarDeclaration(shared_ptr statement) { if (statement->getValueType()->getKind() == ValueTypeKind::DATA) { vector values = valuesForExpression(statement->getExpression()); @@ -518,7 +545,7 @@ llvm::AllocaInst* ModuleBuilder::getAlloca(string name) { bool ModuleBuilder::setFun(string name, llvm::Function *fun) { if (scopes.top().funMap[name] != nullptr) { - markError(0, 0, format("Function \"{}\" already defined", name)); + markError(0, 0, format("Function \"{}\" already defined in scope", name)); return false; } @@ -540,6 +567,30 @@ llvm::Function* ModuleBuilder::getFun(string name) { return nullptr; } +bool ModuleBuilder::setRawFun(string name, llvm::Value *rawFun) { + if (scopes.top().rawFunMap[name] != nullptr) { + markError(0, 0, format("Raw function \"{}\" already defined in scope", name)); + return false; + } + + scopes.top().rawFunMap[name] = rawFun; + return true; +} + +llvm::Value *ModuleBuilder::getRawFun(string name) { + stack scopes = this->scopes; + + while (!scopes.empty()) { + llvm::Value *rawFun = scopes.top().rawFunMap[name]; + if (rawFun != nullptr) + return rawFun; + scopes.pop(); + } + + markError(0, 0, format("Raw function \"{}\" not defined in scope", name)); + return nullptr; +} + llvm::Type *ModuleBuilder::typeForValueType(shared_ptr valueType, int count) { switch (valueType->getKind()) { case ValueTypeKind::NONE: diff --git a/src/Compiler/ModuleBuilder.h b/src/Compiler/ModuleBuilder.h index 783e984..2631e54 100644 --- a/src/Compiler/ModuleBuilder.h +++ b/src/Compiler/ModuleBuilder.h @@ -10,6 +10,7 @@ #include #include #include +#include class Error; class ValueType; @@ -26,6 +27,7 @@ enum class ExpressionBinaryOperation; class Statement; class StatementFunction; +class StatementRawFunction; class StatementVariable; class StatementAssignment; class StatementReturn; @@ -39,6 +41,7 @@ using namespace std; typedef struct { map allocaMap; map funMap; + map rawFunMap; } Scope; class ModuleBuilder { @@ -61,6 +64,7 @@ private: void buildStatement(shared_ptr statement); void buildFunctionDeclaration(shared_ptr statement); + void buildRawFunction(shared_ptr statement); void buildVarDeclaration(shared_ptr statement); void buildAssignment(shared_ptr statement); void buildBlock(shared_ptr statement); @@ -88,6 +92,9 @@ private: bool setFun(string name, llvm::Function *fun); llvm::Function *getFun(string name); + bool setRawFun(string name, llvm::Value *rawFun); + llvm::Value *getRawFun(string name); + llvm::Type *typeForValueType(shared_ptr valueType, int count = 0); void markError(int line, int column, string message); diff --git a/src/Parser/Statement/Statement.h b/src/Parser/Statement/Statement.h index 727e480..963a9c5 100644 --- a/src/Parser/Statement/Statement.h +++ b/src/Parser/Statement/Statement.h @@ -10,6 +10,7 @@ enum class StatementKind { BLOCK, RETURN, FUNCTION, + RAW_FUNCTION, VARIABLE, ASSIGNMENT, REPEAT, diff --git a/src/Parser/Statement/StatementRawFunction.cpp b/src/Parser/Statement/StatementRawFunction.cpp new file mode 100644 index 0000000..e40d9da --- /dev/null +++ b/src/Parser/Statement/StatementRawFunction.cpp @@ -0,0 +1,12 @@ +#include "StatementRawFunction.h" + +StatementRawFunction::StatementRawFunction(string name, string rawSource): +Statement(StatementKind::RAW_FUNCTION), name(name), rawSource(rawSource) { } + +string StatementRawFunction::getName() { + return name; +} + +string StatementRawFunction::getRawSource() { + return rawSource; +} \ No newline at end of file diff --git a/src/Parser/Statement/StatementRawFunction.h b/src/Parser/Statement/StatementRawFunction.h new file mode 100644 index 0000000..1a51566 --- /dev/null +++ b/src/Parser/Statement/StatementRawFunction.h @@ -0,0 +1,14 @@ +#include "Parser/Statement/Statement.h" + +class Expression; + +class StatementRawFunction: public Statement { +private: + string name; + string rawSource; + +public: + StatementRawFunction(string name, string rawSource); + string getName(); + string getRawSource(); +}; \ No newline at end of file From 26c566f4f6ba99805d895298bf62562621ccf507 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Sun, 13 Jul 2025 11:12:35 +0900 Subject: [PATCH 02/28] Parse raw function --- samples/test.brc | 10 +++-- src/Lexer/Lexer.cpp | 92 +++++++++++++++++++++++++++++++++---------- src/Lexer/Lexer.h | 4 ++ src/Lexer/Token.h | 2 + src/Logger.cpp | 24 +++++++++-- src/Logger.h | 2 + src/Parser/Parser.cpp | 37 +++++++++++++++++ src/Parser/Parser.h | 1 + 8 files changed, 145 insertions(+), 27 deletions(-) diff --git a/samples/test.brc b/samples/test.brc index b9222ca..e6a4100 100644 --- a/samples/test.brc +++ b/samples/test.brc @@ -24,10 +24,14 @@ i u32 <- 0, rep text[i] != 0: add $1, $0 ;*/ +rawAdd raw + mov eax, 5 + mov ebx, 42 + add eax, ebx +; + main fun -> sint32 - //text data <- "Hello string!\n" - abc sint32 <- 0 - //addStuff() + rawAdd() ret 0 ; \ No newline at end of file diff --git a/src/Lexer/Lexer.cpp b/src/Lexer/Lexer.cpp index c00f19c..2985d2f 100644 --- a/src/Lexer/Lexer.cpp +++ b/src/Lexer/Lexer.cpp @@ -12,6 +12,8 @@ vector> Lexer::getTokens() { currentIndex = 0; currentLine = 0; currentColumn = 0; + foundRawSourceStart = false; + isParsingRawSource = false; tokens.clear(); errors.clear(); @@ -117,6 +119,11 @@ shared_ptr Lexer::nextToken() { return nextToken(); // gets rid of remaining white spaces without repeating the code } + // raw source + token = matchRawSourceLine(); + if (token != nullptr) + return token; + // structural token = match(TokenKind::LEFT_PAREN, "(", false); if (token != nullptr) @@ -212,6 +219,12 @@ shared_ptr Lexer::nextToken() { token = match(TokenKind::FUNCTION, "fun", true); if (token != nullptr) return token; + + token = match(TokenKind::RAW_FUNCTION, "raw", true); + if (token != nullptr) { + foundRawSourceStart = true; + return token; + } token = match(TokenKind::RETURN, "ret", true); if (token != nullptr) @@ -271,8 +284,10 @@ shared_ptr Lexer::nextToken() { // new line token = match(TokenKind::NEW_LINE, "\n", false); - if (token != nullptr) + if (token != nullptr) { + tryStartingRawSourceParsing(); return token; + } // eof token = matchEnd(); @@ -430,21 +445,6 @@ shared_ptr Lexer::matchString() { return token; } -shared_ptr Lexer::matchIdentifier() { - int nextIndex = currentIndex; - - while (nextIndex < source.length() && isIdentifier(nextIndex)) - nextIndex++; - - if (nextIndex == currentIndex || !isSeparator(nextIndex)) - return nullptr; - - string lexme = source.substr(currentIndex, nextIndex - currentIndex); - shared_ptr token = make_shared(TokenKind::IDENTIFIER, lexme, currentLine, currentColumn); - advanceWithToken(token); - return token; -} - shared_ptr Lexer::matchType() { int nextIndex = currentIndex; @@ -463,6 +463,52 @@ shared_ptr Lexer::matchType() { return token; } +shared_ptr Lexer::matchIdentifier() { + int nextIndex = currentIndex; + + while (nextIndex < source.length() && isIdentifier(nextIndex)) + nextIndex++; + + if (nextIndex == currentIndex || !isSeparator(nextIndex)) + return nullptr; + + string lexme = source.substr(currentIndex, nextIndex - currentIndex); + shared_ptr token = make_shared(TokenKind::IDENTIFIER, lexme, currentLine, currentColumn); + advanceWithToken(token); + return token; +} + +void Lexer::tryStartingRawSourceParsing() { + if (!foundRawSourceStart) + return; + + if (!tokens.at(tokens.size() - 2)->isOfKind({TokenKind::COLON, TokenKind::COMMA, TokenKind::RIGHT_ARROW})) { + foundRawSourceStart = false; + isParsingRawSource = true; + } +} + +shared_ptr Lexer::matchRawSourceLine() { + int nextIndex = currentIndex; + + if (!isParsingRawSource) + return nullptr; + + if (source.at(nextIndex) == ';') { + isParsingRawSource = false; + return nullptr; + } + + while (source.at(nextIndex) != '\n') + nextIndex++; + + string lexme = source.substr(currentIndex, nextIndex - currentIndex); + shared_ptr token = make_shared(TokenKind::RAW_SOURCE_LINE, lexme, currentLine, currentColumn); + advanceWithToken(token); + currentIndex++; // skip newline + return token; +} + shared_ptr Lexer::matchEnd() { if (currentIndex >= source.length()) return make_shared(TokenKind::END, "", currentLine, currentColumn); @@ -530,11 +576,15 @@ bool Lexer::isSeparator(int index) { } void Lexer::advanceWithToken(shared_ptr token) { - if (token->getKind() == TokenKind::NEW_LINE) { - currentLine++; - currentColumn = 0; - } else { - currentColumn += token->getLexme().length(); + switch (token->getKind()) { + case TokenKind::NEW_LINE: + case TokenKind::RAW_SOURCE_LINE: + currentLine++; + currentColumn = 0; + break; + default: + currentColumn += token->getLexme().length(); + break; } currentIndex += token->getLexme().length(); } diff --git a/src/Lexer/Lexer.h b/src/Lexer/Lexer.h index 9cc8cc6..805ad50 100644 --- a/src/Lexer/Lexer.h +++ b/src/Lexer/Lexer.h @@ -17,6 +17,8 @@ private: int currentColumn; vector> tokens; vector> errors; + bool foundRawSourceStart; + bool isParsingRawSource; shared_ptr nextToken(); shared_ptr match(TokenKind kind, string lexme, bool needsSeparator); @@ -28,6 +30,8 @@ private: shared_ptr matchString(); shared_ptr matchType(); shared_ptr matchIdentifier(); + void tryStartingRawSourceParsing(); + shared_ptr matchRawSourceLine(); shared_ptr matchEnd(); bool isWhiteSpace(int index); diff --git a/src/Lexer/Token.h b/src/Lexer/Token.h index 2c4ce2e..c6ee86a 100644 --- a/src/Lexer/Token.h +++ b/src/Lexer/Token.h @@ -30,6 +30,8 @@ enum class TokenKind { RIGHT_ARROW, FUNCTION, + RAW_FUNCTION, + RAW_SOURCE_LINE, RETURN, REPEAT, IF, diff --git a/src/Logger.cpp b/src/Logger.cpp index 9055750..8e22542 100644 --- a/src/Logger.cpp +++ b/src/Logger.cpp @@ -11,6 +11,7 @@ #include "Parser/Statement/StatementMetaExternFunction.h" #include "Parser/Statement/StatementVariable.h" #include "Parser/Statement/StatementFunction.h" +#include "Parser/Statement/StatementRawFunction.h" #include "Parser/Statement/StatementBlock.h" #include "Parser/Statement/StatementAssignment.h" #include "Parser/Statement/StatementReturn.h" @@ -97,6 +98,10 @@ string Logger::toString(shared_ptr token) { return "ELSE"; case TokenKind::FUNCTION: return "FUN"; + case TokenKind::RAW_FUNCTION: + return "RAW"; + case TokenKind::RAW_SOURCE_LINE: + return format("RAW_SOURCE_LINE({})", token->getLexme()); case TokenKind::RETURN: return "RET"; case TokenKind::REPEAT: @@ -179,6 +184,8 @@ string Logger::toString(TokenKind tokenKind) { return "ELSE"; case TokenKind::FUNCTION: return "FUN"; + case TokenKind::RAW_FUNCTION: + return "RAW"; case TokenKind::RETURN: return "RET"; case TokenKind::REPEAT: @@ -217,6 +224,8 @@ string Logger::toString(shared_ptr statement) { return toString(dynamic_pointer_cast(statement)); case StatementKind::FUNCTION: return toString(dynamic_pointer_cast(statement)); + case StatementKind::RAW_FUNCTION: + return toString(dynamic_pointer_cast(statement)); case StatementKind::BLOCK: return toString(dynamic_pointer_cast(statement)); case StatementKind::ASSIGNMENT: @@ -262,6 +271,15 @@ string Logger::toString(shared_ptr statement) { return text; } +string Logger::toString(shared_ptr statement) { + string text; + + text += format("RAW(\"{}\"):\n", statement->getName()); + text += statement->getRawSource(); + + return text; +} + string Logger::toString(shared_ptr statement) { string text; @@ -468,13 +486,13 @@ void Logger::print(shared_ptr error) { if (expectedTokenKind) { message = format( - "Expected token {} but instead found \"{}\" at line: {}, column: {}", - toString(*expectedTokenKind), token->getLexme(), token->getLine() + 1, token->getColumn() + 1 + "Expected token {} but instead found {} at line: {}, column: {}", + toString(*expectedTokenKind), toString(token), token->getLine() + 1, token->getColumn() + 1 ); } else { message = format( "Unexpected token \"{}\" found at line: {}, column: {}", - token->getLexme(), token->getLine() + 1, token->getColumn() + 1 + toString(token), token->getLine() + 1, token->getColumn() + 1 ); } if (errorMessage) diff --git a/src/Logger.h b/src/Logger.h index d5f1eba..3101911 100644 --- a/src/Logger.h +++ b/src/Logger.h @@ -11,6 +11,7 @@ class Statement; class StatementMetaExternFunction; class StatementVariable; class StatementFunction; +class StatementRawFunction; class StatementBlock; class StatementAssignment; class StatementReturn; @@ -41,6 +42,7 @@ private: static string toString(shared_ptr statement); static string toString(shared_ptr statement); static string toString(shared_ptr statement); + static string toString(shared_ptr statement); static string toString(shared_ptr statement); static string toString(shared_ptr statement); static string toString(shared_ptr statement); diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index c8922ed..62bb8f7 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -16,6 +16,7 @@ #include "Parser/Expression/ExpressionBlock.h" #include "Parser/Statement/StatementFunction.h" +#include "Parser/Statement/StatementRawFunction.h" #include "Parser/Statement/StatementVariable.h" #include "Parser/Statement/StatementAssignment.h" #include "Parser/Statement/StatementReturn.h" @@ -61,6 +62,10 @@ shared_ptr Parser::nextStatement() { if (statement != nullptr || errors.size() > errorsCount) return statement; + statement = matchStatementRawFunction(); + if (statement != nullptr || errors.size() > errorsCount) + return statement; + statement = matchStatementVariable(); if (statement != nullptr || errors.size() > errorsCount) return statement; @@ -230,6 +235,38 @@ shared_ptr Parser::matchStatementFunction() { return make_shared(name, arguments, returnType, dynamic_pointer_cast(statementBlock)); } +shared_ptr Parser::matchStatementRawFunction() { + if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER, TokenKind::RAW_FUNCTION}, true, false)) + return nullptr; + + string name; + string rawSource; + + // name + name = tokens.at(currentIndex++)->getLexme(); + currentIndex++; // skip raw + + // consume new line + if (!tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true)) { + markError(TokenKind::NEW_LINE, {}); + return nullptr; + } + + // source + while (tryMatchingTokenKinds({TokenKind::RAW_SOURCE_LINE}, true, false)) { + if (!rawSource.empty()) + rawSource += "\n"; + rawSource += tokens.at(currentIndex++)->getLexme(); + } + + if(!tryMatchingTokenKinds({TokenKind::SEMICOLON}, false, true)) { + markError(TokenKind::SEMICOLON, {}); + return nullptr; + } + + return make_shared(name, rawSource); +} + shared_ptr Parser::matchStatementBlock(vector terminalTokenKinds) { vector> statements; diff --git a/src/Parser/Parser.h b/src/Parser/Parser.h index 952a087..fdfe4a2 100644 --- a/src/Parser/Parser.h +++ b/src/Parser/Parser.h @@ -26,6 +26,7 @@ private: shared_ptr matchStatementMetaExternFunction(); shared_ptr matchStatementVariable(); shared_ptr matchStatementFunction(); + shared_ptr matchStatementRawFunction(); shared_ptr matchStatementBlock(vector terminalTokenKinds); shared_ptr matchStatementAssignment(); From 228dd804236192769b7b94b0389dfa225669ac5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Sun, 13 Jul 2025 15:06:52 +0900 Subject: [PATCH 03/28] Build raw function --- samples/test.brc | 6 +++-- src/Compiler/ModuleBuilder.cpp | 40 +++++++++++++++++++++------------- src/Compiler/ModuleBuilder.h | 6 ++--- src/Parser/Parser.cpp | 3 +++ 4 files changed, 35 insertions(+), 20 deletions(-) diff --git a/samples/test.brc b/samples/test.brc index e6a4100..ec9d515 100644 --- a/samples/test.brc +++ b/samples/test.brc @@ -25,8 +25,10 @@ i u32 <- 0, rep text[i] != 0: ;*/ rawAdd raw - mov eax, 5 - mov ebx, 42 + //push rbx + mov ebx, 5 + //pop rbx + mov eax, 42 add eax, ebx ; diff --git a/src/Compiler/ModuleBuilder.cpp b/src/Compiler/ModuleBuilder.cpp index dcb14c2..979efa3 100644 --- a/src/Compiler/ModuleBuilder.cpp +++ b/src/Compiler/ModuleBuilder.cpp @@ -131,8 +131,11 @@ void ModuleBuilder::buildFunctionDeclaration(shared_ptr state } void ModuleBuilder::buildRawFunction(shared_ptr statement) { - llvm::FunctionType *funType = llvm::FunctionType::get(llvm::Type::getVoidTy(*context), nullptr, false); - llvm::InlineAsm *rawFun = llvm::InlineAsm::get(funType, statement->getRawSource(), "", false, false, llvm::InlineAsm::AsmDialect::AD_Intel); + // get argument types + vector types; + + llvm::FunctionType *funType = llvm::FunctionType::get(llvm::Type::getVoidTy(*context), types, false); + llvm::InlineAsm *rawFun = llvm::InlineAsm::get(funType, statement->getRawSource(), "~{ebx}", false, false, llvm::InlineAsm::AsmDialect::AD_Intel); if (!setRawFun(statement->getName(), rawFun)) return; @@ -508,15 +511,24 @@ llvm::Value *ModuleBuilder::valueForVar(shared_ptr expressio llvm::Value *ModuleBuilder::valueForCall(shared_ptr expression) { llvm::Function *fun = getFun(expression->getName()); - if (fun == nullptr) - return nullptr; - llvm::FunctionType *funType = fun->getFunctionType(); - vector argValues; - for (shared_ptr &argumentExpression : expression->getArgumentExpressions()) { - llvm::Value *argValue = valueForExpression(argumentExpression); - argValues.push_back(argValue); + if (fun != nullptr) { + llvm::FunctionType *funType = fun->getFunctionType(); + vector argValues; + for (shared_ptr &argumentExpression : expression->getArgumentExpressions()) { + llvm::Value *argValue = valueForExpression(argumentExpression); + argValues.push_back(argValue); + } + return builder->CreateCall(funType, fun, llvm::ArrayRef(argValues)); } - return builder->CreateCall(funType, fun, llvm::ArrayRef(argValues)); + + llvm::InlineAsm *rawFun = getRawFun(expression->getName()); + if (rawFun != nullptr) { + vectorargValues; + return builder->CreateCall(rawFun, llvm::ArrayRef(argValues)); + } + + markError(0, 0, format("Function \"{}\" not defined in scope", expression->getName())); + return nullptr; } bool ModuleBuilder::setAlloca(string name, llvm::AllocaInst *alloca) { @@ -563,11 +575,10 @@ llvm::Function* ModuleBuilder::getFun(string name) { scopes.pop(); } - markError(0, 0, format("Function \"{}\" not defined in scope", name)); return nullptr; } -bool ModuleBuilder::setRawFun(string name, llvm::Value *rawFun) { +bool ModuleBuilder::setRawFun(string name, llvm::InlineAsm *rawFun) { if (scopes.top().rawFunMap[name] != nullptr) { markError(0, 0, format("Raw function \"{}\" already defined in scope", name)); return false; @@ -577,17 +588,16 @@ bool ModuleBuilder::setRawFun(string name, llvm::Value *rawFun) { return true; } -llvm::Value *ModuleBuilder::getRawFun(string name) { +llvm::InlineAsm *ModuleBuilder::getRawFun(string name) { stack scopes = this->scopes; while (!scopes.empty()) { - llvm::Value *rawFun = scopes.top().rawFunMap[name]; + llvm::InlineAsm *rawFun = scopes.top().rawFunMap[name]; if (rawFun != nullptr) return rawFun; scopes.pop(); } - markError(0, 0, format("Raw function \"{}\" not defined in scope", name)); return nullptr; } diff --git a/src/Compiler/ModuleBuilder.h b/src/Compiler/ModuleBuilder.h index 2631e54..6518f6e 100644 --- a/src/Compiler/ModuleBuilder.h +++ b/src/Compiler/ModuleBuilder.h @@ -41,7 +41,7 @@ using namespace std; typedef struct { map allocaMap; map funMap; - map rawFunMap; + map rawFunMap; } Scope; class ModuleBuilder { @@ -92,8 +92,8 @@ private: bool setFun(string name, llvm::Function *fun); llvm::Function *getFun(string name); - bool setRawFun(string name, llvm::Value *rawFun); - llvm::Value *getRawFun(string name); + bool setRawFun(string name, llvm::InlineAsm *rawFun); + llvm::InlineAsm *getRawFun(string name); llvm::Type *typeForValueType(shared_ptr valueType, int count = 0); diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index 62bb8f7..6759a14 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -257,6 +257,9 @@ shared_ptr Parser::matchStatementRawFunction() { if (!rawSource.empty()) rawSource += "\n"; rawSource += tokens.at(currentIndex++)->getLexme(); + + // Consume optional new line (for example because of a comment) + tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true); } if(!tryMatchingTokenKinds({TokenKind::SEMICOLON}, false, true)) { From 5616036c17507df465e30032369b522a79fc8579 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Mon, 14 Jul 2025 21:40:18 +0900 Subject: [PATCH 04/28] Pass in constraints --- samples/test.brc | 4 ++-- src/Compiler/ModuleBuilder.cpp | 2 +- src/Parser/Parser.cpp | 16 +++++++++++++++- src/Parser/Statement/StatementRawFunction.cpp | 8 ++++++-- src/Parser/Statement/StatementRawFunction.h | 4 +++- 5 files changed, 27 insertions(+), 7 deletions(-) diff --git a/samples/test.brc b/samples/test.brc index ec9d515..ed136ac 100644 --- a/samples/test.brc +++ b/samples/test.brc @@ -20,11 +20,11 @@ i u32 <- 0, rep text[i] != 0: // text data <- "Hello world!" -/*addStuff asm<+r, r>: num1 u32, num2 u32 -> u32 +/*addStuff asm<"+r, r">: num1 u32, num2 u32 -> u32 add $1, $0 ;*/ -rawAdd raw +rawAdd raw<"~{ebx}"> //push rbx mov ebx, 5 //pop rbx diff --git a/src/Compiler/ModuleBuilder.cpp b/src/Compiler/ModuleBuilder.cpp index 979efa3..d9b5194 100644 --- a/src/Compiler/ModuleBuilder.cpp +++ b/src/Compiler/ModuleBuilder.cpp @@ -135,7 +135,7 @@ void ModuleBuilder::buildRawFunction(shared_ptr statement) vector types; llvm::FunctionType *funType = llvm::FunctionType::get(llvm::Type::getVoidTy(*context), types, false); - llvm::InlineAsm *rawFun = llvm::InlineAsm::get(funType, statement->getRawSource(), "~{ebx}", false, false, llvm::InlineAsm::AsmDialect::AD_Intel); + llvm::InlineAsm *rawFun = llvm::InlineAsm::get(funType, statement->getRawSource(), statement->getConstraints(), false, false, llvm::InlineAsm::AsmDialect::AD_Intel); if (!setRawFun(statement->getName(), rawFun)) return; diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index 6759a14..54c4e1f 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -240,12 +240,26 @@ shared_ptr Parser::matchStatementRawFunction() { return nullptr; string name; + string constraints; string rawSource; // name name = tokens.at(currentIndex++)->getLexme(); currentIndex++; // skip raw + // constraints + + if (tryMatchingTokenKinds({TokenKind::LESS}, true, true)) { + if (tokens.at(currentIndex)->isOfKind({TokenKind::STRING})) { + constraints = tokens.at(currentIndex++)->getLexme(); + // remove enclosing quotes + if (constraints.length() >= 2) + constraints = constraints.substr(1, constraints.length() - 2); + } + if (!tryMatchingTokenKinds({TokenKind::GREATER}, true, true)) + markError({TokenKind::GREATER}, {}); + } + // consume new line if (!tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true)) { markError(TokenKind::NEW_LINE, {}); @@ -267,7 +281,7 @@ shared_ptr Parser::matchStatementRawFunction() { return nullptr; } - return make_shared(name, rawSource); + return make_shared(name, constraints, rawSource); } shared_ptr Parser::matchStatementBlock(vector terminalTokenKinds) { diff --git a/src/Parser/Statement/StatementRawFunction.cpp b/src/Parser/Statement/StatementRawFunction.cpp index e40d9da..5369a42 100644 --- a/src/Parser/Statement/StatementRawFunction.cpp +++ b/src/Parser/Statement/StatementRawFunction.cpp @@ -1,12 +1,16 @@ #include "StatementRawFunction.h" -StatementRawFunction::StatementRawFunction(string name, string rawSource): -Statement(StatementKind::RAW_FUNCTION), name(name), rawSource(rawSource) { } +StatementRawFunction::StatementRawFunction(string name, string constraints, string rawSource): +Statement(StatementKind::RAW_FUNCTION), name(name), constraints(constraints), rawSource(rawSource) { } string StatementRawFunction::getName() { return name; } +string StatementRawFunction::getConstraints() { + return constraints; +} + string StatementRawFunction::getRawSource() { return rawSource; } \ No newline at end of file diff --git a/src/Parser/Statement/StatementRawFunction.h b/src/Parser/Statement/StatementRawFunction.h index 1a51566..989e5ea 100644 --- a/src/Parser/Statement/StatementRawFunction.h +++ b/src/Parser/Statement/StatementRawFunction.h @@ -5,10 +5,12 @@ class Expression; class StatementRawFunction: public Statement { private: string name; + string constraints; string rawSource; public: - StatementRawFunction(string name, string rawSource); + StatementRawFunction(string name, string constraints, string rawSource); string getName(); + string getConstraints(); string getRawSource(); }; \ No newline at end of file From 51115f5883c5b6d7fd5c8e676fdf30e1f00444a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Tue, 15 Jul 2025 10:23:32 +0900 Subject: [PATCH 05/28] Added args and return type --- src/Compiler/ModuleBuilder.cpp | 26 +++++-------------- src/Parser/Parser.cpp | 8 +++++- src/Parser/Statement/StatementRawFunction.cpp | 12 +++++++-- src/Parser/Statement/StatementRawFunction.h | 8 ++++-- 4 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/Compiler/ModuleBuilder.cpp b/src/Compiler/ModuleBuilder.cpp index d9b5194..e06d831 100644 --- a/src/Compiler/ModuleBuilder.cpp +++ b/src/Compiler/ModuleBuilder.cpp @@ -131,29 +131,17 @@ void ModuleBuilder::buildFunctionDeclaration(shared_ptr state } void ModuleBuilder::buildRawFunction(shared_ptr statement) { - // get argument types - vector types; + // function types + llvm::Type *returnType = typeForValueType(statement->getReturnValueType()); + vector argTypes; + for (pair> &arg : statement->getArguments()) + argTypes.push_back(typeForValueType(arg.second)); - llvm::FunctionType *funType = llvm::FunctionType::get(llvm::Type::getVoidTy(*context), types, false); + // function declaration & body + llvm::FunctionType *funType = llvm::FunctionType::get(returnType, argTypes, false); llvm::InlineAsm *rawFun = llvm::InlineAsm::get(funType, statement->getRawSource(), statement->getConstraints(), false, false, llvm::InlineAsm::AsmDialect::AD_Intel); if (!setRawFun(statement->getName(), rawFun)) return; - - /*int res; - int a = 42; - int b = 13; - - vector types; - types.push_back(typeSint32); - types.push_back(typeSint32); - llvm::FunctionType *asmType = llvm::FunctionType::get(typeSint32, types, false); - llvm::InlineAsm *asmm = llvm::InlineAsm::get(asmType, "add $0, $1", "+{ebx},i", false, false, llvm::InlineAsm::AsmDialect::AD_Intel); - - vectorargValues; - argValues.push_back(llvm::ConstantInt::get(typeSint32, 5, true)); - argValues.push_back(llvm::ConstantInt::get(typeSint32, 4, true)); - - llvm::Value *valu = builder->CreateCall(asmm, llvm::ArrayRef(argValues));*/ } void ModuleBuilder::buildVarDeclaration(shared_ptr statement) { diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index 54c4e1f..c012bf6 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -241,6 +241,8 @@ shared_ptr Parser::matchStatementRawFunction() { string name; string constraints; + vector>> arguments; + shared_ptr returnType = ValueType::NONE; string rawSource; // name @@ -260,6 +262,10 @@ shared_ptr Parser::matchStatementRawFunction() { markError({TokenKind::GREATER}, {}); } + // arguments + + // return type + // consume new line if (!tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true)) { markError(TokenKind::NEW_LINE, {}); @@ -281,7 +287,7 @@ shared_ptr Parser::matchStatementRawFunction() { return nullptr; } - return make_shared(name, constraints, rawSource); + return make_shared(name, constraints, arguments, returnType, rawSource); } shared_ptr Parser::matchStatementBlock(vector terminalTokenKinds) { diff --git a/src/Parser/Statement/StatementRawFunction.cpp b/src/Parser/Statement/StatementRawFunction.cpp index 5369a42..6417c6a 100644 --- a/src/Parser/Statement/StatementRawFunction.cpp +++ b/src/Parser/Statement/StatementRawFunction.cpp @@ -1,7 +1,7 @@ #include "StatementRawFunction.h" -StatementRawFunction::StatementRawFunction(string name, string constraints, string rawSource): -Statement(StatementKind::RAW_FUNCTION), name(name), constraints(constraints), rawSource(rawSource) { } +StatementRawFunction::StatementRawFunction(string name, string constraints, vector>> arguments, shared_ptr returnValueType, string rawSource): +Statement(StatementKind::RAW_FUNCTION), name(name), constraints(constraints), arguments(arguments), returnValueType(returnValueType), rawSource(rawSource) { } string StatementRawFunction::getName() { return name; @@ -11,6 +11,14 @@ string StatementRawFunction::getConstraints() { return constraints; } +vector>> StatementRawFunction::getArguments() { + return arguments; +} + +shared_ptr StatementRawFunction::getReturnValueType() { + return returnValueType; +} + string StatementRawFunction::getRawSource() { return rawSource; } \ No newline at end of file diff --git a/src/Parser/Statement/StatementRawFunction.h b/src/Parser/Statement/StatementRawFunction.h index 989e5ea..372592f 100644 --- a/src/Parser/Statement/StatementRawFunction.h +++ b/src/Parser/Statement/StatementRawFunction.h @@ -1,16 +1,20 @@ #include "Parser/Statement/Statement.h" -class Expression; +class ValueType; class StatementRawFunction: public Statement { private: string name; string constraints; + vector>> arguments; + shared_ptr returnValueType; string rawSource; public: - StatementRawFunction(string name, string constraints, string rawSource); + StatementRawFunction(string name, string constraints, vector>> arguments, shared_ptr returnValueType, string rawSource); string getName(); string getConstraints(); + vector>> getArguments(); + shared_ptr getReturnValueType(); string getRawSource(); }; \ No newline at end of file From 9d991f46a25544651cdc636e3e6823bb40d73bd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Tue, 15 Jul 2025 10:27:50 +0900 Subject: [PATCH 06/28] Renamed --- src/Compiler/ModuleBuilder.cpp | 20 ++++++++++---------- src/Compiler/ModuleBuilder.h | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Compiler/ModuleBuilder.cpp b/src/Compiler/ModuleBuilder.cpp index e06d831..36adc31 100644 --- a/src/Compiler/ModuleBuilder.cpp +++ b/src/Compiler/ModuleBuilder.cpp @@ -53,7 +53,7 @@ shared_ptr ModuleBuilder::getModule() { void ModuleBuilder::buildStatement(shared_ptr statement) { switch (statement->getKind()) { case StatementKind::FUNCTION: - buildFunctionDeclaration(dynamic_pointer_cast(statement)); + buildFunction(dynamic_pointer_cast(statement)); break; case StatementKind::RAW_FUNCTION: buildRawFunction(dynamic_pointer_cast(statement)); @@ -84,15 +84,15 @@ void ModuleBuilder::buildStatement(shared_ptr statement) { } } -void ModuleBuilder::buildFunctionDeclaration(shared_ptr statement) { - // get argument types - vector types; - for (pair> &arg : statement->getArguments()) { - types.push_back(typeForValueType(arg.second)); - } +void ModuleBuilder::buildFunction(shared_ptr statement) { + // function types + llvm::Type *returnType = typeForValueType(statement->getReturnValueType()); + vector argTypes; + for (pair> &arg : statement->getArguments()) + argTypes.push_back(typeForValueType(arg.second)); // build function declaration - llvm::FunctionType *funType = llvm::FunctionType::get(typeForValueType(statement->getReturnValueType()), types, false); + llvm::FunctionType *funType = llvm::FunctionType::get(returnType, argTypes, false); llvm::Function *fun = llvm::Function::Create(funType, llvm::GlobalValue::ExternalLinkage, statement->getName(), module.get()); if (!setFun(statement->getName(), fun)) return; @@ -107,7 +107,7 @@ void ModuleBuilder::buildFunctionDeclaration(shared_ptr state int i=0; for (auto &arg : fun->args()) { string name = statement->getArguments()[i].first; - llvm::Type *type = types[i]; + llvm::Type *type = argTypes[i]; arg.setName(name); llvm::AllocaInst *alloca = builder->CreateAlloca(type, nullptr, name); @@ -137,7 +137,7 @@ void ModuleBuilder::buildRawFunction(shared_ptr statement) for (pair> &arg : statement->getArguments()) argTypes.push_back(typeForValueType(arg.second)); - // function declaration & body + // build function declaration & body llvm::FunctionType *funType = llvm::FunctionType::get(returnType, argTypes, false); llvm::InlineAsm *rawFun = llvm::InlineAsm::get(funType, statement->getRawSource(), statement->getConstraints(), false, false, llvm::InlineAsm::AsmDialect::AD_Intel); if (!setRawFun(statement->getName(), rawFun)) diff --git a/src/Compiler/ModuleBuilder.h b/src/Compiler/ModuleBuilder.h index 6518f6e..3378856 100644 --- a/src/Compiler/ModuleBuilder.h +++ b/src/Compiler/ModuleBuilder.h @@ -63,7 +63,7 @@ private: stack scopes; void buildStatement(shared_ptr statement); - void buildFunctionDeclaration(shared_ptr statement); + void buildFunction(shared_ptr statement); void buildRawFunction(shared_ptr statement); void buildVarDeclaration(shared_ptr statement); void buildAssignment(shared_ptr statement); From fbc71f4a31f34e3bc86b85992d3b9ed92ef9e1bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Tue, 15 Jul 2025 13:10:03 +0900 Subject: [PATCH 07/28] Arguments for raw calls --- samples/test.brc | 28 +++++++++++++++++++++------- src/Compiler/ModuleBuilder.cpp | 12 +++++++++++- src/Lexer/Lexer.cpp | 2 +- src/Logger.cpp | 8 +++++++- src/Parser/Parser.cpp | 26 ++++++++++++++++++++++++++ 5 files changed, 66 insertions(+), 10 deletions(-) diff --git a/samples/test.brc b/samples/test.brc index ed136ac..64e0a6e 100644 --- a/samples/test.brc +++ b/samples/test.brc @@ -24,16 +24,30 @@ i u32 <- 0, rep text[i] != 0: add $1, $0 ;*/ -rawAdd raw<"~{ebx}"> - //push rbx - mov ebx, 5 - //pop rbx - mov eax, 42 - add eax, ebx +normAdd fun: num1 sint32, num2 sint32 -> sint32 + ret num1 + num2 ; +rawAdd raw<"=r,r,r">: num1 sint32, num2 sint32 -> sint32 + add $1, $2 + mov $0, $1 +; + +/*printChar raw + .global REGISTER + .text + .REGISTER: + .byte "Hello", 0xa0 + .long RegisterTable + //push 0x21 + +;*/ + main fun -> sint32 - rawAdd() + //printChar() + + res1 sint32 <- normAdd(4, 5) + res2 sint32 <- rawAdd(4, 5) ret 0 ; \ No newline at end of file diff --git a/src/Compiler/ModuleBuilder.cpp b/src/Compiler/ModuleBuilder.cpp index 36adc31..525652c 100644 --- a/src/Compiler/ModuleBuilder.cpp +++ b/src/Compiler/ModuleBuilder.cpp @@ -41,6 +41,12 @@ shared_ptr ModuleBuilder::getModule() { for (shared_ptr &statement : statements) buildStatement(statement); + // verify module + string errorMessage; + llvm::raw_string_ostream llvmErrorMessage(errorMessage); + if (llvm::verifyModule(*module, &llvmErrorMessage)) + markError(0, 0, errorMessage); + if (!errors.empty()) { for (shared_ptr &error : errors) Logger::print(error); @@ -139,7 +145,7 @@ void ModuleBuilder::buildRawFunction(shared_ptr statement) // build function declaration & body llvm::FunctionType *funType = llvm::FunctionType::get(returnType, argTypes, false); - llvm::InlineAsm *rawFun = llvm::InlineAsm::get(funType, statement->getRawSource(), statement->getConstraints(), false, false, llvm::InlineAsm::AsmDialect::AD_Intel); + llvm::InlineAsm *rawFun = llvm::InlineAsm::get(funType, statement->getRawSource(), statement->getConstraints(), true, false, llvm::InlineAsm::AsmDialect::AD_Intel); if (!setRawFun(statement->getName(), rawFun)) return; } @@ -512,6 +518,10 @@ llvm::Value *ModuleBuilder::valueForCall(shared_ptr expression) llvm::InlineAsm *rawFun = getRawFun(expression->getName()); if (rawFun != nullptr) { vectorargValues; + for (shared_ptr &argumentExpression : expression->getArgumentExpressions()) { + llvm::Value *argValue = valueForExpression(argumentExpression); + argValues.push_back(argValue); + } return builder->CreateCall(rawFun, llvm::ArrayRef(argValues)); } diff --git a/src/Lexer/Lexer.cpp b/src/Lexer/Lexer.cpp index 2985d2f..0706245 100644 --- a/src/Lexer/Lexer.cpp +++ b/src/Lexer/Lexer.cpp @@ -482,7 +482,7 @@ void Lexer::tryStartingRawSourceParsing() { if (!foundRawSourceStart) return; - if (!tokens.at(tokens.size() - 2)->isOfKind({TokenKind::COLON, TokenKind::COMMA, TokenKind::RIGHT_ARROW})) { + if (!tokens.at(tokens.size() - 1)->isOfKind({TokenKind::COLON, TokenKind::COMMA, TokenKind::RIGHT_ARROW})) { foundRawSourceStart = false; isParsingRawSource = true; } diff --git a/src/Logger.cpp b/src/Logger.cpp index 8e22542..b8f85e0 100644 --- a/src/Logger.cpp +++ b/src/Logger.cpp @@ -274,7 +274,13 @@ string Logger::toString(shared_ptr statement) { string Logger::toString(shared_ptr statement) { string text; - text += format("RAW(\"{}\"):\n", statement->getName()); + string argsString; + for (int i = 0; i < statement->getArguments().size(); i++) { + auto arg = statement->getArguments().at(i); + argsString += format("ARG({}, {})", arg.first, toString(arg.second)); + } + text += format("RAW(\"{}\"|{}|{}):\n", statement->getName(), argsString, toString(statement->getReturnValueType())); + text += statement->getRawSource(); return text; diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index c012bf6..9852fa2 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -263,8 +263,34 @@ shared_ptr Parser::matchStatementRawFunction() { } // arguments + if (tryMatchingTokenKinds({TokenKind::COLON}, true, true)) { + do { + tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true); // skip new line + if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER, TokenKind::TYPE}, true, false)) { + markError({}, "Expected function argument"); + return nullptr; + } + shared_ptr identifierToken = tokens.at(currentIndex++); + shared_ptr argumentType = matchValueType(); + if (argumentType == nullptr) { + markError(TokenKind::TYPE, {}); + return nullptr; + } + + arguments.push_back(pair>(identifierToken->getLexme(), argumentType)); + } while (tryMatchingTokenKinds({TokenKind::COMMA}, true, true)); + } // return type + if (tryMatchingTokenKinds({TokenKind::RIGHT_ARROW}, true, true)) { + tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true); // skip new line + + returnType = matchValueType(); + if (returnType == nullptr) { + markError(TokenKind::TYPE, {}); + return nullptr; + } + } // consume new line if (!tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true)) { From dc6668459f0bc42e940b51fa6d1a2eb876ac120a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Tue, 15 Jul 2025 18:50:15 +0900 Subject: [PATCH 08/28] Added parsee and parsee group --- src/Parser/Parsee.cpp | 39 +++++++++++++++++++++++++++++++++ src/Parser/Parsee.h | 37 +++++++++++++++++++++++++++++++ src/Parser/Parser.cpp | 51 +++++++++++++++++++++++++++++++++++++++++++ src/Parser/Parser.h | 3 +++ 4 files changed, 130 insertions(+) create mode 100644 src/Parser/Parsee.cpp create mode 100644 src/Parser/Parsee.h diff --git a/src/Parser/Parsee.cpp b/src/Parser/Parsee.cpp new file mode 100644 index 0000000..735be13 --- /dev/null +++ b/src/Parser/Parsee.cpp @@ -0,0 +1,39 @@ +#include "Parsee.h" + +#include "Lexer/Token.h" + +ParseeToken::ParseeToken(TokenKind tokenKind, bool isRequired, bool shouldReturn): +tokenKind(tokenKind), isRequired(isRequired), shouldReturn(shouldReturn) { } + +TokenKind ParseeToken::getTokenKind() { + return tokenKind; +} + +bool ParseeToken::getIsRequired() { + return isRequired; +} + +bool ParseeToken::getShouldReturn() { + return shouldReturn; +} + +ParseeTokensGroup::ParseeTokensGroup(bool isRequired, vector tokens, optional repeatedGroup): +isRequired(isRequired), tokens(tokens) { + if (repeatedGroup) { + this->repeatedGroup = *repeatedGroup; + } else { + this->repeatedGroup = {}; + } + } + +bool ParseeTokensGroup::getIsRequired() { + return isRequired; +} + +vector ParseeTokensGroup::getTokens() { + return tokens; +} + +optional> ParseeTokensGroup::getRepeatedGroup() { + return repeatedGroup; +} \ No newline at end of file diff --git a/src/Parser/Parsee.h b/src/Parser/Parsee.h new file mode 100644 index 0000000..22c274e --- /dev/null +++ b/src/Parser/Parsee.h @@ -0,0 +1,37 @@ +#ifndef PARSEE_H +#define PARSEE_H + +#include +#include + +enum class TokenKind; + +using namespace std; + +class ParseeToken { +private: + TokenKind tokenKind; + bool isRequired; + bool shouldReturn; + +public: + ParseeToken(TokenKind tokenKind, bool isRequired, bool shouldReturn); + TokenKind getTokenKind(); + bool getIsRequired(); + bool getShouldReturn(); +}; + +class ParseeTokensGroup { +private: + bool isRequired; + vector tokens; + optional> repeatedGroup; + +public: + ParseeTokensGroup(bool isRequired, vector tokens, optional repeatedGroup); + bool getIsRequired(); + vector getTokens(); + optional> getRepeatedGroup(); +}; + +#endif \ No newline at end of file diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index 9852fa2..f4f824c 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -25,6 +25,8 @@ #include "Parser/Statement/StatementBlock.h" #include "Parser/Statement/StatementRepeat.h" +#include "Parsee.h" + Parser::Parser(vector> tokens) : tokens(tokens) { } @@ -236,6 +238,55 @@ shared_ptr Parser::matchStatementFunction() { } shared_ptr Parser::matchStatementRawFunction() { + ParseeTokensGroup idGroup = ParseeTokensGroup( + true, + { + ParseeToken(TokenKind::IDENTIFIER, true, true), + ParseeToken(TokenKind::RAW_FUNCTION, true, false) + }, + {} + ); + + ParseeTokensGroup optionsGroup = ParseeTokensGroup( + false, + { + ParseeToken(TokenKind::LESS, true, false), + ParseeToken(TokenKind::STRING, true, true), + ParseeToken(TokenKind::GREATER, true, false) + }, + {} + ); + + ParseeTokensGroup argumentsGroup = ParseeTokensGroup( + false, + { + ParseeToken(TokenKind::COLON, true, false), + ParseeToken(TokenKind::NEW_LINE, false, false), + ParseeToken(TokenKind::IDENTIFIER, true, true), + ParseeToken(TokenKind::TYPE, true, true) + }, + ParseeTokensGroup( + true, + { + ParseeToken(TokenKind::COMMA, true, false), + ParseeToken(TokenKind::NEW_LINE, false, false), + ParseeToken(TokenKind::IDENTIFIER, true, true), + ParseeToken(TokenKind::TYPE, true, true) + }, + {} + ) + ); + + ParseeTokensGroup returnGroup = ParseeTokensGroup( + false, + { + ParseeToken(TokenKind::RIGHT_ARROW, true, false), + ParseeToken(TokenKind::NEW_LINE, false, false), + ParseeToken(TokenKind::TYPE, true, true) + }, + {} + ); + if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER, TokenKind::RAW_FUNCTION}, true, false)) return nullptr; diff --git a/src/Parser/Parser.h b/src/Parser/Parser.h index fdfe4a2..026c609 100644 --- a/src/Parser/Parser.h +++ b/src/Parser/Parser.h @@ -12,6 +12,9 @@ class ValueType; class Expression; class Statement; +class ParseeToken; +class ParseeTokensGroup; + using namespace std; class Parser { From 1dc6010b9b2de9fd738f5f10c21b5d08f511787f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Tue, 15 Jul 2025 23:30:28 +0900 Subject: [PATCH 09/28] wip --- samples/test.brc | 6 +- src/Parser/Parser.cpp | 183 ++++++++++++++++++++++++++++++------------ src/Parser/Parser.h | 1 + 3 files changed, 136 insertions(+), 54 deletions(-) diff --git a/samples/test.brc b/samples/test.brc index 64e0a6e..78e2ede 100644 --- a/samples/test.brc +++ b/samples/test.brc @@ -1,4 +1,4 @@ -@extern putchar fun: character sint32 -> sint32 +//@extern putchar fun: character sint32 -> sint32 // ./build/brb samples/test.brc -S -x86-asm-syntax=intel @@ -24,9 +24,9 @@ i u32 <- 0, rep text[i] != 0: add $1, $0 ;*/ -normAdd fun: num1 sint32, num2 sint32 -> sint32 +/*normAdd fun: num1 sint32, num2 sint32 -> sint32 ret num1 + num2 -; +;*/ rawAdd raw<"=r,r,r">: num1 sint32, num2 sint32 -> sint32 add $1, $2 diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index f4f824c..9f37104 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -238,62 +238,105 @@ shared_ptr Parser::matchStatementFunction() { } shared_ptr Parser::matchStatementRawFunction() { - ParseeTokensGroup idGroup = ParseeTokensGroup( - true, - { - ParseeToken(TokenKind::IDENTIFIER, true, true), - ParseeToken(TokenKind::RAW_FUNCTION, true, false) - }, - {} - ); - - ParseeTokensGroup optionsGroup = ParseeTokensGroup( - false, - { - ParseeToken(TokenKind::LESS, true, false), - ParseeToken(TokenKind::STRING, true, true), - ParseeToken(TokenKind::GREATER, true, false) - }, - {} - ); - - ParseeTokensGroup argumentsGroup = ParseeTokensGroup( - false, - { - ParseeToken(TokenKind::COLON, true, false), - ParseeToken(TokenKind::NEW_LINE, false, false), - ParseeToken(TokenKind::IDENTIFIER, true, true), - ParseeToken(TokenKind::TYPE, true, true) - }, - ParseeTokensGroup( - true, - { - ParseeToken(TokenKind::COMMA, true, false), - ParseeToken(TokenKind::NEW_LINE, false, false), - ParseeToken(TokenKind::IDENTIFIER, true, true), - ParseeToken(TokenKind::TYPE, true, true) - }, - {} - ) - ); - - ParseeTokensGroup returnGroup = ParseeTokensGroup( - false, - { - ParseeToken(TokenKind::RIGHT_ARROW, true, false), - ParseeToken(TokenKind::NEW_LINE, false, false), - ParseeToken(TokenKind::TYPE, true, true) - }, - {} - ); - - if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER, TokenKind::RAW_FUNCTION}, true, false)) - return nullptr; + bool hasError = false; + optional>> groupTokens; string name; string constraints; vector>> arguments; shared_ptr returnType = ValueType::NONE; + + // identifier + groupTokens = tokensForParseeTokensGroup( + ParseeTokensGroup( + true, + { + ParseeToken(TokenKind::IDENTIFIER, true, true), + ParseeToken(TokenKind::RAW_FUNCTION, true, false) + }, + {} + ) + ); + if (groupTokens) { + name = (*groupTokens).at(0)->getLexme(); + } else { + hasError = true; + } + + // options + if (!hasError) { + groupTokens = tokensForParseeTokensGroup( + ParseeTokensGroup( + false, + { + ParseeToken(TokenKind::LESS, true, false), + ParseeToken(TokenKind::STRING, true, true), + ParseeToken(TokenKind::GREATER, true, false) + }, + {} + ) + ); + if (groupTokens && !(*groupTokens).empty()) { + constraints = (*groupTokens).at(0)->getLexme(); + } else if (!groupTokens) { + hasError = true; + } + } + + // arguments + if (!hasError) { + groupTokens = tokensForParseeTokensGroup( + ParseeTokensGroup( + false, + { + ParseeToken(TokenKind::COLON, true, false), + ParseeToken(TokenKind::NEW_LINE, false, false), + ParseeToken(TokenKind::IDENTIFIER, true, true), + ParseeToken(TokenKind::TYPE, true, true) + }, + ParseeTokensGroup( + true, + { + ParseeToken(TokenKind::COMMA, true, false), + ParseeToken(TokenKind::NEW_LINE, false, false), + ParseeToken(TokenKind::IDENTIFIER, true, true), + ParseeToken(TokenKind::TYPE, true, true) + }, + {} + ) + ) + ); + if (groupTokens && !(*groupTokens).empty()) { + + } else if (!groupTokens) { + hasError = true; + } + } + + // return type + if (!hasError) { + groupTokens = tokensForParseeTokensGroup( + ParseeTokensGroup( + false, + { + ParseeToken(TokenKind::RIGHT_ARROW, true, false), + ParseeToken(TokenKind::NEW_LINE, false, false), + ParseeToken(TokenKind::TYPE, true, true) + }, + {} + ) + ); + + if (groupTokens && !(*groupTokens).empty()) { + + } else if (!groupTokens) { + hasError = true; + } + } + + if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER, TokenKind::RAW_FUNCTION}, true, false)) + return nullptr; + string rawSource; // name @@ -828,6 +871,44 @@ shared_ptr Parser::matchValueType() { return ValueType::valueTypeForToken(typeToken, subType, valueArg); } +optional>> Parser::tokensForParseeTokensGroup(ParseeTokensGroup group) { + int nextIndex = currentIndex; + vector> returnTokens; + bool mustFulfill = false; + + for (ParseeToken &parsee : group.getTokens()) { + shared_ptr currentToken = tokens.at(nextIndex); + bool matches = currentToken->isOfKind({parsee.getTokenKind()}); + + // if doesn't match on optional group + if (!matches && parsee.getIsRequired() && !group.getIsRequired() && mustFulfill) + return vector>(); + + // return matching token? + if (matches && parsee.getShouldReturn()) + returnTokens.push_back(currentToken); + + // decide if we're decoding the expected sequence + if (!parsee.getIsRequired() && nextIndex > currentIndex) + mustFulfill = true; + + // invalid sequence detected? + if (!matches && parsee.getIsRequired() && mustFulfill) { + currentIndex = nextIndex; + markError(parsee.getTokenKind(), {}); + return {}; + } + + // got to the next token if we got a match + if (matches) + nextIndex++; + } + + currentIndex = nextIndex; + + return returnTokens; +} + bool Parser::tryMatchingTokenKinds(vector kinds, bool shouldMatchAll, bool shouldAdvance) { int requiredCount = shouldMatchAll ? kinds.size() : 1; if (currentIndex + requiredCount > tokens.size()) diff --git a/src/Parser/Parser.h b/src/Parser/Parser.h index 026c609..3e325e6 100644 --- a/src/Parser/Parser.h +++ b/src/Parser/Parser.h @@ -55,6 +55,7 @@ private: shared_ptr matchValueType(); + optional>> tokensForParseeTokensGroup(ParseeTokensGroup group); bool tryMatchingTokenKinds(vector kinds, bool shouldMatchAll, bool shouldAdvance); void markError(optional expectedTokenKind, optional message); From 502e4d2f6f5fcd7625102eaa31b3599986f87c37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Thu, 17 Jul 2025 16:00:12 +0900 Subject: [PATCH 10/28] added parsee and parsee group --- src/Parser/Parsee.cpp | 39 --------------------- src/Parser/Parsee.h | 37 -------------------- src/Parser/Parsee/Parsee.cpp | 36 +++++++++++++++++++ src/Parser/Parsee/Parsee.h | 31 +++++++++++++++++ src/Parser/Parsee/ParseeGroup.cpp | 24 +++++++++++++ src/Parser/Parsee/ParseeGroup.h | 24 +++++++++++++ src/Parser/Parser.cpp | 57 ++++++++++++++++--------------- src/Parser/Parser.h | 5 ++- 8 files changed, 146 insertions(+), 107 deletions(-) delete mode 100644 src/Parser/Parsee.cpp delete mode 100644 src/Parser/Parsee.h create mode 100644 src/Parser/Parsee/Parsee.cpp create mode 100644 src/Parser/Parsee/Parsee.h create mode 100644 src/Parser/Parsee/ParseeGroup.cpp create mode 100644 src/Parser/Parsee/ParseeGroup.h diff --git a/src/Parser/Parsee.cpp b/src/Parser/Parsee.cpp deleted file mode 100644 index 735be13..0000000 --- a/src/Parser/Parsee.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "Parsee.h" - -#include "Lexer/Token.h" - -ParseeToken::ParseeToken(TokenKind tokenKind, bool isRequired, bool shouldReturn): -tokenKind(tokenKind), isRequired(isRequired), shouldReturn(shouldReturn) { } - -TokenKind ParseeToken::getTokenKind() { - return tokenKind; -} - -bool ParseeToken::getIsRequired() { - return isRequired; -} - -bool ParseeToken::getShouldReturn() { - return shouldReturn; -} - -ParseeTokensGroup::ParseeTokensGroup(bool isRequired, vector tokens, optional repeatedGroup): -isRequired(isRequired), tokens(tokens) { - if (repeatedGroup) { - this->repeatedGroup = *repeatedGroup; - } else { - this->repeatedGroup = {}; - } - } - -bool ParseeTokensGroup::getIsRequired() { - return isRequired; -} - -vector ParseeTokensGroup::getTokens() { - return tokens; -} - -optional> ParseeTokensGroup::getRepeatedGroup() { - return repeatedGroup; -} \ No newline at end of file diff --git a/src/Parser/Parsee.h b/src/Parser/Parsee.h deleted file mode 100644 index 22c274e..0000000 --- a/src/Parser/Parsee.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef PARSEE_H -#define PARSEE_H - -#include -#include - -enum class TokenKind; - -using namespace std; - -class ParseeToken { -private: - TokenKind tokenKind; - bool isRequired; - bool shouldReturn; - -public: - ParseeToken(TokenKind tokenKind, bool isRequired, bool shouldReturn); - TokenKind getTokenKind(); - bool getIsRequired(); - bool getShouldReturn(); -}; - -class ParseeTokensGroup { -private: - bool isRequired; - vector tokens; - optional> repeatedGroup; - -public: - ParseeTokensGroup(bool isRequired, vector tokens, optional repeatedGroup); - bool getIsRequired(); - vector getTokens(); - optional> getRepeatedGroup(); -}; - -#endif \ No newline at end of file diff --git a/src/Parser/Parsee/Parsee.cpp b/src/Parser/Parsee/Parsee.cpp new file mode 100644 index 0000000..945494e --- /dev/null +++ b/src/Parser/Parsee/Parsee.cpp @@ -0,0 +1,36 @@ +#include "Parsee.h" + +Parsee Parsee::tokenParsee(TokenKind tokenKind, bool isRequired, bool shouldReturn) { + Parsee parsee; + parsee.kind = ParseeKind::TOKEN; + parsee.tokenKind = tokenKind; + parsee.isRequired = isRequired; + parsee.shouldReturn = shouldReturn; + + return parsee; +} + +Parsee Parsee::typeParsee() { + Parsee parsee; + parsee.kind = ParseeKind::TYPE; + + return parsee; +} + +Parsee::Parsee() { } + +ParseeKind Parsee::getKind() { + return kind; +} + +TokenKind Parsee::getTokenKind() { + return tokenKind; +} + +bool Parsee::getIsRequired() { + return isRequired; +} + +bool Parsee::getShouldReturn() { + return shouldReturn; +} \ No newline at end of file diff --git a/src/Parser/Parsee/Parsee.h b/src/Parser/Parsee/Parsee.h new file mode 100644 index 0000000..649b50a --- /dev/null +++ b/src/Parser/Parsee/Parsee.h @@ -0,0 +1,31 @@ +#ifndef PARSEE_H +#define PARSEE_H + +enum class TokenKind; + +enum class ParseeKind { + TOKEN, + TYPE +}; + +class Parsee { +private: + ParseeKind kind; + TokenKind tokenKind; + bool isRequired; + bool shouldReturn; + + Parsee(); + +public: + static Parsee tokenParsee(TokenKind tokenKind, bool isRequired, bool shouldReturn); + static Parsee typeParsee(); + + ParseeKind getKind(); + + TokenKind getTokenKind(); + bool getIsRequired(); + bool getShouldReturn(); +}; + +#endif \ No newline at end of file diff --git a/src/Parser/Parsee/ParseeGroup.cpp b/src/Parser/Parsee/ParseeGroup.cpp new file mode 100644 index 0000000..debd442 --- /dev/null +++ b/src/Parser/Parsee/ParseeGroup.cpp @@ -0,0 +1,24 @@ +#include "ParseeGroup.h" + +#include "Parsee.h" + +ParseeGroup::ParseeGroup(bool isRequired, vector parsees, optional repeatedGroup): +isRequired(isRequired), parsees(parsees) { + if (repeatedGroup) { + this->repeatedGroup = *repeatedGroup; + } else { + this->repeatedGroup = {}; + } + } + +bool ParseeGroup::getIsRequired() { + return isRequired; +} + +vector ParseeGroup::getParsees() { + return parsees; +} + +optional> ParseeGroup::getRepeatedGroup() { + return repeatedGroup; +} \ No newline at end of file diff --git a/src/Parser/Parsee/ParseeGroup.h b/src/Parser/Parsee/ParseeGroup.h new file mode 100644 index 0000000..0dfb4f8 --- /dev/null +++ b/src/Parser/Parsee/ParseeGroup.h @@ -0,0 +1,24 @@ +#ifndef PARSEE_GROUP_H +#define PARSEE_GROUP_H + +#include +#include + +class Parsee; + +using namespace std; + +class ParseeGroup { +private: + bool isRequired; + vector parsees; + optional> repeatedGroup; + +public: + ParseeGroup(bool isRequired, vector parsees, optional repeatedGroup); + bool getIsRequired(); + vector getParsees(); + optional> getRepeatedGroup(); +}; + +#endif \ No newline at end of file diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index 9f37104..20fc531 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -25,7 +25,8 @@ #include "Parser/Statement/StatementBlock.h" #include "Parser/Statement/StatementRepeat.h" -#include "Parsee.h" +#include "Parsee/Parsee.h" +#include "Parsee/ParseeGroup.h" Parser::Parser(vector> tokens) : tokens(tokens) { } @@ -247,12 +248,12 @@ shared_ptr Parser::matchStatementRawFunction() { shared_ptr returnType = ValueType::NONE; // identifier - groupTokens = tokensForParseeTokensGroup( - ParseeTokensGroup( + groupTokens = tokensForParseeGroup( + ParseeGroup( true, { - ParseeToken(TokenKind::IDENTIFIER, true, true), - ParseeToken(TokenKind::RAW_FUNCTION, true, false) + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true), + Parsee::tokenParsee(TokenKind::RAW_FUNCTION, true, false) }, {} ) @@ -265,13 +266,13 @@ shared_ptr Parser::matchStatementRawFunction() { // options if (!hasError) { - groupTokens = tokensForParseeTokensGroup( - ParseeTokensGroup( + groupTokens = tokensForParseeGroup( + ParseeGroup( false, { - ParseeToken(TokenKind::LESS, true, false), - ParseeToken(TokenKind::STRING, true, true), - ParseeToken(TokenKind::GREATER, true, false) + Parsee::tokenParsee(TokenKind::LESS, true, false), + Parsee::tokenParsee(TokenKind::STRING, true, true), + Parsee::tokenParsee(TokenKind::GREATER, true, false) }, {} ) @@ -285,22 +286,22 @@ shared_ptr Parser::matchStatementRawFunction() { // arguments if (!hasError) { - groupTokens = tokensForParseeTokensGroup( - ParseeTokensGroup( + groupTokens = tokensForParseeGroup( + ParseeGroup( false, { - ParseeToken(TokenKind::COLON, true, false), - ParseeToken(TokenKind::NEW_LINE, false, false), - ParseeToken(TokenKind::IDENTIFIER, true, true), - ParseeToken(TokenKind::TYPE, true, true) + Parsee::tokenParsee(TokenKind::COLON, true, false), + Parsee::tokenParsee(TokenKind::NEW_LINE, false, false), + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true), + Parsee::typeParsee() }, - ParseeTokensGroup( + ParseeGroup( true, { - ParseeToken(TokenKind::COMMA, true, false), - ParseeToken(TokenKind::NEW_LINE, false, false), - ParseeToken(TokenKind::IDENTIFIER, true, true), - ParseeToken(TokenKind::TYPE, true, true) + Parsee::tokenParsee(TokenKind::COMMA, true, false), + Parsee::tokenParsee(TokenKind::NEW_LINE, false, false), + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true), + Parsee::typeParsee() }, {} ) @@ -315,13 +316,13 @@ shared_ptr Parser::matchStatementRawFunction() { // return type if (!hasError) { - groupTokens = tokensForParseeTokensGroup( - ParseeTokensGroup( + groupTokens = tokensForParseeGroup( + ParseeGroup( false, { - ParseeToken(TokenKind::RIGHT_ARROW, true, false), - ParseeToken(TokenKind::NEW_LINE, false, false), - ParseeToken(TokenKind::TYPE, true, true) + Parsee::tokenParsee(TokenKind::RIGHT_ARROW, true, false), + Parsee::tokenParsee(TokenKind::NEW_LINE, false, false), + Parsee::typeParsee() }, {} ) @@ -871,12 +872,12 @@ shared_ptr Parser::matchValueType() { return ValueType::valueTypeForToken(typeToken, subType, valueArg); } -optional>> Parser::tokensForParseeTokensGroup(ParseeTokensGroup group) { +optional>> Parser::tokensForParseeGroup(ParseeGroup group) { int nextIndex = currentIndex; vector> returnTokens; bool mustFulfill = false; - for (ParseeToken &parsee : group.getTokens()) { + for (Parsee &parsee : group.getParsees()) { shared_ptr currentToken = tokens.at(nextIndex); bool matches = currentToken->isOfKind({parsee.getTokenKind()}); diff --git a/src/Parser/Parser.h b/src/Parser/Parser.h index 3e325e6..cbac15e 100644 --- a/src/Parser/Parser.h +++ b/src/Parser/Parser.h @@ -12,8 +12,7 @@ class ValueType; class Expression; class Statement; -class ParseeToken; -class ParseeTokensGroup; +class ParseeGroup; using namespace std; @@ -55,7 +54,7 @@ private: shared_ptr matchValueType(); - optional>> tokensForParseeTokensGroup(ParseeTokensGroup group); + optional>> tokensForParseeGroup(ParseeGroup group); bool tryMatchingTokenKinds(vector kinds, bool shouldMatchAll, bool shouldAdvance); void markError(optional expectedTokenKind, optional message); From 8a708d8936c2aa86a335b99ba5d6c69f438b62ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Thu, 17 Jul 2025 17:14:19 +0900 Subject: [PATCH 11/28] Use parsee results --- src/Parser/Parsee/Parsee.cpp | 6 ++-- src/Parser/Parsee/Parsee.h | 6 ++-- src/Parser/Parsee/ParseeResult.cpp | 33 ++++++++++++++++++ src/Parser/Parsee/ParseeResult.h | 32 ++++++++++++++++++ src/Parser/Parser.cpp | 54 +++++++++++++++++------------- src/Parser/Parser.h | 3 +- 6 files changed, 102 insertions(+), 32 deletions(-) create mode 100644 src/Parser/Parsee/ParseeResult.cpp create mode 100644 src/Parser/Parsee/ParseeResult.h diff --git a/src/Parser/Parsee/Parsee.cpp b/src/Parser/Parsee/Parsee.cpp index 945494e..227b23e 100644 --- a/src/Parser/Parsee/Parsee.cpp +++ b/src/Parser/Parsee/Parsee.cpp @@ -10,9 +10,9 @@ Parsee Parsee::tokenParsee(TokenKind tokenKind, bool isRequired, bool shouldRetu return parsee; } -Parsee Parsee::typeParsee() { - Parsee parsee; - parsee.kind = ParseeKind::TYPE; +Parsee Parsee::valueTypeParsee() { + Parsee parsee; + parsee.kind = ParseeKind::VALUE_TYPE; return parsee; } diff --git a/src/Parser/Parsee/Parsee.h b/src/Parser/Parsee/Parsee.h index 649b50a..dc7cfd4 100644 --- a/src/Parser/Parsee/Parsee.h +++ b/src/Parser/Parsee/Parsee.h @@ -5,7 +5,7 @@ enum class TokenKind; enum class ParseeKind { TOKEN, - TYPE + VALUE_TYPE }; class Parsee { @@ -14,15 +14,13 @@ private: TokenKind tokenKind; bool isRequired; bool shouldReturn; - Parsee(); public: static Parsee tokenParsee(TokenKind tokenKind, bool isRequired, bool shouldReturn); - static Parsee typeParsee(); + static Parsee valueTypeParsee(); ParseeKind getKind(); - TokenKind getTokenKind(); bool getIsRequired(); bool getShouldReturn(); diff --git a/src/Parser/Parsee/ParseeResult.cpp b/src/Parser/Parsee/ParseeResult.cpp new file mode 100644 index 0000000..66dc619 --- /dev/null +++ b/src/Parser/Parsee/ParseeResult.cpp @@ -0,0 +1,33 @@ +#include "ParseeResult.h" + +#include "Lexer/Token.h" +#include "Parser/ValueType.h" + +ParseeResult ParseeResult::tokenResult(shared_ptr token) { + ParseeResult parseeResult; + parseeResult.kind = ParseeResultKind::TOKEN; + parseeResult.token = token; + return parseeResult; +} + +ParseeResult ParseeResult::valueTypeResult(shared_ptr valueType) { + ParseeResult parseeResult; + parseeResult.kind = ParseeResultKind::VALUE_TYPE; + parseeResult.valueType = valueType; + return parseeResult; +} + +ParseeResult::ParseeResult() { } + + +ParseeResultKind ParseeResult::getKind() { + return kind; +} + +shared_ptr ParseeResult::getToken() { + return token; +} + +shared_ptr ParseeResult::getValueType() { + return valueType; +} \ No newline at end of file diff --git a/src/Parser/Parsee/ParseeResult.h b/src/Parser/Parsee/ParseeResult.h new file mode 100644 index 0000000..a909152 --- /dev/null +++ b/src/Parser/Parsee/ParseeResult.h @@ -0,0 +1,32 @@ +#ifndef PARSEE_RESULT_H +#define PARSEE_RESULT_H + +#include + +class Token; +class ValueType; + +using namespace std; + +enum class ParseeResultKind { + TOKEN, + VALUE_TYPE, +}; + +class ParseeResult { +private: + ParseeResultKind kind; + shared_ptr token; + shared_ptr valueType; + ParseeResult(); + +public: + static ParseeResult tokenResult(shared_ptr token); + static ParseeResult valueTypeResult(shared_ptr valueType); + + ParseeResultKind getKind(); + shared_ptr getToken(); + shared_ptr getValueType(); +}; + +#endif \ No newline at end of file diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index 20fc531..cd0d81e 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -27,6 +27,7 @@ #include "Parsee/Parsee.h" #include "Parsee/ParseeGroup.h" +#include "Parsee/ParseeResult.h" Parser::Parser(vector> tokens) : tokens(tokens) { } @@ -240,7 +241,7 @@ shared_ptr Parser::matchStatementFunction() { shared_ptr Parser::matchStatementRawFunction() { bool hasError = false; - optional>> groupTokens; + optional> parseeResults; string name; string constraints; @@ -248,7 +249,7 @@ shared_ptr Parser::matchStatementRawFunction() { shared_ptr returnType = ValueType::NONE; // identifier - groupTokens = tokensForParseeGroup( + parseeResults = parseeResultsForParseeGroup( ParseeGroup( true, { @@ -258,15 +259,15 @@ shared_ptr Parser::matchStatementRawFunction() { {} ) ); - if (groupTokens) { - name = (*groupTokens).at(0)->getLexme(); + if (parseeResults) { + name = (*parseeResults).at(0).getToken()->getLexme(); } else { hasError = true; } // options if (!hasError) { - groupTokens = tokensForParseeGroup( + parseeResults = parseeResultsForParseeGroup( ParseeGroup( false, { @@ -277,23 +278,23 @@ shared_ptr Parser::matchStatementRawFunction() { {} ) ); - if (groupTokens && !(*groupTokens).empty()) { - constraints = (*groupTokens).at(0)->getLexme(); - } else if (!groupTokens) { + if (parseeResults && !(*parseeResults).empty()) { + constraints = (*parseeResults).at(0).getToken()->getLexme(); + } else if (!parseeResults) { hasError = true; } } // arguments if (!hasError) { - groupTokens = tokensForParseeGroup( + parseeResults = parseeResultsForParseeGroup( ParseeGroup( false, { Parsee::tokenParsee(TokenKind::COLON, true, false), Parsee::tokenParsee(TokenKind::NEW_LINE, false, false), Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true), - Parsee::typeParsee() + Parsee::valueTypeParsee() }, ParseeGroup( true, @@ -301,36 +302,41 @@ shared_ptr Parser::matchStatementRawFunction() { Parsee::tokenParsee(TokenKind::COMMA, true, false), Parsee::tokenParsee(TokenKind::NEW_LINE, false, false), Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true), - Parsee::typeParsee() + Parsee::valueTypeParsee() }, {} ) ) ); - if (groupTokens && !(*groupTokens).empty()) { - - } else if (!groupTokens) { + if (parseeResults && !(*parseeResults).empty()) { + for (int i=0; i<(*parseeResults).size(); i+=2) { + pair> arg; + arg.first = (*parseeResults).at(i).getToken()->getLexme(); + arg.second = (*parseeResults).at(i+1).getValueType(); + arguments.push_back(arg); + } + } else if (!parseeResults) { hasError = true; } } // return type if (!hasError) { - groupTokens = tokensForParseeGroup( + parseeResults = parseeResultsForParseeGroup( ParseeGroup( false, { Parsee::tokenParsee(TokenKind::RIGHT_ARROW, true, false), Parsee::tokenParsee(TokenKind::NEW_LINE, false, false), - Parsee::typeParsee() + Parsee::valueTypeParsee() }, {} ) ); - if (groupTokens && !(*groupTokens).empty()) { - - } else if (!groupTokens) { + if (parseeResults && !(*parseeResults).empty()) { + returnType = (*parseeResults).at(0).getValueType(); + } else if (!parseeResults) { hasError = true; } } @@ -872,9 +878,9 @@ shared_ptr Parser::matchValueType() { return ValueType::valueTypeForToken(typeToken, subType, valueArg); } -optional>> Parser::tokensForParseeGroup(ParseeGroup group) { +optional> Parser::parseeResultsForParseeGroup(ParseeGroup group) { int nextIndex = currentIndex; - vector> returnTokens; + vector results; bool mustFulfill = false; for (Parsee &parsee : group.getParsees()) { @@ -883,11 +889,11 @@ optional>> Parser::tokensForParseeGroup(ParseeGroup gro // if doesn't match on optional group if (!matches && parsee.getIsRequired() && !group.getIsRequired() && mustFulfill) - return vector>(); + return vector(); // return matching token? if (matches && parsee.getShouldReturn()) - returnTokens.push_back(currentToken); + results.push_back(ParseeResult::tokenResult(currentToken)); // decide if we're decoding the expected sequence if (!parsee.getIsRequired() && nextIndex > currentIndex) @@ -907,7 +913,7 @@ optional>> Parser::tokensForParseeGroup(ParseeGroup gro currentIndex = nextIndex; - return returnTokens; + return results; } bool Parser::tryMatchingTokenKinds(vector kinds, bool shouldMatchAll, bool shouldAdvance) { diff --git a/src/Parser/Parser.h b/src/Parser/Parser.h index cbac15e..db079d4 100644 --- a/src/Parser/Parser.h +++ b/src/Parser/Parser.h @@ -13,6 +13,7 @@ class Expression; class Statement; class ParseeGroup; +class ParseeResult; using namespace std; @@ -54,7 +55,7 @@ private: shared_ptr matchValueType(); - optional>> tokensForParseeGroup(ParseeGroup group); + optional> parseeResultsForParseeGroup(ParseeGroup group); bool tryMatchingTokenKinds(vector kinds, bool shouldMatchAll, bool shouldAdvance); void markError(optional expectedTokenKind, optional message); From 3041c4383b74970c5edd91f2f090d9e292d75754 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Tue, 22 Jul 2025 15:03:34 +0900 Subject: [PATCH 12/28] Single parsing logic --- samples/test.brc | 11 ++- src/Parser/Parsee/Parsee.cpp | 1 + src/Parser/Parsee/ParseeResult.cpp | 8 +- src/Parser/Parsee/ParseeResult.h | 4 +- src/Parser/Parser.cpp | 139 +++++++++++++++-------------- src/Parser/Parser.h | 2 + 6 files changed, 95 insertions(+), 70 deletions(-) diff --git a/samples/test.brc b/samples/test.brc index 78e2ede..9fabe98 100644 --- a/samples/test.brc +++ b/samples/test.brc @@ -28,7 +28,12 @@ i u32 <- 0, rep text[i] != 0: ret num1 + num2 ;*/ -rawAdd raw<"=r,r,r">: num1 sint32, num2 sint32 -> sint32 +/*rawAdd raw<"=r,r,r">: num1 sint32, num2 sint32 -> sint32 + add $1, $2 + mov $0, $1 +;*/ + +rawAdd raw: num1 sint32, num2 sint32 -> sint32 add $1, $2 mov $0, $1 ; @@ -46,8 +51,8 @@ rawAdd raw<"=r,r,r">: num1 sint32, num2 sint32 -> sint32 main fun -> sint32 //printChar() - res1 sint32 <- normAdd(4, 5) - res2 sint32 <- rawAdd(4, 5) + //res1 sint32 <- normAdd(4, 5) + //res2 sint32 <- rawAdd(4, 5) ret 0 ; \ No newline at end of file diff --git a/src/Parser/Parsee/Parsee.cpp b/src/Parser/Parsee/Parsee.cpp index 227b23e..292e997 100644 --- a/src/Parser/Parsee/Parsee.cpp +++ b/src/Parser/Parsee/Parsee.cpp @@ -13,6 +13,7 @@ Parsee Parsee::tokenParsee(TokenKind tokenKind, bool isRequired, bool shouldRetu Parsee Parsee::valueTypeParsee() { Parsee parsee; parsee.kind = ParseeKind::VALUE_TYPE; + parsee.shouldReturn = true; return parsee; } diff --git a/src/Parser/Parsee/ParseeResult.cpp b/src/Parser/Parsee/ParseeResult.cpp index 66dc619..ce00984 100644 --- a/src/Parser/Parsee/ParseeResult.cpp +++ b/src/Parser/Parsee/ParseeResult.cpp @@ -7,13 +7,15 @@ ParseeResult ParseeResult::tokenResult(shared_ptr token) { ParseeResult parseeResult; parseeResult.kind = ParseeResultKind::TOKEN; parseeResult.token = token; + parseeResult.tokensCount = 1; return parseeResult; } -ParseeResult ParseeResult::valueTypeResult(shared_ptr valueType) { +ParseeResult ParseeResult::valueTypeResult(shared_ptr valueType, int tokensCount) { ParseeResult parseeResult; parseeResult.kind = ParseeResultKind::VALUE_TYPE; parseeResult.valueType = valueType; + parseeResult.tokensCount = tokensCount; return parseeResult; } @@ -30,4 +32,8 @@ shared_ptr ParseeResult::getToken() { shared_ptr ParseeResult::getValueType() { return valueType; +} + +int ParseeResult::getTokensCount() { + return tokensCount; } \ No newline at end of file diff --git a/src/Parser/Parsee/ParseeResult.h b/src/Parser/Parsee/ParseeResult.h index a909152..fb56d45 100644 --- a/src/Parser/Parsee/ParseeResult.h +++ b/src/Parser/Parsee/ParseeResult.h @@ -18,15 +18,17 @@ private: ParseeResultKind kind; shared_ptr token; shared_ptr valueType; + int tokensCount; ParseeResult(); public: static ParseeResult tokenResult(shared_ptr token); - static ParseeResult valueTypeResult(shared_ptr valueType); + static ParseeResult valueTypeResult(shared_ptr valueType, int tokensCount); ParseeResultKind getKind(); shared_ptr getToken(); shared_ptr getValueType(); + int getTokensCount(); }; #endif \ No newline at end of file diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index cd0d81e..5550800 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -247,6 +247,7 @@ shared_ptr Parser::matchStatementRawFunction() { string constraints; vector>> arguments; shared_ptr returnType = ValueType::NONE; + string rawSource; // identifier parseeResults = parseeResultsForParseeGroup( @@ -297,7 +298,7 @@ shared_ptr Parser::matchStatementRawFunction() { Parsee::valueTypeParsee() }, ParseeGroup( - true, + false, { Parsee::tokenParsee(TokenKind::COMMA, true, false), Parsee::tokenParsee(TokenKind::NEW_LINE, false, false), @@ -341,58 +342,6 @@ shared_ptr Parser::matchStatementRawFunction() { } } - if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER, TokenKind::RAW_FUNCTION}, true, false)) - return nullptr; - - string rawSource; - - // name - name = tokens.at(currentIndex++)->getLexme(); - currentIndex++; // skip raw - - // constraints - - if (tryMatchingTokenKinds({TokenKind::LESS}, true, true)) { - if (tokens.at(currentIndex)->isOfKind({TokenKind::STRING})) { - constraints = tokens.at(currentIndex++)->getLexme(); - // remove enclosing quotes - if (constraints.length() >= 2) - constraints = constraints.substr(1, constraints.length() - 2); - } - if (!tryMatchingTokenKinds({TokenKind::GREATER}, true, true)) - markError({TokenKind::GREATER}, {}); - } - - // arguments - if (tryMatchingTokenKinds({TokenKind::COLON}, true, true)) { - do { - tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true); // skip new line - if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER, TokenKind::TYPE}, true, false)) { - markError({}, "Expected function argument"); - return nullptr; - } - shared_ptr identifierToken = tokens.at(currentIndex++); - shared_ptr argumentType = matchValueType(); - if (argumentType == nullptr) { - markError(TokenKind::TYPE, {}); - return nullptr; - } - - arguments.push_back(pair>(identifierToken->getLexme(), argumentType)); - } while (tryMatchingTokenKinds({TokenKind::COMMA}, true, true)); - } - - // return type - if (tryMatchingTokenKinds({TokenKind::RIGHT_ARROW}, true, true)) { - tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true); // skip new line - - returnType = matchValueType(); - if (returnType == nullptr) { - markError(TokenKind::TYPE, {}); - return nullptr; - } - } - // consume new line if (!tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true)) { markError(TokenKind::NEW_LINE, {}); @@ -879,43 +828,103 @@ shared_ptr Parser::matchValueType() { } optional> Parser::parseeResultsForParseeGroup(ParseeGroup group) { - int nextIndex = currentIndex; + int startIndex = currentIndex; vector results; bool mustFulfill = false; for (Parsee &parsee : group.getParsees()) { - shared_ptr currentToken = tokens.at(nextIndex); - bool matches = currentToken->isOfKind({parsee.getTokenKind()}); + optional result; + switch (parsee.getKind()) { + case ParseeKind::TOKEN: + result = tokenParseeResult(currentIndex, parsee.getTokenKind()); + break; + case ParseeKind::VALUE_TYPE: + result = valueTypeParseeResult(currentIndex); + break; + } // if doesn't match on optional group - if (!matches && parsee.getIsRequired() && !group.getIsRequired() && mustFulfill) + if (!result && parsee.getIsRequired() && !group.getIsRequired() && !mustFulfill) { + currentIndex = startIndex; return vector(); + } // return matching token? - if (matches && parsee.getShouldReturn()) - results.push_back(ParseeResult::tokenResult(currentToken)); + if (result && parsee.getShouldReturn()) + results.push_back(*result); // decide if we're decoding the expected sequence - if (!parsee.getIsRequired() && nextIndex > currentIndex) + if (!parsee.getIsRequired() && currentIndex > startIndex) mustFulfill = true; // invalid sequence detected? - if (!matches && parsee.getIsRequired() && mustFulfill) { - currentIndex = nextIndex; + if (!result && parsee.getIsRequired() && mustFulfill) { markError(parsee.getTokenKind(), {}); return {}; } // got to the next token if we got a match - if (matches) - nextIndex++; + if (result) + currentIndex += (*result).getTokensCount(); } - currentIndex = nextIndex; + if (group.getRepeatedGroup()) { + bool hasSubResults = false; + + optional> subResults; + do { + subResults = parseeResultsForParseeGroup(*group.getRepeatedGroup()); + if (!subResults) + return {}; + + for (ParseeResult &subResult : *subResults) + results.push_back(subResult); + } while (!(*subResults).empty()); + } return results; } +optional Parser::tokenParseeResult(int index, TokenKind tokenKind) { + shared_ptr token = tokens.at(index); + if (token->isOfKind({tokenKind})) + return ParseeResult::tokenResult(token); + return {}; +} + +optional Parser::valueTypeParseeResult(int index) { + int startIndex = index; + + if (!tokens.at(index)->isOfKind({TokenKind::TYPE})) + return {}; + + shared_ptr typeToken = tokens.at(index++); + shared_ptr subType; + int typeArg = 0; + + if (tokens.at(index)->isOfKind({TokenKind::LESS})) { + index++; + optional subResult = valueTypeParseeResult(index); + if (!subResult) + return {}; + subType = (*subResult).getValueType(); + + + if (tokens.at(index)->isOfKind({TokenKind::COMMA})) { + index++; + + if (!tokens.at(index)->isOfKind({TokenKind::INTEGER_DEC, TokenKind::INTEGER_HEX, TokenKind::INTEGER_BIN, TokenKind::INTEGER_CHAR})) + return {}; + } + + if (!tokens.at(index)->isOfKind({TokenKind::GREATER})) + return {}; + } + + shared_ptr valueType = ValueType::valueTypeForToken(typeToken, subType, 0); + return ParseeResult::valueTypeResult(valueType, index - startIndex); +} + bool Parser::tryMatchingTokenKinds(vector kinds, bool shouldMatchAll, bool shouldAdvance) { int requiredCount = shouldMatchAll ? kinds.size() : 1; if (currentIndex + requiredCount > tokens.size()) diff --git a/src/Parser/Parser.h b/src/Parser/Parser.h index db079d4..a3c35ef 100644 --- a/src/Parser/Parser.h +++ b/src/Parser/Parser.h @@ -56,6 +56,8 @@ private: shared_ptr matchValueType(); optional> parseeResultsForParseeGroup(ParseeGroup group); + optional tokenParseeResult(int index, TokenKind tokenKind); + optional valueTypeParseeResult(int index); bool tryMatchingTokenKinds(vector kinds, bool shouldMatchAll, bool shouldAdvance); void markError(optional expectedTokenKind, optional message); From 68018e71067a4e2d7b76d9edd2c86a8eb5893e9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Wed, 30 Jul 2025 21:52:22 +0900 Subject: [PATCH 13/28] wip --- samples/test.brc | 6 +- src/Parser/Parsee/Parsee.cpp | 13 +- src/Parser/Parsee/Parsee.h | 9 +- src/Parser/Parsee/ParseeGroup.cpp | 8 +- src/Parser/Parsee/ParseeGroup.h | 6 +- src/Parser/Parsee/ParseeResult.cpp | 12 ++ src/Parser/Parsee/ParseeResult.h | 5 + src/Parser/Parsee/ParseeResultsGroup.cpp | 30 ++++ src/Parser/Parsee/ParseeResultsGroup.h | 30 ++++ src/Parser/Parser.cpp | 183 ++++++++++++++++++++--- src/Parser/Parser.h | 5 +- 11 files changed, 269 insertions(+), 38 deletions(-) create mode 100644 src/Parser/Parsee/ParseeResultsGroup.cpp create mode 100644 src/Parser/Parsee/ParseeResultsGroup.h diff --git a/samples/test.brc b/samples/test.brc index 9fabe98..1862622 100644 --- a/samples/test.brc +++ b/samples/test.brc @@ -33,10 +33,10 @@ i u32 <- 0, rep text[i] != 0: mov $0, $1 ;*/ -rawAdd raw: num1 sint32, num2 sint32 -> sint32 +/*rawAdd raw: num1 sint32, num2 sint32 -> sint32 add $1, $2 mov $0, $1 -; +;*/ /*printChar raw .global REGISTER @@ -54,5 +54,5 @@ main fun -> sint32 //res1 sint32 <- normAdd(4, 5) //res2 sint32 <- rawAdd(4, 5) - ret 0 + ret 2- ; \ No newline at end of file diff --git a/src/Parser/Parsee/Parsee.cpp b/src/Parser/Parsee/Parsee.cpp index 292e997..dc8c526 100644 --- a/src/Parser/Parsee/Parsee.cpp +++ b/src/Parser/Parsee/Parsee.cpp @@ -1,20 +1,29 @@ #include "Parsee.h" +#include "Parser/Expression/Expression.h" + Parsee Parsee::tokenParsee(TokenKind tokenKind, bool isRequired, bool shouldReturn) { Parsee parsee; parsee.kind = ParseeKind::TOKEN; parsee.tokenKind = tokenKind; parsee.isRequired = isRequired; parsee.shouldReturn = shouldReturn; - return parsee; } -Parsee Parsee::valueTypeParsee() { +Parsee Parsee::valueTypeParsee(bool isRequired) { Parsee parsee; parsee.kind = ParseeKind::VALUE_TYPE; + parsee.isRequired = isRequired; parsee.shouldReturn = true; + return parsee; +} +Parsee Parsee::expressionParsee(bool isRequired) { + Parsee parsee; + parsee.kind = ParseeKind::EXPRESSION; + parsee.isRequired = isRequired; + parsee.shouldReturn = true; return parsee; } diff --git a/src/Parser/Parsee/Parsee.h b/src/Parser/Parsee/Parsee.h index dc7cfd4..9b1db48 100644 --- a/src/Parser/Parsee/Parsee.h +++ b/src/Parser/Parsee/Parsee.h @@ -1,11 +1,15 @@ #ifndef PARSEE_H #define PARSEE_H +#include + enum class TokenKind; +class Expression; enum class ParseeKind { TOKEN, - VALUE_TYPE + VALUE_TYPE, + EXPRESSION }; class Parsee { @@ -18,7 +22,8 @@ private: public: static Parsee tokenParsee(TokenKind tokenKind, bool isRequired, bool shouldReturn); - static Parsee valueTypeParsee(); + static Parsee valueTypeParsee(bool isRequired); + static Parsee expressionParsee(bool isRequired); ParseeKind getKind(); TokenKind getTokenKind(); diff --git a/src/Parser/Parsee/ParseeGroup.cpp b/src/Parser/Parsee/ParseeGroup.cpp index debd442..81e7b81 100644 --- a/src/Parser/Parsee/ParseeGroup.cpp +++ b/src/Parser/Parsee/ParseeGroup.cpp @@ -2,8 +2,8 @@ #include "Parsee.h" -ParseeGroup::ParseeGroup(bool isRequired, vector parsees, optional repeatedGroup): -isRequired(isRequired), parsees(parsees) { +ParseeGroup::ParseeGroup(/*bool isRequired, */vector parsees, optional repeatedGroup): +/*isRequired(isRequired), */parsees(parsees) { if (repeatedGroup) { this->repeatedGroup = *repeatedGroup; } else { @@ -11,9 +11,9 @@ isRequired(isRequired), parsees(parsees) { } } -bool ParseeGroup::getIsRequired() { +/*bool ParseeGroup::getIsRequired() { return isRequired; -} +}*/ vector ParseeGroup::getParsees() { return parsees; diff --git a/src/Parser/Parsee/ParseeGroup.h b/src/Parser/Parsee/ParseeGroup.h index 0dfb4f8..62d2570 100644 --- a/src/Parser/Parsee/ParseeGroup.h +++ b/src/Parser/Parsee/ParseeGroup.h @@ -10,13 +10,13 @@ using namespace std; class ParseeGroup { private: - bool isRequired; + //bool isRequired; vector parsees; optional> repeatedGroup; public: - ParseeGroup(bool isRequired, vector parsees, optional repeatedGroup); - bool getIsRequired(); + ParseeGroup(/*bool isRequired, */vector parsees, optional repeatedGroup); + //bool getIsRequired(); vector getParsees(); optional> getRepeatedGroup(); }; diff --git a/src/Parser/Parsee/ParseeResult.cpp b/src/Parser/Parsee/ParseeResult.cpp index ce00984..5e09309 100644 --- a/src/Parser/Parsee/ParseeResult.cpp +++ b/src/Parser/Parsee/ParseeResult.cpp @@ -19,6 +19,14 @@ ParseeResult ParseeResult::valueTypeResult(shared_ptr valueType, int return parseeResult; } +ParseeResult ParseeResult::expressionResult(shared_ptr expression, int tokensCount) { + ParseeResult result; + result.kind = ParseeResultKind::EXPRESSION; + result.expression = expression; + result.tokensCount = tokensCount; + return result; +} + ParseeResult::ParseeResult() { } @@ -34,6 +42,10 @@ shared_ptr ParseeResult::getValueType() { return valueType; } +shared_ptr ParseeResult::getExpression() { + return expression; +} + int ParseeResult::getTokensCount() { return tokensCount; } \ No newline at end of file diff --git a/src/Parser/Parsee/ParseeResult.h b/src/Parser/Parsee/ParseeResult.h index fb56d45..f59114e 100644 --- a/src/Parser/Parsee/ParseeResult.h +++ b/src/Parser/Parsee/ParseeResult.h @@ -5,12 +5,14 @@ class Token; class ValueType; +class Expression; using namespace std; enum class ParseeResultKind { TOKEN, VALUE_TYPE, + EXPRESSION }; class ParseeResult { @@ -18,16 +20,19 @@ private: ParseeResultKind kind; shared_ptr token; shared_ptr valueType; + shared_ptr expression; int tokensCount; ParseeResult(); public: static ParseeResult tokenResult(shared_ptr token); static ParseeResult valueTypeResult(shared_ptr valueType, int tokensCount); + static ParseeResult expressionResult(shared_ptr expression, int tokensCount); ParseeResultKind getKind(); shared_ptr getToken(); shared_ptr getValueType(); + shared_ptr getExpression(); int getTokensCount(); }; diff --git a/src/Parser/Parsee/ParseeResultsGroup.cpp b/src/Parser/Parsee/ParseeResultsGroup.cpp new file mode 100644 index 0000000..ca3cc9c --- /dev/null +++ b/src/Parser/Parsee/ParseeResultsGroup.cpp @@ -0,0 +1,30 @@ +#include "ParseeResultsGroup.h" + +#include "ParseeResult.h" + +ParseeResultsGroup ParseeResultsGroup::success(vector results) { + ParseeResultsGroup resultsGroup; + resultsGroup.kind = ParseeResultsGroupKind::SUCCESS; + resultsGroup.results = results; + return resultsGroup; +} + +ParseeResultsGroup ParseeResultsGroup::noMatch() { + ParseeResultsGroup resultsGroup; + resultsGroup.kind = ParseeResultsGroupKind::NO_MATCH; + return resultsGroup; +} + +ParseeResultsGroup ParseeResultsGroup::failure() { + ParseeResultsGroup resultsGroup; + resultsGroup.kind = ParseeResultsGroupKind::FAILURE; + return resultsGroup; +} + +ParseeResultsGroupKind ParseeResultsGroup::getKind() { + return kind; +} + +vector ParseeResultsGroup::getResults() { + return results; +} \ No newline at end of file diff --git a/src/Parser/Parsee/ParseeResultsGroup.h b/src/Parser/Parsee/ParseeResultsGroup.h new file mode 100644 index 0000000..3ba23b4 --- /dev/null +++ b/src/Parser/Parsee/ParseeResultsGroup.h @@ -0,0 +1,30 @@ +#ifndef PARSEE_RESULTS_GROUP_H +#define PARSEE_RESULTS_GROUP_H + +#include + +class ParseeResult; + +using namespace std; + +enum class ParseeResultsGroupKind { + SUCCESS, + NO_MATCH, + FAILURE +}; + +class ParseeResultsGroup { +private: + ParseeResultsGroupKind kind; + vector results; + +public: + static ParseeResultsGroup success(vector results); + static ParseeResultsGroup noMatch(); + static ParseeResultsGroup failure(); + + ParseeResultsGroupKind getKind(); + vector getResults(); +}; + +#endif \ No newline at end of file diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index 5550800..25f2204 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -28,6 +28,7 @@ #include "Parsee/Parsee.h" #include "Parsee/ParseeGroup.h" #include "Parsee/ParseeResult.h" +#include "Parsee/ParseeResultsGroup.h" Parser::Parser(vector> tokens) : tokens(tokens) { } @@ -158,7 +159,7 @@ shared_ptr Parser::matchStatementMetaExternFunction() { } shared_ptr Parser::matchStatementVariable() { - if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER, TokenKind::TYPE}, true, false)) + /*if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER, TokenKind::TYPE}, true, false)) return nullptr; shared_ptr identifierToken = tokens.at(currentIndex++); @@ -174,7 +175,43 @@ shared_ptr Parser::matchStatementVariable() { if (expression == nullptr) return nullptr; - return make_shared(identifierToken->getLexme(), valueType, expression); + return make_shared(identifierToken->getLexme(), valueType, expression);*/ + + ParseeResultsGroup resultsGroup = parseeResultsGroupForParseeGroup( + ParseeGroup( + { + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true), + Parsee::valueTypeParsee(true), + Parsee::tokenParsee(TokenKind::LEFT_ARROW, true, false), + Parsee::expressionParsee(true) + }, + { } + ) + ); + + if (resultsGroup.getKind() != ParseeResultsGroupKind::SUCCESS) + return nullptr; + + string name = resultsGroup.getResults().at(0).getToken()->getLexme();// tokens.at(currentIndex++); + shared_ptr valueType = resultsGroup.getResults().at(1).getValueType(); + shared_ptr expression = resultsGroup.getResults().at(2).getExpression(); + + return make_shared(name, valueType, expression); + + /*optional> parseeResults = parseeResultsForParseeGroup( + ParseeGroup( + false, + { + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true), + Parsee::valueTypeParsee(), + Parsee::tokenParsee(TokenKind::LEFT_ARROW, true, false), + Parsee::expressionParsee() + }, + { } + ) + ); + + optional> parseeResults = parseeResultsForParseeGroup(parseeGroup);*/ } shared_ptr Parser::matchStatementFunction() { @@ -227,7 +264,7 @@ shared_ptr Parser::matchStatementFunction() { } // block - statementBlock = matchStatementBlock({TokenKind::SEMICOLON}); + statementBlock = matchStatementBlock({TokenKind::SEMICOLON, TokenKind::END}); if (statementBlock == nullptr) return nullptr; @@ -240,7 +277,8 @@ shared_ptr Parser::matchStatementFunction() { } shared_ptr Parser::matchStatementRawFunction() { - bool hasError = false; + return nullptr; + /*bool hasError = false; optional> parseeResults; string name; @@ -295,7 +333,7 @@ shared_ptr Parser::matchStatementRawFunction() { Parsee::tokenParsee(TokenKind::COLON, true, false), Parsee::tokenParsee(TokenKind::NEW_LINE, false, false), Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true), - Parsee::valueTypeParsee() + Parsee::valueTypeParsee(true) }, ParseeGroup( false, @@ -303,7 +341,7 @@ shared_ptr Parser::matchStatementRawFunction() { Parsee::tokenParsee(TokenKind::COMMA, true, false), Parsee::tokenParsee(TokenKind::NEW_LINE, false, false), Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true), - Parsee::valueTypeParsee() + Parsee::valueTypeParsee(true) }, {} ) @@ -329,7 +367,7 @@ shared_ptr Parser::matchStatementRawFunction() { { Parsee::tokenParsee(TokenKind::RIGHT_ARROW, true, false), Parsee::tokenParsee(TokenKind::NEW_LINE, false, false), - Parsee::valueTypeParsee() + Parsee::valueTypeParsee(true) }, {} ) @@ -363,7 +401,7 @@ shared_ptr Parser::matchStatementRawFunction() { return nullptr; } - return make_shared(name, constraints, arguments, returnType, rawSource); + return make_shared(name, constraints, arguments, returnType, rawSource);*/ } shared_ptr Parser::matchStatementBlock(vector terminalTokenKinds) { @@ -418,13 +456,27 @@ shared_ptr Parser::matchStatementAssignment() { } shared_ptr Parser::matchStatementReturn() { - if (!tryMatchingTokenKinds({TokenKind::RETURN}, true, true)) - return nullptr; + shared_ptr expression; + + ParseeResultsGroup resultsGroup = parseeResultsGroupForParseeGroup( + ParseeGroup( + { + Parsee::tokenParsee(TokenKind::RETURN, true, false), + Parsee::expressionParsee(false) + }, + { } + ) + ); + + switch (resultsGroup.getKind()) { + case ParseeResultsGroupKind::SUCCESS: + expression = !resultsGroup.getResults().empty() ? resultsGroup.getResults().at(0).getExpression() : nullptr; + break; + case ParseeResultsGroupKind::NO_MATCH: + case ParseeResultsGroupKind::FAILURE: + return nullptr; + } - shared_ptr expression = nextExpression(); - if (expression == nullptr) - return nullptr; - return make_shared(expression); } @@ -521,7 +573,7 @@ shared_ptr Parser::nextExpression() { if (expression != nullptr || errors.size() > errorsCount) return expression; - markError({}, {}); + //markError({}, {}); return nullptr; } @@ -757,6 +809,7 @@ shared_ptr Parser::matchExpressionBinary(shared_ptr left } if (right == nullptr) { + markError({}, "Expected expression"); return nullptr; } else { return make_shared(token, left, right); @@ -827,7 +880,8 @@ shared_ptr Parser::matchValueType() { return ValueType::valueTypeForToken(typeToken, subType, valueArg); } -optional> Parser::parseeResultsForParseeGroup(ParseeGroup group) { +ParseeResultsGroup Parser::parseeResultsGroupForParseeGroup(ParseeGroup group) { + int errorsCount = errors.size(); int startIndex = currentIndex; vector results; bool mustFulfill = false; @@ -835,12 +889,83 @@ optional> Parser::parseeResultsForParseeGroup(ParseeGroup g for (Parsee &parsee : group.getParsees()) { optional result; switch (parsee.getKind()) { - case ParseeKind::TOKEN: - result = tokenParseeResult(currentIndex, parsee.getTokenKind()); - break; - case ParseeKind::VALUE_TYPE: - result = valueTypeParseeResult(currentIndex); - break; + case ParseeKind::TOKEN: + result = tokenParseeResult(currentIndex, parsee.getTokenKind()); + break; + case ParseeKind::VALUE_TYPE: + result = valueTypeParseeResult(currentIndex); + break; + case ParseeKind::EXPRESSION: + result = expressionParseeResult(currentIndex); + break; + } + + // generated an error? + if (errors.size() > errorsCount) + return ParseeResultsGroup::failure(); + + // if doesn't match on optional group + if (!result && parsee.getIsRequired() && !mustFulfill) { + currentIndex = startIndex; + //return vector(); + return ParseeResultsGroup::noMatch(); + } + + // return matching token? + if (result && parsee.getShouldReturn()) + results.push_back(*result); + + // decide if we're decoding the expected sequence + if (!parsee.getIsRequired() && currentIndex > startIndex) + mustFulfill = true; + + // invalid sequence detected? + if (!result && parsee.getIsRequired() && mustFulfill) { + markError(parsee.getTokenKind(), {}); + //return {}; + return ParseeResultsGroup::failure(); + } + + // got to the next token if we got a match + if (result) + currentIndex += (*result).getTokensCount(); + } + + /*if (group.getRepeatedGroup()) { + bool hasSubResults = false; + + optional> subResults; + do { + subResults = parseeResultsForParseeGroup(*group.getRepeatedGroup()); + if (!subResults) + return ParseeResultsGroup::failure(); + //return {}; + + for (ParseeResult &subResult : *subResults) + results.push_back(subResult); + } while (!(*subResults).empty()); + }*/ + + return ParseeResultsGroup::success(results); +} + +/*optional> Parser::parseeResultsForParseeGroup(ParseeGroup group) { + int startIndex = currentIndex; + vector results; + bool mustFulfill = false; + + for (Parsee &parsee : group.getParsees()) { + optional result; + switch (parsee.getKind()) { + case ParseeKind::TOKEN: + result = tokenParseeResult(currentIndex, parsee.getTokenKind()); + break; + case ParseeKind::VALUE_TYPE: + result = valueTypeParseeResult(currentIndex); + break; + case ParseeKind::EXPRESSION: + result = expressionParseeResult(currentIndex); + break; } // if doesn't match on optional group @@ -883,7 +1008,7 @@ optional> Parser::parseeResultsForParseeGroup(ParseeGroup g } return results; -} +}*/ optional Parser::tokenParseeResult(int index, TokenKind tokenKind) { shared_ptr token = tokens.at(index); @@ -925,6 +1050,18 @@ optional Parser::valueTypeParseeResult(int index) { return ParseeResult::valueTypeResult(valueType, index - startIndex); } +optional Parser::expressionParseeResult(int index) { + int startIndex = currentIndex; + int errorsCount = errors.size(); + shared_ptr expression = nextExpression(); + if (errors.size() > errorsCount) + return {}; + + int tokensCount = currentIndex - startIndex; + currentIndex = startIndex; + return ParseeResult::expressionResult(expression, tokensCount); +} + bool Parser::tryMatchingTokenKinds(vector kinds, bool shouldMatchAll, bool shouldAdvance) { int requiredCount = shouldMatchAll ? kinds.size() : 1; if (currentIndex + requiredCount > tokens.size()) diff --git a/src/Parser/Parser.h b/src/Parser/Parser.h index a3c35ef..7e80f40 100644 --- a/src/Parser/Parser.h +++ b/src/Parser/Parser.h @@ -14,6 +14,7 @@ class Statement; class ParseeGroup; class ParseeResult; +class ParseeResultsGroup; using namespace std; @@ -55,9 +56,11 @@ private: shared_ptr matchValueType(); - optional> parseeResultsForParseeGroup(ParseeGroup group); + ParseeResultsGroup parseeResultsGroupForParseeGroup(ParseeGroup group); + //optional> parseeResultsForParseeGroup(ParseeGroup group); optional tokenParseeResult(int index, TokenKind tokenKind); optional valueTypeParseeResult(int index); + optional expressionParseeResult(int index); bool tryMatchingTokenKinds(vector kinds, bool shouldMatchAll, bool shouldAdvance); void markError(optional expectedTokenKind, optional message); From 953a8acb181e764fe32f71d4e6c362b3fa14e57e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Wed, 30 Jul 2025 23:41:28 +0900 Subject: [PATCH 14/28] Use new parser for function --- samples/test.brc | 6 +- src/Parser/Parsee/ParseeGroup.cpp | 8 +- src/Parser/Parsee/ParseeGroup.h | 4 +- src/Parser/Parser.cpp | 224 ++++++++++++------------------ src/Parser/Parser.h | 1 - 5 files changed, 96 insertions(+), 147 deletions(-) diff --git a/samples/test.brc b/samples/test.brc index 1862622..563c1bc 100644 --- a/samples/test.brc +++ b/samples/test.brc @@ -48,11 +48,11 @@ i u32 <- 0, rep text[i] != 0: ;*/ -main fun -> sint32 +main fun: a sint32, b sint32 -> sint32 //printChar() - //res1 sint32 <- normAdd(4, 5) + res1 sint32 <- a - b //res2 sint32 <- rawAdd(4, 5) - ret 2- + ret res1 ; \ No newline at end of file diff --git a/src/Parser/Parsee/ParseeGroup.cpp b/src/Parser/Parsee/ParseeGroup.cpp index 81e7b81..ead5352 100644 --- a/src/Parser/Parsee/ParseeGroup.cpp +++ b/src/Parser/Parsee/ParseeGroup.cpp @@ -2,8 +2,8 @@ #include "Parsee.h" -ParseeGroup::ParseeGroup(/*bool isRequired, */vector parsees, optional repeatedGroup): -/*isRequired(isRequired), */parsees(parsees) { +ParseeGroup::ParseeGroup(vector parsees, optional repeatedGroup): +parsees(parsees) { if (repeatedGroup) { this->repeatedGroup = *repeatedGroup; } else { @@ -11,10 +11,6 @@ ParseeGroup::ParseeGroup(/*bool isRequired, */vector parsees, optional

ParseeGroup::getParsees() { return parsees; } diff --git a/src/Parser/Parsee/ParseeGroup.h b/src/Parser/Parsee/ParseeGroup.h index 62d2570..4e4cc82 100644 --- a/src/Parser/Parsee/ParseeGroup.h +++ b/src/Parser/Parsee/ParseeGroup.h @@ -10,13 +10,11 @@ using namespace std; class ParseeGroup { private: - //bool isRequired; vector parsees; optional> repeatedGroup; public: - ParseeGroup(/*bool isRequired, */vector parsees, optional repeatedGroup); - //bool getIsRequired(); + ParseeGroup(vector parsees, optional repeatedGroup); vector getParsees(); optional> getRepeatedGroup(); }; diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index 25f2204..9aa2130 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -159,24 +159,6 @@ shared_ptr Parser::matchStatementMetaExternFunction() { } shared_ptr Parser::matchStatementVariable() { - /*if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER, TokenKind::TYPE}, true, false)) - return nullptr; - - shared_ptr identifierToken = tokens.at(currentIndex++); - shared_ptr valueType = matchValueType(); - - // Expect left arrow - if (!tryMatchingTokenKinds({TokenKind::LEFT_ARROW}, true, true)) { - markError(TokenKind::LEFT_ARROW, {}); - return nullptr; - } - - shared_ptr expression = nextExpression(); - if (expression == nullptr) - return nullptr; - - return make_shared(identifierToken->getLexme(), valueType, expression);*/ - ParseeResultsGroup resultsGroup = parseeResultsGroupForParseeGroup( ParseeGroup( { @@ -192,68 +174,105 @@ shared_ptr Parser::matchStatementVariable() { if (resultsGroup.getKind() != ParseeResultsGroupKind::SUCCESS) return nullptr; - string name = resultsGroup.getResults().at(0).getToken()->getLexme();// tokens.at(currentIndex++); + string name = resultsGroup.getResults().at(0).getToken()->getLexme(); shared_ptr valueType = resultsGroup.getResults().at(1).getValueType(); shared_ptr expression = resultsGroup.getResults().at(2).getExpression(); return make_shared(name, valueType, expression); - - /*optional> parseeResults = parseeResultsForParseeGroup( - ParseeGroup( - false, - { - Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true), - Parsee::valueTypeParsee(), - Parsee::tokenParsee(TokenKind::LEFT_ARROW, true, false), - Parsee::expressionParsee() - }, - { } - ) - ); - - optional> parseeResults = parseeResultsForParseeGroup(parseeGroup);*/ } shared_ptr Parser::matchStatementFunction() { - if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER, TokenKind::FUNCTION}, true, false)) - return nullptr; + bool hasError = false; + ParseeResultsGroup resultsGroup; string name; vector>> arguments; shared_ptr returnType = ValueType::NONE; shared_ptr statementBlock; - // name - name = tokens.at(currentIndex++)->getLexme(); - currentIndex++; // skip fun + // identifier + resultsGroup = parseeResultsGroupForParseeGroup( + ParseeGroup( + { + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true), + Parsee::tokenParsee(TokenKind::FUNCTION, true, false) + }, + {} + ) + ); - // arguments - if (tryMatchingTokenKinds({TokenKind::COLON}, true, true)) { - do { - tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true); // skip new line - if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER, TokenKind::TYPE}, true, false)) { - markError({}, "Expected function argument"); - return nullptr; - } - shared_ptr identifierToken = tokens.at(currentIndex++); - shared_ptr argumentType = matchValueType(); - if (argumentType == nullptr) { - markError(TokenKind::TYPE, {}); - return nullptr; - } - - arguments.push_back(pair>(identifierToken->getLexme(), argumentType)); - } while (tryMatchingTokenKinds({TokenKind::COMMA}, true, true)); + switch (resultsGroup.getKind()) { + case ParseeResultsGroupKind::SUCCESS: + name = resultsGroup.getResults().at(0).getToken()->getLexme(); + break; + case ParseeResultsGroupKind::NO_MATCH: + return nullptr; + break; + case ParseeResultsGroupKind::FAILURE: + hasError = true; + break; } - // return type - if (tryMatchingTokenKinds({TokenKind::RIGHT_ARROW}, true, true)) { - tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true); // skip new line + // arguments + if (!hasError) { + resultsGroup = parseeResultsGroupForParseeGroup( + ParseeGroup( + { + Parsee::tokenParsee(TokenKind::COLON, true, false), + Parsee::tokenParsee(TokenKind::NEW_LINE, false, false), + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true), + Parsee::valueTypeParsee(true) + }, + ParseeGroup( + { + Parsee::tokenParsee(TokenKind::COMMA, true, false), + Parsee::tokenParsee(TokenKind::NEW_LINE, false, false), + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true), + Parsee::valueTypeParsee(true) + }, + {} + ) + ) + ); + switch (resultsGroup.getKind()) { + case ParseeResultsGroupKind::SUCCESS: + for (int i=0; i> arg; + arg.first = resultsGroup.getResults().at(i).getToken()->getLexme(); + arg.second = resultsGroup.getResults().at(i+1).getValueType(); + arguments.push_back(arg); + } + break; + case ParseeResultsGroupKind::NO_MATCH: + break; + case ParseeResultsGroupKind::FAILURE: + hasError = true; + break; + } + } - returnType = matchValueType(); - if (returnType == nullptr) { - markError(TokenKind::TYPE, {}); - return nullptr; + // return type + if (!hasError) { + resultsGroup = parseeResultsGroupForParseeGroup( + ParseeGroup( + { + Parsee::tokenParsee(TokenKind::RIGHT_ARROW, true, false), + Parsee::tokenParsee(TokenKind::NEW_LINE, false, false), + Parsee::valueTypeParsee(true) + }, + {} + ) + ); + + switch (resultsGroup.getKind()) { + case ParseeResultsGroupKind::SUCCESS: + returnType = resultsGroup.getResults().at(0).getValueType(); + break; + case ParseeResultsGroupKind::NO_MATCH: + break; + case ParseeResultsGroupKind::FAILURE: + hasError = true; + break; } } @@ -268,6 +287,7 @@ shared_ptr Parser::matchStatementFunction() { if (statementBlock == nullptr) return nullptr; + // closing semicolon if(!tryMatchingTokenKinds({TokenKind::SEMICOLON}, false, true)) { markError(TokenKind::SEMICOLON, {}); return nullptr; @@ -931,85 +951,21 @@ ParseeResultsGroup Parser::parseeResultsGroupForParseeGroup(ParseeGroup group) { currentIndex += (*result).getTokensCount(); } - /*if (group.getRepeatedGroup()) { - bool hasSubResults = false; - - optional> subResults; + if (group.getRepeatedGroup()) { + ParseeResultsGroup subResultsGroup; do { - subResults = parseeResultsForParseeGroup(*group.getRepeatedGroup()); - if (!subResults) + subResultsGroup = parseeResultsGroupForParseeGroup(*group.getRepeatedGroup()); + if (subResultsGroup.getKind() == ParseeResultsGroupKind::FAILURE) return ParseeResultsGroup::failure(); - //return {}; - for (ParseeResult &subResult : *subResults) + for (ParseeResult &subResult : subResultsGroup.getResults()) results.push_back(subResult); - } while (!(*subResults).empty()); - }*/ + } while (subResultsGroup.getKind() == ParseeResultsGroupKind::SUCCESS); + } return ParseeResultsGroup::success(results); } -/*optional> Parser::parseeResultsForParseeGroup(ParseeGroup group) { - int startIndex = currentIndex; - vector results; - bool mustFulfill = false; - - for (Parsee &parsee : group.getParsees()) { - optional result; - switch (parsee.getKind()) { - case ParseeKind::TOKEN: - result = tokenParseeResult(currentIndex, parsee.getTokenKind()); - break; - case ParseeKind::VALUE_TYPE: - result = valueTypeParseeResult(currentIndex); - break; - case ParseeKind::EXPRESSION: - result = expressionParseeResult(currentIndex); - break; - } - - // if doesn't match on optional group - if (!result && parsee.getIsRequired() && !group.getIsRequired() && !mustFulfill) { - currentIndex = startIndex; - return vector(); - } - - // return matching token? - if (result && parsee.getShouldReturn()) - results.push_back(*result); - - // decide if we're decoding the expected sequence - if (!parsee.getIsRequired() && currentIndex > startIndex) - mustFulfill = true; - - // invalid sequence detected? - if (!result && parsee.getIsRequired() && mustFulfill) { - markError(parsee.getTokenKind(), {}); - return {}; - } - - // got to the next token if we got a match - if (result) - currentIndex += (*result).getTokensCount(); - } - - if (group.getRepeatedGroup()) { - bool hasSubResults = false; - - optional> subResults; - do { - subResults = parseeResultsForParseeGroup(*group.getRepeatedGroup()); - if (!subResults) - return {}; - - for (ParseeResult &subResult : *subResults) - results.push_back(subResult); - } while (!(*subResults).empty()); - } - - return results; -}*/ - optional Parser::tokenParseeResult(int index, TokenKind tokenKind) { shared_ptr token = tokens.at(index); if (token->isOfKind({tokenKind})) diff --git a/src/Parser/Parser.h b/src/Parser/Parser.h index 7e80f40..9ab27a3 100644 --- a/src/Parser/Parser.h +++ b/src/Parser/Parser.h @@ -57,7 +57,6 @@ private: shared_ptr matchValueType(); ParseeResultsGroup parseeResultsGroupForParseeGroup(ParseeGroup group); - //optional> parseeResultsForParseeGroup(ParseeGroup group); optional tokenParseeResult(int index, TokenKind tokenKind); optional valueTypeParseeResult(int index); optional expressionParseeResult(int index); From 163bcb4057336a0c4c69c72148734ea283a2bad9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Wed, 30 Jul 2025 23:58:19 +0900 Subject: [PATCH 15/28] Fixed up raw function --- samples/test.brc | 14 +++--- src/Parser/Parsee/Parsee.cpp | 2 - src/Parser/Parsee/Parsee.h | 1 - src/Parser/Parser.cpp | 92 ++++++++++++++++++++++-------------- 4 files changed, 63 insertions(+), 46 deletions(-) diff --git a/samples/test.brc b/samples/test.brc index 563c1bc..6077f04 100644 --- a/samples/test.brc +++ b/samples/test.brc @@ -28,10 +28,10 @@ i u32 <- 0, rep text[i] != 0: ret num1 + num2 ;*/ -/*rawAdd raw<"=r,r,r">: num1 sint32, num2 sint32 -> sint32 +rawAdd raw<"=r,r,r">: num1 sint32, num2 sint32 -> sint32 add $1, $2 mov $0, $1 -;*/ +; /*rawAdd raw: num1 sint32, num2 sint32 -> sint32 add $1, $2 @@ -48,11 +48,11 @@ i u32 <- 0, rep text[i] != 0: ;*/ -main fun: a sint32, b sint32 -> sint32 - //printChar() +main fun -> sint32 + a sint32 <- 4 + b sint32 <- 5 - res1 sint32 <- a - b - //res2 sint32 <- rawAdd(4, 5) + res sint32 <- rawAdd(4, 5) - ret res1 + ret res ; \ No newline at end of file diff --git a/src/Parser/Parsee/Parsee.cpp b/src/Parser/Parsee/Parsee.cpp index dc8c526..3ec80d9 100644 --- a/src/Parser/Parsee/Parsee.cpp +++ b/src/Parser/Parsee/Parsee.cpp @@ -1,7 +1,5 @@ #include "Parsee.h" -#include "Parser/Expression/Expression.h" - Parsee Parsee::tokenParsee(TokenKind tokenKind, bool isRequired, bool shouldReturn) { Parsee parsee; parsee.kind = ParseeKind::TOKEN; diff --git a/src/Parser/Parsee/Parsee.h b/src/Parser/Parsee/Parsee.h index 9b1db48..6dfdf0e 100644 --- a/src/Parser/Parsee/Parsee.h +++ b/src/Parser/Parsee/Parsee.h @@ -4,7 +4,6 @@ #include enum class TokenKind; -class Expression; enum class ParseeKind { TOKEN, diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index 9aa2130..d55b31e 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -297,9 +297,8 @@ shared_ptr Parser::matchStatementFunction() { } shared_ptr Parser::matchStatementRawFunction() { - return nullptr; - /*bool hasError = false; - optional> parseeResults; + bool hasError = false; + ParseeResultsGroup resultsGroup; string name; string constraints; @@ -308,9 +307,8 @@ shared_ptr Parser::matchStatementRawFunction() { string rawSource; // identifier - parseeResults = parseeResultsForParseeGroup( + resultsGroup = parseeResultsGroupForParseeGroup( ParseeGroup( - true, { Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true), Parsee::tokenParsee(TokenKind::RAW_FUNCTION, true, false) @@ -318,17 +316,23 @@ shared_ptr Parser::matchStatementRawFunction() { {} ) ); - if (parseeResults) { - name = (*parseeResults).at(0).getToken()->getLexme(); - } else { - hasError = true; + + switch (resultsGroup.getKind()) { + case ParseeResultsGroupKind::SUCCESS: + name = resultsGroup.getResults().at(0).getToken()->getLexme(); + break; + case ParseeResultsGroupKind::NO_MATCH: + return nullptr; + break; + case ParseeResultsGroupKind::FAILURE: + hasError = true; + break; } - // options + // constraints if (!hasError) { - parseeResults = parseeResultsForParseeGroup( + resultsGroup = parseeResultsGroupForParseeGroup( ParseeGroup( - false, { Parsee::tokenParsee(TokenKind::LESS, true, false), Parsee::tokenParsee(TokenKind::STRING, true, true), @@ -337,18 +341,27 @@ shared_ptr Parser::matchStatementRawFunction() { {} ) ); - if (parseeResults && !(*parseeResults).empty()) { - constraints = (*parseeResults).at(0).getToken()->getLexme(); - } else if (!parseeResults) { - hasError = true; + + switch (resultsGroup.getKind()) { + case ParseeResultsGroupKind::SUCCESS: + constraints = resultsGroup.getResults().at(0).getToken()->getLexme(); + // remove enclosing quotes + if (constraints.length() >= 2) + constraints = constraints.substr(1, constraints.length() - 2); + break; + case ParseeResultsGroupKind::NO_MATCH: + return nullptr; + break; + case ParseeResultsGroupKind::FAILURE: + hasError = true; + break; } } // arguments if (!hasError) { - parseeResults = parseeResultsForParseeGroup( + resultsGroup = parseeResultsGroupForParseeGroup( ParseeGroup( - false, { Parsee::tokenParsee(TokenKind::COLON, true, false), Parsee::tokenParsee(TokenKind::NEW_LINE, false, false), @@ -356,7 +369,6 @@ shared_ptr Parser::matchStatementRawFunction() { Parsee::valueTypeParsee(true) }, ParseeGroup( - false, { Parsee::tokenParsee(TokenKind::COMMA, true, false), Parsee::tokenParsee(TokenKind::NEW_LINE, false, false), @@ -367,23 +379,27 @@ shared_ptr Parser::matchStatementRawFunction() { ) ) ); - if (parseeResults && !(*parseeResults).empty()) { - for (int i=0; i<(*parseeResults).size(); i+=2) { - pair> arg; - arg.first = (*parseeResults).at(i).getToken()->getLexme(); - arg.second = (*parseeResults).at(i+1).getValueType(); - arguments.push_back(arg); - } - } else if (!parseeResults) { - hasError = true; + switch (resultsGroup.getKind()) { + case ParseeResultsGroupKind::SUCCESS: + for (int i=0; i> arg; + arg.first = resultsGroup.getResults().at(i).getToken()->getLexme(); + arg.second = resultsGroup.getResults().at(i+1).getValueType(); + arguments.push_back(arg); + } + break; + case ParseeResultsGroupKind::NO_MATCH: + break; + case ParseeResultsGroupKind::FAILURE: + hasError = true; + break; } } // return type if (!hasError) { - parseeResults = parseeResultsForParseeGroup( + resultsGroup = parseeResultsGroupForParseeGroup( ParseeGroup( - false, { Parsee::tokenParsee(TokenKind::RIGHT_ARROW, true, false), Parsee::tokenParsee(TokenKind::NEW_LINE, false, false), @@ -393,10 +409,15 @@ shared_ptr Parser::matchStatementRawFunction() { ) ); - if (parseeResults && !(*parseeResults).empty()) { - returnType = (*parseeResults).at(0).getValueType(); - } else if (!parseeResults) { - hasError = true; + switch (resultsGroup.getKind()) { + case ParseeResultsGroupKind::SUCCESS: + returnType = resultsGroup.getResults().at(0).getValueType(); + break; + case ParseeResultsGroupKind::NO_MATCH: + break; + case ParseeResultsGroupKind::FAILURE: + hasError = true; + break; } } @@ -421,7 +442,7 @@ shared_ptr Parser::matchStatementRawFunction() { return nullptr; } - return make_shared(name, constraints, arguments, returnType, rawSource);*/ + return make_shared(name, constraints, arguments, returnType, rawSource); } shared_ptr Parser::matchStatementBlock(vector terminalTokenKinds) { @@ -593,7 +614,6 @@ shared_ptr Parser::nextExpression() { if (expression != nullptr || errors.size() > errorsCount) return expression; - //markError({}, {}); return nullptr; } From d3b1d053562fb3e1bcdf4960a3d2685919b5370e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Thu, 31 Jul 2025 12:37:49 +0900 Subject: [PATCH 16/28] Converted assignment --- src/Parser/Parser.cpp | 98 +++++++++++++++++++++++++++---------------- 1 file changed, 63 insertions(+), 35 deletions(-) diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index d55b31e..a5f3246 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -207,7 +207,6 @@ shared_ptr Parser::matchStatementFunction() { break; case ParseeResultsGroupKind::NO_MATCH: return nullptr; - break; case ParseeResultsGroupKind::FAILURE: hasError = true; break; @@ -465,58 +464,87 @@ shared_ptr Parser::matchStatementBlock(vector terminalToke } shared_ptr Parser::matchStatementAssignment() { - int startIndex = currentIndex; + ParseeResultsGroup resultsGroup; - if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER}, true, false)) - return nullptr; - shared_ptr identifierToken = tokens.at(currentIndex++); + string identifier; shared_ptr indexExpression; + shared_ptr expression; - if (tryMatchingTokenKinds({TokenKind::LEFT_SQUARE_BRACKET}, true, true)) { - indexExpression = nextExpression(); - if (indexExpression == nullptr) - return nullptr; + // identifier + resultsGroup = parseeResultsGroupForParseeGroup( + ParseeGroup( + { + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true), + }, + {} + ) + ); - if (!tryMatchingTokenKinds({TokenKind::RIGHT_SQUARE_BRACKET}, true, true)) { - markError(TokenKind::RIGHT_SQUARE_BRACKET, {}); - return nullptr; - } - } - - // assignment requires left arrow, otherwise abort - if (!tryMatchingTokenKinds({TokenKind::LEFT_ARROW}, true, true)) { - currentIndex = startIndex; - return nullptr; - } - - shared_ptr expression = nextExpression(); - if (expression == nullptr) + if (resultsGroup.getKind() != ParseeResultsGroupKind::SUCCESS) return nullptr; - return make_shared(identifierToken->getLexme(), indexExpression, expression); + identifier = resultsGroup.getResults().at(0).getToken()->getLexme(); + + // index expression + resultsGroup = parseeResultsGroupForParseeGroup( + ParseeGroup( + { + Parsee::tokenParsee(TokenKind::LEFT_SQUARE_BRACKET, true, false), + Parsee::expressionParsee(true), + Parsee::tokenParsee(TokenKind::RIGHT_SQUARE_BRACKET, true, false), + }, + {} + ) + ); + + switch (resultsGroup.getKind()) { + case ParseeResultsGroupKind::SUCCESS: + indexExpression = resultsGroup.getResults().at(0).getExpression(); + break; + case ParseeResultsGroupKind::NO_MATCH: + break; + case ParseeResultsGroupKind::FAILURE: + return nullptr; + } + + // expression + resultsGroup = parseeResultsGroupForParseeGroup( + ParseeGroup( + { + Parsee::tokenParsee(TokenKind::LEFT_ARROW, true, false), + Parsee::expressionParsee(true) + }, + {} + ) + ); + + switch (resultsGroup.getKind()) { + case ParseeResultsGroupKind::SUCCESS: + expression = resultsGroup.getResults().at(0).getExpression(); + break; + case ParseeResultsGroupKind::NO_MATCH: + case ParseeResultsGroupKind::FAILURE: + return nullptr; + } + + return make_shared(identifier, indexExpression, expression); } shared_ptr Parser::matchStatementReturn() { - shared_ptr expression; - ParseeResultsGroup resultsGroup = parseeResultsGroupForParseeGroup( ParseeGroup( { Parsee::tokenParsee(TokenKind::RETURN, true, false), Parsee::expressionParsee(false) }, - { } + {} ) ); - switch (resultsGroup.getKind()) { - case ParseeResultsGroupKind::SUCCESS: - expression = !resultsGroup.getResults().empty() ? resultsGroup.getResults().at(0).getExpression() : nullptr; - break; - case ParseeResultsGroupKind::NO_MATCH: - case ParseeResultsGroupKind::FAILURE: - return nullptr; - } + if (resultsGroup.getKind() != ParseeResultsGroupKind::SUCCESS) + return nullptr; + + shared_ptr expression = !resultsGroup.getResults().empty() ? resultsGroup.getResults().at(0).getExpression() : nullptr; return make_shared(expression); } From 1522aa517b3b6f1f40804e5dd44cad4ecf34d000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Thu, 31 Jul 2025 13:25:06 +0900 Subject: [PATCH 17/28] refactored meta function --- samples/test.brc | 10 ++-- src/Parser/Parser.cpp | 112 +++++++++++++++++++++++++++++------------- 2 files changed, 84 insertions(+), 38 deletions(-) diff --git a/samples/test.brc b/samples/test.brc index 6077f04..21321d7 100644 --- a/samples/test.brc +++ b/samples/test.brc @@ -1,4 +1,4 @@ -//@extern putchar fun: character sint32 -> sint32 +@extern putchar fun: character sint32 -> sint32 // ./build/brb samples/test.brc -S -x86-asm-syntax=intel @@ -49,10 +49,12 @@ rawAdd raw<"=r,r,r">: num1 sint32, num2 sint32 -> sint32 ;*/ main fun -> sint32 - a sint32 <- 4 + /*a sint32 <- 4 b sint32 <- 5 - res sint32 <- rawAdd(4, 5) + res sint32 <- rawAdd(4, 5)*/ + putchar('@') + putchar('\n') - ret res + ret 0 ; \ No newline at end of file diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index a5f3246..3eb154c 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -112,50 +112,91 @@ shared_ptr Parser::nextInBlockStatement() { } shared_ptr Parser::matchStatementMetaExternFunction() { - if (!tryMatchingTokenKinds({TokenKind::M_EXTERN, TokenKind::IDENTIFIER, TokenKind::FUNCTION}, true, false)) - return nullptr; + ParseeResultsGroup resultsGroup; - string name; + string identifier; vector>> arguments; shared_ptr returnType = ValueType::NONE; - currentIndex++; // skip meta - shared_ptr identifierToken = tokens.at(currentIndex++); - currentIndex++; // skip fun + // identifier + resultsGroup = parseeResultsGroupForParseeGroup( + ParseeGroup( + { + Parsee::tokenParsee(TokenKind::M_EXTERN, true, false), + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true), + Parsee::tokenParsee(TokenKind::FUNCTION, true, false) + }, + {} + ) + ); + + switch (resultsGroup.getKind()) { + case ParseeResultsGroupKind::SUCCESS: + identifier = resultsGroup.getResults().at(0).getToken()->getLexme(); + break; + case ParseeResultsGroupKind::NO_MATCH: + case ParseeResultsGroupKind::FAILURE: + return nullptr; + } // arguments - if (tryMatchingTokenKinds({TokenKind::COLON}, true, true)) { - do { - tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true); // skip new line - if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER, TokenKind::TYPE}, true, false)) { - markError({}, "Expected function argument"); - return nullptr; + resultsGroup = parseeResultsGroupForParseeGroup( + ParseeGroup( + { + Parsee::tokenParsee(TokenKind::COLON, true, false), + Parsee::tokenParsee(TokenKind::NEW_LINE, false, false), + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true), + Parsee::valueTypeParsee(true) + }, + ParseeGroup( + { + Parsee::tokenParsee(TokenKind::COMMA, true, false), + Parsee::tokenParsee(TokenKind::NEW_LINE, false, false), + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true), + Parsee::valueTypeParsee(true) + }, + {} + ) + ) + ); + switch (resultsGroup.getKind()) { + case ParseeResultsGroupKind::SUCCESS: + for (int i=0; i> arg; + arg.first = resultsGroup.getResults().at(i).getToken()->getLexme(); + arg.second = resultsGroup.getResults().at(i+1).getValueType(); + arguments.push_back(arg); } - shared_ptr identifierToken = tokens.at(currentIndex++); - //shared_ptr argumentTypeToken = tokens.at(currentIndex++); - shared_ptr argumentType = matchValueType(); - if (argumentType == nullptr) { - markError(TokenKind::TYPE, {}); - return nullptr; - } - - arguments.push_back(pair>(identifierToken->getLexme(), argumentType)); - } while (tryMatchingTokenKinds({TokenKind::COMMA}, true, true)); - } - - // Return type - if (tryMatchingTokenKinds({TokenKind::RIGHT_ARROW}, true, true)) { - tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true); // skip new line - - //shared_ptr returnTypeToken = tokens.at(currentIndex); - returnType = matchValueType(); - if (returnType == nullptr) { - markError(TokenKind::TYPE, {}); + break; + case ParseeResultsGroupKind::NO_MATCH: + break; + case ParseeResultsGroupKind::FAILURE: return nullptr; - } } - return make_shared(identifierToken->getLexme(), arguments, returnType); + // return type + resultsGroup = parseeResultsGroupForParseeGroup( + ParseeGroup( + { + Parsee::tokenParsee(TokenKind::RIGHT_ARROW, true, false), + Parsee::tokenParsee(TokenKind::NEW_LINE, false, false), + Parsee::valueTypeParsee(true) + }, + {} + ) + ); + + switch (resultsGroup.getKind()) { + case ParseeResultsGroupKind::SUCCESS: + returnType = resultsGroup.getResults().at(0).getValueType(); + break; + case ParseeResultsGroupKind::NO_MATCH: + break; + case ParseeResultsGroupKind::FAILURE: + return nullptr; + } + + return make_shared(identifier, arguments, returnType); } shared_ptr Parser::matchStatementVariable() { @@ -464,6 +505,7 @@ shared_ptr Parser::matchStatementBlock(vector terminalToke } shared_ptr Parser::matchStatementAssignment() { + int startIndex = currentIndex; ParseeResultsGroup resultsGroup; string identifier; @@ -523,6 +565,8 @@ shared_ptr Parser::matchStatementAssignment() { expression = resultsGroup.getResults().at(0).getExpression(); break; case ParseeResultsGroupKind::NO_MATCH: + currentIndex = startIndex; + return nullptr; case ParseeResultsGroupKind::FAILURE: return nullptr; } From ad17bd2b5f7c34c11b254f1c8d15ec1be1c709f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Thu, 31 Jul 2025 13:30:50 +0900 Subject: [PATCH 18/28] Cleaned up --- src/Parser/Parser.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index 3eb154c..a7d06b4 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -208,18 +208,18 @@ shared_ptr Parser::matchStatementVariable() { Parsee::tokenParsee(TokenKind::LEFT_ARROW, true, false), Parsee::expressionParsee(true) }, - { } + {} ) ); if (resultsGroup.getKind() != ParseeResultsGroupKind::SUCCESS) return nullptr; - string name = resultsGroup.getResults().at(0).getToken()->getLexme(); + string identifier = resultsGroup.getResults().at(0).getToken()->getLexme(); shared_ptr valueType = resultsGroup.getResults().at(1).getValueType(); shared_ptr expression = resultsGroup.getResults().at(2).getExpression(); - return make_shared(name, valueType, expression); + return make_shared(identifier, valueType, expression); } shared_ptr Parser::matchStatementFunction() { From def96445b27e4dcbb8f456db8f7018fe551fb5ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Thu, 31 Jul 2025 13:39:15 +0900 Subject: [PATCH 19/28] Better log message --- src/Logger.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Logger.cpp b/src/Logger.cpp index b8f85e0..98dd04e 100644 --- a/src/Logger.cpp +++ b/src/Logger.cpp @@ -482,7 +482,7 @@ void Logger::print(shared_ptr error) { switch (error->getKind()) { case ErrorKind::LEXER_ERROR: { string lexme = error->getLexme() ? *(error->getLexme()) : ""; - message = format("Unexpected token \"{}\" at line: {}, column: {}", lexme, error->getLine() + 1, error->getColumn() + 1); + message = format("At line {}, column {}: Unexpected token \"{}\"", error->getLine() + 1, error->getColumn() + 1, lexme); break; } case ErrorKind::PARSER_ERROR: { @@ -492,13 +492,13 @@ void Logger::print(shared_ptr error) { if (expectedTokenKind) { message = format( - "Expected token {} but instead found {} at line: {}, column: {}", - toString(*expectedTokenKind), toString(token), token->getLine() + 1, token->getColumn() + 1 + "At line {}, column {}: Expected token {} but found {} instead", + token->getLine() + 1, token->getColumn() + 1, toString(*expectedTokenKind), toString(token) ); } else { message = format( - "Unexpected token \"{}\" found at line: {}, column: {}", - toString(token), token->getLine() + 1, token->getColumn() + 1 + "At line {}, column {}: Unexpected token \"{}\" found", + token->getLine() + 1, token->getColumn() + 1, toString(token) ); } if (errorMessage) @@ -507,7 +507,7 @@ void Logger::print(shared_ptr error) { } case ErrorKind::BUILDER_ERROR: { string errorMessage = error->getMessage() ? *(error->getMessage()) : ""; - message = format("Error at line {}, column {}: {}", error->getLine(), error->getColumn(), errorMessage); + message = format("At line {}, column {}: {}", error->getLine(), error->getColumn(), errorMessage); break; } } From e37a34b4e65372b23b51db2488e99cef931799c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Thu, 31 Jul 2025 14:01:15 +0900 Subject: [PATCH 20/28] Parse value type arg --- src/Parser/Parser.cpp | 52 +++++++++---------------------------------- src/Parser/Parser.h | 2 -- 2 files changed, 10 insertions(+), 44 deletions(-) diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index a7d06b4..0db1a3d 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -952,46 +952,6 @@ shared_ptr Parser::matchExpressionBlock(vector terminalTo return make_shared(statements); } -shared_ptr Parser::matchValueType() { - if (!tryMatchingTokenKinds({TokenKind::TYPE}, true, false)) - return nullptr; - shared_ptr typeToken = tokens.at(currentIndex++); - shared_ptr subType; - int valueArg = 0; - - if (tryMatchingTokenKinds({TokenKind::LESS}, true, true)) { - if (!tryMatchingTokenKinds({TokenKind::TYPE}, true, false)) { - markError(TokenKind::TYPE, {}); - return nullptr; - } - subType = matchValueType(); - if (subType == nullptr) - return subType; - - if (tryMatchingTokenKinds({TokenKind::COMMA}, true, true)) { - if (!tryMatchingTokenKinds({TokenKind::INTEGER_DEC, TokenKind::INTEGER_HEX, TokenKind::INTEGER_BIN, TokenKind::INTEGER_CHAR}, false, false)) { - markError({}, "Expected integer literal"); - return nullptr; - } - shared_ptr expressionValue = matchExpressionLiteral(); - if (expressionValue == nullptr) { - markError({}, "Expected integer literal"); - return nullptr; - } - - valueArg = dynamic_pointer_cast(expressionValue)->getSint32Value(); - } - - - if (!tryMatchingTokenKinds({TokenKind::GREATER}, true, true)) { - markError(TokenKind::GREATER, {}); - return nullptr; - } - } - - return ValueType::valueTypeForToken(typeToken, subType, valueArg); -} - ParseeResultsGroup Parser::parseeResultsGroupForParseeGroup(ParseeGroup group) { int errorsCount = errors.size(); int startIndex = currentIndex; @@ -1081,20 +1041,28 @@ optional Parser::valueTypeParseeResult(int index) { if (!subResult) return {}; subType = (*subResult).getValueType(); - + index += (*subResult).getTokensCount(); if (tokens.at(index)->isOfKind({TokenKind::COMMA})) { index++; if (!tokens.at(index)->isOfKind({TokenKind::INTEGER_DEC, TokenKind::INTEGER_HEX, TokenKind::INTEGER_BIN, TokenKind::INTEGER_CHAR})) return {}; + + int storedIndex = currentIndex; + currentIndex = index; + shared_ptr expressionValue = matchExpressionLiteral(); + typeArg = dynamic_pointer_cast(expressionValue)->getSint32Value(); + currentIndex = storedIndex; + index++; } if (!tokens.at(index)->isOfKind({TokenKind::GREATER})) return {}; + index++; } - shared_ptr valueType = ValueType::valueTypeForToken(typeToken, subType, 0); + shared_ptr valueType = ValueType::valueTypeForToken(typeToken, subType, typeArg); return ParseeResult::valueTypeResult(valueType, index - startIndex); } diff --git a/src/Parser/Parser.h b/src/Parser/Parser.h index 9ab27a3..8e5a8d5 100644 --- a/src/Parser/Parser.h +++ b/src/Parser/Parser.h @@ -54,8 +54,6 @@ private: shared_ptr matchExpressionBinary(shared_ptr left); shared_ptr matchExpressionBlock(vector terminalTokenKinds); - shared_ptr matchValueType(); - ParseeResultsGroup parseeResultsGroupForParseeGroup(ParseeGroup group); optional tokenParseeResult(int index, TokenKind tokenKind); optional valueTypeParseeResult(int index); From da11f522a1146c57c7f784e01e3f524ca7caf8be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Thu, 31 Jul 2025 16:02:11 +0900 Subject: [PATCH 21/28] Update ingnored files --- .gitignore | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.gitignore b/.gitignore index 94ff068..b46f74d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,8 @@ +# ingnore files without extension +* +!*.* +!*/ + .DS_Store .vscode/settings.json @@ -7,3 +12,4 @@ build/ # brb build artifiacts *.o +*.asm \ No newline at end of file From 4242600ea0fbe8fc389028464b843b8219ab22b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Thu, 31 Jul 2025 16:56:09 +0900 Subject: [PATCH 22/28] Added clean task, fixed build task --- .vscode/tasks.json | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 0fc81a3..99f9dd4 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -3,12 +3,17 @@ "tasks": [ { "label": "Build Bits Runner Builder (Debug)", - "type": "cmake", - "command": "build", + "type": "shell", + "command": "cmake -B build && cmake --build build --config Debug", "group": { "kind": "build", "isDefault": true } + }, + { + "label": "Clean", + "type": "shell", + "command": "rm -rf build *.o *.asm; find ./ -perm +100 -type f -maxdepth 1 -delete" } ] } \ No newline at end of file From 2e79188cd3a7f96101d78e9cf199d59e9059a531 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Thu, 31 Jul 2025 20:28:50 +0900 Subject: [PATCH 23/28] Signed and unsinged int variants --- samples/test.brc | 19 ++-- src/Compiler/ModuleBuilder.cpp | 116 ++++++++++++++------ src/Compiler/ModuleBuilder.h | 10 +- src/Logger.cpp | 28 +++-- src/Parser/Expression/ExpressionLiteral.cpp | 30 +++-- src/Parser/Expression/ExpressionLiteral.h | 14 ++- src/Parser/Parser.cpp | 2 +- src/Parser/ValueType.cpp | 25 +++-- src/Parser/ValueType.h | 14 ++- 9 files changed, 175 insertions(+), 83 deletions(-) diff --git a/samples/test.brc b/samples/test.brc index 21321d7..25c5641 100644 --- a/samples/test.brc +++ b/samples/test.brc @@ -1,4 +1,4 @@ -@extern putchar fun: character sint32 -> sint32 +//@extern putchar fun: character sint32 -> sint32 // ./build/brb samples/test.brc -S -x86-asm-syntax=intel @@ -28,10 +28,10 @@ i u32 <- 0, rep text[i] != 0: ret num1 + num2 ;*/ -rawAdd raw<"=r,r,r">: num1 sint32, num2 sint32 -> sint32 +/*rawAdd raw<"=r,r,r">: num1 sint32, num2 sint32 -> sint32 add $1, $2 mov $0, $1 -; +;*/ /*rawAdd raw: num1 sint32, num2 sint32 -> sint32 add $1, $2 @@ -48,13 +48,12 @@ rawAdd raw<"=r,r,r">: num1 sint32, num2 sint32 -> sint32 ;*/ -main fun -> sint32 - /*a sint32 <- 4 - b sint32 <- 5 - - res sint32 <- rawAdd(4, 5)*/ - putchar('@') - putchar('\n') +main fun -> u32 + num1 u8 <- 42 + num2 s8 <- 15 + num3 u32 <- 1234123 + num4 s32 <- 345345 + num5 r32 <- 42.58 ret 0 ; \ No newline at end of file diff --git a/src/Compiler/ModuleBuilder.cpp b/src/Compiler/ModuleBuilder.cpp index 525652c..ca59586 100644 --- a/src/Compiler/ModuleBuilder.cpp +++ b/src/Compiler/ModuleBuilder.cpp @@ -32,8 +32,11 @@ moduleName(moduleName), sourceFileName(sourceFileName), statements(statements) { typeVoid = llvm::Type::getVoidTy(*context); typeBool = llvm::Type::getInt1Ty(*context); - typeSint32 = llvm::Type::getInt32Ty(*context); - typeReal32 = llvm::Type::getFloatTy(*context); + typeU8 = llvm::Type::getInt8Ty(*context); + typeU32 = llvm::Type::getInt32Ty(*context); + typeS8 = llvm::Type::getInt8Ty(*context); + typeS32 = llvm::Type::getInt32Ty(*context); + typeR32 = llvm::Type::getFloatTy(*context); } shared_ptr ModuleBuilder::getModule() { @@ -325,10 +328,16 @@ llvm::Value *ModuleBuilder::valueForLiteral(shared_ptr expres return llvm::UndefValue::get(typeVoid); case ValueTypeKind::BOOL: return llvm::ConstantInt::get(typeBool, expression->getBoolValue(), true); - case ValueTypeKind::SINT32: - return llvm::ConstantInt::get(typeSint32, expression->getSint32Value(), true); - case ValueTypeKind::REAL32: - return llvm::ConstantInt::get(typeReal32, expression->getReal32Value(), true); + case ValueTypeKind::U8: + return llvm::ConstantInt::get(typeU8, expression->getU8Value(), true); + case ValueTypeKind::U32: + return llvm::ConstantInt::get(typeU32, expression->getU32Value(), true); + case ValueTypeKind::S8: + return llvm::ConstantInt::get(typeS8, expression->getS8Value(), true); + case ValueTypeKind::S32: + return llvm::ConstantInt::get(typeS32, expression->getS32Value(), true); + case ValueTypeKind::R32: + return llvm::ConstantInt::get(typeR32, expression->getR32Value(), true); } } @@ -355,9 +364,11 @@ llvm::Value *ModuleBuilder::valueForBinary(shared_ptr expressi if (type == typeBool) { return valueForBinaryBool(expression->getOperation(), leftValue, rightValue); - } else if (type == typeSint32 || type == typeVoid) { - return valueForBinaryInteger(expression->getOperation(), leftValue, rightValue); - } else if (type == typeReal32) { + } else if (type == typeU8 || type == typeU32) { + return valueForBinaryUnsignedInteger(expression->getOperation(), leftValue, rightValue); + } else if (type == typeS8 || type == typeS32) { + return valueForBinarySignedInteger(expression->getOperation(), leftValue, rightValue); + } else if (type == typeR32) { return valueForBinaryReal(expression->getOperation(), leftValue, rightValue); } @@ -377,30 +388,57 @@ llvm::Value *ModuleBuilder::valueForBinaryBool(ExpressionBinaryOperation operati } } -llvm::Value *ModuleBuilder::valueForBinaryInteger(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue) { +llvm::Value *ModuleBuilder::valueForBinaryUnsignedInteger(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue) { switch (operation) { - case ExpressionBinaryOperation::EQUAL: - return builder->CreateICmpEQ(leftValue, rightValue); - case ExpressionBinaryOperation::NOT_EQUAL: - return builder->CreateICmpNE(leftValue, rightValue); - case ExpressionBinaryOperation::LESS: - return builder->CreateICmpSLT(leftValue, rightValue); - case ExpressionBinaryOperation::LESS_EQUAL: - return builder->CreateICmpSLE(leftValue, rightValue); - case ExpressionBinaryOperation::GREATER: - return builder->CreateICmpSGT(leftValue, rightValue); - case ExpressionBinaryOperation::GREATER_EQUAL: - return builder->CreateICmpSGE(leftValue, rightValue); - case ExpressionBinaryOperation::ADD: - return builder->CreateNSWAdd(leftValue, rightValue); - case ExpressionBinaryOperation::SUB: - return builder->CreateNSWSub(leftValue, rightValue); - case ExpressionBinaryOperation::MUL: - return builder->CreateNSWMul(leftValue, rightValue); - case ExpressionBinaryOperation::DIV: - return builder->CreateSDiv(leftValue, rightValue); - case ExpressionBinaryOperation::MOD: - return builder->CreateSRem(leftValue, rightValue); + case ExpressionBinaryOperation::EQUAL: + return builder->CreateICmpEQ(leftValue, rightValue); + case ExpressionBinaryOperation::NOT_EQUAL: + return builder->CreateICmpNE(leftValue, rightValue); + case ExpressionBinaryOperation::LESS: + return builder->CreateICmpSLT(leftValue, rightValue); + case ExpressionBinaryOperation::LESS_EQUAL: + return builder->CreateICmpSLE(leftValue, rightValue); + case ExpressionBinaryOperation::GREATER: + return builder->CreateICmpSGT(leftValue, rightValue); + case ExpressionBinaryOperation::GREATER_EQUAL: + return builder->CreateICmpSGE(leftValue, rightValue); + case ExpressionBinaryOperation::ADD: + return builder->CreateNUWAdd(leftValue, rightValue); + case ExpressionBinaryOperation::SUB: + return builder->CreateNUWSub(leftValue, rightValue); + case ExpressionBinaryOperation::MUL: + return builder->CreateNUWMul(leftValue, rightValue); + case ExpressionBinaryOperation::DIV: + return builder->CreateUDiv(leftValue, rightValue); + case ExpressionBinaryOperation::MOD: + return builder->CreateURem(leftValue, rightValue); + } +} + +llvm::Value *ModuleBuilder::valueForBinarySignedInteger(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue) { + switch (operation) { + case ExpressionBinaryOperation::EQUAL: + return builder->CreateICmpEQ(leftValue, rightValue); + case ExpressionBinaryOperation::NOT_EQUAL: + return builder->CreateICmpNE(leftValue, rightValue); + case ExpressionBinaryOperation::LESS: + return builder->CreateICmpSLT(leftValue, rightValue); + case ExpressionBinaryOperation::LESS_EQUAL: + return builder->CreateICmpSLE(leftValue, rightValue); + case ExpressionBinaryOperation::GREATER: + return builder->CreateICmpSGT(leftValue, rightValue); + case ExpressionBinaryOperation::GREATER_EQUAL: + return builder->CreateICmpSGE(leftValue, rightValue); + case ExpressionBinaryOperation::ADD: + return builder->CreateNSWAdd(leftValue, rightValue); + case ExpressionBinaryOperation::SUB: + return builder->CreateNSWSub(leftValue, rightValue); + case ExpressionBinaryOperation::MUL: + return builder->CreateNSWMul(leftValue, rightValue); + case ExpressionBinaryOperation::DIV: + return builder->CreateSDiv(leftValue, rightValue); + case ExpressionBinaryOperation::MOD: + return builder->CreateSRem(leftValue, rightValue); } } @@ -605,10 +643,16 @@ llvm::Type *ModuleBuilder::typeForValueType(shared_ptr valueType, int return typeVoid; case ValueTypeKind::BOOL: return typeBool; - case ValueTypeKind::SINT32: - return typeSint32; - case ValueTypeKind::REAL32: - return typeReal32; + case ValueTypeKind::U8: + return typeU8; + case ValueTypeKind::U32: + return typeU32; + case ValueTypeKind::S8: + return typeS8; + case ValueTypeKind::S32: + return typeS32; + case ValueTypeKind::R32: + return typeR32; case ValueTypeKind::DATA: { if (valueType->getSubType() == nullptr) return nullptr; diff --git a/src/Compiler/ModuleBuilder.h b/src/Compiler/ModuleBuilder.h index 3378856..b9f0100 100644 --- a/src/Compiler/ModuleBuilder.h +++ b/src/Compiler/ModuleBuilder.h @@ -56,8 +56,11 @@ private: llvm::Type *typeVoid; llvm::Type *typeBool; - llvm::IntegerType *typeSint32; - llvm::Type *typeReal32; + llvm::IntegerType *typeU8; + llvm::IntegerType *typeU32; + llvm::IntegerType *typeS8; + llvm::IntegerType *typeS32; + llvm::Type *typeR32; vector> statements; stack scopes; @@ -80,7 +83,8 @@ private: llvm::Value *valueForGrouping(shared_ptr expression); llvm::Value *valueForBinary(shared_ptr expression); llvm::Value *valueForBinaryBool(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue); - llvm::Value *valueForBinaryInteger(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue); + llvm::Value *valueForBinaryUnsignedInteger(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue); + llvm::Value *valueForBinarySignedInteger(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue); llvm::Value *valueForBinaryReal(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue); llvm::Value *valueForIfElse(shared_ptr expression); llvm::Value *valueForVar(shared_ptr expression); diff --git a/src/Logger.cpp b/src/Logger.cpp index 98dd04e..a2c9543 100644 --- a/src/Logger.cpp +++ b/src/Logger.cpp @@ -207,10 +207,16 @@ string Logger::toString(shared_ptr valueType) { return "NONE"; case ValueTypeKind::BOOL: return "BOOL"; - case ValueTypeKind::SINT32: - return "SINT32"; - case ValueTypeKind::REAL32: - return "REAL32"; + case ValueTypeKind::U8: + return "U8"; + case ValueTypeKind::U32: + return "U32"; + case ValueTypeKind::S8: + return "S8"; + case ValueTypeKind::S32: + return "S32"; + case ValueTypeKind::R32: + return "R32"; case ValueTypeKind::DATA: return "[]"; } @@ -420,10 +426,16 @@ string Logger::toString(shared_ptr expression) { return "NONE"; case ValueTypeKind::BOOL: return expression->getBoolValue() ? "true" : "false"; - case ValueTypeKind::SINT32: - return to_string(expression->getSint32Value()); - case ValueTypeKind::REAL32: - return to_string(expression->getReal32Value()); + case ValueTypeKind::U8: + return to_string(expression->getU8Value()); + case ValueTypeKind::U32: + return to_string(expression->getU32Value()); + case ValueTypeKind::S8: + return to_string(expression->getS8Value()); + case ValueTypeKind::S32: + return to_string(expression->getS32Value()); + case ValueTypeKind::R32: + return to_string(expression->getR32Value()); default: return "?"; } diff --git a/src/Parser/Expression/ExpressionLiteral.cpp b/src/Parser/Expression/ExpressionLiteral.cpp index 648046e..76238a3 100644 --- a/src/Parser/Expression/ExpressionLiteral.cpp +++ b/src/Parser/Expression/ExpressionLiteral.cpp @@ -15,14 +15,14 @@ shared_ptr ExpressionLiteral::expressionLiteralForToken(share case TokenKind::INTEGER_DEC: { string numString = token->getLexme(); erase(numString, '_'); - expression->sint32Value = stoi(numString, nullptr, 10); + expression->s32Value = stoi(numString, nullptr, 10); expression->valueType = ValueType::valueTypeForToken(token, nullptr, 0); break; } case TokenKind::INTEGER_HEX: { string numString = token->getLexme(); erase(numString, '_'); - expression->sint32Value = stoi(numString, nullptr, 16); + expression->u32Value = stoul(numString, nullptr, 16); expression->valueType = ValueType::valueTypeForToken(token, nullptr, 0); break; } @@ -30,7 +30,7 @@ shared_ptr ExpressionLiteral::expressionLiteralForToken(share string numString = token->getLexme(); erase(numString, '_'); numString = numString.substr(2, numString.size()-1); - expression->sint32Value = stoi(numString, nullptr, 2); + expression->u32Value = stoul(numString, nullptr, 2); expression->valueType = ValueType::valueTypeForToken(token, nullptr, 0); break; } @@ -41,11 +41,11 @@ shared_ptr ExpressionLiteral::expressionLiteralForToken(share return nullptr; expression->valueType = ValueType::valueTypeForToken(token, nullptr, 0); - expression->sint32Value = *charValue; + expression->u32Value = *charValue; return expression; } case TokenKind::REAL: - expression->real32Value = stof(token->getLexme()); + expression->r32Value = stof(token->getLexme()); expression->valueType = ValueType::valueTypeForToken(token, nullptr, 0); break; default: @@ -62,10 +62,22 @@ bool ExpressionLiteral::getBoolValue() { return boolValue; } -int32_t ExpressionLiteral::getSint32Value() { - return sint32Value; +uint8_t ExpressionLiteral::getU8Value() { + return s32Value; } -float ExpressionLiteral::getReal32Value() { - return real32Value; +uint32_t ExpressionLiteral::getU32Value() { + return s32Value; +} + +int8_t ExpressionLiteral::getS8Value() { + return s32Value; +} + +int32_t ExpressionLiteral::getS32Value() { + return s32Value; +} + +float ExpressionLiteral::getR32Value() { + return r32Value; } diff --git a/src/Parser/Expression/ExpressionLiteral.h b/src/Parser/Expression/ExpressionLiteral.h index 89b545e..89b8bf4 100644 --- a/src/Parser/Expression/ExpressionLiteral.h +++ b/src/Parser/Expression/ExpressionLiteral.h @@ -6,16 +6,22 @@ class ExpressionLiteral: public Expression { private: bool boolValue; - int32_t sint32Value; - float real32Value; + uint8_t u8Value; + uint32_t u32Value; + int8_t s8Value; + int32_t s32Value; + float r32Value; public: static shared_ptr expressionLiteralForToken(shared_ptr token); ExpressionLiteral(); bool getBoolValue(); - int32_t getSint32Value(); - float getReal32Value(); + uint8_t getU8Value(); + uint32_t getU32Value(); + int8_t getS8Value(); + int32_t getS32Value(); + float getR32Value(); }; #endif \ No newline at end of file diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index 0db1a3d..9906eeb 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -1052,7 +1052,7 @@ optional Parser::valueTypeParseeResult(int index) { int storedIndex = currentIndex; currentIndex = index; shared_ptr expressionValue = matchExpressionLiteral(); - typeArg = dynamic_pointer_cast(expressionValue)->getSint32Value(); + typeArg = dynamic_pointer_cast(expressionValue)->getU32Value(); currentIndex = storedIndex; index++; } diff --git a/src/Parser/ValueType.cpp b/src/Parser/ValueType.cpp index 6f5945d..0230362 100644 --- a/src/Parser/ValueType.cpp +++ b/src/Parser/ValueType.cpp @@ -4,8 +4,11 @@ shared_ptr ValueType::NONE = make_shared(ValueTypeKind::NONE, nullptr, 0); shared_ptr ValueType::BOOL = make_shared(ValueTypeKind::BOOL, nullptr, 0); -shared_ptr ValueType::SINT32 = make_shared(ValueTypeKind::SINT32, nullptr, 0); -shared_ptr ValueType::REAL32 = make_shared(ValueTypeKind::REAL32, nullptr, 0); +shared_ptr ValueType::U8 = make_shared(ValueTypeKind::U8, nullptr, 0); +shared_ptr ValueType::U32 = make_shared(ValueTypeKind::U32, nullptr, 0); +shared_ptr ValueType::S8 = make_shared(ValueTypeKind::S8, nullptr, 0); +shared_ptr ValueType::S32 = make_shared(ValueTypeKind::S32, nullptr, 0); +shared_ptr ValueType::R32 = make_shared(ValueTypeKind::R32, nullptr, 0); ValueType::ValueType(ValueTypeKind kind, shared_ptr subType, int valueArg): kind(kind), subType(subType), valueArg(valueArg) { } @@ -16,10 +19,16 @@ shared_ptr ValueType::valueTypeForToken(shared_ptr token, shar string lexme = token->getLexme(); if (lexme.compare("bool") == 0) return make_shared(ValueTypeKind::BOOL, subType, valueArg); - else if (lexme.compare("sint32") == 0) - return make_shared(ValueTypeKind::SINT32, subType, valueArg); - else if (lexme.compare("real32") == 0) - return make_shared(ValueTypeKind::REAL32, subType, valueArg); + else if (lexme.compare("u8") == 0) + return make_shared(ValueTypeKind::U8, subType, valueArg); + else if (lexme.compare("u32") == 0) + return make_shared(ValueTypeKind::U32, subType, valueArg); + else if (lexme.compare("s8") == 0) + return make_shared(ValueTypeKind::S8, subType, valueArg); + else if (lexme.compare("s32") == 0) + return make_shared(ValueTypeKind::S32, subType, valueArg); + else if (lexme.compare("r32") == 0) + return make_shared(ValueTypeKind::R32, subType, valueArg); else if (lexme.compare("data") == 0) return make_shared(ValueTypeKind::DATA, subType, valueArg); else @@ -31,9 +40,9 @@ shared_ptr ValueType::valueTypeForToken(shared_ptr token, shar case TokenKind::INTEGER_HEX: case TokenKind::INTEGER_BIN: case TokenKind::INTEGER_CHAR: - return make_shared(ValueTypeKind::SINT32, nullptr, 0); + return make_shared(ValueTypeKind::U32, nullptr, 0); case TokenKind::REAL: - return make_shared(ValueTypeKind::REAL32, nullptr, 0); + return make_shared(ValueTypeKind::R32, nullptr, 0); default: return nullptr; } diff --git a/src/Parser/ValueType.h b/src/Parser/ValueType.h index ce118eb..2b77f2f 100644 --- a/src/Parser/ValueType.h +++ b/src/Parser/ValueType.h @@ -10,8 +10,11 @@ using namespace std; enum class ValueTypeKind { NONE, BOOL, - SINT32, - REAL32, + U8, + U32, + S8, + S32, + R32, DATA }; @@ -24,8 +27,11 @@ private: public: static shared_ptr NONE; static shared_ptr BOOL; - static shared_ptr SINT32; - static shared_ptr REAL32; + static shared_ptr U8; + static shared_ptr U32; + static shared_ptr S8; + static shared_ptr S32; + static shared_ptr R32; static shared_ptr valueTypeForToken(shared_ptr token, shared_ptr subType, int valueArg); ValueType(ValueTypeKind kind, shared_ptr subType, int valueArg); From c75052e35f7b2bc01bdcba394b0b189ababdbe28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Thu, 31 Jul 2025 22:04:30 +0900 Subject: [PATCH 24/28] Added expression unary --- samples/test.brc | 6 +++--- src/Parser/Expression/Expression.h | 1 + src/Parser/Expression/ExpressionBinary.h | 9 ++++++-- src/Parser/Expression/ExpressionUnary.cpp | 26 +++++++++++++++++++++++ src/Parser/Expression/ExpressionUnary.h | 23 ++++++++++++++++++++ 5 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 src/Parser/Expression/ExpressionUnary.cpp create mode 100644 src/Parser/Expression/ExpressionUnary.h diff --git a/samples/test.brc b/samples/test.brc index 25c5641..b2f978b 100644 --- a/samples/test.brc +++ b/samples/test.brc @@ -50,10 +50,10 @@ i u32 <- 0, rep text[i] != 0: main fun -> u32 num1 u8 <- 42 - num2 s8 <- 15 + num2 s8 <- -15 num3 u32 <- 1234123 - num4 s32 <- 345345 - num5 r32 <- 42.58 + num4 s32 <- -345345 + num5 r32 <- -42.58 ret 0 ; \ No newline at end of file diff --git a/src/Parser/Expression/Expression.h b/src/Parser/Expression/Expression.h index 66bd170..a335052 100644 --- a/src/Parser/Expression/Expression.h +++ b/src/Parser/Expression/Expression.h @@ -12,6 +12,7 @@ enum class ExpressionKind { LITERAL, ARRAY_LITERAL, GROUPING, + UNARY, BINARY, IF_ELSE, VAR, diff --git a/src/Parser/Expression/ExpressionBinary.h b/src/Parser/Expression/ExpressionBinary.h index 0c5bb4c..56b31fa 100644 --- a/src/Parser/Expression/ExpressionBinary.h +++ b/src/Parser/Expression/ExpressionBinary.h @@ -1,4 +1,7 @@ -#include "Parser/Expression/Expression.h" +#ifndef EXPRESSION_BINARY_H +#define EXPRESSION_BINARY_H + +#include "Expression.h" enum class ExpressionBinaryOperation { EQUAL, @@ -26,4 +29,6 @@ public: ExpressionBinaryOperation getOperation(); shared_ptr getLeft(); shared_ptr getRight(); -}; \ No newline at end of file +}; + +#endif \ No newline at end of file diff --git a/src/Parser/Expression/ExpressionUnary.cpp b/src/Parser/Expression/ExpressionUnary.cpp new file mode 100644 index 0000000..420cdd9 --- /dev/null +++ b/src/Parser/Expression/ExpressionUnary.cpp @@ -0,0 +1,26 @@ +#include "ExpressionUnary.h" + +#include "Lexer/Token.h" + +ExpressionUnary::ExpressionUnary(shared_ptr token, shared_ptr expression): +Expression(ExpressionKind::UNARY, nullptr), expression(expression) { + switch (token->getKind()) { + case TokenKind::PLUS: + operation = ExpressionUnaryOperation::PLUS; + break; + case TokenKind::MINUS: + operation = ExpressionUnaryOperation::MINUS; + break; + default: + operation = ExpressionUnaryOperation::INVALID; + break; + } +} + +ExpressionUnaryOperation ExpressionUnary::getOperation() { + return operation; +} + +shared_ptr ExpressionUnary::getExpression() { + return expression; +} \ No newline at end of file diff --git a/src/Parser/Expression/ExpressionUnary.h b/src/Parser/Expression/ExpressionUnary.h new file mode 100644 index 0000000..2ba56fd --- /dev/null +++ b/src/Parser/Expression/ExpressionUnary.h @@ -0,0 +1,23 @@ +#ifndef EXPRESSION_UNARY_H +#define EXPRESSION_UNARY_H + +#include "Expression.h" + +enum class ExpressionUnaryOperation { + PLUS, + MINUS, + INVALID +}; + +class ExpressionUnary: public Expression { +private: + ExpressionUnaryOperation operation; + shared_ptr expression; + +public: + ExpressionUnary(shared_ptr token, shared_ptr expression); + ExpressionUnaryOperation getOperation(); + shared_ptr getExpression(); +}; + +#endif \ No newline at end of file From 7dfa6bcffeeccabccb36b2a02d62a0b4f075a1d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Thu, 31 Jul 2025 23:28:33 +0900 Subject: [PATCH 25/28] Added unary expressions --- samples/test.brc | 6 ++--- src/Compiler/ModuleBuilder.cpp | 29 +++++++++++++++++++++-- src/Compiler/ModuleBuilder.h | 2 ++ src/Lexer/Token.cpp | 10 ++++++++ src/Lexer/Token.h | 1 + src/Logger.cpp | 16 ++++++++++++- src/Logger.h | 2 ++ src/Parser/Expression/ExpressionUnary.cpp | 3 +++ src/Parser/Parser.cpp | 16 ++++++++++++- src/Parser/Parser.h | 3 ++- 10 files changed, 80 insertions(+), 8 deletions(-) diff --git a/samples/test.brc b/samples/test.brc index b2f978b..02f3f71 100644 --- a/samples/test.brc +++ b/samples/test.brc @@ -49,10 +49,10 @@ i u32 <- 0, rep text[i] != 0: ;*/ main fun -> u32 - num1 u8 <- 42 - num2 s8 <- -15 + /*num1 u8 <- 42 + num2 s8 <- 3 - +15 num3 u32 <- 1234123 - num4 s32 <- -345345 + num4 s32 <- -345345*/ num5 r32 <- -42.58 ret 0 diff --git a/src/Compiler/ModuleBuilder.cpp b/src/Compiler/ModuleBuilder.cpp index ca59586..5a8c3c7 100644 --- a/src/Compiler/ModuleBuilder.cpp +++ b/src/Compiler/ModuleBuilder.cpp @@ -11,6 +11,7 @@ #include "Parser/Expression/ExpressionCall.h" #include "Parser/Expression/ExpressionIfElse.h" #include "Parser/Expression/ExpressionBinary.h" +#include "Parser/Expression/ExpressionUnary.h" #include "Parser/Expression/ExpressionBlock.h" #include "Parser/Statement/StatementFunction.h" @@ -172,6 +173,8 @@ void ModuleBuilder::buildVarDeclaration(shared_ptr statement) } } else { llvm::Value *value = valueForExpression(statement->getExpression()); + if (value == nullptr) + return; llvm::AllocaInst *alloca = builder->CreateAlloca(typeForValueType(statement->getValueType(), 0), nullptr, statement->getName()); if (!setAlloca(statement->getName(), alloca)) @@ -297,6 +300,8 @@ llvm::Value *ModuleBuilder::valueForExpression(shared_ptr expression return valueForExpression(dynamic_pointer_cast(expression)->getExpression()); case ExpressionKind::BINARY: return valueForBinary(dynamic_pointer_cast(expression)); + case ExpressionKind::UNARY: + return valueForUnary(dynamic_pointer_cast(expression)); case ExpressionKind::IF_ELSE: return valueForIfElse(dynamic_pointer_cast(expression)); case ExpressionKind::VAR: @@ -337,7 +342,7 @@ llvm::Value *ModuleBuilder::valueForLiteral(shared_ptr expres case ValueTypeKind::S32: return llvm::ConstantInt::get(typeS32, expression->getS32Value(), true); case ValueTypeKind::R32: - return llvm::ConstantInt::get(typeR32, expression->getR32Value(), true); + return llvm::ConstantFP::get(typeR32, expression->getR32Value()); } } @@ -383,7 +388,7 @@ llvm::Value *ModuleBuilder::valueForBinaryBool(ExpressionBinaryOperation operati case ExpressionBinaryOperation::NOT_EQUAL: return builder->CreateICmpNE(leftValue, rightValue); default: - markError(0, 0, "Unexpecgted operation for boolean operands"); + markError(0, 0, "Unexpected operation for boolean operands"); return nullptr; } } @@ -469,6 +474,26 @@ llvm::Value *ModuleBuilder::valueForBinaryReal(ExpressionBinaryOperation operati } } +llvm::Value *ModuleBuilder::valueForUnary(shared_ptr expression) { + llvm::Value *value = valueForExpression(expression->getExpression()); + llvm::Type *type = value->getType(); + + // do nothing for plus + if (expression->getOperation() == ExpressionUnaryOperation::PLUS) + return value; + + if (type == typeU8 || type == typeU32) { + return builder->CreateNeg(value); + } else if (type == typeS8 || type == typeS32) { + return builder->CreateNSWNeg(value); + } else if (type == typeR32) { + return builder->CreateFNeg(value); + } + + markError(0, 0, "Unexpected operation"); + return nullptr; +} + llvm::Value *ModuleBuilder::valueForIfElse(shared_ptr expression) { shared_ptr conditionExpression = expression->getCondition(); diff --git a/src/Compiler/ModuleBuilder.h b/src/Compiler/ModuleBuilder.h index b9f0100..872b4ad 100644 --- a/src/Compiler/ModuleBuilder.h +++ b/src/Compiler/ModuleBuilder.h @@ -23,6 +23,7 @@ class ExpressionVariable; class ExpressionCall; class ExpressionIfElse; class ExpressionBinary; +class ExpressionUnary; enum class ExpressionBinaryOperation; class Statement; @@ -86,6 +87,7 @@ private: llvm::Value *valueForBinaryUnsignedInteger(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue); llvm::Value *valueForBinarySignedInteger(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue); llvm::Value *valueForBinaryReal(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue); + llvm::Value *valueForUnary(shared_ptr expression); llvm::Value *valueForIfElse(shared_ptr expression); llvm::Value *valueForVar(shared_ptr expression); llvm::Value *valueForCall(shared_ptr expression); diff --git a/src/Lexer/Token.cpp b/src/Lexer/Token.cpp index 5fcc1df..2adddfe 100644 --- a/src/Lexer/Token.cpp +++ b/src/Lexer/Token.cpp @@ -4,21 +4,30 @@ vector Token::tokensEquality = { TokenKind::EQUAL, TokenKind::NOT_EQUAL }; + vector Token::tokensComparison = { TokenKind::LESS, TokenKind::LESS_EQUAL, TokenKind::GREATER, TokenKind::GREATER_EQUAL }; + vector Token::tokensTerm = { TokenKind::PLUS, TokenKind::MINUS }; + vector Token::tokensFactor = { TokenKind::STAR, TokenKind::SLASH, TokenKind::PERCENT }; + +vector Token::tokensUnary = { + TokenKind::PLUS, + TokenKind::MINUS +}; + vector Token::tokensBinary = { TokenKind::EQUAL, TokenKind::NOT_EQUAL, @@ -35,6 +44,7 @@ vector Token::tokensBinary = { TokenKind::SLASH, TokenKind::PERCENT }; + vector Token::tokensLiteral = { TokenKind::BOOL, TokenKind::INTEGER_DEC, diff --git a/src/Lexer/Token.h b/src/Lexer/Token.h index c6ee86a..4b1ab57 100644 --- a/src/Lexer/Token.h +++ b/src/Lexer/Token.h @@ -65,6 +65,7 @@ public: static vector tokensComparison; static vector tokensTerm; static vector tokensFactor; + static vector tokensUnary; static vector tokensBinary; static vector tokensLiteral; diff --git a/src/Logger.cpp b/src/Logger.cpp index a2c9543..6cfbd4f 100644 --- a/src/Logger.cpp +++ b/src/Logger.cpp @@ -20,6 +20,7 @@ #include "Parser/Expression/Expression.h" #include "Parser/Expression/ExpressionBinary.h" +#include "Parser/Expression/ExpressionUnary.h" #include "Parser/Expression/ExpressionIfElse.h" #include "Parser/Expression/ExpressionVariable.h" #include "Parser/Expression/ExpressionGrouping.h" @@ -344,7 +345,9 @@ string Logger::toString(shared_ptr statement) { string Logger::toString(shared_ptr expression) { switch (expression->getKind()) { case ExpressionKind::BINARY: - return toString(dynamic_pointer_cast(expression)); + return toString(dynamic_pointer_cast(expression)); + case ExpressionKind::UNARY: + return toString(dynamic_pointer_cast(expression)); case ExpressionKind::IF_ELSE: return toString(dynamic_pointer_cast(expression)); case ExpressionKind::VAR: @@ -391,6 +394,17 @@ string Logger::toString(shared_ptr expression) { } } +string Logger::toString(shared_ptr expression) { + switch (expression->getOperation()) { + case ExpressionUnaryOperation::PLUS: + return "+" + toString(expression->getExpression()); + case ExpressionUnaryOperation::MINUS: + return "-" + toString(expression->getExpression()); + case ExpressionUnaryOperation::INVALID: + return "{INVALID}"; + } +} + string Logger::toString(shared_ptr expression) { string text; diff --git a/src/Logger.h b/src/Logger.h index 3101911..72e6746 100644 --- a/src/Logger.h +++ b/src/Logger.h @@ -20,6 +20,7 @@ class StatementExpression; class Expression; class ExpressionBinary; +class ExpressionUnary; class ExpressionIfElse; class ExpressionVariable; class ExpressionGrouping; @@ -51,6 +52,7 @@ private: static string toString(shared_ptr expression); static string toString(shared_ptr expression); + static string toString(shared_ptr expression); static string toString(shared_ptr expression); static string toString(shared_ptr expression); static string toString(shared_ptr expression); diff --git a/src/Parser/Expression/ExpressionUnary.cpp b/src/Parser/Expression/ExpressionUnary.cpp index 420cdd9..ddc570d 100644 --- a/src/Parser/Expression/ExpressionUnary.cpp +++ b/src/Parser/Expression/ExpressionUnary.cpp @@ -7,12 +7,15 @@ Expression(ExpressionKind::UNARY, nullptr), expression(expression) { switch (token->getKind()) { case TokenKind::PLUS: operation = ExpressionUnaryOperation::PLUS; + valueType = expression->getValueType(); break; case TokenKind::MINUS: operation = ExpressionUnaryOperation::MINUS; + valueType = expression->getValueType(); break; default: operation = ExpressionUnaryOperation::INVALID; + valueType = nullptr; break; } } diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index 9906eeb..cd9b957 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -12,6 +12,7 @@ #include "Parser/Expression/ExpressionVariable.h" #include "Parser/Expression/ExpressionCall.h" #include "Parser/Expression/ExpressionIfElse.h" +#include "Parser/Expression/ExpressionUnary.h" #include "Parser/Expression/ExpressionBinary.h" #include "Parser/Expression/ExpressionBlock.h" @@ -723,7 +724,7 @@ shared_ptr Parser::matchTerm() { } shared_ptr Parser::matchFactor() { - shared_ptr expression = matchPrimary(); + shared_ptr expression = matchUnary(); if (expression == nullptr) return nullptr; @@ -733,6 +734,19 @@ shared_ptr Parser::matchFactor() { return expression; } +shared_ptr Parser::matchUnary() { + shared_ptr token = tokens.at(currentIndex); + + if (tryMatchingTokenKinds(Token::tokensUnary, false, true)) { + shared_ptr expression = matchPrimary(); + if (expression == nullptr) + return nullptr; + return make_shared(token, expression); + } + + return matchPrimary(); +} + shared_ptr Parser::matchPrimary() { shared_ptr expression; int errorsCount = errors.size(); diff --git a/src/Parser/Parser.h b/src/Parser/Parser.h index 8e5a8d5..0e27960 100644 --- a/src/Parser/Parser.h +++ b/src/Parser/Parser.h @@ -43,7 +43,8 @@ private: shared_ptr matchComparison(); // <, <=, >, >= shared_ptr matchTerm(); // +, - shared_ptr matchFactor(); // *, /, % - shared_ptr matchPrimary(); // integer, () + shared_ptr matchUnary(); // +, - + shared_ptr matchPrimary(); // literal, () shared_ptr matchExpressionGrouping(); shared_ptr matchExpressionLiteral(); From d3f45e72986795466441dc92443efc109ac496fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Fri, 1 Aug 2025 12:22:02 +0900 Subject: [PATCH 26/28] Fixed values handling --- samples/hello.brc | 8 ++++---- samples/test.brc | 6 ++++-- src/Parser/Expression/ExpressionLiteral.cpp | 9 +++++---- src/Parser/Parser.cpp | 4 ++-- src/Parser/ValueType.cpp | 1 + 5 files changed, 16 insertions(+), 12 deletions(-) diff --git a/samples/hello.brc b/samples/hello.brc index b8fa9d7..e93c560 100644 --- a/samples/hello.brc +++ b/samples/hello.brc @@ -1,9 +1,9 @@ -@extern putchar fun: character sint32 -> sint32 +@extern putchar fun: character u32 -> u32 -main fun -> sint32 - text data <- "Hello, world!\n" +main fun -> u32 + text data <- "Hello, world!\n" - rep i sint32 <- 0, text[i] != 0: + rep i u32 <- 0, text[i] != 0: putchar(text[i]) i <- i + 1 ; diff --git a/samples/test.brc b/samples/test.brc index 02f3f71..baa3e8f 100644 --- a/samples/test.brc +++ b/samples/test.brc @@ -49,11 +49,13 @@ i u32 <- 0, rep text[i] != 0: ;*/ main fun -> u32 - /*num1 u8 <- 42 + num1 u8 <- 42 num2 s8 <- 3 - +15 num3 u32 <- 1234123 - num4 s32 <- -345345*/ + num4 s32 <- -345345 num5 r32 <- -42.58 + num5 + num3 + ret 0 ; \ No newline at end of file diff --git a/src/Parser/Expression/ExpressionLiteral.cpp b/src/Parser/Expression/ExpressionLiteral.cpp index 76238a3..4675d40 100644 --- a/src/Parser/Expression/ExpressionLiteral.cpp +++ b/src/Parser/Expression/ExpressionLiteral.cpp @@ -44,10 +44,11 @@ shared_ptr ExpressionLiteral::expressionLiteralForToken(share expression->u32Value = *charValue; return expression; } - case TokenKind::REAL: + case TokenKind::REAL: { expression->r32Value = stof(token->getLexme()); expression->valueType = ValueType::valueTypeForToken(token, nullptr, 0); break; + } default: return nullptr; } @@ -63,15 +64,15 @@ bool ExpressionLiteral::getBoolValue() { } uint8_t ExpressionLiteral::getU8Value() { - return s32Value; + return u8Value; } uint32_t ExpressionLiteral::getU32Value() { - return s32Value; + return u32Value; } int8_t ExpressionLiteral::getS8Value() { - return s32Value; + return s8Value; } int32_t ExpressionLiteral::getS32Value() { diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index cd9b957..bdf291f 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -756,8 +756,8 @@ shared_ptr Parser::matchPrimary() { return expression; expression = matchExpressionArrayLiteral(); - if (expression != nullptr || errors.size() > errorsCount) - return expression; + if (expression != nullptr || errors.size() > errorsCount) + return expression; expression = matchExpressionLiteral(); if (expression != nullptr || errors.size() > errorsCount) diff --git a/src/Parser/ValueType.cpp b/src/Parser/ValueType.cpp index 0230362..566342b 100644 --- a/src/Parser/ValueType.cpp +++ b/src/Parser/ValueType.cpp @@ -37,6 +37,7 @@ shared_ptr ValueType::valueTypeForToken(shared_ptr token, shar case TokenKind::BOOL: return make_shared(ValueTypeKind::BOOL, nullptr, 0); case TokenKind::INTEGER_DEC: + return make_shared(ValueTypeKind::S32, nullptr, 0); case TokenKind::INTEGER_HEX: case TokenKind::INTEGER_BIN: case TokenKind::INTEGER_CHAR: From 9a04c0c49a9e8f722c86b72796fdcc52c1b0775a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Fri, 1 Aug 2025 12:36:42 +0900 Subject: [PATCH 27/28] Fixed crashes --- src/Compiler/ModuleBuilder.cpp | 21 +++++++++++++++++---- src/Logger.cpp | 3 +++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/Compiler/ModuleBuilder.cpp b/src/Compiler/ModuleBuilder.cpp index 5a8c3c7..4fdd0d8 100644 --- a/src/Compiler/ModuleBuilder.cpp +++ b/src/Compiler/ModuleBuilder.cpp @@ -97,9 +97,15 @@ void ModuleBuilder::buildStatement(shared_ptr statement) { void ModuleBuilder::buildFunction(shared_ptr statement) { // function types llvm::Type *returnType = typeForValueType(statement->getReturnValueType()); + if (returnType == nullptr) + return; vector argTypes; - for (pair> &arg : statement->getArguments()) - argTypes.push_back(typeForValueType(arg.second)); + for (pair> &arg : statement->getArguments()) { + llvm::Type *argType = typeForValueType(arg.second); + if (argType == nullptr) + return; + argTypes.push_back(argType); + } // build function declaration llvm::FunctionType *funType = llvm::FunctionType::get(returnType, argTypes, false); @@ -274,7 +280,10 @@ void ModuleBuilder::buildMetaExternFunction(shared_ptrgetReturnValueType()), types, false); + llvm::Type *returnType = typeForValueType(statement->getReturnValueType()); + if (returnType == nullptr) + return; + llvm::FunctionType *funType = llvm::FunctionType::get(returnType, types, false); llvm::Function *fun = llvm::Function::Create(funType, llvm::GlobalValue::ExternalLinkage, statement->getName(), module.get()); if (!setFun(statement->getName(), fun)) return; @@ -663,6 +672,11 @@ llvm::InlineAsm *ModuleBuilder::getRawFun(string name) { } llvm::Type *ModuleBuilder::typeForValueType(shared_ptr valueType, int count) { + if (valueType == nullptr) { + markError(0, 0, "Missing type"); + return nullptr; + } + switch (valueType->getKind()) { case ValueTypeKind::NONE: return typeVoid; @@ -684,7 +698,6 @@ llvm::Type *ModuleBuilder::typeForValueType(shared_ptr valueType, int if (valueType->getValueArg() > 0) count = valueType->getValueArg(); return llvm::ArrayType::get(typeForValueType(valueType->getSubType(), count), count); - return nullptr; } } } diff --git a/src/Logger.cpp b/src/Logger.cpp index 6cfbd4f..d5ca83d 100644 --- a/src/Logger.cpp +++ b/src/Logger.cpp @@ -203,6 +203,9 @@ string Logger::toString(TokenKind tokenKind) { } string Logger::toString(shared_ptr valueType) { + if (valueType == nullptr) + return "{INVALID}"; + switch (valueType->getKind()) { case ValueTypeKind::NONE: return "NONE"; From 3726e888653e0ebf12df52f36fb03ddd5e925fce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Fri, 1 Aug 2025 12:39:09 +0900 Subject: [PATCH 28/28] Fixed fib sample --- samples/fib.brc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/samples/fib.brc b/samples/fib.brc index 11fd516..9835c85 100644 --- a/samples/fib.brc +++ b/samples/fib.brc @@ -1,6 +1,6 @@ -@extern putchar fun: character sint32 -> sint32 +@extern putchar fun: character u32 -> u32 -fib fun: number sint32 -> sint32 +fib fun: number u32 -> u32 ret if number < 2: number else @@ -8,13 +8,13 @@ fib fun: number sint32 -> sint32 ; ; -printNum fun: number sint32 - biggest sint32 <- 10 +printNum fun: number u32 + biggest u32 <- 10 rep biggest <= number: biggest <- biggest * 10 biggest <- biggest / 10 rep biggest > 0: - digit sint32 <- number / biggest + digit u32 <- number / biggest putchar(digit + '0') number <- number % biggest biggest <- biggest / 10 @@ -22,9 +22,9 @@ printNum fun: number sint32 ; // Print first 20 fibonaci numbers -main fun -> sint32 - rep i sint32 <- 0, i < 20: - res sint32 <- fib(i) +main fun -> u32 + rep i u32 <- 0, i < 20: + res u32 <- fib(i) printNum(res) putchar('\n') i <- i + 1