diff --git a/juno_frontend/src/lang.l b/juno_frontend/src/lang.l
index 4039ef0a32b89742254be2d69b5c0f15f395abfb..6399e5f266640966ce660c5ec28c9c5c5be2beb2 100644
--- a/juno_frontend/src/lang.l
+++ b/juno_frontend/src/lang.l
@@ -28,6 +28,7 @@ for      "for"
 if       "if"
 inout    "inout"
 integer  "integer"
+in       "in"
 let      "let"
 match    "match"
 mod      "mod"
diff --git a/juno_frontend/src/lang.y b/juno_frontend/src/lang.y
index 7efc01256c68ad07cc8234475bfebba3f7294104..a5b82452d5aa588782dd01396c208ef2d159be45 100644
--- a/juno_frontend/src/lang.y
+++ b/juno_frontend/src/lang.y
@@ -292,11 +292,17 @@ Stmt -> Result<Stmt, ()>
   | 'match' NonStructExpr Cases
       { Ok(Stmt::MatchStmt{ span : $span, expr : $2?, body : $3? }) }
   | 'for' VarBind '=' NonStructExpr 'to' NonStructExpr Stmts
-      { Ok(Stmt::ForStmt{ span : $span, var : $2?, init : $4?, bound : $6?, step : None,
-                          body : Box::new($7?) }) }
+      { Ok(Stmt::ForStmt{ span : $span, var : $2?, init : $4?, bound : $6?,
+                          inclusive: false, step : None, body : Box::new($7?) }) }
   | 'for' VarBind '=' NonStructExpr 'to' NonStructExpr 'by' SignedIntLit Stmts
-      { Ok(Stmt::ForStmt{ span : $span, var : $2?, init : $4?, bound : $6?, step : Some($8?),
-                          body : Box::new($9?) }) }
+      { Ok(Stmt::ForStmt{ span : $span, var : $2?, init : $4?, bound : $6?,
+                          inclusive: false, step : Some($8?), body : Box::new($9?) }) }
+  | 'for' VarBind 'in' NonStructExpr '..' NonStructExpr Stmts
+      { Ok(Stmt::ForStmt{ span: $span, var: $2?, init: $4?, bound: $6?,
+                          inclusive: false, step: None, body: Box::new($7?) }) }
+  | 'for' VarBind 'in' NonStructExpr '..' '=' NonStructExpr Stmts
+      { Ok(Stmt::ForStmt{ span: $span, var: $2?, init: $4?, bound: $7?,
+                          inclusive: false, step: None, body: Box::new($8?) }) }
   | 'while' NonStructExpr Stmts
       { Ok(Stmt::WhileStmt{ span : $span, cond : $2?, body : Box::new($3?) }) }
   | 'return' ';'
@@ -687,9 +693,9 @@ pub enum Stmt {
   AssignStmt { span : Span, lhs : LExpr, assign : AssignOp, assign_span : Span, rhs : Expr },
   IfStmt     { span : Span, cond : Expr, thn : Box<Stmt>, els : Option<Box<Stmt>> },
   MatchStmt  { span : Span, expr : Expr, body : Vec<Case> },
-  // The step records: negative, number, base
-  ForStmt    { span : Span, var : VarBind, init : Expr, bound : Expr, step : Option<(bool, Span, IntBase)>,
-               body : Box<Stmt> },
+  // The step records: negative, number, base, inclusive records whether the bound is included in the range
+  ForStmt    { span : Span, var : VarBind, init : Expr, bound : Expr,
+               inclusive: bool, step : Option<(bool, Span, IntBase)>, body : Box<Stmt> },
   WhileStmt  { span : Span, cond : Expr, body : Box<Stmt> },
   ReturnStmt { span : Span, expr : Option<Expr> },
   BreakStmt  { span : Span },
diff --git a/juno_frontend/src/semant.rs b/juno_frontend/src/semant.rs
index 1059229a8f44b5363fae945f0640cd041d140496..bfd4cf7f52f46274db5ad42fd495884fd8195fbd 100644
--- a/juno_frontend/src/semant.rs
+++ b/juno_frontend/src/semant.rs
@@ -1999,6 +1999,7 @@ fn process_stmt(
                 },
             init,
             bound,
+            inclusive,
             step,
             body,
         } => {
@@ -2130,10 +2131,19 @@ fn process_stmt(
                 val: bound_val,
             };
 
-            // The condition of the loop is var < bound, unless the step is negative in which case
-            // it is var > bound
+            // There are four cases for the condition that we generate, though it always takes the
+            // form var OP bound:
+            // 1. The step is positive and the range is exclusive of the bound, OP = <
+            // 2. The step is positive and the range is inclusive of the bound, OP = <=
+            // 3. The step is negative and the range is exclusive of the bound, OP = >
+            // 4. The step is negative and the range is inclusive of the bound, OP = >=
             let condition = Expr::BinaryExp {
-                op: if step_pos { BinaryOp::Lt } else { BinaryOp::Gt },
+                op: match (step_pos, inclusive) {
+                    (true, false) => BinaryOp::Lt,
+                    (true, true) => BinaryOp::Le,
+                    (false, false) => BinaryOp::Gt,
+                    (false, true) => BinaryOp::Ge,
+                },
                 lhs: Box::new(Expr::Variable {
                     var: var,
                     typ: var_type,