Arguments for raw calls
This commit is contained in:
@@ -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
|
||||
;
|
||||
@@ -41,6 +41,12 @@ shared_ptr<llvm::Module> ModuleBuilder::getModule() {
|
||||
for (shared_ptr<Statement> &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> &error : errors)
|
||||
Logger::print(error);
|
||||
@@ -139,7 +145,7 @@ void ModuleBuilder::buildRawFunction(shared_ptr<StatementRawFunction> 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<ExpressionCall> expression)
|
||||
llvm::InlineAsm *rawFun = getRawFun(expression->getName());
|
||||
if (rawFun != nullptr) {
|
||||
vector<llvm::Value *>argValues;
|
||||
for (shared_ptr<Expression> &argumentExpression : expression->getArgumentExpressions()) {
|
||||
llvm::Value *argValue = valueForExpression(argumentExpression);
|
||||
argValues.push_back(argValue);
|
||||
}
|
||||
return builder->CreateCall(rawFun, llvm::ArrayRef(argValues));
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -274,7 +274,13 @@ string Logger::toString(shared_ptr<StatementFunction> statement) {
|
||||
string Logger::toString(shared_ptr<StatementRawFunction> 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;
|
||||
|
||||
@@ -263,8 +263,34 @@ shared_ptr<Statement> 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<Token> identifierToken = tokens.at(currentIndex++);
|
||||
shared_ptr<ValueType> argumentType = matchValueType();
|
||||
if (argumentType == nullptr) {
|
||||
markError(TokenKind::TYPE, {});
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
arguments.push_back(pair<string, shared_ptr<ValueType>>(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)) {
|
||||
|
||||
Reference in New Issue
Block a user