mirror of
https://github.com/HigherOrderCO/Bend.git
synced 2024-09-11 03:45:29 +03:00
[sc-688] Add string resugaring of readback term
This commit is contained in:
parent
a763052c11
commit
2f7ae6c276
@ -85,6 +85,7 @@
|
|||||||
"scopeless",
|
"scopeless",
|
||||||
"scrutinee",
|
"scrutinee",
|
||||||
"snil",
|
"snil",
|
||||||
|
"SOTA",
|
||||||
"stdext",
|
"stdext",
|
||||||
"struct",
|
"struct",
|
||||||
"subcmd",
|
"subcmd",
|
||||||
|
@ -16,4 +16,5 @@ pub mod float_combinators;
|
|||||||
pub mod linearize_matches;
|
pub mod linearize_matches;
|
||||||
pub mod linearize_vars;
|
pub mod linearize_vars;
|
||||||
pub mod resolve_refs;
|
pub mod resolve_refs;
|
||||||
|
pub mod resugar_string;
|
||||||
pub mod unique_names;
|
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 net = hvmc_to_net(net);
|
||||||
let mut term = net_to_term(&net, book, labels, linear, &mut diags);
|
let mut term = net_to_term(&net, book, labels, linear, &mut diags);
|
||||||
term.expand_generated(book);
|
term.expand_generated(book);
|
||||||
|
term.resugar_strings();
|
||||||
(term, diags)
|
(term, diags)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,8 +5,8 @@ input_file: tests/golden_tests/cli/run_pretty.bend
|
|||||||
Result:
|
Result:
|
||||||
λa switch a = a {
|
λa switch a = a {
|
||||||
0: λa switch a {
|
0: λa switch a {
|
||||||
0: (String/cons 98 (String/cons 97 String/nil));
|
0: "ba";
|
||||||
_: λ* (String/cons 116 (String/cons 97 String/nil));
|
_: λ* "ta";
|
||||||
};
|
};
|
||||||
_: λ* λb λ* (b 97 λc λ* (c 116 λd λ* (d 97 String/nil)));
|
_: λ* "ata";
|
||||||
}
|
}
|
||||||
|
@ -2,4 +2,4 @@
|
|||||||
source: tests/golden_tests.rs
|
source: tests/golden_tests.rs
|
||||||
input_file: tests/golden_tests/run_file/chars.bend
|
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
|
source: tests/golden_tests.rs
|
||||||
input_file: tests/golden_tests/run_file/escape_sequences.bend
|
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
|
source: tests/golden_tests.rs
|
||||||
input_file: tests/golden_tests/run_file/match_builtins.bend
|
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
|
source: tests/golden_tests.rs
|
||||||
input_file: tests/golden_tests/run_file/match_num_adt_tup_parser.bend
|
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
|
source: tests/golden_tests.rs
|
||||||
input_file: tests/golden_tests/run_file/nested_list_and_string.bend
|
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
|
source: tests/golden_tests.rs
|
||||||
input_file: tests/golden_tests/run_file/nested_str.bend
|
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
|
source: tests/golden_tests.rs
|
||||||
input_file: tests/golden_tests/run_file/readback_list_other_ctr.bend
|
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
|
source: tests/golden_tests.rs
|
||||||
input_file: tests/golden_tests/run_file/str_concat.bend
|
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
|
source: tests/golden_tests.rs
|
||||||
input_file: tests/golden_tests/run_file/tup_list_strings.bend
|
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
|
source: tests/golden_tests.rs
|
||||||
input_file: tests/golden_tests/run_file/unaplied_str.bend
|
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
|
source: tests/golden_tests.rs
|
||||||
input_file: tests/golden_tests/run_file/world.bend
|
input_file: tests/golden_tests/run_file/world.bend
|
||||||
---
|
---
|
||||||
λa λ* (a 127758 String/nil)
|
"🌎"
|
||||||
|
@ -2,4 +2,4 @@
|
|||||||
source: tests/golden_tests.rs
|
source: tests/golden_tests.rs
|
||||||
input_file: tests/golden_tests/run_file/wrong_string.bend
|
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