Slightly change call semantics, add looping construct, inline some JS
This commit is contained in:
parent
9291e65c11
commit
74f1fdc5ea
@ -1,9 +1,10 @@
|
|||||||
## Obligatory
|
## Obligatory
|
||||||
fizzbuzz <- x ->
|
fizzbuzz <- ->
|
||||||
if x % 15 = 0 print("fizzbuzz")
|
loop(range(100), x ->
|
||||||
elif x % 3 = 0 print("fizz")
|
if x % 15 = 0 print("fizzbuzz")
|
||||||
elif x % 5 = 0 print("buzz")
|
elif x % 3 = 0 print("fizz")
|
||||||
else print(x)
|
elif x % 5 = 0 print("buzz")
|
||||||
if x < 100 fizzbuzz(x + 1) ## TODO add looping construct(s)
|
else print(x)
|
||||||
|
)
|
||||||
fizzbuzz(1)
|
|
||||||
|
fizzbuzz()
|
||||||
|
@ -120,18 +120,28 @@ pub fn emit_expr(w: &mut dyn Write, expr: &parser::Expr, ctx: &mut LexicalContex
|
|||||||
write!(w, "{}", atom)?;
|
write!(w, "{}", atom)?;
|
||||||
}
|
}
|
||||||
parser::Expr::Funcall(id, args) => {
|
parser::Expr::Funcall(id, args) => {
|
||||||
if let Some((last, butlast)) = args.split_last() {
|
write!(w, "{}", munge(id))?;
|
||||||
write!(w, "T({}, ", munge(id))?;
|
if args.is_empty() {
|
||||||
for expr in butlast {
|
write!(w, "()")?;
|
||||||
emit_expr(w, expr, ctx)?;
|
} else if ctx.contains(id) {
|
||||||
write!(w, ", ")?;
|
// Use deelang calling semantics
|
||||||
|
for arg in args {
|
||||||
|
write!(w, "(")?;
|
||||||
|
emit_expr(w, arg, ctx)?;
|
||||||
|
write!(w, ")")?
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Use JS calling semantics
|
||||||
|
write!(w, "(")?;
|
||||||
|
let (last, butlast) = args.split_last().unwrap();
|
||||||
|
for arg in butlast {
|
||||||
|
emit_expr(w, arg, ctx)?;
|
||||||
|
write!(w, ",")?
|
||||||
}
|
}
|
||||||
emit_expr(w, last, ctx)?;
|
emit_expr(w, last, ctx)?;
|
||||||
write!(w, ")")?;
|
write!(w, ")")?;
|
||||||
} else {
|
|
||||||
write!(w, "{}", munge(id))?;
|
|
||||||
write!(w, "()")?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
parser::Expr::Funcdef(arg, body) => {
|
parser::Expr::Funcdef(arg, body) => {
|
||||||
if let Some(arg) = arg {
|
if let Some(arg) = arg {
|
||||||
@ -174,9 +184,9 @@ pub fn emit_expr(w: &mut dyn Write, expr: &parser::Expr, ctx: &mut LexicalContex
|
|||||||
write!(w, " == ")?;
|
write!(w, " == ")?;
|
||||||
emit_expr(w, e2.as_ref(), ctx)?;
|
emit_expr(w, e2.as_ref(), ctx)?;
|
||||||
}
|
}
|
||||||
parser::Expr::Lt(e1, e2) => {
|
parser::Expr::Relop(op, e1, e2) => {
|
||||||
emit_expr(w, e1.as_ref(), ctx)?;
|
emit_expr(w, e1.as_ref(), ctx)?;
|
||||||
write!(w, " < ")?;
|
write!(w, " {} ", op)?;
|
||||||
emit_expr(w, e2.as_ref(), ctx)?;
|
emit_expr(w, e2.as_ref(), ctx)?;
|
||||||
}
|
}
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
|
@ -1,10 +1,16 @@
|
|||||||
const print = console.log
|
const print = console.log
|
||||||
|
|
||||||
function T(f, ...args) {
|
function loop(seq, f) {
|
||||||
let res = f;
|
for (el of seq) {
|
||||||
for (arg of args) {
|
f(el)
|
||||||
res = res(arg);
|
|
||||||
}
|
}
|
||||||
return res;
|
}
|
||||||
|
|
||||||
|
function range(x) {
|
||||||
|
const ret = []
|
||||||
|
for (let i = 0; i < x; i++) {
|
||||||
|
ret.push(i);
|
||||||
|
}
|
||||||
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ pub enum Expr {
|
|||||||
Div(Box<Expr>, Box<Expr>),
|
Div(Box<Expr>, Box<Expr>),
|
||||||
Mod(Box<Expr>, Box<Expr>),
|
Mod(Box<Expr>, Box<Expr>),
|
||||||
Equal(Box<Expr>, Box<Expr>),
|
Equal(Box<Expr>, Box<Expr>),
|
||||||
Lt(Box<Expr>, Box<Expr>),
|
Relop(String, Box<Expr>, Box<Expr>),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Block = Vec<Stmt>;
|
pub type Block = Vec<Stmt>;
|
||||||
@ -60,8 +60,9 @@ peg::parser! {
|
|||||||
e:expr() stop() { Stmt::BareExpr(e) }
|
e:expr() stop() { Stmt::BareExpr(e) }
|
||||||
rule expr() -> Expr = precedence! {
|
rule expr() -> Expr = precedence! {
|
||||||
e1:(@) "=" _ e2:@ { Expr::Equal(Box::new(e1), Box::new(e2)) }
|
e1:(@) "=" _ e2:@ { Expr::Equal(Box::new(e1), Box::new(e2)) }
|
||||||
e1:(@) "<" _ e2:@ { Expr::Lt(Box::new(e1), Box::new(e2)) }
|
--
|
||||||
--
|
e1:(@) r:relop() e2:@ { Expr::Relop(r, Box::new(e1), Box::new(e2)) }
|
||||||
|
--
|
||||||
"-" _ e1:@ { Expr::UnaryMinus(Box::new(e1)) }
|
"-" _ e1:@ { Expr::UnaryMinus(Box::new(e1)) }
|
||||||
--
|
--
|
||||||
e1:(@) "+" _ e2:@ { Expr::Plus(Box::new(e1), Box::new(e2)) }
|
e1:(@) "+" _ e2:@ { Expr::Plus(Box::new(e1), Box::new(e2)) }
|
||||||
@ -87,10 +88,12 @@ peg::parser! {
|
|||||||
= i:$(letter() (letter() / digit() / ['?'|'.'|'-'])*) _ { i.to_string() }
|
= i:$(letter() (letter() / digit() / ['?'|'.'|'-'])*) _ { i.to_string() }
|
||||||
rule assignment() -> Stmt
|
rule assignment() -> Stmt
|
||||||
= i:id() "<-" _ e:expr() stop() { Stmt::Assignment(i, e) }
|
= i:id() "<-" _ e:expr() stop() { Stmt::Assignment(i, e) }
|
||||||
|
rule relop() -> String
|
||||||
|
= r:$("<" / ">" / "<=" / ">=") _ { r.to_string() }
|
||||||
rule num() -> f64
|
rule num() -> f64
|
||||||
= n:$(digit()+ "."? digit()* / "." digit()+) _ { n.parse().unwrap() }
|
= n:$(digit()+ "."? digit()* / "." digit()+) _ { n.parse().unwrap() }
|
||||||
rule funcall() -> Expr
|
rule funcall() -> Expr
|
||||||
= i:id() "(" _ e:(expr() ** ("," _)) ")" _ { Expr::Funcall(i, e) }
|
= i:id() "(" _ e:(expr() ** ("," _)) __* ")" _ { Expr::Funcall(i, e) }
|
||||||
rule funcdef() -> Expr
|
rule funcdef() -> Expr
|
||||||
= i:id()? "->" _ b:(block()) { Expr::Funcdef(i, b) }
|
= i:id()? "->" _ b:(block()) { Expr::Funcdef(i, b) }
|
||||||
rule conditional() -> Stmt
|
rule conditional() -> Stmt
|
||||||
|
Loading…
Reference in New Issue
Block a user