From c7d8f8fe3ca45fbbaa224cf42ad5c3f79f2bee6f Mon Sep 17 00:00:00 2001 From: Peter Matta <mattapet@fit.cvut.cz> Date: Mon, 7 May 2018 09:30:45 +0200 Subject: [PATCH] Adding standart func decls --- include/dusk/AST/Decl.h | 1 + include/dusk/CMakeLists.txt | 1 + include/dusk/Runtime/CMakeLists.txt | 6 ++ include/dusk/Runtime/RuntimeFuncWrapper.h | 27 +++++++++ include/dusk/Runtime/RuntimeFuncs.h | 68 +++++++++++++++++++++++ lib/AST/Decl.cpp | 3 + lib/Frontend/CompilerInstance.cpp | 7 +-- lib/IRGen/GenExpr.cpp | 3 +- lib/IRGen/IRGenModule.cpp | 17 +++++- lib/Parser/ParseExpr.cpp | 7 ++- lib/Parser/ParseStmt.cpp | 1 + lib/Parser/Parser.cpp | 6 -- lib/Sema/Sema.cpp | 18 +++--- lib/Sema/TypeCheckPattern.cpp | 2 + 14 files changed, 141 insertions(+), 26 deletions(-) create mode 100644 include/dusk/Runtime/CMakeLists.txt create mode 100644 include/dusk/Runtime/RuntimeFuncWrapper.h create mode 100644 include/dusk/Runtime/RuntimeFuncs.h diff --git a/include/dusk/AST/Decl.h b/include/dusk/AST/Decl.h index f4541af..8fb3506 100644 --- a/include/dusk/AST/Decl.h +++ b/include/dusk/AST/Decl.h @@ -168,6 +168,7 @@ public: ModuleDecl(StringRef N, std::vector<ASTNode *> &&C); ArrayRef<ASTNode *> getContents() const { return Contents; } + std::vector<ASTNode *> &getContents() { return Contents; } virtual SMRange getSourceRange() const override; }; diff --git a/include/dusk/CMakeLists.txt b/include/dusk/CMakeLists.txt index 9b4b9d6..f731b2d 100644 --- a/include/dusk/CMakeLists.txt +++ b/include/dusk/CMakeLists.txt @@ -3,6 +3,7 @@ add_subdirectory(Basic) add_subdirectory(Frontend) add_subdirectory(IRGen) add_subdirectory(Parse) +add_subdirectory(Runtime) add_subdirectory(Sema) set(HEADERS diff --git a/include/dusk/Runtime/CMakeLists.txt b/include/dusk/Runtime/CMakeLists.txt new file mode 100644 index 0000000..4060374 --- /dev/null +++ b/include/dusk/Runtime/CMakeLists.txt @@ -0,0 +1,6 @@ +SET(HEADERS + ${CMAKE_CURRENT_SOURCE_DIR}/RuntimeFuncs.h + ${CMAKE_CURRENT_SOURCE_DIR}/RuntimeFuncWrapper.h + ${HEADERS} + PARENT_SCOPE +) diff --git a/include/dusk/Runtime/RuntimeFuncWrapper.h b/include/dusk/Runtime/RuntimeFuncWrapper.h new file mode 100644 index 0000000..ac13337 --- /dev/null +++ b/include/dusk/Runtime/RuntimeFuncWrapper.h @@ -0,0 +1,27 @@ +//===--- RuntimeFuncWrapper.h - Runtime function generation -----*- C++ -*-===// +// +// dusk-lang +// This source file is part of a dusk-lang project, which is a semestral +// assignement for BI-PJP course at Czech Technical University in Prague. +// The software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND. +// +//===----------------------------------------------------------------------===// + +#ifndef DUSK_RUNTIME_FUNC_WRAPPER_H +#define DUSK_RUNTIME_FUNC_WRAPPER_H + +#include "dusk/Basic/LLVM.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/Type.h" +#include "llvm/IR/Value.h" + +namespace dusk { + llvm::Value *getRuntimeFunc(llvm::Module *M, + StringRef N, + ArrayRef<llvm::Type *> ArgsT, + llvm::Type *RetT); +} + +#endif /* DUSK_RUNTIME_FUNC_WRAPPER_H */ diff --git a/include/dusk/Runtime/RuntimeFuncs.h b/include/dusk/Runtime/RuntimeFuncs.h new file mode 100644 index 0000000..4285c9e --- /dev/null +++ b/include/dusk/Runtime/RuntimeFuncs.h @@ -0,0 +1,68 @@ +//===--- RuntimeFuncs.h - Runtime function declarations ---------*- C++ -*-===// +// +// dusk-lang +// This source file is part of a dusk-lang project, which is a semestral +// assignement for BI-PJP course at Czech Technical University in Prague. +// The software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND. +// +//===----------------------------------------------------------------------===// + +#ifndef DUSK_RUNTIME_FUNCS_H +#define DUSK_RUNTIME_FUNCS_H + +#include "dusk/Basic/LLVM.h" +#include "dusk/AST/Decl.h" +#include "dusk/AST/Expr.h" +#include "dusk/AST/Stmt.h" +#include "dusk/AST/Pattern.h" +#include "dusk/AST/Type.h" +#include "dusk/AST/NameLookup.h" +#include "dusk/AST/ASTContext.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/SourceMgr.h" +#include <memory> +#include <vector> + +namespace dusk { + +static ASTNode *getPrintln(ASTContext &Context) { + auto TyRepr = std::make_unique<FuncRetTypeRepr>(SMLoc{}, "Int"); + auto P = std::make_unique<ParamDecl>("val", SMLoc{}, + Context.pushTypeRepr(std::move(TyRepr))); + llvm::SmallVector<Decl *, 128> Prms; + Prms.push_back(Context.pushNode(std::move(P))); + auto Pttrn = std::make_unique<VarPattern>(std::move(Prms), SMLoc{}, SMLoc{}); + auto Fn = std::make_unique<FuncDecl>("println", SMLoc{}, SMLoc{}, + Context.pushPattern(std::move(Pttrn))); + auto Extrn = + std::make_unique<ExternStmt>(SMLoc{}, Context.pushNode(std::move(Fn))); + auto C = Context.getRootModule()->getContents(); + return Context.pushNode(std::move(Extrn)); +} + +static ASTNode *getReadln(ASTContext &Context) { + NameLookup NL; + llvm::SmallVector<Decl *, 128> Prms; + auto Pttrn = std::make_unique<VarPattern>(std::move(Prms), SMLoc{}, SMLoc{}); + auto TyRepr = std::make_unique<FuncRetTypeRepr>(SMLoc{}, "Int"); + auto Fn = std::make_unique<FuncDecl>("readln", SMLoc{}, SMLoc{}, + Context.pushPattern(std::move(Pttrn)), + Context.pushTypeRepr(std::move(TyRepr))); + auto Extrn = + std::make_unique<ExternStmt>(SMLoc{}, Context.pushNode(std::move(Fn))); + auto C = Context.getRootModule()->getContents(); + return Context.pushNode(std::move(Extrn)); +} + +static void getFuncs(ASTContext &Context) { + std::vector<ASTNode *> NF; + NF.push_back(getPrintln(Context)); + NF.push_back(getReadln(Context)); + auto &C = Context.getRootModule()->getContents(); + NF.insert(NF.end(), C.begin(), C.end()); + C = NF; +} + +} // namespace dusk + +#endif /* DUSK_RUNTIME_FUNCS_H */ diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index e62c4a5..f948dde 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -88,6 +88,9 @@ ParamDecl::ParamDecl(StringRef N, SMLoc NL, TypeRepr *TR) // MARK: - FuncDecl class +FuncDecl::FuncDecl(StringRef N, SMLoc NL, SMLoc FuncL, VarPattern *A) +: Decl(DeclKind::Func, N, NL), FuncLoc(FuncL), Params(A) {} + FuncDecl::FuncDecl(StringRef N, SMLoc NL, SMLoc FuncL, VarPattern *A, TypeRepr *TR) : Decl(DeclKind::Func, N, NL, TR), FuncLoc(FuncL), Params(A) {} diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp index 5b5fecb..5644193 100644 --- a/lib/Frontend/CompilerInstance.cpp +++ b/lib/Frontend/CompilerInstance.cpp @@ -11,6 +11,7 @@ #include "dusk/AST/Diagnostics.h" #include "dusk/Parse/Parser.h" +#include "dusk/Runtime/RuntimeFuncs.h" #include "dusk/Sema/Sema.h" #include "dusk/IRGen/IRGenerator.h" #include "llvm/IR/Module.h" @@ -58,6 +59,7 @@ void CompilerInstance::performSema() { performParseOnly(); if (Context->isError()) return; + getFuncs(*Context); sema::Sema S(*Context, Diag); S.perform(); } @@ -104,7 +106,7 @@ void CompilerInstance::emitObjectFile(llvm::Module *M) { auto RM = Optional<llvm::Reloc::Model>(); auto TargetMachine = Target->createTargetMachine(Invocation.getTargetTriple(), CPU, Features, Opt, RM); - + M->setDataLayout(TargetMachine->createDataLayout()); M->setTargetTriple(Invocation.getTargetTriple()); @@ -131,6 +133,3 @@ void CompilerInstance::emitObjectFile(llvm::Module *M) { dest.flush(); } - - - diff --git a/lib/IRGen/GenExpr.cpp b/lib/IRGen/GenExpr.cpp index 19ede3a..67f41ed 100644 --- a/lib/IRGen/GenExpr.cpp +++ b/lib/IRGen/GenExpr.cpp @@ -110,7 +110,8 @@ llvm::Value *irgen::codegenExpr(IRGenModule &IRGM, AssignExpr *E) { if (!VarAddr || !Val) llvm_unreachable("Invalid val or addr"); - return IRGM.Builder.CreateStore(Val, VarAddr, "assign"); + IRGM.Builder.CreateStore(Val, VarAddr, "assign"); + return Val; } llvm::Value *irgen::codegenExpr(IRGenModule &IRGM, CallExpr *E) { diff --git a/lib/IRGen/IRGenModule.cpp b/lib/IRGen/IRGenModule.cpp index 32d10d1..1ec5a16 100644 --- a/lib/IRGen/IRGenModule.cpp +++ b/lib/IRGen/IRGenModule.cpp @@ -12,6 +12,8 @@ #include "dusk/AST/Decl.h" #include "dusk/AST/Type.h" #include "dusk/AST/ASTContext.h" +#include "dusk/Runtime/RuntimeFuncWrapper.h" +#include "dusk/Runtime/RuntimeFuncs.h" #include "llvm/ADT/APSInt.h" #include "llvm/IR/Type.h" #include "llvm/IR/Module.h" @@ -36,11 +38,11 @@ Address IRGenModule::declareVal(Decl *D) { auto Ty = llvm::Type::getInt64Ty(LLVMContext); - auto gvar = new llvm::GlobalVariable(*Module, Ty, false, + auto GV = new llvm::GlobalVariable(*Module, Ty, false, llvm::GlobalValue::InternalLinkage, nullptr, D->getName()); - gvar->setInitializer(llvm::ConstantInt::get(Ty, 0)); - return gvar; + GV->setInitializer(llvm::ConstantInt::get(Ty, 0)); + return GV; } else { if (!Lookup.declareVar(D)) llvm_unreachable("Redefinition of a variable"); @@ -86,3 +88,12 @@ Address IRGenModule::getVal(StringRef N) { llvm::Function *IRGenModule::getFunc(StringRef N) { return Module->getFunction(N); } + +llvm::Value *dusk::getRuntimeFunc(llvm::Module *M, StringRef N, + ArrayRef<llvm::Type *> ArgsT, + llvm::Type *RetT) { + auto Proto = llvm::FunctionType::get(RetT, ArgsT, false); + auto Fn = llvm::Function::Create(Proto, llvm::GlobalValue::ExternalLinkage); + return Fn; +} + diff --git a/lib/Parser/ParseExpr.cpp b/lib/Parser/ParseExpr.cpp index b8f9627..0316a92 100644 --- a/lib/Parser/ParseExpr.cpp +++ b/lib/Parser/ParseExpr.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "dusk/Parse/Parser.h" +#include <cctype> using namespace dusk; @@ -156,15 +157,15 @@ Expr *Parser::parseNumberLiteralExpr() { llvm::StringRef B = Str.slice(2, Str.size()); // Parse hexadecimal literal - if (Str[0] == '0' && Str[1] == 'x') + if (Str[0] == '0' && std::tolower(Str[1]) == 'x') B.getAsInteger(16, Value); // Parse octal litera - else if (Str[0] == '0' && Str[1] == 'o') + else if (Str[0] == '0' && std::tolower(Str[1]) == 'o') B.getAsInteger(8, Value); // Parse binary literal - else if (Str[0] == '0' && Str[1] == 'b') + else if (Str[0] == '0' && std::tolower(Str[1]) == 'b') B.getAsInteger(2, Value); else // Parse decimal literal diff --git a/lib/Parser/ParseStmt.cpp b/lib/Parser/ParseStmt.cpp index 1529d9d..a9af3a8 100644 --- a/lib/Parser/ParseStmt.cpp +++ b/lib/Parser/ParseStmt.cpp @@ -67,6 +67,7 @@ Stmt *Parser::parseReturnStmt() { case tok::number_literal: case tok::l_paren: case tok::minus: + case tok::lnot: E = parseExpr(); break; case tok::semicolon: diff --git a/lib/Parser/Parser.cpp b/lib/Parser/Parser.cpp index da8fb7d..70bd811 100644 --- a/lib/Parser/Parser.cpp +++ b/lib/Parser/Parser.cpp @@ -72,12 +72,6 @@ ASTNode *Parser::parseGlobal() { return parseExterStmt(); case tok::kwFunc: return parseFuncStmt(); - case tok::kwFor: - return parseForStmt(); - case tok::kwWhile: - return parseWhileStmt(); - case tok::kwIf: - return parseIfStmt(); case tok::identifier: case tok::number_literal: diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index 46b62e6..495ca1e 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -36,7 +36,7 @@ public: FwdDeclarator(Sema &S, NameLookup &C, DiagnosticEngine &D) : S(S), Ctx(C), Diag(D) {} - virtual bool preWalk(Decl *D) override { + bool preWalk(Decl *D) override { if (D->getKind() == DeclKind::Func) return true; if (D->getKind() == DeclKind::Module) @@ -44,29 +44,27 @@ public: return false; } - virtual bool postWalk(Decl *D) override { + bool postWalk(Decl *D) override { if (auto FD = dynamic_cast<FuncDecl *>(D)) { if (!Ctx.declareFunc(D)) { Diag.diagnose(D->getLocStart(), diag::redefinition_of_identifier); return false; } D->setType(S.typeReprResolve(FD)); - return true; } return true; } // Skip all expressions. - virtual bool preWalk(Expr *E) override { return false; } - virtual bool preWalk(Stmt *S) override { + bool preWalk(Expr *E) override { return false; } + + bool preWalk(Stmt *S) override { switch (S->getKind()) { case StmtKind::Func: case StmtKind::Extern: return true; - // Skip all non-func related statements. - default: - return false; + default: return false; } } }; @@ -76,6 +74,7 @@ public: Sema::Sema(ASTContext &C, DiagnosticEngine &D) : Ctx(C), Diag(D) {} void Sema::perform() { + declareFuncs(); typeCheck(); } @@ -112,6 +111,7 @@ Type *Sema::typeReprResolve(TypeRepr *TR) { } Type *Sema::typeReprResolve(FuncDecl *FD) { + // Aggregate args types llvm::SmallVector<Type *, 128> Args; for (auto Arg : FD->getArgs()->getVars()) Args.push_back(typeReprResolve(Arg->getTypeRepr())); @@ -119,6 +119,7 @@ Type *Sema::typeReprResolve(FuncDecl *FD) { auto ArgsT = std::make_unique<PatternType>(std::move(Args)); auto ArgsTT = Ctx.pushType(std::move(ArgsT)); + // Resolve return type Type *RetT = nullptr; if (!FD->hasTypeRepr()) { auto F = std::make_unique<VoidType>(); @@ -130,4 +131,3 @@ Type *Sema::typeReprResolve(FuncDecl *FD) { auto Ty = std::make_unique<FunctionType>(ArgsTT, RetT); return Ctx.pushType(std::move(Ty)); } - diff --git a/lib/Sema/TypeCheckPattern.cpp b/lib/Sema/TypeCheckPattern.cpp index d0a5a72..47889f7 100644 --- a/lib/Sema/TypeCheckPattern.cpp +++ b/lib/Sema/TypeCheckPattern.cpp @@ -34,6 +34,7 @@ bool TypeChecker::postWalkVarPattern(VarPattern *P) { return false; Ty.push_back(V->getType()); } + auto PTy = std::make_unique<PatternType>(std::move(Ty)); P->setType(Ctx.pushType(std::move(PTy))); return true; @@ -46,6 +47,7 @@ bool TypeChecker::postWalkExprPattern(ExprPattern *P) { return false; Ty.push_back(V->getType()); } + auto PTy = std::make_unique<PatternType>(std::move(Ty)); P->setType(Ctx.pushType(std::move(PTy))); return true; -- GitLab