diff --git a/examples/globExpr.dusk b/examples/globExpr.dusk index 4ad8c8977ca00722cdf3b6abd73a313027717655..028c5abc6582ea1d52a318bc090374583a798e34 100644 --- a/examples/globExpr.dusk +++ b/examples/globExpr.dusk @@ -1,9 +1,9 @@ let a = 4; var arr: Int[a]; -// var a: Int; +var b: Int; func main() { - println(a = 14); + println(b = 14); println(10); } diff --git a/include/dusk/AST/ASTWalker.h b/include/dusk/AST/ASTWalker.h index 125089318a163c33042883f602ecc96c48d93562..e69af267f390f05a5166388593862d29a4385587 100644 --- a/include/dusk/AST/ASTWalker.h +++ b/include/dusk/AST/ASTWalker.h @@ -30,68 +30,6 @@ public: ASTWalker() = default; virtual ~ASTWalker() = default; - /// This method is called before a node is being walked. - /// - /// \param D A declaration node that will be walked. - /// - /// \return \c true if the node should be walked, \c false otherwise. - virtual bool preWalk(Decl *D) { return true; } - - /// This method is called before a node was walked. - /// - /// \param D A declaration node that was walked. - /// - /// \return \c true if the node should terminate traversal, - /// \c false otherwise. - virtual bool postWalk(Decl *D) { return true; } - - /// This method is called before a node is being walked. - /// - /// \param E An expression node that will be walked. - /// - /// \return \c true if the node should be walked, \c false otherwise. - virtual bool preWalk(Expr *E) { return true; } - - /// This method is called before a node was walked. - /// - /// \param E An expression node that was walked. - /// - /// \return \c true if the node should terminate traversal, - /// \c false otherwise. - virtual bool postWalk(Expr *E) { return true; } - - /// This method is called before a node is being walked. - /// - /// \param S A statement node that will be walked. - /// - /// \return \c true if the node should be walked, \c false otherwise. - virtual bool preWalk(Stmt *S) { return true; } - - /// This method is called before a node was walked. - /// - /// \param S A statement node that was walked. - /// - /// \return \c true if the node should terminate traversal, - /// \c false otherwise. - virtual bool postWalk(Stmt *S) { return true; } - - /// This method is called before a node is being walked. - /// - /// \param P A pattern node that will be walked. - /// - /// \return \c true if the node should be walked, \c false otherwise. - virtual bool preWalk(Pattern *P) { return true; } - - /// This method is called before a node was walked. - /// - /// \param P A pattern node that was walked. - /// - /// \return \c true if the node should terminate traversal, - /// \c false otherwise. - virtual bool postWalk(Pattern *P) { return true; } - - - /// This method is called before a declaration is being walked. /// /// \param D A declaration node that will be walked. diff --git a/include/dusk/Sema/CMakeLists.txt b/include/dusk/Sema/CMakeLists.txt index a0825e3a5c295dcf49a4a4947039739360ea5327..f79444778b836feb3bd5b3a34cabc30a94b63d4e 100644 --- a/include/dusk/Sema/CMakeLists.txt +++ b/include/dusk/Sema/CMakeLists.txt @@ -1,6 +1,5 @@ set(HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/Sema.h - ${CMAKE_CURRENT_SOURCE_DIR}/TypeResolver.h ${HEADERS} PARENT_SCOPE ) diff --git a/include/dusk/Sema/TypeResolver.h b/include/dusk/Sema/TypeResolver.h deleted file mode 100644 index 98dd5990049935eaaf5dd5a783d379777d1d8b2f..0000000000000000000000000000000000000000 --- a/include/dusk/Sema/TypeResolver.h +++ /dev/null @@ -1,72 +0,0 @@ -//===--- TypeResolver.h - Type resolution -----------------------*- 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_SEMA_TYPE_RESOLVER_H -#define DUSK_SEMA_TYPE_RESOLVER_H - -#include "dusk/AST/ASTWalker.h" - -namespace dusk { -class NumberLiteralExpr; -class ArrayLiteralExpr; -class IdentifierExpr; -class ParenExpr; -class AssignExpr; -class InfixExpr; -class PrefixExpr; -class CallExpr; -class SubscriptExpr; -class ASTcontext; -class NameLookup; -class DiagnosticEngine; - -namespace sema { - -class TypeResolver : public ASTWalker { - ASTContext &Context; - NameLookup &NL; - DiagnosticEngine &Diag; - -public: - TypeResolver(ASTContext &Ctx, NameLookup &NL, DiagnosticEngine &D); - - bool preWalkDecl(Decl *D) override; - bool postWalkDecl(Decl *D) override; - - std::pair<bool, Expr *> preWalkExpr(Expr *E) override; - Expr *postWalkExpr(Expr *E) override; - - bool preWalkTypeRepr(TypeRepr *TR) override; - bool postWalkTypeRepr(TypeRepr *TR) override; - -private: - bool resolveLetDecl(LetDecl *D); - bool resolveFuncDecl(FuncDecl *D); - bool resolveModuleDecl(ModuleDecl *D); - bool resolveParamDecl(ParamDecl *D); - bool resolveVarDecl(VarDecl *D); - - Expr *resolveNumberLiteralExpr(NumberLiteralExpr *E); - Expr *resolveArrayLiteralExpr(ArrayLiteralExpr *E); - Expr *resolveIdentifierExpr(IdentifierExpr *E); - Expr *resolveParenExpr(ParenExpr *E); - Expr *resolveAssignExpr(AssignExpr *E); - Expr *resolveInfixExpr(InfixExpr *E); - Expr *resolvePrefixExpr(PrefixExpr *E); - Expr *resolveCallExpr(CallExpr *E); - Expr *resolveSubscriptExpr(SubscriptExpr *E); - - bool typeResolveIdentTypeRepr(IdentTypeRepr *TR); - bool typeResolveArrayTypeRepr(ArrayTypeRepr *TR); -}; - -} // namespace sema -} // namespace dusk - -#endif /* DUSK_SEMA_TYPE_RESOLVER_H */ diff --git a/lib/IRGen/GenModule.cpp b/lib/IRGen/GenModule.cpp index e265ddcb98cbb523a1045a23fa0e449b574a0bcc..7c965797fe3eef6b410a8b56cca971d8ff4ae8b6 100644 --- a/lib/IRGen/GenModule.cpp +++ b/lib/IRGen/GenModule.cpp @@ -26,25 +26,29 @@ using namespace irgen; namespace { /// A simple AST walker, that declares all functions. -class FuncDeclarator: public ASTWalker { +class FuncDeclarator : public ASTWalker { IRGenModule &IRGM; public: FuncDeclarator(IRGenModule &IRGM) : IRGM(IRGM) {} - + // Skip all global declarations except function and module declarations - virtual bool preWalk(Decl *D) override { + virtual bool preWalkDecl(Decl *D) override { if (dynamic_cast<FuncDecl *>(D) != nullptr) return true; if (dynamic_cast<ModuleDecl *>(D) != nullptr) return true; return false; } - + // Skip all expressions - virtual bool preWalk(Expr *E) override { return false; } - - virtual bool preWalk(Stmt *S) override { + std::pair<bool, Expr *> preWalkExpr(Expr *E) override { return {false, E}; } + // Skip all patterns + bool preWalkPattern(Pattern *P) override { return false; } + // Skip all types + bool preWalkTypeRepr(TypeRepr *TR) override { return false; } + + bool preWalkStmt(Stmt *S) override { // Skip all statements except function declarations if (dynamic_cast<FuncStmt *>(S) != nullptr) return true; @@ -52,9 +56,9 @@ public: return true; return false; } - + // Actually declare given function - virtual bool postWalk(Decl *D) override { + bool postWalkDecl(Decl *D) override { auto Fn = static_cast<FuncDecl *>(D); assert(IRGM.declareFunc(Fn) != nullptr && "Redefinition of a function"); return true; @@ -63,7 +67,6 @@ public: } // anonymous namespace - static void decalreFunctions(IRGenModule &IRGM) { FuncDeclarator FD(IRGM); for (auto N : IRGM.Context.getRootModule()->getContents()) @@ -72,22 +75,22 @@ static void decalreFunctions(IRGenModule &IRGM) { void irgen::genModule(IRGenModule &IRGM) { decalreFunctions(IRGM); - + for (auto N : IRGM.Context.getRootModule()->getContents()) { if (auto D = dynamic_cast<ValDecl *>(N)) { if (!IRGM.declareVal(D)) llvm_unreachable("Redefinition of a value"); - + } else if (auto Fn = dynamic_cast<FuncStmt *>(N)) { IRGenFunc IRGF(IRGM, IRGM.Builder, IRGM.getFunc(Fn->getPrototype()->getName()), Fn); if (!genFunc(IRGF, Fn)) llvm_unreachable("Error generating a function."); - + } else if (auto Fn = dynamic_cast<ExternStmt *>(N)) { continue; - + } else { llvm_unreachable("Unexpected top-level statement"); } diff --git a/lib/Sema/CMakeLists.txt b/lib/Sema/CMakeLists.txt index 3272d7be7b545b761047adfafe6e07403ef38ff8..c6cb2c8e008c6b9d50f8502376ba8fe8c05d6b94 100644 --- a/lib/Sema/CMakeLists.txt +++ b/lib/Sema/CMakeLists.txt @@ -7,7 +7,6 @@ set(SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/TypeCheckPattern.cpp ${CMAKE_CURRENT_SOURCE_DIR}/TypeCheckStmt.cpp ${CMAKE_CURRENT_SOURCE_DIR}/TypeCheckType.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/TypeResolver.cpp ${SOURCE} PARENT_SCOPE ) diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index 27ca952bdc0ab02d39efd9b59cd8bc261c06adf7..7fa937122208f1c5c906ab7facbb43febf67ea0f 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -40,7 +40,7 @@ public: FwdDeclarator(Sema &S, NameLookup &C, DiagnosticEngine &D) : S(S), Ctx(C), Diag(D) {} - bool preWalk(Decl *D) override { + bool preWalkDecl(Decl *D) override { if (D->getKind() == DeclKind::Func) return true; if (D->getKind() == DeclKind::Module) @@ -48,7 +48,7 @@ public: return false; } - bool postWalk(Decl *D) override { + bool postWalkDecl(Decl *D) override { if (auto FD = dynamic_cast<FuncDecl *>(D)) { if (!Ctx.declareFunc(D)) { Diag.diagnose(D->getLocStart(), diag::redefinition_of_identifier); @@ -59,10 +59,14 @@ public: return true; } - // Skip all expressions. - bool preWalk(Expr *E) override { return false; } + // Skip all expressions + std::pair<bool, Expr *> preWalkExpr(Expr *E) override { return {false, E}; } + // Skip all patterns + bool preWalkPattern(Pattern *P) override { return false; } + // Skip all types + bool preWalkTypeRepr(TypeRepr *TR) override { return false; } - bool preWalk(Stmt *S) override { + bool preWalkStmt(Stmt *S) override { switch (S->getKind()) { case StmtKind::Func: case StmtKind::Extern: diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp index c6a54e60ef08095ba0b3aa58913879457a706d4a..0b59fa14e085c7b0ca431092b2c595c09f974c0c 100644 --- a/lib/Sema/TypeCheckDecl.cpp +++ b/lib/Sema/TypeCheckDecl.cpp @@ -14,7 +14,6 @@ #include "dusk/AST/NameLookup.h" #include "dusk/AST/ASTVisitor.h" #include "dusk/Sema/Sema.h" -#include "dusk/Sema/TypeResolver.h" using namespace dusk; using namespace sema; @@ -82,10 +81,21 @@ private: void visitFuncDecl(FuncDecl *D) { PushScopeRAII Push(TC.ASTScope, Scope::FnProtoScope); - TC.Lookup.declareFunc(D); TC.typeCheckPattern(D->getArgs()); - if (D->hasTypeRepr()) + + Type *ArgsTy = D->getArgs()->getType(); + Type *RetTy = TC.Ctx.getVoidType(); + + // Override return type if specified + if (D->hasTypeRepr()) { TC.typeCheckType(D->getTypeRepr()); + RetTy = D->getTypeRepr()->getType(); + } + + if (!ArgsTy || !RetTy) + return; + + D->setType(new (TC.Ctx) FunctionType(ArgsTy, RetTy)); } void visitModuleDecl(ModuleDecl *D) { @@ -103,7 +113,7 @@ private: public: void typeCheckDecl(Decl *D) { - if (TC.Lookup.contains(D->getName())) + if (D->isValDecl() && TC.Lookup.contains(D->getName())) TC.diagnose(D->getLocStart(), diag::redefinition_of_identifier); super::visit(D); @@ -116,102 +126,3 @@ void TypeChecker::typeCheckDecl(Decl *D) { DeclChecker(*this).typeCheckDecl(D); } -//bool TypeChecker::preWalkLetDecl(LetDecl *D) { -// // Check for initialization value -// if (!D->hasValue()) { -// diagnose(D->getLocStart(), diag::expected_default_initialization); -// return false; -// } -// -// if (D->hasTypeRepr()) -// D->setType(S.typeReprResolve(D->getTypeRepr())); -// return true; -//} -// -//bool TypeChecker::preWalkVarDecl(VarDecl *D) { -// if (!D->hasValue() && !D->hasTypeRepr()) { -// diagnose(D->getLocEnd(), diag::expected_type_specifier); -// return false; -// } -// -// if (D->hasTypeRepr()) -// D->setType(S.typeReprResolve(D->getTypeRepr())); -// return true; -//} -// -//bool TypeChecker::preWalkParamDecl(ParamDecl *D) { -// if (D->hasTypeRepr()) -// D->setType(S.typeReprResolve(D->getTypeRepr())); -// return false; -//} -// -//bool TypeChecker::preWalkFuncDecl(FuncDecl *D) { -// D->setType(S.typeReprResolve(D)); -// return true; -//} -// -//bool TypeChecker::preWalkModuleDecl(ModuleDecl *D) { return true; } -// -//bool TypeChecker::postWalkLetDecl(LetDecl *D) { -// // Infer type -// if (!D->getType()) -// D->setType(D->getValue()->getType()); -// -// // Check if resolved both types -// if (!D->getType() || !D->getValue()->getType()) -// return false; -// -// if (!D->getType()->isValueType()) { -// diagnose(D->getValue()->getLocStart(), -// diag::expected_value_type_expression); -// return false; -// } -// -// // Validate types -// if (D->getType()->isClassOf(D->getValue()->getType())) { -// // If types match, declare -// if (Lookup.declareLet(D)) { -// return true; -// } else { -// diagnose(D->getLocStart(), diag::redefinition_of_identifier); -// return false; -// } -// } -// -// diagnose(D->getValue()->getLocStart(), diag::type_missmatch); -// return false; -//} -// -//bool TypeChecker::postWalkVarDecl(VarDecl *D) { -// // Infer type -// if (!D->getType() && D->hasValue()) -// D->setType(D->getValue()->getType()); -// -// // Check if resolved both types -// if (!D->getType() || (D->hasValue() && !D->getValue()->getType())) -// return false; -// -// if (!D->getType()->isValueType()) { -// diagnose(D->getValue()->getLocStart(), -// diag::expected_value_type_expression); -// return false; -// } -// -// // Validate types -// if (!D->hasValue() || D->getType()->isClassOf(D->getValue()->getType())) -// // If types match, declare -// return Lookup.declareVar(D); -// -// diagnose(D->getValue()->getLocStart(), diag::type_missmatch); -// return false; -//} -// -//bool TypeChecker::postWalkParamDecl(ParamDecl *D) { -// return D->getType() != nullptr; -//} -// -//bool TypeChecker::postWalkFuncDecl(FuncDecl *D) { -// return (D->getType()) != nullptr; -//} -// -//bool TypeChecker::postWalkModuleDecl(ModuleDecl *D) { return true; } diff --git a/lib/Sema/TypeCheckExpr.cpp b/lib/Sema/TypeCheckExpr.cpp index b78c3262d939688eb4b7efd97853ad98b6a0939c..a2675394d2aa8039863cb98626b3dc9c7a5e900a 100644 --- a/lib/Sema/TypeCheckExpr.cpp +++ b/lib/Sema/TypeCheckExpr.cpp @@ -362,101 +362,3 @@ public: Expr *TypeChecker::typeCheckExpr(Expr *E) { return ExprChecker(*this).typeCheckExpr(E); } - -//bool TypeChecker::postWalkNumberLiteralExpr(NumberLiteralExpr *E) { -// return true; -//} -// -//bool TypeChecker::postWalkArrayLiteralExpr(ArrayLiteralExpr *E) { -// E->setType(S.typeReprResolve(E)); -// return true; -//} -// -//bool TypeChecker::postWalkIdentifierExpr(IdentifierExpr *E) { -// // Check if it's a value type -// if (auto D = Lookup.getVal(E->getName())) { -// E->setType(D->getType()); -// return true; -// } -// // Check if it's a function reference -// if (auto Fn = Lookup.getFunc(E->getName())) { -// E->setType(Fn->getType()); -// return true; -// } -// diagnose(E->getLocStart(), diag::undefined_identifier); -// return false; -//} -// -//bool TypeChecker::postWalkParenExpr(ParenExpr *E) { -// E->setType(E->getExpr()->getType()); -// return true; -//} -// -//bool TypeChecker::postWalkAssignExpr(AssignExpr *E) { -// auto Ident = dynamic_cast<IdentifierExpr *>(E->getDest()); -// // Check if its an assignable expression -// if (!Ident || Lookup.getFunc(Ident->getName())) { -// diagnose(E->getDest()->getLocStart(), diag::expression_not_assignable); -// return false; -// } -// // Check if it is a variable -// if (Lookup.getVal(Ident->getName()) && !Lookup.getVar(Ident->getName())) { -// diagnose(E->getDest()->getLocStart(), diag::cannot_reassign_let_value); -// } -// -// // Check type match. -// if (E->getDest()->getType()->isClassOf(E->getSource()->getType())) { -// E->setType(E->getDest()->getType()); -// return true; -// } -// diagnose(E->getDest()->getLocEnd(), diag::type_missmatch); -// return false; -//} -// -//bool TypeChecker::postWalkInfixExpr(InfixExpr *E) { -// if (!E->getLHS()->getType() || !E->getRHS()->getType()) -// return false; -// -// // Check type match. -// if (E->getLHS()->getType()->isClassOf(E->getRHS()->getType())) { -// E->setType(E->getLHS()->getType()); -// return true; -// } -// diagnose(E->getOp().getLoc(), diag::type_missmatch); -// return false; -//} -// -//bool TypeChecker::postWalkPrefixExpr(PrefixExpr *E) { -// E->setType(E->getDest()->getType()); -// return true; -//} -// -//bool TypeChecker::postWalkCallExpr(CallExpr *E) { -// auto FTy = dynamic_cast<FunctionType *>(E->getCallee()->getType()); -// -// // Check if references a function -// if (!FTy) { -// diagnose(E->getCallee()->getLocStart(), diag::func_call_non_func_type); -// return false; -// } -// -// // Check is arguments are the same as in proto -// if (E->getArgs()->getType()->isClassOf(FTy->getArgsType())) { -// E->setType(FTy->getRetType()); -// return true; -// } else { -// diagnose(E->getArgs()->getLocStart(), diag::arguments_mismatch); -// return false; -// } -//} -// -//bool TypeChecker::postWalkSubscriptExpr(SubscriptExpr *E) { -// if (E->getBase()->getType()->getKind() != TypeKind::Array) { -// diagnose(E->getBase()->getLocStart(), diag::subscripted_value_not_array); -// return false; -// } else { -// auto ArrTy = static_cast<ArrayType *>(E->getBase()->getType()); -// E->setType(ArrTy->getBaseType()); -// return true; -// } -//} diff --git a/lib/Sema/TypeCheckPattern.cpp b/lib/Sema/TypeCheckPattern.cpp index 3b9d88a9e3957b7f9f12c55a44a4953e0bcbff97..448d4075d1efe5567863299a0cfa4af110abc63e 100644 --- a/lib/Sema/TypeCheckPattern.cpp +++ b/lib/Sema/TypeCheckPattern.cpp @@ -66,36 +66,3 @@ void TypeChecker::typeCheckPattern(Pattern *P) { PatternChecker(*this).typeCheckPattern(P); } -// bool TypeChecker::preWalkVarPattern(VarPattern *P) { -// return P->getType() == nullptr; -//} -// -// bool TypeChecker::preWalkExprPattern(ExprPattern *P) { -// return P->getType() == nullptr; -//} -// -// bool TypeChecker::postWalkVarPattern(VarPattern *P) { -// llvm::SmallVector<Type *, 128> Ty; -// for (auto V : P->getVars()) { -// if (!V->getType()) -// return false; -// Ty.push_back(V->getType()); -// } -// -// P->setType(new(Ctx) PatternType(std::move(Ty))); -// return true; -//} -// -// bool TypeChecker::postWalkExprPattern(ExprPattern *P) { -// llvm::SmallVector<Type *, 128> Ty; -// for (auto V : P->getValues()) { -// if (!V->getType()) -// return false; -// Ty.push_back(V->getType()); -// } -// -// P->setType(new(Ctx) PatternType(std::move(Ty))); -// return true; -//} -// - diff --git a/lib/Sema/TypeCheckStmt.cpp b/lib/Sema/TypeCheckStmt.cpp index 8b1322dd74c0e137b477c79e1eb8120c5a8e9903..7da4dbdc340fc4321eeadde94107ec1dab3f81fa 100644 --- a/lib/Sema/TypeCheckStmt.cpp +++ b/lib/Sema/TypeCheckStmt.cpp @@ -136,141 +136,3 @@ public: void TypeChecker::typeCheckStmt(Stmt *S) { StmtChecker(*this).typeCheckStmt(S); } - -// bool TypeChecker::preWalkBlockStmt(BlockStmt *S) { -// Lookup.push(); -// if (auto Fn = dynamic_cast<FuncStmt *>(Scp.top().getStmt())) { -// auto Proto = static_cast<FuncDecl *>(Fn->getPrototype()); -// auto Args = static_cast<VarPattern *>(Proto->getArgs()); -// for (auto Arg : Args->getVars()) -// if (!Lookup.declareVar(Arg)) { -// diagnose(Args->getLocStart(), diag::redefinition_of_identifier); -// return false; -// } -// } -// -// if (auto For = dynamic_cast<ForStmt *>(Scp.top().getStmt())) { -// if (!For->getRange()->walk(*this)) -// return false; -// auto Rng = static_cast<RangeStmt *>(For->getRange()); -// auto Iter = static_cast<ParamDecl *>(For->getIter()); -// Iter->setType(Rng->getStart()->getType()); -// Lookup.declareLet(Iter); -// } -// Scp.push(Scope(&Scp.top(), Scope::BlockScope, S)); -// return true; -//} -// -// bool TypeChecker::preWalkExternStmt(ExternStmt *S) { -// Scp.push(Scope(&Scp.top(), Scope::FnScope, S)); -// Lookup.push(); -// return true; -//} -// -// bool TypeChecker::preWalkForStmt(ForStmt *S) { -// Scp.push(Scope(&Scp.top(), Scope::ControlScope | Scope::BreakScope, S)); -// return true; -//} -// -// bool TypeChecker::preWalkFuncStmt(FuncStmt *S) { -// Scp.push(Scope(&Scp.top(), Scope::FnScope, S)); -// return true; -//} -// -// bool TypeChecker::preWalkIfStmt(IfStmt *S) { -// Scp.push(Scope(&Scp.top(), Scope::ControlScope, S)); -// return true; -//} -// -// bool TypeChecker::preWalkWhileStmt(WhileStmt *S) { -// Scp.push(Scope(&Scp.top(), Scope::ControlScope | Scope::BreakScope, S)); -// return true; -//} -// -// bool TypeChecker::postWalkBreakStmt(BreakStmt *S) { -// if (Scp.top().isBreakScope() || Scp.top().getBreakParent() != nullptr) -// return true; -// diagnose(S->getLocStart(), diag::unexpected_break_stmt); -// return false; -//} -// -// bool TypeChecker::postWalkReturnStmt(ReturnStmt *S) { -// if (!Scp.top().isFnScope() && Scp.top().getFnParent() == nullptr) { -// diagnose(S->getLocStart(), diag::unexpected_return_stmt); -// return false; -// } -// auto &FnScp = Scp.top().isFnScope() ? Scp.top() : *Scp.top().getFnParent(); -// -// auto F = static_cast<FuncStmt *>(FnScp.getStmt()); -// auto FD = static_cast<FuncDecl *>(F->getPrototype()); -// auto FTy = static_cast<FunctionType *>(FD->getType()); -// -// if (!S->hasValue()) { -// if (FTy->getRetType()->isVoidType()) -// return true; -// diagnose(S->getLocStart(), diag::return_missing_value); -// return false; -// } -// -// if (FTy->getRetType()->isClassOf(S->getValue()->getType())) -// return true; -// -// diagnose(S->getLocStart(), diag::type_missmatch); -// return false; -//} -// -// bool TypeChecker::postWalkRangeStmt(RangeStmt *S) { -// if (!S->getStart()->getType()->isValueType()) { -// diagnose(S->getStart()->getLocStart(), -// diag::expected_value_type_expression); -// return false; -// } -// if (!S->getEnd()->getType()->isValueType()) { -// diagnose(S->getEnd()->getLocStart(), -// diag::expected_value_type_expression); -// return false; -// } -// return true; -//} -// -// bool TypeChecker::postWalkSubscriptStmt(SubscriptStmt *S) { -// return S->getValue()->getType()->isValueType(); -//} -// -// bool TypeChecker::postWalkBlockStmt(BlockStmt *S) { -// Lookup.pop(); -// Scp.pop(); -// return true; -//} -// -// bool TypeChecker::postWalkExternStmt(ExternStmt *S) { -// Lookup.pop(); -// Scp.pop(); -// return true; -//} -// -// bool TypeChecker::postWalkForStmt(ForStmt *S) { -// Scp.pop(); -// return true; -//} -// -// bool TypeChecker::postWalkFuncStmt(FuncStmt *S) { -// Scp.pop(); -// return true; -//} -// -// bool TypeChecker::postWalkIfStmt(IfStmt *S) { -// Scp.pop(); -// if (S->getCond()->getType()->isValueType()) -// return true; -// diagnose(S->getCond()->getLocStart(), diag::expected_value_type_expression); -// return false; -//} -// -// bool TypeChecker::postWalkWhileStmt(WhileStmt *S) { -// Scp.pop(); -// if (S->getCond()->getType()->isValueType()) -// return true; -// diagnose(S->getCond()->getLocStart(), diag::expected_value_type_expression); -// return false; -//} diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index 6da0dfa8f36bc614bddabe4b0187294e3a74534d..7673de9e82e12d12e04919e06b0e6f9b8aad0500 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -15,7 +15,6 @@ #include "dusk/AST/NameLookup.h" #include "dusk/AST/ASTVisitor.h" #include "dusk/Sema/Sema.h" -#include "dusk/Sema/TypeResolver.h" #include "dusk/AST/ASTWalker.h" #include "llvm/ADT/StringSwitch.h" diff --git a/lib/Sema/TypeChecker.cpp b/lib/Sema/TypeChecker.cpp index 34f62c0d1fb8a5bd1bc9b577ba0be0552995e3f6..756dc1a60d63346366cbd800236a911e45e90cdc 100644 --- a/lib/Sema/TypeChecker.cpp +++ b/lib/Sema/TypeChecker.cpp @@ -19,132 +19,9 @@ using namespace sema; TypeChecker::TypeChecker(Sema &S, NameLookup &C, ASTContext &Ctx, DiagnosticEngine &D) - : S(S), Lookup(C), Ctx(Ctx), Diag(D) { - Scp.push(Scope()); -} + : S(S), Lookup(C), Ctx(Ctx), Diag(D) {} void TypeChecker::diagnose(SMLoc Loc, diag::DiagID ID) { Diag.diagnose(Loc, ID); Ctx.setError(); } - -//bool TypeChecker::preWalk(Decl *D) { -// switch (D->getKind()) { -// case DeclKind::Let: -// return preWalkLetDecl(static_cast<LetDecl *>(D)); -// case DeclKind::Func: -// return preWalkFuncDecl(static_cast<FuncDecl *>(D)); -// case DeclKind::Module: -// return preWalkModuleDecl(static_cast<ModuleDecl *>(D)); -// case DeclKind::Param: -// return preWalkParamDecl(static_cast<ParamDecl *>(D)); -// case DeclKind::Var: -// return preWalkVarDecl(static_cast<VarDecl *>(D)); -// } -//} -// -//bool TypeChecker::postWalk(Decl *D) { -// switch (D->getKind()) { -// case DeclKind::Let: -// return postWalkLetDecl(static_cast<LetDecl *>(D)); -// case DeclKind::Func: -// return postWalkFuncDecl(static_cast<FuncDecl *>(D)); -// case DeclKind::Module: -// return postWalkModuleDecl(static_cast<ModuleDecl *>(D)); -// case DeclKind::Param: -// return postWalkParamDecl(static_cast<ParamDecl *>(D)); -// case DeclKind::Var: -// return postWalkVarDecl(static_cast<VarDecl *>(D)); -// } -//} -// -//bool TypeChecker::preWalk(Expr *E) { -// // Skip expression type validation tree if the root expression has a type. -// return E->getType() == nullptr; -//} -// -//bool TypeChecker::postWalk(Expr *E) { -// switch (E->getKind()) { -// case ExprKind::NumberLiteral: -// return postWalkNumberLiteralExpr(static_cast<NumberLiteralExpr *>(E)); -// case ExprKind::ArrayLiteral: -// return postWalkArrayLiteralExpr(static_cast<ArrayLiteralExpr *>(E)); -// case ExprKind::Identifier: -// return postWalkIdentifierExpr(static_cast<IdentifierExpr *>(E)); -// case ExprKind::Paren: -// return postWalkParenExpr(static_cast<ParenExpr *>(E)); -// case ExprKind::Assign: -// return postWalkAssignExpr(static_cast<AssignExpr *>(E)); -// case ExprKind::Infix: -// return postWalkInfixExpr(static_cast<InfixExpr *>(E)); -// case ExprKind::Prefix: -// return postWalkPrefixExpr(static_cast<PrefixExpr *>(E)); -// case ExprKind::Call: -// return postWalkCallExpr(static_cast<CallExpr *>(E)); -// case ExprKind::Subscript: -// return postWalkSubscriptExpr(static_cast<SubscriptExpr *>(E)); -// } -//} -// -//bool TypeChecker::preWalk(Stmt *S) { -// switch (S->getKind()) { -// case StmtKind::Block: -// return preWalkBlockStmt(static_cast<BlockStmt *>(S)); -// case StmtKind::Extern: -// return preWalkExternStmt(static_cast<ExternStmt *>(S)); -// case StmtKind::For: -// return preWalkForStmt(static_cast<ForStmt *>(S)); -// case StmtKind::Func: -// return preWalkFuncStmt(static_cast<FuncStmt *>(S)); -// case StmtKind::If: -// return preWalkIfStmt(static_cast<IfStmt *>(S)); -// case StmtKind::While: -// return preWalkWhileStmt(static_cast<WhileStmt *>(S)); -// default: return true; -// } -//} -// -//bool TypeChecker::postWalk(Stmt *S) { -// switch (S->getKind()) { -// case StmtKind::Break: -// return postWalkBreakStmt(static_cast<BreakStmt *>(S)); -// case StmtKind::Return: -// return postWalkReturnStmt(static_cast<ReturnStmt *>(S)); -// case StmtKind::Range: -// return postWalkRangeStmt(static_cast<RangeStmt *>(S)); -// case StmtKind::Subscript: -// return postWalkSubscriptStmt(static_cast<SubscriptStmt *>(S)); -// case StmtKind::Block: -// return postWalkBlockStmt(static_cast<BlockStmt *>(S)); -// case StmtKind::Extern: -// return postWalkExternStmt(static_cast<ExternStmt *>(S)); -// case StmtKind::For: -// return postWalkForStmt(static_cast<ForStmt *>(S)); -// case StmtKind::Func: -// return postWalkFuncStmt(static_cast<FuncStmt *>(S)); -// case StmtKind::If: -// return postWalkIfStmt(static_cast<IfStmt *>(S)); -// case StmtKind::While: -// return postWalkWhileStmt(static_cast<WhileStmt *>(S)); -// } -//} -// -//bool TypeChecker::preWalk(Pattern *P) { -// switch (P->getKind()) { -// case PatternKind::Variable: -// return preWalkVarPattern(static_cast<VarPattern *>(P)); -// case PatternKind::Expr: -// return preWalkExprPattern(static_cast<ExprPattern *>(P)); -// } -//} -// -//bool TypeChecker::postWalk(Pattern *P) { -// switch (P->getKind()) { -// case PatternKind::Variable: -// return postWalkVarPattern(static_cast<VarPattern *>(P)); -// case PatternKind::Expr: -// return postWalkExprPattern(static_cast<ExprPattern *>(P)); -// } -//} - - diff --git a/lib/Sema/TypeChecker.h b/lib/Sema/TypeChecker.h index e240f767ab7c3477eca80bfb7577f705301f7ff4..7be2d544d9700c52c57b0460b56fc4f0b90b798e 100644 --- a/lib/Sema/TypeChecker.h +++ b/lib/Sema/TypeChecker.h @@ -17,7 +17,6 @@ #include "dusk/AST/ASTContext.h" #include "dusk/AST/ASTWalker.h" #include "dusk/AST/Scope.h" -#include <stack> namespace dusk { class Type; @@ -37,30 +36,17 @@ class Sema; /// /// This class takes an AST as an input and resolves types of all it's nodes, /// while validating them. -class TypeChecker /*: public ASTWalker*/ { +class TypeChecker { Sema &S; public: NameLookup &Lookup; ASTContext &Ctx; - std::stack<Scope> Scp; Scope ASTScope; DiagnosticEngine &Diag; TypeChecker(Sema &S, NameLookup &DC, ASTContext &Ctx, DiagnosticEngine &Diag); -// virtual bool preWalk(Decl *D) override; -// virtual bool postWalk(Decl *D) override; -// -// virtual bool preWalk(Expr *E) override; -// virtual bool postWalk(Expr *E) override; -// -// virtual bool preWalk(Stmt *S) override; -// virtual bool postWalk(Stmt *S) override; -// -// virtual bool preWalk(Pattern *P) override; -// virtual bool postWalk(Pattern *P) override; - void diagnose(SMLoc Loc, diag::DiagID ID); bool typeCheckEquals(Type *LHS, Type *RHS) { @@ -72,57 +58,6 @@ public: void typeCheckStmt(Stmt *S); void typeCheckPattern(Pattern *P); void typeCheckType(TypeRepr *TR); - -//private: -// // MARK: - Declarations -// bool preWalkLetDecl(LetDecl *D); -// bool preWalkFuncDecl(FuncDecl *D); -// bool preWalkModuleDecl(ModuleDecl *D); -// bool preWalkParamDecl(ParamDecl *D); -// bool preWalkVarDecl(VarDecl *D); -// -// bool postWalkLetDecl(LetDecl *D); -// bool postWalkFuncDecl(FuncDecl *D); -// bool postWalkModuleDecl(ModuleDecl *D); -// bool postWalkParamDecl(ParamDecl *D); -// bool postWalkVarDecl(VarDecl *D); -// -// // MARK: - Expressions -// bool postWalkNumberLiteralExpr(NumberLiteralExpr *E); -// bool postWalkArrayLiteralExpr(ArrayLiteralExpr *E); -// bool postWalkIdentifierExpr(IdentifierExpr *E); -// bool postWalkParenExpr(ParenExpr *E); -// bool postWalkAssignExpr(AssignExpr *E); -// bool postWalkInfixExpr(InfixExpr *E); -// bool postWalkPrefixExpr(PrefixExpr *E); -// bool postWalkCallExpr(CallExpr *E); -// bool postWalkSubscriptExpr(SubscriptExpr *E); -// -// // MARK: - Statements -// bool preWalkBlockStmt(BlockStmt *S); -// bool preWalkExternStmt(ExternStmt *S); -// bool preWalkForStmt(ForStmt *S); -// bool preWalkFuncStmt(FuncStmt *S); -// bool preWalkIfStmt(IfStmt *S); -// bool preWalkWhileStmt(WhileStmt *S); -// -// bool postWalkBreakStmt(BreakStmt *S); -// bool postWalkReturnStmt(ReturnStmt *S); -// bool postWalkRangeStmt(RangeStmt *S); -// bool postWalkSubscriptStmt(SubscriptStmt *S); -// bool postWalkBlockStmt(BlockStmt *S); -// bool postWalkExternStmt(ExternStmt *S); -// bool postWalkForStmt(ForStmt *S); -// bool postWalkFuncStmt(FuncStmt *S); -// bool postWalkIfStmt(IfStmt *S); -// bool postWalkWhileStmt(WhileStmt *S); -// -// // MARK: - Patterns -// bool preWalkVarPattern(VarPattern *P); -// bool preWalkExprPattern(ExprPattern *P); -// -// bool postWalkVarPattern(VarPattern *P); -// bool postWalkExprPattern(ExprPattern *P); }; } // namespace sema diff --git a/lib/Sema/TypeResolver.cpp b/lib/Sema/TypeResolver.cpp deleted file mode 100644 index 2572c68583a2ca7519f05dc123b862ab0cc2a5b8..0000000000000000000000000000000000000000 --- a/lib/Sema/TypeResolver.cpp +++ /dev/null @@ -1,234 +0,0 @@ -//===--- TypeResolver.cpp -------------------------------------------------===// -// -// 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. -// -//===----------------------------------------------------------------------===// - -#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/TypeRepr.h" -#include "dusk/AST/ASTContext.h" -#include "dusk/AST/NameLookup.h" -#include "dusk/AST/Diagnostics.h" -#include "dusk/Sema/TypeResolver.h" -#include <memory> - -using namespace dusk; -using namespace sema; - -TypeResolver::TypeResolver(ASTContext &Ctx, NameLookup &NL, DiagnosticEngine &D) - : Context(Ctx), NL(NL), Diag(D) {} - -bool TypeResolver::preWalkDecl(Decl *D) { - // Skip all declarations, that already were type resolved. - return D->getType() != nullptr; -} - -bool TypeResolver::postWalkDecl(Decl *D) { - switch (D->getKind()) { - case DeclKind::Var: - return resolveVarDecl(static_cast<VarDecl *>(D)); - case DeclKind::Let: - return resolveLetDecl(static_cast<LetDecl *>(D)); - case DeclKind::Func: - return resolveFuncDecl(static_cast<FuncDecl *>(D)); - case DeclKind::Module: - return resolveModuleDecl(static_cast<ModuleDecl *>(D)); - case DeclKind::Param: - return resolveParamDecl(static_cast<ParamDecl *>(D)); - } -} - -std::pair<bool, Expr *> TypeResolver::preWalkExpr(Expr *E) { - // Skip all expression that do already have a type - return {E->getType() != nullptr, E}; -} - -Expr *TypeResolver::postWalkExpr(Expr *E) { - switch (E->getKind()) { - case ExprKind::NumberLiteral: - return resolveNumberLiteralExpr(static_cast<NumberLiteralExpr *>(E)); - case ExprKind::ArrayLiteral: - return resolveArrayLiteralExpr(static_cast<ArrayLiteralExpr *>(E)); - case ExprKind::Identifier: - return resolveIdentifierExpr(static_cast<IdentifierExpr *>(E)); - case ExprKind::Paren: - return resolveParenExpr(static_cast<ParenExpr *>(E)); - case ExprKind::Assign: - return resolveAssignExpr(static_cast<AssignExpr *>(E)); - case ExprKind::Infix: - return resolveInfixExpr(static_cast<InfixExpr *>(E)); - case ExprKind::Prefix: - return resolvePrefixExpr(static_cast<PrefixExpr *>(E)); - case ExprKind::Call: - return resolveCallExpr(static_cast<CallExpr *>(E)); - case ExprKind::Subscript: - return resolveSubscriptExpr(static_cast<SubscriptExpr *>(E)); - } -} - -bool TypeResolver::preWalkTypeRepr(TypeRepr *TR) { - // Skip all type representation that were type resolved - return TR->getType() != nullptr; -} - -bool TypeResolver::postWalkTypeRepr(TypeRepr *TR) { - switch (TR->getKind()) { - case TypeReprKind::Ident: - return typeResolveIdentTypeRepr(static_cast<IdentTypeRepr *>(TR)); - case TypeReprKind::Array: - return typeResolveArrayTypeRepr(static_cast<ArrayTypeRepr *>(TR)); - } -} - -// MARK: - Declarations - -bool TypeResolver::resolveLetDecl(LetDecl *D) { - if (D->hasTypeRepr()) - D->setType(D->getTypeRepr()->getType()); - else if (D->hasValue()) - D->setType(D->getValue()->getType()); - else - Diag.diagnose(D->getLocStart(), diag::ambigous_types); - return true; -} - -bool TypeResolver::resolveVarDecl(VarDecl *D) { - if (D->hasTypeRepr()) - D->setType(D->getTypeRepr()->getType()); - else if (D->hasValue()) - D->setType(D->getValue()->getType()); - else - Diag.diagnose(D->getLocStart(), diag::ambigous_types); - return true; -} - -bool TypeResolver::resolveFuncDecl(FuncDecl *D) { - auto AT = D->getArgs()->getType(); - Type *RT; - if (D->hasTypeRepr()) { - RT = D->getTypeRepr()->getType(); - } else { - RT = new (Context) VoidType(); - } - - D->setType(new (Context) FunctionType(AT, RT)); - return true; -} - -bool TypeResolver::resolveModuleDecl(ModuleDecl *D) { return true; } - -bool TypeResolver::resolveParamDecl(ParamDecl *D) { - if (D->hasTypeRepr()) - D->setType(D->getTypeRepr()->getType()); - return true; -} - -// MARK: - Expressions - -Expr *TypeResolver::resolveNumberLiteralExpr(NumberLiteralExpr *E) { - E->setType(Context.getIntType()); - return E; -} - -Expr *TypeResolver::resolveArrayLiteralExpr(ArrayLiteralExpr *E) { - auto Size = E->getValues()->count(); - auto Vals = static_cast<ExprPattern *>(E->getValues()); - auto BaseTy = Vals->getValues().front()->getType(); - E->setType(new (Context) ArrayType(BaseTy, Size)); - return E; -} - -Expr *TypeResolver::resolveIdentifierExpr(IdentifierExpr *E) { - if (auto D = NL.getVal(E->getName())) { - E->setType(D->getType()); - return E; - } - Diag.diagnose(E->getLocStart(), diag::undefined_identifier); - return E; -} - -Expr *TypeResolver::resolveParenExpr(ParenExpr *E) { - E->setType(E->getExpr()->getType()); - return E; -} - -Expr *TypeResolver::resolveAssignExpr(AssignExpr *E) { - E->setType(E->getSource()->getType()); - return E; -} - -Expr *TypeResolver::resolveInfixExpr(InfixExpr *E) { - E->setType(E->getLHS()->getType()); - return E; -} - -Expr *TypeResolver::resolvePrefixExpr(PrefixExpr *E) { - E->setType(E->getDest()->getType()); - return E; -} - -Expr *TypeResolver::resolveCallExpr(CallExpr *E) { - if (auto Ident = dynamic_cast<IdentifierExpr *>(E)) { - if (auto Fn = NL.getFunc(Ident->getName())) { - auto FnTy = static_cast<FunctionType *>(Fn->getType()); - if (FnTy->getRetType()->isValueType()) { - E->setType(FnTy->getRetType()); - return E; - - } else { - Diag.diagnose(E->getLocStart(), diag::expected_value_type_expression); - } - - } else { - if (NL.contains(Ident->getName())) { - Diag.diagnose(E->getLocStart(), diag::func_call_non_func_type); - } else { - Diag.diagnose(E->getLocStart(), diag::undefined_identifier); - } - } - - } else { - Diag.diagnose(E->getLocStart(), diag::func_call_non_func_type); - } - return E; -} - -Expr *TypeResolver::resolveSubscriptExpr(SubscriptExpr *E) { - if (auto ArrTy = dynamic_cast<ArrayType *>(E->getBase()->getType())) { - E->setType(ArrTy->getBaseType()); - return E; - } - Diag.diagnose(E->getLocStart(), diag::subscripted_value_not_array); - return E; -} - -// MARK: - Type representations - -bool TypeResolver::typeResolveIdentTypeRepr(IdentTypeRepr *TR) { - if (TR->getIdent() == "Void") { - TR->setType(Context.getVoidType()); - return true; - - } else if (TR->getIdent() == "Int") { - TR->setType(Context.getVoidType()); - return true; - } - - Diag.diagnose(TR->getLocStart(), diag::unknown_type); - return true; -} - -bool TypeResolver::typeResolveArrayTypeRepr(ArrayTypeRepr *TR) { - auto BaseTy = TR->getBaseTyRepr()->getType(); - auto Size = 0; // TODO: perform exctraction. TR->getSize(); - - TR->setType(new (Context) ArrayType(BaseTy, Size)); - return true; -}