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