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,
|
let x: num = 1,
|
||||||
y: num = 35
|
y: num = 2,
|
||||||
in
|
in
|
||||||
println(x + y);
|
println(if x + y == 3 then 69 else 0);
|
||||||
|
|
||||||
let foo: num = 69;
|
|
||||||
println(foo);
|
|
|
@ -34,6 +34,11 @@ pub enum Expr {
|
||||||
args: Vec<String>,
|
args: Vec<String>,
|
||||||
body: Vec<Self>,
|
body: Vec<Self>,
|
||||||
},
|
},
|
||||||
|
If {
|
||||||
|
cond: Box<Self>,
|
||||||
|
t: Box<Self>,
|
||||||
|
f: Box<Self>,
|
||||||
|
},
|
||||||
Defines(Vec<(String, Self)>),
|
Defines(Vec<(String, Self)>),
|
||||||
Return(Box<Self>),
|
Return(Box<Self>),
|
||||||
}
|
}
|
||||||
|
@ -93,6 +98,9 @@ impl Display for Expr {
|
||||||
write!(f, "))")
|
write!(f, "))")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Expr::If { cond, t, f: fe } => {
|
||||||
|
write!(f, "(if {} {} {})", cond, t, fe)
|
||||||
|
},
|
||||||
Expr::Defines(defs) => {
|
Expr::Defines(defs) => {
|
||||||
write!(f, "(defs ")?;
|
write!(f, "(defs ")?;
|
||||||
for (name, expr) in defs {
|
for (name, expr) in defs {
|
||||||
|
|
|
@ -19,6 +19,11 @@ pub enum JSExpr {
|
||||||
args: Vec<String>,
|
args: Vec<String>,
|
||||||
body: Vec<Self>,
|
body: Vec<Self>,
|
||||||
},
|
},
|
||||||
|
If {
|
||||||
|
cond: Box<Self>,
|
||||||
|
t: Box<Self>,
|
||||||
|
f: Box<Self>,
|
||||||
|
},
|
||||||
Defines(Vec<(String, Self)>),
|
Defines(Vec<(String, Self)>),
|
||||||
Return(Box<Self>),
|
Return(Box<Self>),
|
||||||
}
|
}
|
||||||
|
@ -99,6 +104,9 @@ impl Display for JSExpr {
|
||||||
write!(f, "}})")
|
write!(f, "}})")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
JSExpr::If { cond, t, f: fe } => {
|
||||||
|
write!(f, "({} ? {} : {})", cond, t, fe)
|
||||||
|
},
|
||||||
JSExpr::Defines(vs) => {
|
JSExpr::Defines(vs) => {
|
||||||
write!(f, "let [")?;
|
write!(f, "let [")?;
|
||||||
for (i, (name, _)) in vs.iter().enumerate() {
|
for (i, (name, _)) in vs.iter().enumerate() {
|
||||||
|
|
|
@ -38,6 +38,11 @@ pub enum PExpr {
|
||||||
vars: Vec<(String, Type, Spanned<Self>)>,
|
vars: Vec<(String, Type, Spanned<Self>)>,
|
||||||
body: Option<Box<Spanned<Self>>>,
|
body: Option<Box<Spanned<Self>>>,
|
||||||
},
|
},
|
||||||
|
If {
|
||||||
|
cond: Box<Spanned<Self>>,
|
||||||
|
t: Box<Spanned<Self>>,
|
||||||
|
f: Box<Spanned<Self>>,
|
||||||
|
},
|
||||||
Block(Vec<Spanned<Self>>),
|
Block(Vec<Spanned<Self>>),
|
||||||
Return(Box<Spanned<Self>>),
|
Return(Box<Spanned<Self>>),
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ pub enum Token {
|
||||||
Open(Delim), Close(Delim),
|
Open(Delim), Close(Delim),
|
||||||
Lambda, Arrow,
|
Lambda, Arrow,
|
||||||
|
|
||||||
Let, In, Func, Return,
|
Let, In, Func, Return, If, Then, Else,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for Token {
|
impl Display for Token {
|
||||||
|
@ -67,6 +67,9 @@ impl Display for Token {
|
||||||
Token::In => write!(f, "in"),
|
Token::In => write!(f, "in"),
|
||||||
Token::Func => write!(f, "func"),
|
Token::Func => write!(f, "func"),
|
||||||
Token::Return => write!(f, "return"),
|
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,
|
"in" => Token::In,
|
||||||
"func" => Token::Func,
|
"func" => Token::Func,
|
||||||
"return" => Token::Return,
|
"return" => Token::Return,
|
||||||
|
"if" => Token::If,
|
||||||
|
"then" => Token::Then,
|
||||||
|
"else" => Token::Else,
|
||||||
_ => Token::Sym(s),
|
_ => Token::Sym(s),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -285,6 +291,8 @@ pub fn expr_parser() -> impl P<Spanned<PExpr>> {
|
||||||
.then_ignore(just(Token::Assign))
|
.then_ignore(just(Token::Assign))
|
||||||
.then(expr.clone())
|
.then(expr.clone())
|
||||||
.map(|((sym, ty), body)| (sym, ty, body))
|
.map(|((sym, ty), body)| (sym, ty, body))
|
||||||
|
.boxed()
|
||||||
|
.labelled("let binding")
|
||||||
.separated_by(just(Token::Comma))
|
.separated_by(just(Token::Comma))
|
||||||
.allow_trailing()
|
.allow_trailing()
|
||||||
.labelled("let bindings");
|
.labelled("let bindings");
|
||||||
|
@ -322,6 +330,20 @@ pub fn expr_parser() -> impl P<Spanned<PExpr>> {
|
||||||
.map(PExpr::Return)
|
.map(PExpr::Return)
|
||||||
.labelled("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
|
let atom = lit
|
||||||
.or(sym)
|
.or(sym)
|
||||||
.or(vec)
|
.or(vec)
|
||||||
|
@ -331,6 +353,7 @@ pub fn expr_parser() -> impl P<Spanned<PExpr>> {
|
||||||
.or(let_def)
|
.or(let_def)
|
||||||
.or(block)
|
.or(block)
|
||||||
.or(ret)
|
.or(ret)
|
||||||
|
.or(ifelse)
|
||||||
.map_with_span(|e, s| (e, s))
|
.map_with_span(|e, s| (e, s))
|
||||||
.boxed()
|
.boxed()
|
||||||
.labelled("atom");
|
.labelled("atom");
|
||||||
|
|
|
@ -93,6 +93,11 @@ pub fn translate_expr(expr: PExpr) -> Expr {
|
||||||
}).collect())
|
}).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) => {
|
PExpr::Block(es) => {
|
||||||
exprs_to_lam(es.into_iter().map(|e| e.0).collect())
|
exprs_to_lam(es.into_iter().map(|e| e.0).collect())
|
||||||
},
|
},
|
||||||
|
@ -172,6 +177,11 @@ pub fn translate_js_expr(expr: Expr) -> JSExpr {
|
||||||
args,
|
args,
|
||||||
body: body.into_iter().map(translate_js_expr).collect(),
|
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)| {
|
Expr::Defines(defs) => JSExpr::Defines(defs.into_iter().map(|(name, val)| {
|
||||||
(name, translate_js_expr(val))
|
(name, translate_js_expr(val))
|
||||||
}).collect()),
|
}).collect()),
|
||||||
|
|
Loading…
Reference in a new issue