Arguments for raw calls

This commit is contained in:
Rafał Grodziński
2025-07-15 13:10:03 +09:00
parent 9d991f46a2
commit fbc71f4a31
5 changed files with 66 additions and 10 deletions

View File

@@ -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
;

View File

@@ -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));
}

View File

@@ -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;
}

View File

@@ -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;

View File

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