mirror of
https://github.com/HigherOrderCO/Bend.git
synced 2024-08-14 22:30:30 +03:00
[sc-688] Add string resugaring of readback term
This commit is contained in:
parent
a763052c11
commit
2f7ae6c276
@ -85,6 +85,7 @@
|
||||
"scopeless",
|
||||
"scrutinee",
|
||||
"snil",
|
||||
"SOTA",
|
||||
"stdext",
|
||||
"struct",
|
||||
"subcmd",
|
||||
|
@ -16,4 +16,5 @@ pub mod float_combinators;
|
||||
pub mod linearize_matches;
|
||||
pub mod linearize_vars;
|
||||
pub mod resolve_refs;
|
||||
pub mod resugar_string;
|
||||
pub mod unique_names;
|
||||
|
125
src/fun/transform/resugar_string.rs
Normal file
125
src/fun/transform/resugar_string.rs
Normal file
@ -0,0 +1,125 @@
|
||||
use crate::{
|
||||
fun::{builtins, Num, Pattern, Tag, Term},
|
||||
maybe_grow,
|
||||
};
|
||||
|
||||
impl Term {
|
||||
/// Converts lambda-encoded strings ending with String/nil to a string literals.
|
||||
pub fn resugar_strings(&mut self) {
|
||||
maybe_grow(|| {
|
||||
// Search for a String/cons pattern in the term and try to build a string from that point on.
|
||||
// If successful, replace the term with the string.
|
||||
// If not, keep as-is.
|
||||
match self {
|
||||
// Nil: String/nil
|
||||
Term::Ref { nam } if nam == builtins::SNIL => *self = Term::str(""),
|
||||
// Cons: @a @* (a <num> <str>)
|
||||
Term::Lam {
|
||||
tag: Tag::Static,
|
||||
pat: box Pattern::Var(Some(nam_cons_lam)),
|
||||
bod:
|
||||
box Term::Lam {
|
||||
tag: Tag::Static,
|
||||
pat: box Pattern::Var(None),
|
||||
bod:
|
||||
box Term::App {
|
||||
tag: Tag::Static,
|
||||
fun:
|
||||
box Term::App {
|
||||
tag: Tag::Static,
|
||||
fun: box Term::Var { nam: nam_cons_app },
|
||||
arg: box Term::Num { val: Num::U24(c) },
|
||||
},
|
||||
arg: nxt,
|
||||
},
|
||||
},
|
||||
} if nam_cons_lam == nam_cons_app => {
|
||||
let head = char::from_u32(*c).unwrap_or('.');
|
||||
if let Some(str) = build_string(nxt, head.to_string()) {
|
||||
*self = Term::str(&str);
|
||||
} else {
|
||||
// Not a string term, keep as-is.
|
||||
}
|
||||
}
|
||||
// Cons: (String/cons <num> <str>)
|
||||
Term::App {
|
||||
tag: Tag::Static,
|
||||
fun:
|
||||
box Term::App {
|
||||
tag: Tag::Static,
|
||||
fun: box Term::Ref { nam },
|
||||
arg: box Term::Num { val: Num::U24(c) },
|
||||
},
|
||||
arg: nxt,
|
||||
} if nam == builtins::SCONS => {
|
||||
let head = char::from_u32(*c).unwrap_or('.');
|
||||
if let Some(str) = build_string(nxt, head.to_string()) {
|
||||
*self = Term::str(&str);
|
||||
} else {
|
||||
// Not a string term, keep as-is.
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
for child in self.children_mut() {
|
||||
child.resugar_strings();
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn build_string(term: &Term, mut s: String) -> Option<String> {
|
||||
maybe_grow(|| {
|
||||
match term {
|
||||
// Nil: String/nil
|
||||
Term::Ref { nam } if nam == builtins::SNIL => Some(s),
|
||||
// Cons: @a @* (a <num> <str>)
|
||||
Term::Lam {
|
||||
tag: Tag::Static,
|
||||
pat: box Pattern::Var(Some(nam_cons_lam)),
|
||||
bod:
|
||||
box Term::Lam {
|
||||
tag: Tag::Static,
|
||||
pat: box Pattern::Var(None),
|
||||
bod:
|
||||
box Term::App {
|
||||
tag: Tag::Static,
|
||||
fun:
|
||||
box Term::App {
|
||||
tag: Tag::Static,
|
||||
fun: box Term::Var { nam: nam_cons_app },
|
||||
arg: box Term::Num { val: Num::U24(c) },
|
||||
},
|
||||
arg: nxt,
|
||||
},
|
||||
},
|
||||
} if nam_cons_lam == nam_cons_app => {
|
||||
// New string character, append and recurse
|
||||
let head = char::from_u32(*c).unwrap_or('.');
|
||||
s.push(head);
|
||||
build_string(nxt, s)
|
||||
}
|
||||
// Cons: (String/cons <num> <str>)
|
||||
Term::App {
|
||||
tag: Tag::Static,
|
||||
fun:
|
||||
box Term::App {
|
||||
tag: Tag::Static,
|
||||
fun: box Term::Ref { nam },
|
||||
arg: box Term::Num { val: Num::U24(c) },
|
||||
},
|
||||
arg: nxt,
|
||||
} if nam == builtins::SCONS => {
|
||||
// New string character, append and recurse
|
||||
let head = char::from_u32(*c).unwrap_or('.');
|
||||
s.push(head);
|
||||
build_string(nxt, s)
|
||||
}
|
||||
_ => {
|
||||
// Not a string term, stop
|
||||
None
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
@ -215,6 +215,7 @@ pub fn readback_hvm_net(net: &Net, book: &Book, labels: &Labels, linear: bool) -
|
||||
let net = hvmc_to_net(net);
|
||||
let mut term = net_to_term(&net, book, labels, linear, &mut diags);
|
||||
term.expand_generated(book);
|
||||
term.resugar_strings();
|
||||
(term, diags)
|
||||
}
|
||||
|
||||
|
@ -5,8 +5,8 @@ input_file: tests/golden_tests/cli/run_pretty.bend
|
||||
Result:
|
||||
λa switch a = a {
|
||||
0: λa switch a {
|
||||
0: (String/cons 98 (String/cons 97 String/nil));
|
||||
_: λ* (String/cons 116 (String/cons 97 String/nil));
|
||||
0: "ba";
|
||||
_: λ* "ta";
|
||||
};
|
||||
_: λ* λb λ* (b 97 λc λ* (c 116 λd λ* (d 97 String/nil)));
|
||||
_: λ* "ata";
|
||||
}
|
||||
|
@ -2,4 +2,4 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/chars.bend
|
||||
---
|
||||
λa λ* (a 4660 λb λ* (b 33 λc λ* (c 55 String/nil)))
|
||||
"ሴ!7"
|
||||
|
@ -2,4 +2,4 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/escape_sequences.bend
|
||||
---
|
||||
λa (Join (List/cons (String/cons 10 String/nil) (List/cons (String/cons 13 String/nil) (List/cons (String/cons 9 String/nil) (List/cons (String/cons 0 String/nil) (List/cons (String/cons 34 String/nil) (List/cons (String/cons 39 String/nil) (List/cons (String/cons 2814 String/nil) (List/cons (String/cons 92 String/nil) List/nil)))))))))
|
||||
λa (Join (List/cons "\n" (List/cons "\r" (List/cons "\t" (List/cons "\0" (List/cons "\"" (List/cons "'" (List/cons "\u{afe}" (List/cons "\\" List/nil)))))))))
|
||||
|
@ -2,4 +2,4 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/match_builtins.bend
|
||||
---
|
||||
{λa λ* (a 101 λb λ* (b 108 λc λ* (c 108 λd λ* (d 111 String/nil)))) λe λ* (e 119 λf λ* (f 111 λg λ* (g 114 λh λ* (h 108 λi λ* (i 100 String/nil)))))}
|
||||
{"ello" "world"}
|
||||
|
@ -2,4 +2,4 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/match_num_adt_tup_parser.bend
|
||||
---
|
||||
λ* λa (a {λb λ* (b 40 λc λ* (c 43 String/nil)) *})
|
||||
λ* λa (a {"(+" *})
|
||||
|
@ -2,4 +2,4 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/nested_list_and_string.bend
|
||||
---
|
||||
λa λb λ* (b a λc λ* (c λ* 2 λd λ* (d λe λ* (e λf λ* (f 7 λg λ* (g λh λ* (h 49 λi λ* (i 50 λj λ* (j 51 λk λ* (k 52 String/nil)))) λl λ* (l 9 List/nil))) λm λ* (m a (String/cons * (String/cons 52 (String/cons 50 String/nil))))) List/nil)))
|
||||
λa λb λ* (b a λc λ* (c λ* 2 λd λ* (d λe λ* (e λf λ* (f 7 λg λ* (g "1234" λl λ* (l 9 List/nil))) λm λ* (m a (String/cons * "42"))) List/nil)))
|
||||
|
@ -2,4 +2,4 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/nested_str.bend
|
||||
---
|
||||
λa λb λc λd λ* (d λe λ* (e 97 λf λ* (f 98 String/nil)) λg λ* (g λh λ* (h 99 λi λ* (i 100 String/nil)) String/nil))
|
||||
λa λb λc λd λ* (d "ab" λg λ* (g "cd" ""))
|
||||
|
@ -2,4 +2,4 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/readback_list_other_ctr.bend
|
||||
---
|
||||
λa λ* (a λb λ* (b 97 λc (c 98 λd λ* (d 99 String/nil))) λe λ* (e 1 λf (f 2 λg λ* (g 3 λh λ* (h 4 List/nil)))))
|
||||
λa λ* (a λb λ* (b 97 λc (c 98 "c")) λe λ* (e 1 λf (f 2 λg λ* (g 3 λh λ* (h 4 List/nil)))))
|
||||
|
@ -2,4 +2,4 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/str_concat.bend
|
||||
---
|
||||
λa λ* (a 104 λb λ* (b 101 λc λ* (c 108 λd λ* (d 108 λe λ* (e 111 λf λ* (f 32 λg λ* (g 119 λh λ* (h 111 λi λ* (i 114 λj λ* (j 108 λk λ* (k 100 String/nil)))))))))))
|
||||
"hello world"
|
||||
|
@ -2,4 +2,4 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/tup_list_strings.bend
|
||||
---
|
||||
{λa λ* (a {λb λ* (b 102 λc λ* (c 111 λd λ* (d 111 String/nil))) 0} λe λ* (e {λf λ* (f 102 λg λ* (g 111 λh λ* (h 111 String/nil))) 0} λi λ* (i {λj λ* (j 102 λk λ* (k 111 λl λ* (l 111 String/nil))) 1} List/nil))) 4}
|
||||
{λa λ* (a {"foo" 0} λe λ* (e {"foo" 0} λi λ* (i {"foo" 1} List/nil))) 4}
|
||||
|
@ -2,4 +2,4 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/unaplied_str.bend
|
||||
---
|
||||
λa λb λc λ* (c a λd λ* (d 98 λe λ* (e 99 λf λ* (f b String/nil))))
|
||||
λa λb λc λ* (c a λd λ* (d 98 λe λ* (e 99 λf λ* (f b ""))))
|
||||
|
@ -2,4 +2,4 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/world.bend
|
||||
---
|
||||
λa λ* (a 127758 String/nil)
|
||||
"🌎"
|
||||
|
@ -2,4 +2,4 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/wrong_string.bend
|
||||
---
|
||||
λa λ* (a λ* 4 λb λ* (b * String/nil))
|
||||
λa λ* (a λ* 4 λb λ* (b * ""))
|
||||
|
Loading…
Reference in New Issue
Block a user