diff --git a/examples/funcDecl.dusk b/examples/funcDecl.dusk
index 9c558bc77b71d4716ad9b0f3ba9ca051239b4041..b67f82850ebb23101c7c132d9664b1cd24522154 100644
--- a/examples/funcDecl.dusk
+++ b/examples/funcDecl.dusk
@@ -1,10 +1,15 @@
 extern func test();
+extern func println(output: Int) -> Void;
 
 func main(arg1: Int) -> Int {
-    if arg1 % 2 != 0 {
-        return inc(arg1);
+    for i in 0..arg1 {
+        println(i);
+        if i > 5 {
+            break;
+        }
+        break;
     }
-    return arg1;
+    return 0;
 }
 
 func inc(i: Int) -> Int {
diff --git a/include/dusk/AST/Stmt.h b/include/dusk/AST/Stmt.h
index ac10dca241be6565efd8190d6dee28ce00b7c31b..ade30dc290f34b19a16ddeb4c3d9705717aa3c74 100644
--- a/include/dusk/AST/Stmt.h
+++ b/include/dusk/AST/Stmt.h
@@ -176,7 +176,7 @@ class ForStmt : public Stmt {
   SMLoc ForLoc;
 
   /// Iterabling variable
-  Expr *Var;
+  Decl *Iter;
 
   /// For-in range statement
   Stmt *Range;
@@ -185,9 +185,9 @@ class ForStmt : public Stmt {
   Stmt *Body;
 
 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 *getBody() const { return Body; }
 
diff --git a/include/dusk/Parse/Token.h b/include/dusk/Parse/Token.h
index 158308547e04dc24d2b092df411a8840cfc20a3c..bcea3580f4c104a64e36207cbf1a232908309c7f 100644
--- a/include/dusk/Parse/Token.h
+++ b/include/dusk/Parse/Token.h
@@ -84,8 +84,6 @@ public:
   bool isBinaryOperator() const {
     switch (Kind) {
     case tok::assign:
-    case tok::elipsis_excl:
-    case tok::elipsis_incl:
     case tok::land:
     case tok::lor:
     case tok::equals:
@@ -150,10 +148,6 @@ public:
     case tok::assign:
       return 5;
 
-    case tok::elipsis_excl:
-    case tok::elipsis_incl:
-      return 10;
-
     case tok::land:
     case tok::lor:
       return 20;
diff --git a/include/dusk/Sema/Context.h b/include/dusk/Sema/Context.h
index df3e54ebf43877ed549ae4eb959ef7ee5a00d416..3c3a08c415cb06b8dd24742d3ed87f4b7e66588a 100644
--- a/include/dusk/Sema/Context.h
+++ b/include/dusk/Sema/Context.h
@@ -46,9 +46,6 @@ public:
   /// Returns variable for given name, if found, \c nullptr otherwise.
   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.
   Decl *get(StringRef Str) const;
   
diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp
index 53a9644e36199a723919de182a43d7db67f5ded8..5f68351d549cbcdf872cf1072547955c1832004b 100644
--- a/lib/AST/ASTPrinter.cpp
+++ b/lib/AST/ASTPrinter.cpp
@@ -228,7 +228,7 @@ public:
     Printer.printStmtPre(S);
 
     Printer << tok::kwFor << " ";
-    super::visit(S->getVar());
+    super::visit(S->getIter());
     Printer << " " << tok::kwIn << " ";
     super::visit(S->getRange());
     Printer << " ";
diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp
index f449fed52a99957682157f7dc34aaf3a9f5202cc..36527857cc3b11d6e32b2accca4a5101f3c3cba8 100644
--- a/lib/AST/Stmt.cpp
+++ b/lib/AST/Stmt.cpp
@@ -76,8 +76,8 @@ SMRange FuncStmt::getSourceRange() const {
 
 // MARK: Fot-in statement
 
-ForStmt::ForStmt(SMLoc FL, Expr *V, Stmt *R, Stmt *B)
-    : Stmt(StmtKind::For), ForLoc(FL), Var(V), Range(R), Body(B) {}
+ForStmt::ForStmt(SMLoc FL, Decl *V, Stmt *R, Stmt *B)
+    : Stmt(StmtKind::For), ForLoc(FL), Iter(V), Range(R), Body(B) {}
 
 SMRange ForStmt::getSourceRange() const { return {ForLoc, Body->getLocEnd()}; }
 
diff --git a/lib/Parser/ParseStmt.cpp b/lib/Parser/ParseStmt.cpp
index ec0e39f637bab47219460a6d4b1836fd2e0fc1eb..1529d9d092bf57a3d0d0e06db3b3be3e14b1c4b8 100644
--- a/lib/Parser/ParseStmt.cpp
+++ b/lib/Parser/ParseStmt.cpp
@@ -199,16 +199,19 @@ Stmt *Parser::parseFuncStmt() {
   return nullptr;
 }
 
+/// ForStmt ::=
+///     'for' identifier 'in' Expr ('..' | '...') Expr Block
 Stmt *Parser::parseForStmt() {
   // Validate `for` keyword.
   assert(Tok.is(tok::kwFor) && "Invalid parse method");
   auto FLoc = consumeToken();
-  if (!Tok.is(tok::identifier)) {
-    diagnose(Tok.getLoc(), diag::DiagID::expected_identifier);
+  auto Ident = Tok;
+  if (!consumeIf(tok::identifier)) {
+    diagnose(Tok.getLoc(), diag::expected_identifier);
     return nullptr;
   }
 
-  auto Var = parseIdentifierExpr();
+  auto Var = makeNode<ParamDecl>(Ident.getText(), Ident.getLoc());
   if (!consumeIf(tok::kwIn)) {
     diagnose(Tok.getLoc(), diag::DiagID::expected_in_kw)
       .fixItBefore("in", Tok.getLoc());
diff --git a/lib/Sema/Context.cpp b/lib/Sema/Context.cpp
index 6fde8fc8a91ec1d463eb3c81e0a95dbdafcf9d56..f979db6012c23e5968691284032037835e187d2d 100644
--- a/lib/Sema/Context.cpp
+++ b/lib/Sema/Context.cpp
@@ -39,16 +39,6 @@ Decl *ContextImpl::getVar(StringRef Str) const {
   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 {
   if (auto Var = getVar(Str))
     return Var;
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index 42639f52f044000bae980d2fafa76a9dff645310..7b93672ab6d824538dd570936cc2816c35f6dcf3 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -1,4 +1,3 @@
-
 //===--- Sema.cpp ---------------------------------------------------------===//
 //
 //                                 dusk-lang
@@ -22,17 +21,16 @@
 
 #include "TypeChecker.h"
 
-
 using namespace dusk;
 using namespace sema;
 
 namespace {
-  
-class FwdDeclarator: public ASTWalker {
+
+class FwdDeclarator : public ASTWalker {
   Sema &S;
   Context &Ctx;
   DiagnosticEngine &Diag;
-  
+
 public:
   FwdDeclarator(Sema &S, Context &C, DiagnosticEngine &D)
       : S(S), Ctx(C), Diag(D) {}
@@ -44,7 +42,7 @@ public:
       return true;
     return false;
   }
-  
+
   virtual bool postWalk(Decl *D) override {
     if (auto FD = dynamic_cast<FuncDecl *>(D)) {
       if (!Ctx.declareFunc(D)) {
@@ -56,24 +54,23 @@ public:
     }
     return true;
   }
-  
+
   // Skip all expressions.
   virtual bool preWalk(Expr *E) override { return false; }
   virtual 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;
+    case StmtKind::Func:
+    case StmtKind::Extern:
+      return true;
+
+    // Skip all non-func related statements.
+    default:
+      return false;
     }
   }
 };
-  
-} // anonymous namespace
 
+} // anonymous namespace
 
 Sema::Sema(ASTContext &C, DiagnosticEngine &D) : Ctx(C), Diag(D) {}
 
@@ -117,10 +114,10 @@ Type *Sema::typeReprResolve(FuncDecl *FD) {
   llvm::SmallVector<Type *, 128> Args;
   for (auto Arg : FD->getArgs()->getVars())
     Args.push_back(typeReprResolve(Arg->getTypeRepr()));
-  
+
   auto ArgsT = std::make_unique<PatternType>(std::move(Args));
   auto ArgsTT = Ctx.pushType(std::move(ArgsT));
-  
+
   Type *RetT = nullptr;
   if (!FD->hasTypeRepr()) {
     auto F = std::make_unique<VoidType>();
@@ -128,9 +125,8 @@ Type *Sema::typeReprResolve(FuncDecl *FD) {
   } else {
     RetT = typeReprResolve(FD->getTypeRepr());
   }
-  
+
   auto Ty = std::make_unique<FunctionType>(ArgsTT, RetT);
   return Ctx.pushType(std::move(Ty));
 }
 
-
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index 09791168a2f4c287868f6e239d2a1fc62dbabdbc..8c1492d75a99b34accc94d290d0a466f42fac3e7 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -41,7 +41,8 @@ bool TypeChecker::preWalkVarDecl(VarDecl *D) {
 }
 
 bool TypeChecker::preWalkParamDecl(ParamDecl *D) {
-  D->setType(S.typeReprResolve(D->getTypeRepr()));
+  if (D->hasTypeRepr())
+    D->setType(S.typeReprResolve(D->getTypeRepr()));
   return false;
 }
 
@@ -99,12 +100,7 @@ bool TypeChecker::postWalkVarDecl(VarDecl *D) {
 }
 
 bool TypeChecker::postWalkParamDecl(ParamDecl *D) {
-  // Check if has resolved type
-  if (!D->getType())
-    return false;
-  
-  // No default value, therefore don't have a reference to match against.
-  return DeclCtx.declareLet(D);
+  return D->getType() != nullptr;
 }
 
 bool TypeChecker::postWalkFuncDecl(FuncDecl *D) {
diff --git a/lib/Sema/TypeCheckStmt.cpp b/lib/Sema/TypeCheckStmt.cpp
index 348ef69f7b8e842741f116bbe4779e54e2b3280a..8276b782ac71835e325fb13d56670b40e67f0434 100644
--- a/lib/Sema/TypeCheckStmt.cpp
+++ b/lib/Sema/TypeCheckStmt.cpp
@@ -39,7 +39,19 @@ bool TypeChecker::preWalkBlockStmt(BlockStmt *S) {
     auto Proto = static_cast<FuncDecl *>(Fn->getPrototype());
     auto Args = static_cast<VarPattern *>(Proto->getArgs());
     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));
   return true;
@@ -52,7 +64,7 @@ bool TypeChecker::preWalkExternStmt(ExternStmt *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;
 }
 
@@ -62,13 +74,13 @@ bool TypeChecker::preWalkFuncStmt(FuncStmt *S) {
 }
 
 bool TypeChecker::preWalkIfStmt(IfStmt *S) {
-  Scp.push(Scope(&Scp.top(), 0, S));
+  Scp.push(Scope(&Scp.top(), Scope::ControlScope, S));
   return true;
 }
 
 bool TypeChecker::preWalkWhileStmt(WhileStmt *S) {
-  Scp.push(Scope(&Scp.top(), Scope::ControlScope, S));
-  return false;
+  Scp.push(Scope(&Scp.top(), Scope::ControlScope | Scope::BreakScope, S));
+  return true;
 }