From 06159933d56fe4855fa06e05e2e67c2d000acbf1 Mon Sep 17 00:00:00 2001 From: Yujia Qiao Date: Wed, 3 Nov 2021 16:25:04 +0800 Subject: [PATCH] support func prototype ( can use cstdlib now!) --- parser.cc | 6 +++++- parser.h | 2 +- visitor.cc | 14 +++++++++++--- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/parser.cc b/parser.cc index a260a17..eb2b44e 100644 --- a/parser.cc +++ b/parser.cc @@ -322,7 +322,11 @@ FunDecl* Parser::funDecl(Type retType, Token id) { consume(RIGHT_PAREN, "Expect `)` as argument list ends"); - BlockStmt* b = blockStmt(); + BlockStmt* b = nullptr; + if (match(1, LEFT_BRACE)) + b = blockStmt(); + else + consume(SEMICOLON, "Expect `,` after function prototype"); return new FunDecl(id.lexeme, a, b, retType); } diff --git a/parser.h b/parser.h index 6dec2f1..8ec6bda 100644 --- a/parser.h +++ b/parser.h @@ -33,7 +33,7 @@ class Parser { VarDecl* varDecl(Type type, Token id); // TYPE ('['SIZE']')? IDENTIFIER // (EQUAL EXPRESSION)? ; FunDecl* funDecl(Type type, - Token id); // TYPE IDENTIFIER '(' ARGS? ')' BLOCK + Token id); // TYPE IDENTIFIER '(' ARGS? ')' BLOCK? Args args(); // TYPE ID (, TYPE ID)* RealArgs real_args(); // EXPR (, EXPR)* diff --git a/visitor.cc b/visitor.cc index e75a34b..e802e7e 100644 --- a/visitor.cc +++ b/visitor.cc @@ -268,7 +268,7 @@ void CodeGenVisitor::visit(VarDecl* st) { void CodeGenVisitor::visit(FunDecl* st) { if (scope.isWrapped()) abortMsg("nested function is forbidden"); llvm::Function* F = l.mod->getFunction(st->identifier); - if (F) abortMsg("redefine func"); + if (F && !F->empty()) abortMsg("redefine func"); std::vector args; for (auto [type, token] : st->args) { @@ -281,6 +281,15 @@ void CodeGenVisitor::visit(FunDecl* st) { F = llvm::Function::Create(FT, llvm::Function::ExternalLinkage, st->identifier, l.mod.get()); + if (st->body == nullptr) { // a prototype + size_t i = 0; + for (auto& a : F->args()) { + FormalArg formal = st->args[i++]; + std::string name = formal.token.lexeme; + a.setName(name); + } + return; + } // Create a new basic block to start insertion into. llvm::BasicBlock* BB = llvm::BasicBlock::Create(*l.ctx, st->identifier, F); @@ -302,8 +311,7 @@ void CodeGenVisitor::visit(FunDecl* st) { } v.visit(st->body); - if (llvm::verifyFunction(*F, &llvm::errs())) - ; // abortMsg("verify error"); + if (llvm::verifyFunction(*F, &llvm::errs())) abortMsg("verify error"); // F->eraseFromParent(); } void CodeGenVisitor::visit(BlockStmt* st) {