diff --git a/src/imp/gen_map_get.rs b/src/imp/gen_map_get.rs index 6de3dbe4..0ad249c9 100644 --- a/src/imp/gen_map_get.rs +++ b/src/imp/gen_map_get.rs @@ -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) } }) diff --git a/src/imp/mod.rs b/src/imp/mod.rs index f076d471..b641afb8 100644 --- a/src/imp/mod.rs +++ b/src/imp/mod.rs @@ -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, args: Vec, kwargs: Vec<(Name, Expr)> }, // "lambda" {names}* ":" {bod} - Lam { names: Vec, bod: Box }, + Lam { names: Vec<(Name, bool)>, bod: Box }, // {lhs} {op} {rhs} Bin { op: Op, lhs: Box, rhs: Box }, // "\"" ... "\"" @@ -53,10 +55,12 @@ pub struct MapKey(u32); pub enum AssignPattern { // [a-zA-Z_]+ Var(Name), + // "$" [a-zA-Z_]+ + Chn(Name), // "(" ... ")" - Tup(Vec), + Tup(Vec), // "{" ... "}" - Sup(Vec), + Sup(Vec), // {name} "[" {expr} "]" MapSet(Name, Expr), } diff --git a/src/imp/order_kwargs.rs b/src/imp/order_kwargs.rs index 133448b6..8f1ca70a 100644 --- a/src/imp/order_kwargs.rs +++ b/src/imp/order_kwargs.rs @@ -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(()) } diff --git a/src/imp/parser.rs b/src/imp/parser.rs index 8bdac39e..d3d8027d 100644 --- a/src/imp/parser.rs +++ b/src/imp/parser.rs @@ -34,6 +34,8 @@ impl<'a> PyParser<'a> { impl<'a> ParserCommons<'a> for PyParser<'a> {} +type ParseResult = std::result::Result; + 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 { + fn parse_expression(&mut self) -> ParseResult { 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 { + fn parse_map_init(&mut self, head: Expr) -> ParseResult { 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 { + fn list_or_comprehension(&mut self) -> ParseResult { 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 { + fn parse_infix_or_lambda(&mut self) -> ParseResult { + 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 { + fn parse_call(&mut self) -> ParseResult { 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, Expr), String> { + fn parse_named_arg(&mut self) -> ParseResult<(Option, 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 { + fn parse_infix(&mut self, prec: usize) -> ParseResult { 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 { + fn skip_exact_indent(&mut self, Indent(mut count): &Indent, block: bool) -> ParseResult { 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 { + fn parse_statement(&mut self, indent: &mut Indent) -> ParseResult { 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 { + fn parse_symbol(&mut self) -> ParseResult { 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 { + fn parse_map_key(&mut self) -> ParseResult { 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 { + fn parse_assign(&mut self, indent: &mut Indent) -> ParseResult { 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 { + fn parse_in_place_op(&mut self) -> ParseResult { self.advance_inline_trivia(); if self.starts_with("+=") { self.consume("+=")?; @@ -448,13 +453,13 @@ impl<'a> PyParser<'a> { } } - fn parse_return(&mut self) -> Result { + fn parse_return(&mut self) -> ParseResult { 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 { + fn parse_if(&mut self, indent: &mut Indent) -> ParseResult { 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 { + fn parse_match(&mut self, indent: &mut Indent) -> ParseResult { 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, Expr), String> { + fn parse_match_arg(&mut self) -> ParseResult<(Option, 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, String> { + fn name_or_wildcard(&mut self) -> ParseResult> { self.labelled( |p| { if p.try_consume("_") { @@ -515,7 +520,7 @@ impl<'a> PyParser<'a> { ) } - fn parse_case(&mut self, indent: &mut Indent) -> Result { + fn parse_case(&mut self, indent: &mut Indent) -> ParseResult { 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 { + fn parse_switch(&mut self, indent: &mut Indent) -> ParseResult { 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 { + fn parse_fold(&mut self, indent: &mut Indent) -> ParseResult { 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 { + fn parse_bend(&mut self, indent: &mut Indent) -> ParseResult { 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 { + fn parse_do(&mut self, indent: &mut Indent) -> ParseResult { 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 { + fn parse_assign_pattern(&mut self) -> ParseResult { // 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 { + pub fn parse_def(&mut self, indent: usize) -> ParseResult { 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 { - fn parse_variant_field(p: &mut PyParser) -> Result { + pub fn parse_data_type(&mut self, indent: usize) -> ParseResult { + fn parse_variant_field(p: &mut PyParser) -> ParseResult { let rec = p.try_consume("~"); let nam = p.parse_bend_name()?; Ok(CtrField { nam, rec }) diff --git a/src/imp/to_fun.rs b/src/imp/to_fun.rs index f4876fa9..ced5aac8 100644 --- a/src/imp/to_fun.rs +++ b/src/imp/to_fun.rs @@ -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 } => { diff --git a/tests/snapshots/parse_file__imp_map.hvm.snap b/tests/snapshots/parse_file__imp_map.hvm.snap index 362b3207..a61323ea 100644 --- a/tests/snapshots/parse_file__imp_map.hvm.snap +++ b/tests/snapshots/parse_file__imp_map.hvm.snap @@ -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) diff --git a/tests/snapshots/parse_file__imp_program.hvm.snap b/tests/snapshots/parse_file__imp_program.hvm.snap index 34d254f1..196d62be 100644 --- a/tests/snapshots/parse_file__imp_program.hvm.snap +++ b/tests/snapshots/parse_file__imp_program.hvm.snap @@ -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) diff --git a/tests/snapshots/parse_file__scape_chars.hvm.snap b/tests/snapshots/parse_file__scape_chars.hvm.snap index 76064274..8bd24b0d 100644 --- a/tests/snapshots/parse_file__scape_chars.hvm.snap +++ b/tests/snapshots/parse_file__scape_chars.hvm.snap @@ -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 \""