mirror of
https://github.com/azur1s/bobbylisp.git
synced 2024-10-16 02:37:40 -05:00
if expression
This commit is contained in:
parent
39b2f10bb5
commit
7ac147de32
9
a.hlm
9
a.hlm
|
@ -1,7 +1,4 @@
|
|||
let x: num = 34,
|
||||
y: num = 35
|
||||
let x: num = 1,
|
||||
y: num = 2,
|
||||
in
|
||||
println(x + y);
|
||||
|
||||
let foo: num = 69;
|
||||
println(foo);
|
||||
println(if x + y == 3 then 69 else 0);
|
|
@ -34,6 +34,11 @@ pub enum Expr {
|
|||
args: Vec<String>,
|
||||
body: Vec<Self>,
|
||||
},
|
||||
If {
|
||||
cond: Box<Self>,
|
||||
t: Box<Self>,
|
||||
f: Box<Self>,
|
||||
},
|
||||
Defines(Vec<(String, Self)>),
|
||||
Return(Box<Self>),
|
||||
}
|
||||
|
@ -93,6 +98,9 @@ impl Display for Expr {
|
|||
write!(f, "))")
|
||||
}
|
||||
},
|
||||
Expr::If { cond, t, f: fe } => {
|
||||
write!(f, "(if {} {} {})", cond, t, fe)
|
||||
},
|
||||
Expr::Defines(defs) => {
|
||||
write!(f, "(defs ")?;
|
||||
for (name, expr) in defs {
|
||||
|
@ -118,4 +126,4 @@ impl Display for Stmt {
|
|||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,11 @@ pub enum JSExpr {
|
|||
args: Vec<String>,
|
||||
body: Vec<Self>,
|
||||
},
|
||||
If {
|
||||
cond: Box<Self>,
|
||||
t: Box<Self>,
|
||||
f: Box<Self>,
|
||||
},
|
||||
Defines(Vec<(String, Self)>),
|
||||
Return(Box<Self>),
|
||||
}
|
||||
|
@ -99,6 +104,9 @@ impl Display for JSExpr {
|
|||
write!(f, "}})")
|
||||
}
|
||||
},
|
||||
JSExpr::If { cond, t, f: fe } => {
|
||||
write!(f, "({} ? {} : {})", cond, t, fe)
|
||||
},
|
||||
JSExpr::Defines(vs) => {
|
||||
write!(f, "let [")?;
|
||||
for (i, (name, _)) in vs.iter().enumerate() {
|
||||
|
|
|
@ -38,6 +38,11 @@ pub enum PExpr {
|
|||
vars: Vec<(String, Type, Spanned<Self>)>,
|
||||
body: Option<Box<Spanned<Self>>>,
|
||||
},
|
||||
If {
|
||||
cond: Box<Spanned<Self>>,
|
||||
t: Box<Spanned<Self>>,
|
||||
f: Box<Spanned<Self>>,
|
||||
},
|
||||
Block(Vec<Spanned<Self>>),
|
||||
Return(Box<Spanned<Self>>),
|
||||
}
|
||||
|
@ -51,4 +56,4 @@ pub enum PStmt {
|
|||
ret: Type,
|
||||
body: Box<Spanned<PExpr>>,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ pub enum Token {
|
|||
Open(Delim), Close(Delim),
|
||||
Lambda, Arrow,
|
||||
|
||||
Let, In, Func, Return,
|
||||
Let, In, Func, Return, If, Then, Else,
|
||||
}
|
||||
|
||||
impl Display for Token {
|
||||
|
@ -67,6 +67,9 @@ impl Display for Token {
|
|||
Token::In => write!(f, "in"),
|
||||
Token::Func => write!(f, "func"),
|
||||
Token::Return => write!(f, "return"),
|
||||
Token::If => write!(f, "if"),
|
||||
Token::Then => write!(f, "then"),
|
||||
Token::Else => write!(f, "else"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -126,6 +129,9 @@ pub fn lexer() -> impl Parser<char, Vec<(Token, Span)>, Error = Simple<char>> {
|
|||
"in" => Token::In,
|
||||
"func" => Token::Func,
|
||||
"return" => Token::Return,
|
||||
"if" => Token::If,
|
||||
"then" => Token::Then,
|
||||
"else" => Token::Else,
|
||||
_ => Token::Sym(s),
|
||||
});
|
||||
|
||||
|
@ -285,6 +291,8 @@ pub fn expr_parser() -> impl P<Spanned<PExpr>> {
|
|||
.then_ignore(just(Token::Assign))
|
||||
.then(expr.clone())
|
||||
.map(|((sym, ty), body)| (sym, ty, body))
|
||||
.boxed()
|
||||
.labelled("let binding")
|
||||
.separated_by(just(Token::Comma))
|
||||
.allow_trailing()
|
||||
.labelled("let bindings");
|
||||
|
@ -322,6 +330,20 @@ pub fn expr_parser() -> impl P<Spanned<PExpr>> {
|
|||
.map(PExpr::Return)
|
||||
.labelled("return");
|
||||
|
||||
let ifelse = just(Token::If)
|
||||
.ignore_then(expr.clone())
|
||||
.then_ignore(just(Token::Then))
|
||||
.then(expr.clone())
|
||||
.then_ignore(just(Token::Else))
|
||||
.then(expr.clone())
|
||||
.map(|((cond, then), f)| PExpr::If {
|
||||
cond: Box::new(cond),
|
||||
t: Box::new(then),
|
||||
f: Box::new(f),
|
||||
})
|
||||
.boxed()
|
||||
.labelled("if else");
|
||||
|
||||
let atom = lit
|
||||
.or(sym)
|
||||
.or(vec)
|
||||
|
@ -331,6 +353,7 @@ pub fn expr_parser() -> impl P<Spanned<PExpr>> {
|
|||
.or(let_def)
|
||||
.or(block)
|
||||
.or(ret)
|
||||
.or(ifelse)
|
||||
.map_with_span(|e, s| (e, s))
|
||||
.boxed()
|
||||
.labelled("atom");
|
||||
|
|
|
@ -93,6 +93,11 @@ pub fn translate_expr(expr: PExpr) -> Expr {
|
|||
}).collect())
|
||||
}
|
||||
},
|
||||
PExpr::If { cond, t, f } => Expr::If {
|
||||
cond: Box::new(translate_expr((*cond).0)),
|
||||
t: Box::new(translate_expr((*t).0)),
|
||||
f: Box::new(translate_expr((*f).0)),
|
||||
},
|
||||
PExpr::Block(es) => {
|
||||
exprs_to_lam(es.into_iter().map(|e| e.0).collect())
|
||||
},
|
||||
|
@ -172,6 +177,11 @@ pub fn translate_js_expr(expr: Expr) -> JSExpr {
|
|||
args,
|
||||
body: body.into_iter().map(translate_js_expr).collect(),
|
||||
},
|
||||
Expr::If { cond, t, f } => JSExpr::If {
|
||||
cond: Box::new(translate_js_expr(*cond)),
|
||||
t: Box::new(translate_js_expr(*t)),
|
||||
f: Box::new(translate_js_expr(*f)),
|
||||
},
|
||||
Expr::Defines(defs) => JSExpr::Defines(defs.into_iter().map(|(name, val)| {
|
||||
(name, translate_js_expr(val))
|
||||
}).collect()),
|
||||
|
|
Loading…
Reference in a new issue