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)) {