Skip to content

Commit

Permalink
feat: Added varargs, currently only for extern functions, added print…
Browse files Browse the repository at this point in the history
… for all types
  • Loading branch information
alinalihassan committed May 25, 2022
1 parent fc7390a commit 510f78a
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 16 deletions.
14 changes: 11 additions & 3 deletions src/liblesma/AST/AST.h
Original file line number Diff line number Diff line change
Expand Up @@ -259,18 +259,20 @@ namespace lesma {
Type *return_type;
std::vector<std::pair<std::string, Type *>> parameters;
Compound *body;
bool varargs;

public:
FuncDecl(llvm::SMRange Loc, std::string name, Type *return_type,
std::vector<std::pair<std::string, Type *>> parameters, Compound *body) : Statement(Loc), name(std::move(name)), return_type(return_type), parameters(std::move(parameters)),
body(body) {}
std::vector<std::pair<std::string, Type *>> parameters, Compound *body, bool varargs) : Statement(Loc), name(std::move(name)), return_type(return_type), parameters(std::move(parameters)),
body(body), varargs(varargs) {}

~FuncDecl() override = default;

[[nodiscard]] [[maybe_unused]] std::string getName() const { return name; }
[[nodiscard]] [[maybe_unused]] Type *getReturnType() const { return return_type; }
[[nodiscard]] [[maybe_unused]] std::vector<std::pair<std::string, Type *>> getParameters() const { return parameters; }
[[nodiscard]] [[maybe_unused]] Compound *getBody() const { return body; }
[[nodiscard]] [[maybe_unused]] bool getVarArgs() const { return varargs; }

std::string toString(llvm::SourceMgr *srcMgr, int ind) override {
auto ret = fmt::format("{}FuncDecl[Line({}-{}):Col({}-{})]: {}(",
Expand All @@ -284,6 +286,8 @@ namespace lesma {
ret += param.first + ": " + param.second->toString(srcMgr, ind);
if (parameters.back() != param) ret += ", ";
}
if (varargs)
ret += ", ...";
ret += fmt::format(") -> {}\n{}", return_type->toString(srcMgr, ind), body->toString(srcMgr, ind + 2));
return ret;
}
Expand All @@ -293,16 +297,18 @@ namespace lesma {
std::string name;
Type *return_type;
std::vector<std::pair<std::string, Type *>> parameters;
bool varargs;

public:
ExternFuncDecl(llvm::SMRange Loc, std::string name, Type *return_type,
std::vector<std::pair<std::string, Type *>> parameters) : Statement(Loc), name(std::move(name)), return_type(return_type), parameters(std::move(parameters)) {}
std::vector<std::pair<std::string, Type *>> parameters, bool varargs) : Statement(Loc), name(std::move(name)), return_type(return_type), parameters(std::move(parameters)), varargs(varargs) {}

~ExternFuncDecl() override = default;

[[nodiscard]] [[maybe_unused]] std::string getName() const { return name; }
[[nodiscard]] [[maybe_unused]] Type *getReturnType() const { return return_type; }
[[nodiscard]] [[maybe_unused]] std::vector<std::pair<std::string, Type *>> getParameters() const { return parameters; }
[[nodiscard]] [[maybe_unused]] bool getVarArgs() const { return varargs; }

std::string toString(llvm::SourceMgr *srcMgr, int ind) override {
auto ret = fmt::format("{}FuncDecl[Line({}-{}):Col({}-{})]: {}(",
Expand All @@ -316,6 +322,8 @@ namespace lesma {
ret += param.first + ": " + param.second->toString(srcMgr, ind);
if (parameters.back() != param) ret += ", ";
}
if (varargs)
ret += ", ...";
ret += fmt::format(") -> {}\n", return_type->toString(srcMgr, ind));
return ret;
}
Expand Down
5 changes: 2 additions & 3 deletions src/liblesma/Backend/Codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -455,8 +455,7 @@ void Codegen::visit(FuncDecl *node) {
auto linkage = Function::ExternalLinkage;
auto ret_type = visit(node->getReturnType());


FunctionType *FT = FunctionType::get(ret_type, paramTypes, false);
FunctionType *FT = FunctionType::get(ret_type, paramTypes, node->getVarArgs());
Function *F = Function::Create(FT, linkage, name, *TheModule);

deferStack.push({});
Expand Down Expand Up @@ -524,7 +523,7 @@ void Codegen::visit(ExternFuncDecl *node) {
if (TheModule->getFunction(node->getName()) != nullptr && Scope->lookup(node->getName()) != nullptr)
return;

FunctionType *FT = FunctionType::get(visit(node->getReturnType()), paramTypes, false);
FunctionType *FT = FunctionType::get(visit(node->getReturnType()), paramTypes, node->getVarArgs());
auto F = TheModule->getOrInsertFunction(node->getName(), FT);

auto symbol = new SymbolTableEntry(node->getName(), new SymbolType(SymbolSuperType::TY_FUNCTION));
Expand Down
22 changes: 15 additions & 7 deletions src/liblesma/Frontend/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -462,15 +462,23 @@ Statement *Parser::ParseFunctionDeclaration() {
Consume(TokenType::LEFT_PAREN);
std::vector<std::pair<std::string, Type *>> parameters;

bool varargs = false;
while (!Check(TokenType::RIGHT_PAREN)) {
auto param_ident = Consume(TokenType::IDENTIFIER);
Consume(TokenType::COLON);
auto type = ParseType();
if (varargs)
Error(Peek(), "Varargs should be the last parameter");

if (Check(TokenType::ELLIPSIS)) {
Consume(TokenType::ELLIPSIS);
varargs = true;
} else {
auto param_ident = Consume(TokenType::IDENTIFIER);
Consume(TokenType::COLON);
auto type = ParseType();
parameters.emplace_back(param_ident->lexeme, type);
}

if (!Check(TokenType::RIGHT_PAREN) && !Check(TokenType::RIGHT_PAREN, 1))
Consume(TokenType::COMMA);

parameters.emplace_back(param_ident->lexeme, type);
}

Consume(TokenType::RIGHT_PAREN);
Expand All @@ -483,12 +491,12 @@ Statement *Parser::ParseFunctionDeclaration() {

if (extern_func) {
ConsumeNewline();
return new ExternFuncDecl({loc.Start, return_type->getEnd()}, identifier->lexeme, return_type, parameters);
return new ExternFuncDecl({loc.Start, return_type->getEnd()}, identifier->lexeme, return_type, parameters, varargs);
}

auto body = ParseBlock();

return new FuncDecl({loc.Start, return_type->getEnd()}, identifier->lexeme, return_type, parameters, body);
return new FuncDecl({loc.Start, return_type->getEnd()}, identifier->lexeme, return_type, parameters, body, varargs);
}

Statement *Parser::ParseImport() {
Expand Down
17 changes: 14 additions & 3 deletions src/std/base.les
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
def extern printf(x: str)
def extern printf(fmt: str, ...)

def print(x: str)
printf(x)
printf("\n")
printf("%s\n", x)

def print(x: int)
printf("%d\n", x)

def print(x: float)
printf("%g\n", x)

def print(x: bool)
if x
print("true")
else
print("false")

0 comments on commit 510f78a

Please sign in to comment.