Skip to content

Commit

Permalink
Implement continues.
Browse files Browse the repository at this point in the history
  • Loading branch information
Vlamonster committed Oct 30, 2023
1 parent fd0a294 commit 696c335
Show file tree
Hide file tree
Showing 14 changed files with 700 additions and 612 deletions.
5 changes: 4 additions & 1 deletion compiler/src/passes/atomize/atomize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::passes::reveal_functions::{PrgRevealed, RExpr};
use crate::utils::gen_sym::{gen_sym, UniqueSym};

impl<'p> PrgRevealed<'p> {
#[must_use]
pub fn atomize(self) -> PrgAtomized<'p> {
PrgAtomized {
defs: self
Expand Down Expand Up @@ -99,6 +100,7 @@ fn atomize_expr(expr: RExpr) -> AExpr {
sym,
bnd: Box::new(atomize_expr(*bnd)),
},
RExpr::Continue => AExpr::Continue,
}
}

Expand All @@ -114,7 +116,8 @@ fn atomize_atom(expr: RExpr) -> (Atom, Option<(UniqueSym, AExpr)>) {
| RExpr::Break { .. }
| RExpr::Seq { .. }
| RExpr::Assign { .. }
| RExpr::Var { .. } => {
| RExpr::Var { .. }
| RExpr::Continue => {
let tmp = gen_sym("tmp");
(Atom::Var { sym: tmp }, Some((tmp, atomize_expr(expr))))
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/src/passes/atomize/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ pub enum AExpr<'p> {
Break {
bdy: Box<AExpr<'p>>,
},
Continue,
Seq {
stmt: Box<AExpr<'p>>,
cnt: Box<AExpr<'p>>,
Expand Down Expand Up @@ -129,6 +130,7 @@ impl<'p> From<AExpr<'p>> for Expr<UniqueSym<'p>> {
sym,
bnd: Box::new((*bnd).into()),
},
AExpr::Continue => Expr::Continue,
}
}
}
Expand Down
1 change: 1 addition & 0 deletions compiler/src/passes/conclude/conclude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::utils::gen_sym::gen_sym;
use crate::{addq, block, callq_direct, imm, movq, popq, pushq, reg, subq};

impl<'p> X86Patched<'p> {
#[must_use]
pub fn conclude(mut self) -> X86Concluded<'p> {
let entry = gen_sym("main");
self.blocks.insert(
Expand Down
1 change: 1 addition & 0 deletions compiler/src/passes/emit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use crate::utils::gen_sym::UniqueSym;
use std::collections::HashMap;

impl<'p> X86Concluded<'p> {
#[must_use]
pub fn emit(self) -> (usize, Vec<u8>) {
let mut machine_code = Vec::new();

Expand Down
11 changes: 10 additions & 1 deletion compiler/src/passes/explicate/explicate.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::passes::atomize::{AExpr, Atom, PrgAtomized};
use crate::passes::explicate::Tail::Goto;
use crate::passes::explicate::{CExpr, PrgExplicated, Tail};
use crate::passes::parse::{Def, Lit, Op};
use crate::utils::gen_sym::{gen_sym, UniqueSym};
Expand All @@ -8,6 +9,8 @@ struct Env<'a, 'p> {
blocks: &'a mut HashMap<UniqueSym<'p>, Tail<'p>>,
/// (block to jump to, variable to write to)
break_target: Option<(UniqueSym<'p>, UniqueSym<'p>)>,
/// block to jump to
continue_target: Option<UniqueSym<'p>>,
}

impl<'p> PrgAtomized<'p> {
Expand All @@ -17,6 +20,7 @@ impl<'p> PrgAtomized<'p> {
let mut env = Env {
blocks: &mut blocks,
break_target: None,
continue_target: None,
};

let fn_params = self
Expand Down Expand Up @@ -111,6 +115,7 @@ fn explicate_assign<'p>(
let mut env = Env {
blocks: env.blocks,
break_target: Some((tail, sym)),
continue_target: Some(loop_block_sym),
};

let loop_block = explicate_assign(
Expand Down Expand Up @@ -153,6 +158,9 @@ fn explicate_assign<'p>(
),
env,
),
AExpr::Continue => Goto {
lbl: env.continue_target.unwrap(),
},
}
}

Expand Down Expand Up @@ -287,6 +295,7 @@ fn explicate_pred<'p>(
},
}
| AExpr::Assign { .. }
| AExpr::Break { .. } => unreachable!(),
| AExpr::Break { .. }
| AExpr::Continue => unreachable!(),
}
}
4 changes: 3 additions & 1 deletion compiler/src/passes/parse/grammar.lalrpop
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::str::FromStr;
use crate::passes::parse::{Def, Expr, Lit, Op, Param}
use crate::passes::parse::{Def, Expr, Lit, Op, Param};
use crate::passes::parse::PrgParsed;
use crate::passes::type_check::Type;

Expand All @@ -14,6 +14,7 @@ match {
"loop",
"while",
"break",
"continue",
"mut",

// Structural tokens
Expand Down Expand Up @@ -172,6 +173,7 @@ ExprInStmt: Expr<&'input str> = {
"break" <bdy:ExprLogicalOr?> => Expr::Break {
bdy: Box::new(bdy.unwrap_or(Expr::Lit { val: Lit::Unit })),
},
"continue" => Expr::Continue,
ExprLogicalOr,
}

Expand Down
1,251 changes: 648 additions & 603 deletions compiler/src/passes/parse/grammar.rs

Large diffs are not rendered by default.

13 changes: 7 additions & 6 deletions compiler/src/passes/parse/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ use std::hash::Hash;
pub enum ControlFlow<A: Copy + Hash + Eq + Display> {
Val(Val<A>),
Break(Val<A>),
Continue,
}

impl<A: Copy + Hash + Eq + Display> ControlFlow<A> {
pub fn val(self) -> Val<A> {
match self {
ControlFlow::Val(v) => v,
ControlFlow::Break(_) => panic!("Sterf"),
ControlFlow::Break(_) | ControlFlow::Continue => panic!("Sterf"),
}
}
}
Expand All @@ -24,8 +25,8 @@ macro_rules! b {
($e: expr) => {{
let e = $e;
match e {
ControlFlow::Break(_) => return e,
ControlFlow::Val(x) => x,
ControlFlow::Break(_) | ControlFlow::Continue => return e,
ControlFlow::Val(val) => val,
}
}};
}
Expand Down Expand Up @@ -178,9 +179,8 @@ impl<A: Copy + Hash + Eq + Debug + Display> PrgGenericVar<A> {
self.interpret_fn(sym, args, scope, io)
}
Expr::Loop { bdy } => loop {
let x = self.interpret_expr(bdy, scope, io);
if let ControlFlow::Break(x) = x {
return ControlFlow::Val(x);
if let ControlFlow::Break(val) = self.interpret_expr(bdy, scope, io) {
return ControlFlow::Val(val);
}
},
Expr::Break { bdy } => {
Expand All @@ -195,6 +195,7 @@ impl<A: Copy + Hash + Eq + Debug + Display> PrgGenericVar<A> {
scope.0.insert(*sym, bnd);
Val::Unit
}
Expr::Continue => return ControlFlow::Continue,
})
}
}
Expand Down
1 change: 1 addition & 0 deletions compiler/src/passes/parse/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ pub enum Expr<A: Copy + Hash + Eq> {
Break {
bdy: Box<Expr<A>>,
},
Continue,
Seq {
stmt: Box<Expr<A>>,
cnt: Box<Expr<A>>,
Expand Down
2 changes: 2 additions & 0 deletions compiler/src/passes/reveal_functions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ pub enum RExpr<'p> {
Break {
bdy: Box<RExpr<'p>>,
},
Continue,
Seq {
stmt: Box<RExpr<'p>>,
cnt: Box<RExpr<'p>>,
Expand Down Expand Up @@ -126,6 +127,7 @@ impl<'p> From<RExpr<'p>> for Expr<UniqueSym<'p>> {
sym,
bnd: Box::new((*bnd).into()),
},
RExpr::Continue => Expr::Continue,
}
}
}
Expand Down
1 change: 1 addition & 0 deletions compiler/src/passes/reveal_functions/reveal_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,5 +87,6 @@ fn reveal_expr<'p>(expr: Expr<UniqueSym<'p>>, scope: &mut PushMap<UniqueSym<'p>,
sym,
bnd: Box::new(reveal_expr(*bnd, scope)),
},
Expr::Continue => RExpr::Continue,
}
}
1 change: 1 addition & 0 deletions compiler/src/passes/type_check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ fn type_check_expr<'p>(expr: &Expr<&'p str>, env: &mut Env<'_, 'p>) -> Result<Ty
expect_type(bnd, typ, env)?;
Ok(Type::Unit)
}
Expr::Continue => Ok(Type::Never),
}
}

Expand Down
1 change: 1 addition & 0 deletions compiler/src/passes/uniquify/uniquify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,5 +110,6 @@ fn uniquify_expression<'p>(
sym: scope[sym],
bnd: Box::new(uniquify_expression(*bnd, scope)),
},
Expr::Continue => Expr::Continue,
}
}
18 changes: 18 additions & 0 deletions programs/good/loops/while_continue.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
1 2 3 4 5 6 7 8 9 10 0
#
#
30
#
fn main() -> Int {
let mut x = 0;
let mut sum = 0;
while (x = read(); x != 0) {
if x % 2 == 0 {
unit
} else {
continue;
};
sum = sum + x
};
sum
}

0 comments on commit 696c335

Please sign in to comment.