Skip to content
Snippets Groups Projects
Commit e3cf2672 authored by Peter Matta's avatar Peter Matta
Browse files

Sema of while and for loops

parent 1829e6fd
No related branches found
No related tags found
No related merge requests found
extern func test(); extern func test();
extern func println(output: Int) -> Void;
   
func main(arg1: Int) -> Int { func main(arg1: Int) -> Int {
if arg1 % 2 != 0 { for i in 0..arg1 {
return inc(arg1); println(i);
if i > 5 {
break;
}
break;
} }
return arg1; return 0;
} }
   
func inc(i: Int) -> Int { func inc(i: Int) -> Int {
......
...@@ -176,7 +176,7 @@ class ForStmt : public Stmt { ...@@ -176,7 +176,7 @@ class ForStmt : public Stmt {
SMLoc ForLoc; SMLoc ForLoc;
   
/// Iterabling variable /// Iterabling variable
Expr *Var; Decl *Iter;
   
/// For-in range statement /// For-in range statement
Stmt *Range; Stmt *Range;
...@@ -185,9 +185,9 @@ class ForStmt : public Stmt { ...@@ -185,9 +185,9 @@ class ForStmt : public Stmt {
Stmt *Body; Stmt *Body;
   
public: public:
ForStmt(SMLoc FL, Expr *V, Stmt *R, Stmt *C); ForStmt(SMLoc FL, Decl *V, Stmt *R, Stmt *C);
   
Expr *getVar() const { return Var; } Decl *getIter() const { return Iter; }
Stmt *getRange() const { return Range; } Stmt *getRange() const { return Range; }
Stmt *getBody() const { return Body; } Stmt *getBody() const { return Body; }
   
......
...@@ -84,8 +84,6 @@ public: ...@@ -84,8 +84,6 @@ public:
bool isBinaryOperator() const { bool isBinaryOperator() const {
switch (Kind) { switch (Kind) {
case tok::assign: case tok::assign:
case tok::elipsis_excl:
case tok::elipsis_incl:
case tok::land: case tok::land:
case tok::lor: case tok::lor:
case tok::equals: case tok::equals:
...@@ -150,10 +148,6 @@ public: ...@@ -150,10 +148,6 @@ public:
case tok::assign: case tok::assign:
return 5; return 5;
   
case tok::elipsis_excl:
case tok::elipsis_incl:
return 10;
case tok::land: case tok::land:
case tok::lor: case tok::lor:
return 20; return 20;
......
...@@ -46,9 +46,6 @@ public: ...@@ -46,9 +46,6 @@ public:
/// Returns variable for given name, if found, \c nullptr otherwise. /// Returns variable for given name, if found, \c nullptr otherwise.
Decl *getVar(StringRef Str) const; Decl *getVar(StringRef Str) const;
/// Returns variable for given name, if found, \c nullptr otherwise.
Decl *getVar(StringRef Str);
/// Returns variable for given name, if found, \c nullptr otherwise. /// Returns variable for given name, if found, \c nullptr otherwise.
Decl *get(StringRef Str) const; Decl *get(StringRef Str) const;
......
...@@ -228,7 +228,7 @@ public: ...@@ -228,7 +228,7 @@ public:
Printer.printStmtPre(S); Printer.printStmtPre(S);
   
Printer << tok::kwFor << " "; Printer << tok::kwFor << " ";
super::visit(S->getVar()); super::visit(S->getIter());
Printer << " " << tok::kwIn << " "; Printer << " " << tok::kwIn << " ";
super::visit(S->getRange()); super::visit(S->getRange());
Printer << " "; Printer << " ";
......
...@@ -76,8 +76,8 @@ SMRange FuncStmt::getSourceRange() const { ...@@ -76,8 +76,8 @@ SMRange FuncStmt::getSourceRange() const {
   
// MARK: Fot-in statement // MARK: Fot-in statement
   
ForStmt::ForStmt(SMLoc FL, Expr *V, Stmt *R, Stmt *B) ForStmt::ForStmt(SMLoc FL, Decl *V, Stmt *R, Stmt *B)
: Stmt(StmtKind::For), ForLoc(FL), Var(V), Range(R), Body(B) {} : Stmt(StmtKind::For), ForLoc(FL), Iter(V), Range(R), Body(B) {}
   
SMRange ForStmt::getSourceRange() const { return {ForLoc, Body->getLocEnd()}; } SMRange ForStmt::getSourceRange() const { return {ForLoc, Body->getLocEnd()}; }
   
......
...@@ -199,16 +199,19 @@ Stmt *Parser::parseFuncStmt() { ...@@ -199,16 +199,19 @@ Stmt *Parser::parseFuncStmt() {
return nullptr; return nullptr;
} }
   
/// ForStmt ::=
/// 'for' identifier 'in' Expr ('..' | '...') Expr Block
Stmt *Parser::parseForStmt() { Stmt *Parser::parseForStmt() {
// Validate `for` keyword. // Validate `for` keyword.
assert(Tok.is(tok::kwFor) && "Invalid parse method"); assert(Tok.is(tok::kwFor) && "Invalid parse method");
auto FLoc = consumeToken(); auto FLoc = consumeToken();
if (!Tok.is(tok::identifier)) { auto Ident = Tok;
diagnose(Tok.getLoc(), diag::DiagID::expected_identifier); if (!consumeIf(tok::identifier)) {
diagnose(Tok.getLoc(), diag::expected_identifier);
return nullptr; return nullptr;
} }
   
auto Var = parseIdentifierExpr(); auto Var = makeNode<ParamDecl>(Ident.getText(), Ident.getLoc());
if (!consumeIf(tok::kwIn)) { if (!consumeIf(tok::kwIn)) {
diagnose(Tok.getLoc(), diag::DiagID::expected_in_kw) diagnose(Tok.getLoc(), diag::DiagID::expected_in_kw)
.fixItBefore("in", Tok.getLoc()); .fixItBefore("in", Tok.getLoc());
......
...@@ -39,16 +39,6 @@ Decl *ContextImpl::getVar(StringRef Str) const { ...@@ -39,16 +39,6 @@ Decl *ContextImpl::getVar(StringRef Str) const {
return nullptr; return nullptr;
} }
   
Decl *ContextImpl::getVar(StringRef Str) {
auto Var = Vars.find(Str);
if (Var != Vars.end())
return Var->second;
if (Parent != nullptr)
return Parent->getVar(Str);
return nullptr;
}
Decl *ContextImpl::get(StringRef Str) const { Decl *ContextImpl::get(StringRef Str) const {
if (auto Var = getVar(Str)) if (auto Var = getVar(Str))
return Var; return Var;
......
//===--- Sema.cpp ---------------------------------------------------------===// //===--- Sema.cpp ---------------------------------------------------------===//
// //
// dusk-lang // dusk-lang
...@@ -22,17 +21,16 @@ ...@@ -22,17 +21,16 @@
   
#include "TypeChecker.h" #include "TypeChecker.h"
   
using namespace dusk; using namespace dusk;
using namespace sema; using namespace sema;
   
namespace { namespace {
class FwdDeclarator: public ASTWalker { class FwdDeclarator : public ASTWalker {
Sema &S; Sema &S;
Context &Ctx; Context &Ctx;
DiagnosticEngine &Diag; DiagnosticEngine &Diag;
public: public:
FwdDeclarator(Sema &S, Context &C, DiagnosticEngine &D) FwdDeclarator(Sema &S, Context &C, DiagnosticEngine &D)
: S(S), Ctx(C), Diag(D) {} : S(S), Ctx(C), Diag(D) {}
...@@ -44,7 +42,7 @@ public: ...@@ -44,7 +42,7 @@ public:
return true; return true;
return false; return false;
} }
virtual bool postWalk(Decl *D) override { virtual bool postWalk(Decl *D) override {
if (auto FD = dynamic_cast<FuncDecl *>(D)) { if (auto FD = dynamic_cast<FuncDecl *>(D)) {
if (!Ctx.declareFunc(D)) { if (!Ctx.declareFunc(D)) {
...@@ -56,24 +54,23 @@ public: ...@@ -56,24 +54,23 @@ public:
} }
return true; return true;
} }
// Skip all expressions. // Skip all expressions.
virtual bool preWalk(Expr *E) override { return false; } virtual bool preWalk(Expr *E) override { return false; }
virtual bool preWalk(Stmt *S) override { virtual bool preWalk(Stmt *S) override {
switch (S->getKind()) { switch (S->getKind()) {
case StmtKind::Func: case StmtKind::Func:
case StmtKind::Extern: case StmtKind::Extern:
return true; return true;
// Skip all non-func related statements. // Skip all non-func related statements.
default: default:
return false; return false;
} }
} }
}; };
} // anonymous namespace
   
} // anonymous namespace
   
Sema::Sema(ASTContext &C, DiagnosticEngine &D) : Ctx(C), Diag(D) {} Sema::Sema(ASTContext &C, DiagnosticEngine &D) : Ctx(C), Diag(D) {}
   
...@@ -117,10 +114,10 @@ Type *Sema::typeReprResolve(FuncDecl *FD) { ...@@ -117,10 +114,10 @@ Type *Sema::typeReprResolve(FuncDecl *FD) {
llvm::SmallVector<Type *, 128> Args; llvm::SmallVector<Type *, 128> Args;
for (auto Arg : FD->getArgs()->getVars()) for (auto Arg : FD->getArgs()->getVars())
Args.push_back(typeReprResolve(Arg->getTypeRepr())); Args.push_back(typeReprResolve(Arg->getTypeRepr()));
auto ArgsT = std::make_unique<PatternType>(std::move(Args)); auto ArgsT = std::make_unique<PatternType>(std::move(Args));
auto ArgsTT = Ctx.pushType(std::move(ArgsT)); auto ArgsTT = Ctx.pushType(std::move(ArgsT));
Type *RetT = nullptr; Type *RetT = nullptr;
if (!FD->hasTypeRepr()) { if (!FD->hasTypeRepr()) {
auto F = std::make_unique<VoidType>(); auto F = std::make_unique<VoidType>();
...@@ -128,9 +125,8 @@ Type *Sema::typeReprResolve(FuncDecl *FD) { ...@@ -128,9 +125,8 @@ Type *Sema::typeReprResolve(FuncDecl *FD) {
} else { } else {
RetT = typeReprResolve(FD->getTypeRepr()); RetT = typeReprResolve(FD->getTypeRepr());
} }
auto Ty = std::make_unique<FunctionType>(ArgsTT, RetT); auto Ty = std::make_unique<FunctionType>(ArgsTT, RetT);
return Ctx.pushType(std::move(Ty)); return Ctx.pushType(std::move(Ty));
} }
   
...@@ -41,7 +41,8 @@ bool TypeChecker::preWalkVarDecl(VarDecl *D) { ...@@ -41,7 +41,8 @@ bool TypeChecker::preWalkVarDecl(VarDecl *D) {
} }
   
bool TypeChecker::preWalkParamDecl(ParamDecl *D) { bool TypeChecker::preWalkParamDecl(ParamDecl *D) {
D->setType(S.typeReprResolve(D->getTypeRepr())); if (D->hasTypeRepr())
D->setType(S.typeReprResolve(D->getTypeRepr()));
return false; return false;
} }
   
...@@ -99,12 +100,7 @@ bool TypeChecker::postWalkVarDecl(VarDecl *D) { ...@@ -99,12 +100,7 @@ bool TypeChecker::postWalkVarDecl(VarDecl *D) {
} }
   
bool TypeChecker::postWalkParamDecl(ParamDecl *D) { bool TypeChecker::postWalkParamDecl(ParamDecl *D) {
// Check if has resolved type return D->getType() != nullptr;
if (!D->getType())
return false;
// No default value, therefore don't have a reference to match against.
return DeclCtx.declareLet(D);
} }
   
bool TypeChecker::postWalkFuncDecl(FuncDecl *D) { bool TypeChecker::postWalkFuncDecl(FuncDecl *D) {
......
...@@ -39,7 +39,19 @@ bool TypeChecker::preWalkBlockStmt(BlockStmt *S) { ...@@ -39,7 +39,19 @@ bool TypeChecker::preWalkBlockStmt(BlockStmt *S) {
auto Proto = static_cast<FuncDecl *>(Fn->getPrototype()); auto Proto = static_cast<FuncDecl *>(Fn->getPrototype());
auto Args = static_cast<VarPattern *>(Proto->getArgs()); auto Args = static_cast<VarPattern *>(Proto->getArgs());
for (auto Arg : Args->getVars()) for (auto Arg : Args->getVars())
DeclCtx.declareLet(Arg); if (!DeclCtx.declareLet(Arg)) {
Diag.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());
DeclCtx.declareLet(Iter);
} }
Scp.push(Scope(&Scp.top(), Scope::BlockScope, S)); Scp.push(Scope(&Scp.top(), Scope::BlockScope, S));
return true; return true;
...@@ -52,7 +64,7 @@ bool TypeChecker::preWalkExternStmt(ExternStmt *S) { ...@@ -52,7 +64,7 @@ bool TypeChecker::preWalkExternStmt(ExternStmt *S) {
} }
   
bool TypeChecker::preWalkForStmt(ForStmt *S) { bool TypeChecker::preWalkForStmt(ForStmt *S) {
Scp.push(Scope(&Scp.top(), Scope::ControlScope, S)); Scp.push(Scope(&Scp.top(), Scope::ControlScope | Scope::BreakScope, S));
return true; return true;
} }
   
...@@ -62,13 +74,13 @@ bool TypeChecker::preWalkFuncStmt(FuncStmt *S) { ...@@ -62,13 +74,13 @@ bool TypeChecker::preWalkFuncStmt(FuncStmt *S) {
} }
   
bool TypeChecker::preWalkIfStmt(IfStmt *S) { bool TypeChecker::preWalkIfStmt(IfStmt *S) {
Scp.push(Scope(&Scp.top(), 0, S)); Scp.push(Scope(&Scp.top(), Scope::ControlScope, S));
return true; return true;
} }
   
bool TypeChecker::preWalkWhileStmt(WhileStmt *S) { bool TypeChecker::preWalkWhileStmt(WhileStmt *S) {
Scp.push(Scope(&Scp.top(), Scope::ControlScope, S)); Scp.push(Scope(&Scp.top(), Scope::ControlScope | Scope::BreakScope, S));
return false; return true;
} }
   
   
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment