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