Add unscoped lambdas and improve patterns

This commit is contained in:
imaqtkatt 2024-05-14 09:00:56 -03:00
parent 3e8d82774f
commit 02b6baaa71
8 changed files with 188 additions and 61 deletions

View File

@ -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) }
})

View File

@ -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),
}

View File

@ -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(())
}

View File

@ -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 })

View File

@ -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 } => {

View File

@ -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)

View File

@ -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)

View File

@ -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 \""