mirror of
https://github.com/HigherOrderCO/Bend.git
synced 2024-11-05 04:51:40 +03:00
Add unscoped lambdas and improve patterns
This commit is contained in:
parent
3e8d82774f
commit
02b6baaa71
@ -129,7 +129,7 @@ impl Expr {
|
||||
go(entry, substitutions, id);
|
||||
}
|
||||
}
|
||||
Expr::None | Expr::Str { .. } | Expr::Var { .. } | Expr::Num { .. } => {}
|
||||
Expr::None | Expr::Str { .. } | Expr::Var { .. } | Expr::Chn { .. } | Expr::Num { .. } => {}
|
||||
}
|
||||
}
|
||||
let mut substitutions = Substitutions::new();
|
||||
@ -147,7 +147,7 @@ fn gen_get(current: &mut Stmt, substitutions: Substitutions) -> Stmt {
|
||||
args: vec![Expr::Var { nam: map_var.clone() }, *key],
|
||||
kwargs: Vec::new(),
|
||||
};
|
||||
let pat = AssignPattern::Tup(vec![var, map_var]);
|
||||
let pat = AssignPattern::Tup(vec![AssignPattern::Var(var), AssignPattern::Var(map_var)]);
|
||||
|
||||
Stmt::Assign { pat, val: Box::new(map_get_call), nxt: Box::new(acc) }
|
||||
})
|
||||
|
@ -14,12 +14,14 @@ pub enum Expr {
|
||||
None,
|
||||
// [a-zA-Z_]+
|
||||
Var { nam: Name },
|
||||
// "$" [a-zA-Z_]+
|
||||
Chn { nam: Name },
|
||||
// [0-9_]+
|
||||
Num { val: u32 },
|
||||
// {fun}({args},{kwargs},)
|
||||
Call { fun: Box<Expr>, args: Vec<Expr>, kwargs: Vec<(Name, Expr)> },
|
||||
// "lambda" {names}* ":" {bod}
|
||||
Lam { names: Vec<Name>, bod: Box<Expr> },
|
||||
Lam { names: Vec<(Name, bool)>, bod: Box<Expr> },
|
||||
// {lhs} {op} {rhs}
|
||||
Bin { op: Op, lhs: Box<Expr>, rhs: Box<Expr> },
|
||||
// "\"" ... "\""
|
||||
@ -53,10 +55,12 @@ pub struct MapKey(u32);
|
||||
pub enum AssignPattern {
|
||||
// [a-zA-Z_]+
|
||||
Var(Name),
|
||||
// "$" [a-zA-Z_]+
|
||||
Chn(Name),
|
||||
// "(" ... ")"
|
||||
Tup(Vec<Name>),
|
||||
Tup(Vec<AssignPattern>),
|
||||
// "{" ... "}"
|
||||
Sup(Vec<Name>),
|
||||
Sup(Vec<AssignPattern>),
|
||||
// {name} "[" {expr} "]"
|
||||
MapSet(Name, Expr),
|
||||
}
|
||||
|
@ -123,7 +123,12 @@ impl Expr {
|
||||
entry.1.order_kwargs(book)?;
|
||||
}
|
||||
}
|
||||
Expr::MapGet { .. } | Expr::None | Expr::Var { .. } | Expr::Num { .. } | Expr::Str { .. } => {}
|
||||
Expr::MapGet { .. }
|
||||
| Expr::None
|
||||
| Expr::Var { .. }
|
||||
| Expr::Chn { .. }
|
||||
| Expr::Num { .. }
|
||||
| Expr::Str { .. } => {}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -34,6 +34,8 @@ impl<'a> PyParser<'a> {
|
||||
|
||||
impl<'a> ParserCommons<'a> for PyParser<'a> {}
|
||||
|
||||
type ParseResult<T> = std::result::Result<T, String>;
|
||||
|
||||
impl<'a> Parser<'a> for PyParser<'a> {
|
||||
fn input(&mut self) -> &'a str {
|
||||
self.input
|
||||
@ -67,9 +69,14 @@ impl<'a> Parser<'a> for PyParser<'a> {
|
||||
}
|
||||
|
||||
impl<'a> PyParser<'a> {
|
||||
fn parse_expression(&mut self) -> Result<Expr, String> {
|
||||
fn parse_expression(&mut self) -> ParseResult<Expr> {
|
||||
let Some(head) = self.skip_peek_one() else { return self.expected("primary term")? };
|
||||
let res = match head {
|
||||
'$' => {
|
||||
self.consume("$")?;
|
||||
let nam = self.parse_bend_name()?;
|
||||
Expr::Chn { nam }
|
||||
}
|
||||
'(' => {
|
||||
self.consume("(")?;
|
||||
let head = self.parse_infix_or_lambda()?;
|
||||
@ -89,16 +96,6 @@ impl<'a> PyParser<'a> {
|
||||
self.consume("{")?;
|
||||
let head = self.parse_infix_or_lambda()?;
|
||||
if self.skip_starts_with(":") { self.parse_map_init(head)? } else { self.parse_sup(head)? }
|
||||
// let mut entries = Vec::new();
|
||||
// loop {
|
||||
// entries.push(self.parse_map_entry()?);
|
||||
// if self.skip_starts_with("}") {
|
||||
// break;
|
||||
// }
|
||||
// self.consume(",")?;
|
||||
// }
|
||||
// self.consume("}")?;
|
||||
// Expr::MapInit { entries }
|
||||
}
|
||||
'[' => self.list_or_comprehension()?,
|
||||
'`' => Expr::Num { val: self.parse_symbol()? },
|
||||
@ -128,7 +125,7 @@ impl<'a> PyParser<'a> {
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
fn parse_map_init(&mut self, head: Expr) -> Result<Expr, String> {
|
||||
fn parse_map_init(&mut self, head: Expr) -> ParseResult<Expr> {
|
||||
let mut entries = Vec::new();
|
||||
let map_key = match head {
|
||||
Expr::Num { val } => MapKey(val),
|
||||
@ -155,21 +152,21 @@ impl<'a> PyParser<'a> {
|
||||
Ok(Expr::Sup { els })
|
||||
}
|
||||
|
||||
fn data_kwarg(&mut self) -> Result<(Name, Expr), String> {
|
||||
fn data_kwarg(&mut self) -> ParseResult<(Name, Expr)> {
|
||||
let nam = self.parse_bend_name()?;
|
||||
self.consume(":")?;
|
||||
let expr = self.parse_infix_or_lambda()?;
|
||||
Ok((nam, expr))
|
||||
}
|
||||
|
||||
fn parse_map_entry(&mut self) -> Result<(MapKey, Expr), String> {
|
||||
fn parse_map_entry(&mut self) -> ParseResult<(MapKey, Expr)> {
|
||||
let key = self.parse_map_key()?;
|
||||
self.consume(":")?;
|
||||
let val = self.parse_expression()?;
|
||||
Ok((key, val))
|
||||
}
|
||||
|
||||
fn list_or_comprehension(&mut self) -> Result<Expr, String> {
|
||||
fn list_or_comprehension(&mut self) -> ParseResult<Expr> {
|
||||
self.consume("[")?;
|
||||
let head = self.parse_infix_or_lambda()?;
|
||||
if self.try_consume_keyword("for") {
|
||||
@ -191,9 +188,17 @@ impl<'a> PyParser<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_infix_or_lambda(&mut self) -> Result<Expr, String> {
|
||||
fn parse_infix_or_lambda(&mut self) -> ParseResult<Expr> {
|
||||
fn parse_lam_var(p: &mut PyParser) -> ParseResult<(Name, bool)> {
|
||||
if p.skip_starts_with("$") {
|
||||
p.consume("$")?;
|
||||
Ok((p.parse_bend_name()?, true))
|
||||
} else {
|
||||
Ok((p.parse_bend_name()?, false))
|
||||
}
|
||||
}
|
||||
if self.try_consume_keyword("lam") | self.try_consume("λ") {
|
||||
let names = self.list_like(|p| p.parse_bend_name(), "", ":", ",", false, 1)?;
|
||||
let names = self.list_like(parse_lam_var, "", ":", ",", false, 1)?;
|
||||
let bod = self.parse_infix_or_lambda()?;
|
||||
Ok(Expr::Lam { names, bod: Box::new(bod) })
|
||||
} else {
|
||||
@ -201,7 +206,7 @@ impl<'a> PyParser<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_call(&mut self) -> Result<Expr, String> {
|
||||
fn parse_call(&mut self) -> ParseResult<Expr> {
|
||||
let mut args = Vec::new();
|
||||
let mut kwargs = Vec::new();
|
||||
let fun = self.parse_expression()?;
|
||||
@ -231,7 +236,7 @@ impl<'a> PyParser<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_named_arg(&mut self) -> Result<(Option<Name>, Expr), String> {
|
||||
fn parse_named_arg(&mut self) -> ParseResult<(Option<Name>, Expr)> {
|
||||
let arg = self.parse_infix_or_lambda()?;
|
||||
if self.try_consume("=") {
|
||||
if let Expr::Var { nam } = arg {
|
||||
@ -248,7 +253,7 @@ impl<'a> PyParser<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_infix(&mut self, prec: usize) -> Result<Expr, String> {
|
||||
fn parse_infix(&mut self, prec: usize) -> ParseResult<Expr> {
|
||||
maybe_grow(|| {
|
||||
self.advance_inline_trivia();
|
||||
if prec > PREC.len() - 1 {
|
||||
@ -294,7 +299,7 @@ impl<'a> PyParser<'a> {
|
||||
Some(ret)
|
||||
}
|
||||
|
||||
fn skip_exact_indent(&mut self, Indent(mut count): &Indent, block: bool) -> Result<bool, String> {
|
||||
fn skip_exact_indent(&mut self, Indent(mut count): &Indent, block: bool) -> ParseResult<bool> {
|
||||
let expected = count;
|
||||
let ini_idx = *self.index();
|
||||
if count <= 0 {
|
||||
@ -329,7 +334,7 @@ impl<'a> PyParser<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_statement(&mut self, indent: &mut Indent) -> Result<Stmt, String> {
|
||||
fn parse_statement(&mut self, indent: &mut Indent) -> ParseResult<Stmt> {
|
||||
maybe_grow(|| {
|
||||
self.skip_exact_indent(indent, false)?;
|
||||
if self.try_consume_keyword("return") {
|
||||
@ -352,7 +357,7 @@ impl<'a> PyParser<'a> {
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_symbol(&mut self) -> Result<u32, String> {
|
||||
fn parse_symbol(&mut self) -> ParseResult<u32> {
|
||||
self.consume("`")?;
|
||||
let mut result = u32::MAX;
|
||||
let mut count = 0;
|
||||
@ -377,7 +382,7 @@ impl<'a> PyParser<'a> {
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
fn parse_map_key(&mut self) -> Result<MapKey, String> {
|
||||
fn parse_map_key(&mut self) -> ParseResult<MapKey> {
|
||||
if self.skip_starts_with("`") {
|
||||
Ok(MapKey(self.parse_symbol()?))
|
||||
} else {
|
||||
@ -386,7 +391,7 @@ impl<'a> PyParser<'a> {
|
||||
}
|
||||
|
||||
/// Assignments, monadic bind operations and in-place operations.
|
||||
fn parse_assign(&mut self, indent: &mut Indent) -> Result<Stmt, String> {
|
||||
fn parse_assign(&mut self, indent: &mut Indent) -> ParseResult<Stmt> {
|
||||
let ini_idx = *self.index();
|
||||
let pat = self.parse_assign_pattern()?;
|
||||
let end_idx = *self.index();
|
||||
@ -420,7 +425,7 @@ impl<'a> PyParser<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_in_place_op(&mut self) -> Result<InPlaceOp, String> {
|
||||
fn parse_in_place_op(&mut self) -> ParseResult<InPlaceOp> {
|
||||
self.advance_inline_trivia();
|
||||
if self.starts_with("+=") {
|
||||
self.consume("+=")?;
|
||||
@ -448,13 +453,13 @@ impl<'a> PyParser<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_return(&mut self) -> Result<Stmt, String> {
|
||||
fn parse_return(&mut self) -> ParseResult<Stmt> {
|
||||
let term = self.parse_infix_or_lambda()?;
|
||||
self.consume(";")?;
|
||||
Ok(Stmt::Return { term: Box::new(term) })
|
||||
}
|
||||
|
||||
fn parse_if(&mut self, indent: &mut Indent) -> Result<Stmt, String> {
|
||||
fn parse_if(&mut self, indent: &mut Indent) -> ParseResult<Stmt> {
|
||||
let cond = self.parse_infix_or_lambda()?;
|
||||
self.consume(":")?;
|
||||
indent.enter_level();
|
||||
@ -469,7 +474,7 @@ impl<'a> PyParser<'a> {
|
||||
Ok(Stmt::If { cond: Box::new(cond), then: Box::new(then), otherwise: Box::new(otherwise) })
|
||||
}
|
||||
|
||||
fn parse_match(&mut self, indent: &mut Indent) -> Result<Stmt, String> {
|
||||
fn parse_match(&mut self, indent: &mut Indent) -> ParseResult<Stmt> {
|
||||
let (bind, arg) = self.parse_match_arg()?;
|
||||
self.consume(":")?;
|
||||
let mut arms = Vec::new();
|
||||
@ -484,7 +489,7 @@ impl<'a> PyParser<'a> {
|
||||
Ok(Stmt::Match { arg: Box::new(arg), bind, arms })
|
||||
}
|
||||
|
||||
fn parse_match_arg(&mut self) -> Result<(Option<Name>, Expr), String> {
|
||||
fn parse_match_arg(&mut self) -> ParseResult<(Option<Name>, Expr)> {
|
||||
let ini_idx = *self.index();
|
||||
let arg = self.parse_infix_or_lambda()?;
|
||||
let end_idx = *self.index();
|
||||
@ -501,7 +506,7 @@ impl<'a> PyParser<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn name_or_wildcard(&mut self) -> Result<Option<Name>, String> {
|
||||
fn name_or_wildcard(&mut self) -> ParseResult<Option<Name>> {
|
||||
self.labelled(
|
||||
|p| {
|
||||
if p.try_consume("_") {
|
||||
@ -515,7 +520,7 @@ impl<'a> PyParser<'a> {
|
||||
)
|
||||
}
|
||||
|
||||
fn parse_case(&mut self, indent: &mut Indent) -> Result<MatchArm, String> {
|
||||
fn parse_case(&mut self, indent: &mut Indent) -> ParseResult<MatchArm> {
|
||||
self.consume("case")?;
|
||||
let pat = self.name_or_wildcard()?;
|
||||
self.consume(":")?;
|
||||
@ -525,7 +530,7 @@ impl<'a> PyParser<'a> {
|
||||
Ok(MatchArm { lft: pat, rgt: body })
|
||||
}
|
||||
|
||||
fn parse_switch(&mut self, indent: &mut Indent) -> Result<Stmt, String> {
|
||||
fn parse_switch(&mut self, indent: &mut Indent) -> ParseResult<Stmt> {
|
||||
let (bind, arg) = self.parse_match_arg()?;
|
||||
self.consume(":")?;
|
||||
let mut arms = Vec::new();
|
||||
@ -567,7 +572,7 @@ impl<'a> PyParser<'a> {
|
||||
Ok(Stmt::Switch { arg: Box::new(arg), bind, arms })
|
||||
}
|
||||
|
||||
fn parse_fold(&mut self, indent: &mut Indent) -> Result<Stmt, String> {
|
||||
fn parse_fold(&mut self, indent: &mut Indent) -> ParseResult<Stmt> {
|
||||
let (bind, arg) = self.parse_match_arg()?;
|
||||
self.consume(":")?;
|
||||
let mut arms = Vec::new();
|
||||
@ -582,7 +587,7 @@ impl<'a> PyParser<'a> {
|
||||
Ok(Stmt::Fold { arg: Box::new(arg), bind, arms })
|
||||
}
|
||||
|
||||
fn parse_bend(&mut self, indent: &mut Indent) -> Result<Stmt, String> {
|
||||
fn parse_bend(&mut self, indent: &mut Indent) -> ParseResult<Stmt> {
|
||||
let args = self.list_like(|p| p.parse_match_arg(), "", "while", ",", false, 1)?;
|
||||
let (bind, init) = args.into_iter().unzip();
|
||||
let cond = self.parse_infix_or_lambda()?;
|
||||
@ -598,7 +603,7 @@ impl<'a> PyParser<'a> {
|
||||
Ok(Stmt::Bend { bind, init, cond: Box::new(cond), step: Box::new(step), base: Box::new(base) })
|
||||
}
|
||||
|
||||
fn parse_do(&mut self, indent: &mut Indent) -> Result<Stmt, String> {
|
||||
fn parse_do(&mut self, indent: &mut Indent) -> ParseResult<Stmt> {
|
||||
let typ = self.parse_bend_name()?;
|
||||
self.consume(":")?;
|
||||
|
||||
@ -609,22 +614,29 @@ impl<'a> PyParser<'a> {
|
||||
Ok(Stmt::Do { typ, bod: Box::new(bod) })
|
||||
}
|
||||
|
||||
fn parse_assign_pattern(&mut self) -> Result<AssignPattern, String> {
|
||||
fn parse_assign_pattern(&mut self) -> ParseResult<AssignPattern> {
|
||||
// Tup pattern
|
||||
if self.skip_starts_with("(") {
|
||||
let mut binds = self.list_like(|p| p.parse_bend_name(), "(", ")", ",", true, 1)?;
|
||||
let binds = self.list_like(|p| p.parse_assign_pattern(), "(", ")", ",", true, 1)?;
|
||||
if binds.len() == 1 {
|
||||
return Ok(AssignPattern::Var(std::mem::take(&mut binds[0])));
|
||||
return Ok(binds[0].to_owned());
|
||||
} else {
|
||||
return Ok(AssignPattern::Tup(binds));
|
||||
}
|
||||
}
|
||||
// Dup pattern
|
||||
if self.skip_starts_with("{") {
|
||||
let binds = self.list_like(|p| p.parse_bend_name(), "{", "}", "", false, 2)?;
|
||||
let binds = self.list_like(|p| p.parse_assign_pattern(), "{", "}", "", false, 2)?;
|
||||
return Ok(AssignPattern::Sup(binds));
|
||||
}
|
||||
|
||||
// Chn pattern
|
||||
if self.skip_starts_with("$") {
|
||||
self.consume("$")?;
|
||||
let nam = self.parse_bend_name()?;
|
||||
return Ok(AssignPattern::Chn(nam));
|
||||
}
|
||||
|
||||
let var = self.parse_bend_name()?;
|
||||
|
||||
// Map get pattern
|
||||
@ -639,7 +651,7 @@ impl<'a> PyParser<'a> {
|
||||
Ok(AssignPattern::Var(var))
|
||||
}
|
||||
|
||||
pub fn parse_def(&mut self, indent: usize) -> Result<Definition, String> {
|
||||
pub fn parse_def(&mut self, indent: usize) -> ParseResult<Definition> {
|
||||
if indent > 0 {
|
||||
self.expected("Indentation error")?;
|
||||
}
|
||||
@ -654,8 +666,8 @@ impl<'a> PyParser<'a> {
|
||||
Ok(Definition { name, params, body })
|
||||
}
|
||||
|
||||
pub fn parse_data_type(&mut self, indent: usize) -> Result<Enum, String> {
|
||||
fn parse_variant_field(p: &mut PyParser) -> Result<CtrField, String> {
|
||||
pub fn parse_data_type(&mut self, indent: usize) -> ParseResult<Enum> {
|
||||
fn parse_variant_field(p: &mut PyParser) -> ParseResult<CtrField> {
|
||||
let rec = p.try_consume("~");
|
||||
let nam = p.parse_bend_name()?;
|
||||
Ok(CtrField { nam, rec })
|
||||
|
@ -16,16 +16,13 @@ impl AssignPattern {
|
||||
pub fn to_fun(self) -> fun::Pattern {
|
||||
match self {
|
||||
AssignPattern::Var(name) => fun::Pattern::Var(Some(name)),
|
||||
AssignPattern::Tup(names) => fun::Pattern::Fan(
|
||||
fun::FanKind::Tup,
|
||||
fun::Tag::Static,
|
||||
names.into_iter().map(|name| fun::Pattern::Var(Some(name))).collect(),
|
||||
),
|
||||
AssignPattern::Sup(names) => fun::Pattern::Fan(
|
||||
fun::FanKind::Dup,
|
||||
fun::Tag::Auto,
|
||||
names.into_iter().map(|name| fun::Pattern::Var(Some(name))).collect(),
|
||||
),
|
||||
AssignPattern::Chn(name) => fun::Pattern::Chn(name),
|
||||
AssignPattern::Tup(names) => {
|
||||
fun::Pattern::Fan(fun::FanKind::Tup, fun::Tag::Static, names.into_iter().map(Self::to_fun).collect())
|
||||
}
|
||||
AssignPattern::Sup(names) => {
|
||||
fun::Pattern::Fan(fun::FanKind::Dup, fun::Tag::Auto, names.into_iter().map(Self::to_fun).collect())
|
||||
}
|
||||
AssignPattern::MapSet(..) => unreachable!(),
|
||||
}
|
||||
}
|
||||
@ -108,15 +105,16 @@ impl Expr {
|
||||
match self {
|
||||
Expr::None => fun::Term::Era,
|
||||
Expr::Var { nam } => fun::Term::Var { nam },
|
||||
Expr::Chn { nam } => fun::Term::Link { nam },
|
||||
Expr::Num { val } => fun::Term::Num { val: fun::Num::U24(val) },
|
||||
Expr::Call { fun, args, kwargs } => {
|
||||
assert!(kwargs.is_empty());
|
||||
let args = args.into_iter().map(Self::to_fun);
|
||||
fun::Term::call(fun.to_fun(), args)
|
||||
}
|
||||
Expr::Lam { names, bod } => names.into_iter().rfold(bod.to_fun(), |acc, nxt| fun::Term::Lam {
|
||||
Expr::Lam { names, bod } => names.into_iter().rfold(bod.to_fun(), |acc, (name, link)| fun::Term::Lam {
|
||||
tag: fun::Tag::Static,
|
||||
pat: Box::new(fun::Pattern::Var(Some(nxt))),
|
||||
pat: Box::new(if link { fun::Pattern::Chn(name) } else { fun::Pattern::Var(Some(name)) }),
|
||||
bod: Box::new(acc),
|
||||
}),
|
||||
Expr::Bin { op, lhs, rhs } => {
|
||||
|
@ -8,4 +8,40 @@ input_file: tests/golden_tests/parse_file/imp_map.hvm
|
||||
|
||||
(Map/set map key value) = match map = map { Map/node: switch _ = (== 0 key) { 0: switch _ = (% key 2) { 0: (Map/node map.value (Map/set map.left (/ key 2) value) map.right); _ _-1: (Map/node map.value map.left (Map/set map.right (/ key 2) value)); }; _ _-1: (Map/node value map.left map.right); }; Map/leaf: switch _ = (== 0 key) { 0: switch _ = (% key 2) { 0: (Map/node * (Map/set Map/leaf (/ key 2) value) Map/leaf); _ _-1: (Map/node * Map/leaf (Map/set Map/leaf (/ key 2) value)); }; _ _-1: (Map/node value Map/leaf Map/leaf); }; }
|
||||
|
||||
(STRING_NIL_TAG) = 0
|
||||
|
||||
(STRING_CONS_TAG) = 1
|
||||
|
||||
(IO_DONE_TAG) = 0
|
||||
|
||||
(IO_PUT_TEXT_TAG) = 1
|
||||
|
||||
(IO_GET_TEXT_TAG) = 2
|
||||
|
||||
(IO_WRITE_FILE_TAG) = 3
|
||||
|
||||
(IO_READ_FILE_TAG) = 4
|
||||
|
||||
(IO_GET_TIME_TAG) = 5
|
||||
|
||||
(IO_SLEEP_TAG) = 6
|
||||
|
||||
(IO_DRAW_IMAGE_TAG) = 7
|
||||
|
||||
(MkStr (String/cons x xs)) = λt (t STRING_CONS_TAG x (MkStr xs))
|
||||
(MkStr (String/nil)) = λt (t STRING_NIL_TAG)
|
||||
|
||||
(ReadStr s) = (s λtag switch tag = tag { 0: String/nil; _ tag-1: λx λxs (String/cons x (ReadStr xs)); })
|
||||
|
||||
(MkIO (IO/Done term)) = λt (t IO_DONE_TAG term)
|
||||
(MkIO (IO/PutText text cont)) = λt (t IO_PUT_TEXT_TAG text λx (MkIO (cont x)))
|
||||
(MkIO (IO/GetText cont)) = λt (t IO_GET_TEXT_TAG λx (MkIO (cont x)))
|
||||
(MkIO (IO/WriteFile file data cont)) = λt (t IO_WRITE_FILE_TAG file data λx (MkIO (cont x)))
|
||||
(MkIO (IO/ReadFile file cont)) = λt (t IO_READ_FILE_TAG file λx (MkIO (cont x)))
|
||||
(MkIO (IO/GetTime cont)) = λt (t IO_GET_TIME_TAG λx (MkIO (cont x)))
|
||||
(MkIO (IO/Sleep time cont)) = λt (t IO_SLEEP_TAG time λx (MkIO (cont x)))
|
||||
(MkIO (IO/DrawImage tree cont)) = λt (t IO_DRAW_IMAGE_TAG tree λx (MkIO (cont x)))
|
||||
|
||||
(ReadIO io) = (io λtag switch tag = tag { 0: λterm (IO/Done term); 1: λtext (IO/PutText (ReadStr text) λcont (ReadIO cont)); 2: (IO/GetText λcont (ReadIO cont)); 3: λfile λdata (IO/WriteFile file data λcont (ReadIO cont)); 4: λfile (IO/ReadFile file λcont (ReadIO cont)); 5: (IO/GetTime λcont (ReadIO cont)); 6: λtime (IO/Sleep time λcont (ReadIO cont)); 7: λtree (IO/DrawImage tree λcont (ReadIO cont)); _ tag-8: *; })
|
||||
|
||||
(main) = let x = (Map/set (Map/set Map/empty 2 1) 3 2); let (map/get%1, x) = (Map/get x 2); let y = (id map/get%1); let z = 4; let x = (Map/set x z 4); let (map/get%0, x) = (Map/get x z); (+ y map/get%0)
|
||||
|
@ -8,6 +8,42 @@ input_file: tests/golden_tests/parse_file/imp_program.hvm
|
||||
|
||||
(Map/set map key value) = match map = map { Map/node: switch _ = (== 0 key) { 0: switch _ = (% key 2) { 0: (Map/node map.value (Map/set map.left (/ key 2) value) map.right); _ _-1: (Map/node map.value map.left (Map/set map.right (/ key 2) value)); }; _ _-1: (Map/node value map.left map.right); }; Map/leaf: switch _ = (== 0 key) { 0: switch _ = (% key 2) { 0: (Map/node * (Map/set Map/leaf (/ key 2) value) Map/leaf); _ _-1: (Map/node * Map/leaf (Map/set Map/leaf (/ key 2) value)); }; _ _-1: (Map/node value Map/leaf Map/leaf); }; }
|
||||
|
||||
(STRING_NIL_TAG) = 0
|
||||
|
||||
(STRING_CONS_TAG) = 1
|
||||
|
||||
(IO_DONE_TAG) = 0
|
||||
|
||||
(IO_PUT_TEXT_TAG) = 1
|
||||
|
||||
(IO_GET_TEXT_TAG) = 2
|
||||
|
||||
(IO_WRITE_FILE_TAG) = 3
|
||||
|
||||
(IO_READ_FILE_TAG) = 4
|
||||
|
||||
(IO_GET_TIME_TAG) = 5
|
||||
|
||||
(IO_SLEEP_TAG) = 6
|
||||
|
||||
(IO_DRAW_IMAGE_TAG) = 7
|
||||
|
||||
(MkStr (String/cons x xs)) = λt (t STRING_CONS_TAG x (MkStr xs))
|
||||
(MkStr (String/nil)) = λt (t STRING_NIL_TAG)
|
||||
|
||||
(ReadStr s) = (s λtag switch tag = tag { 0: String/nil; _ tag-1: λx λxs (String/cons x (ReadStr xs)); })
|
||||
|
||||
(MkIO (IO/Done term)) = λt (t IO_DONE_TAG term)
|
||||
(MkIO (IO/PutText text cont)) = λt (t IO_PUT_TEXT_TAG text λx (MkIO (cont x)))
|
||||
(MkIO (IO/GetText cont)) = λt (t IO_GET_TEXT_TAG λx (MkIO (cont x)))
|
||||
(MkIO (IO/WriteFile file data cont)) = λt (t IO_WRITE_FILE_TAG file data λx (MkIO (cont x)))
|
||||
(MkIO (IO/ReadFile file cont)) = λt (t IO_READ_FILE_TAG file λx (MkIO (cont x)))
|
||||
(MkIO (IO/GetTime cont)) = λt (t IO_GET_TIME_TAG λx (MkIO (cont x)))
|
||||
(MkIO (IO/Sleep time cont)) = λt (t IO_SLEEP_TAG time λx (MkIO (cont x)))
|
||||
(MkIO (IO/DrawImage tree cont)) = λt (t IO_DRAW_IMAGE_TAG tree λx (MkIO (cont x)))
|
||||
|
||||
(ReadIO io) = (io λtag switch tag = tag { 0: λterm (IO/Done term); 1: λtext (IO/PutText (ReadStr text) λcont (ReadIO cont)); 2: (IO/GetText λcont (ReadIO cont)); 3: λfile λdata (IO/WriteFile file data λcont (ReadIO cont)); 4: λfile (IO/ReadFile file λcont (ReadIO cont)); 5: (IO/GetTime λcont (ReadIO cont)); 6: λtime (IO/Sleep time λcont (ReadIO cont)); 7: λtree (IO/DrawImage tree λcont (ReadIO cont)); _ tag-8: *; })
|
||||
|
||||
(symbols) = let x = (Map/set (Map/set Map/empty 4294967281 5) 2 3); let x = (Map/set x 4294967281 2); let x = (Map/set x 2 3); let (map/get%0, x) = (Map/get x 4294967281); (+ map/get%0 4286483570)
|
||||
|
||||
(mk_point) = (Point/Point 1 2)
|
||||
|
@ -8,4 +8,40 @@ input_file: tests/golden_tests/parse_file/scape_chars.hvm
|
||||
|
||||
(Map/set map key value) = match map = map { Map/node: switch _ = (== 0 key) { 0: switch _ = (% key 2) { 0: (Map/node map.value (Map/set map.left (/ key 2) value) map.right); _ _-1: (Map/node map.value map.left (Map/set map.right (/ key 2) value)); }; _ _-1: (Map/node value map.left map.right); }; Map/leaf: switch _ = (== 0 key) { 0: switch _ = (% key 2) { 0: (Map/node * (Map/set Map/leaf (/ key 2) value) Map/leaf); _ _-1: (Map/node * Map/leaf (Map/set Map/leaf (/ key 2) value)); }; _ _-1: (Map/node value Map/leaf Map/leaf); }; }
|
||||
|
||||
(STRING_NIL_TAG) = 0
|
||||
|
||||
(STRING_CONS_TAG) = 1
|
||||
|
||||
(IO_DONE_TAG) = 0
|
||||
|
||||
(IO_PUT_TEXT_TAG) = 1
|
||||
|
||||
(IO_GET_TEXT_TAG) = 2
|
||||
|
||||
(IO_WRITE_FILE_TAG) = 3
|
||||
|
||||
(IO_READ_FILE_TAG) = 4
|
||||
|
||||
(IO_GET_TIME_TAG) = 5
|
||||
|
||||
(IO_SLEEP_TAG) = 6
|
||||
|
||||
(IO_DRAW_IMAGE_TAG) = 7
|
||||
|
||||
(MkStr (String/cons x xs)) = λt (t STRING_CONS_TAG x (MkStr xs))
|
||||
(MkStr (String/nil)) = λt (t STRING_NIL_TAG)
|
||||
|
||||
(ReadStr s) = (s λtag switch tag = tag { 0: String/nil; _ tag-1: λx λxs (String/cons x (ReadStr xs)); })
|
||||
|
||||
(MkIO (IO/Done term)) = λt (t IO_DONE_TAG term)
|
||||
(MkIO (IO/PutText text cont)) = λt (t IO_PUT_TEXT_TAG text λx (MkIO (cont x)))
|
||||
(MkIO (IO/GetText cont)) = λt (t IO_GET_TEXT_TAG λx (MkIO (cont x)))
|
||||
(MkIO (IO/WriteFile file data cont)) = λt (t IO_WRITE_FILE_TAG file data λx (MkIO (cont x)))
|
||||
(MkIO (IO/ReadFile file cont)) = λt (t IO_READ_FILE_TAG file λx (MkIO (cont x)))
|
||||
(MkIO (IO/GetTime cont)) = λt (t IO_GET_TIME_TAG λx (MkIO (cont x)))
|
||||
(MkIO (IO/Sleep time cont)) = λt (t IO_SLEEP_TAG time λx (MkIO (cont x)))
|
||||
(MkIO (IO/DrawImage tree cont)) = λt (t IO_DRAW_IMAGE_TAG tree λx (MkIO (cont x)))
|
||||
|
||||
(ReadIO io) = (io λtag switch tag = tag { 0: λterm (IO/Done term); 1: λtext (IO/PutText (ReadStr text) λcont (ReadIO cont)); 2: (IO/GetText λcont (ReadIO cont)); 3: λfile λdata (IO/WriteFile file data λcont (ReadIO cont)); 4: λfile (IO/ReadFile file λcont (ReadIO cont)); 5: (IO/GetTime λcont (ReadIO cont)); 6: λtime (IO/Sleep time λcont (ReadIO cont)); 7: λtree (IO/DrawImage tree λcont (ReadIO cont)); _ tag-8: *; })
|
||||
|
||||
(main) = "\\ \n \t \""
|
||||
|
Loading…
Reference in New Issue
Block a user