Build raw function
This commit is contained in:
@@ -25,8 +25,10 @@ i u32 <- 0, rep text[i] != 0:
|
|||||||
;*/
|
;*/
|
||||||
|
|
||||||
rawAdd raw
|
rawAdd raw
|
||||||
mov eax, 5
|
//push rbx
|
||||||
mov ebx, 42
|
mov ebx, 5
|
||||||
|
//pop rbx
|
||||||
|
mov eax, 42
|
||||||
add eax, ebx
|
add eax, ebx
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|||||||
@@ -131,8 +131,11 @@ void ModuleBuilder::buildFunctionDeclaration(shared_ptr<StatementFunction> state
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ModuleBuilder::buildRawFunction(shared_ptr<StatementRawFunction> statement) {
|
void ModuleBuilder::buildRawFunction(shared_ptr<StatementRawFunction> statement) {
|
||||||
llvm::FunctionType *funType = llvm::FunctionType::get(llvm::Type::getVoidTy(*context), nullptr, false);
|
// get argument types
|
||||||
llvm::InlineAsm *rawFun = llvm::InlineAsm::get(funType, statement->getRawSource(), "", false, false, llvm::InlineAsm::AsmDialect::AD_Intel);
|
vector<llvm::Type *> 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))
|
if (!setRawFun(statement->getName(), rawFun))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -508,15 +511,24 @@ llvm::Value *ModuleBuilder::valueForVar(shared_ptr<ExpressionVariable> expressio
|
|||||||
|
|
||||||
llvm::Value *ModuleBuilder::valueForCall(shared_ptr<ExpressionCall> expression) {
|
llvm::Value *ModuleBuilder::valueForCall(shared_ptr<ExpressionCall> expression) {
|
||||||
llvm::Function *fun = getFun(expression->getName());
|
llvm::Function *fun = getFun(expression->getName());
|
||||||
if (fun == nullptr)
|
if (fun != nullptr) {
|
||||||
return nullptr;
|
llvm::FunctionType *funType = fun->getFunctionType();
|
||||||
llvm::FunctionType *funType = fun->getFunctionType();
|
vector<llvm::Value*> argValues;
|
||||||
vector<llvm::Value*> argValues;
|
for (shared_ptr<Expression> &argumentExpression : expression->getArgumentExpressions()) {
|
||||||
for (shared_ptr<Expression> &argumentExpression : expression->getArgumentExpressions()) {
|
llvm::Value *argValue = valueForExpression(argumentExpression);
|
||||||
llvm::Value *argValue = valueForExpression(argumentExpression);
|
argValues.push_back(argValue);
|
||||||
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) {
|
||||||
|
vector<llvm::Value *>argValues;
|
||||||
|
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) {
|
bool ModuleBuilder::setAlloca(string name, llvm::AllocaInst *alloca) {
|
||||||
@@ -563,11 +575,10 @@ llvm::Function* ModuleBuilder::getFun(string name) {
|
|||||||
scopes.pop();
|
scopes.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
markError(0, 0, format("Function \"{}\" not defined in scope", name));
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ModuleBuilder::setRawFun(string name, llvm::Value *rawFun) {
|
bool ModuleBuilder::setRawFun(string name, llvm::InlineAsm *rawFun) {
|
||||||
if (scopes.top().rawFunMap[name] != nullptr) {
|
if (scopes.top().rawFunMap[name] != nullptr) {
|
||||||
markError(0, 0, format("Raw function \"{}\" already defined in scope", name));
|
markError(0, 0, format("Raw function \"{}\" already defined in scope", name));
|
||||||
return false;
|
return false;
|
||||||
@@ -577,17 +588,16 @@ bool ModuleBuilder::setRawFun(string name, llvm::Value *rawFun) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Value *ModuleBuilder::getRawFun(string name) {
|
llvm::InlineAsm *ModuleBuilder::getRawFun(string name) {
|
||||||
stack<Scope> scopes = this->scopes;
|
stack<Scope> scopes = this->scopes;
|
||||||
|
|
||||||
while (!scopes.empty()) {
|
while (!scopes.empty()) {
|
||||||
llvm::Value *rawFun = scopes.top().rawFunMap[name];
|
llvm::InlineAsm *rawFun = scopes.top().rawFunMap[name];
|
||||||
if (rawFun != nullptr)
|
if (rawFun != nullptr)
|
||||||
return rawFun;
|
return rawFun;
|
||||||
scopes.pop();
|
scopes.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
markError(0, 0, format("Raw function \"{}\" not defined in scope", name));
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ using namespace std;
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
map<string, llvm::AllocaInst*> allocaMap;
|
map<string, llvm::AllocaInst*> allocaMap;
|
||||||
map<string, llvm::Function*> funMap;
|
map<string, llvm::Function*> funMap;
|
||||||
map<string, llvm::Value*> rawFunMap;
|
map<string, llvm::InlineAsm*> rawFunMap;
|
||||||
} Scope;
|
} Scope;
|
||||||
|
|
||||||
class ModuleBuilder {
|
class ModuleBuilder {
|
||||||
@@ -92,8 +92,8 @@ private:
|
|||||||
bool setFun(string name, llvm::Function *fun);
|
bool setFun(string name, llvm::Function *fun);
|
||||||
llvm::Function *getFun(string name);
|
llvm::Function *getFun(string name);
|
||||||
|
|
||||||
bool setRawFun(string name, llvm::Value *rawFun);
|
bool setRawFun(string name, llvm::InlineAsm *rawFun);
|
||||||
llvm::Value *getRawFun(string name);
|
llvm::InlineAsm *getRawFun(string name);
|
||||||
|
|
||||||
llvm::Type *typeForValueType(shared_ptr<ValueType> valueType, int count = 0);
|
llvm::Type *typeForValueType(shared_ptr<ValueType> valueType, int count = 0);
|
||||||
|
|
||||||
|
|||||||
@@ -257,6 +257,9 @@ shared_ptr<Statement> Parser::matchStatementRawFunction() {
|
|||||||
if (!rawSource.empty())
|
if (!rawSource.empty())
|
||||||
rawSource += "\n";
|
rawSource += "\n";
|
||||||
rawSource += tokens.at(currentIndex++)->getLexme();
|
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)) {
|
if(!tryMatchingTokenKinds({TokenKind::SEMICOLON}, false, true)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user