complete string interpolation
This commit is contained in:
parent
b6c4c6375b
commit
c9038fd8fb
15
src/main.rs
15
src/main.rs
|
@ -58,7 +58,12 @@ use crate::base::*;
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let src = "
|
let src = "
|
||||||
\"thing\"
|
let foo = :foo
|
||||||
|
let bar = 42
|
||||||
|
let baz = \"foo bar baz\"
|
||||||
|
let quux = (1, 2, [3, 4, #{:five 6, :seven 8}])
|
||||||
|
\"{foo} {bar} {baz}
|
||||||
|
{quux} {fuzz} TADA!\"
|
||||||
";
|
";
|
||||||
let (tokens, lex_errs) = lexer().parse(src).into_output_errors();
|
let (tokens, lex_errs) = lexer().parse(src).into_output_errors();
|
||||||
if !lex_errs.is_empty() {
|
if !lex_errs.is_empty() {
|
||||||
|
@ -73,13 +78,13 @@ pub fn main() {
|
||||||
let (ast, _) = parser()
|
let (ast, _) = parser()
|
||||||
.parse(Stream::from_iter(to_parse).map((0..src.len()).into(), |(t, s)| (t, s)))
|
.parse(Stream::from_iter(to_parse).map((0..src.len()).into(), |(t, s)| (t, s)))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
println!("{}", ast);
|
// println!("{}", ast);
|
||||||
|
|
||||||
// let mut ctx = base();
|
let mut ctx = base();
|
||||||
|
|
||||||
// let result = eval(&ast, &mut ctx).unwrap();
|
let result = eval(&ast, &mut ctx).unwrap();
|
||||||
|
|
||||||
// println!("{}", result);
|
println!("{}", result);
|
||||||
|
|
||||||
// struct_scalpel::print_dissection_info::<value::Value>()
|
// struct_scalpel::print_dissection_info::<value::Value>()
|
||||||
// struct_scalpel::print_dissection_info::<parser::Ast>();
|
// struct_scalpel::print_dissection_info::<parser::Ast>();
|
||||||
|
|
34
src/value.rs
34
src/value.rs
|
@ -175,3 +175,37 @@ impl<'src> PartialEq for Value<'src> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Eq for Value<'_> {}
|
impl Eq for Value<'_> {}
|
||||||
|
|
||||||
|
impl Value<'_> {
|
||||||
|
pub fn interpolate(&self) -> String {
|
||||||
|
match self {
|
||||||
|
Value::Nil => String::new(),
|
||||||
|
Value::Boolean(b) => format!("{b}"),
|
||||||
|
Value::Number(n) => format!("{n}"),
|
||||||
|
Value::Keyword(k) => format!(":{k}"),
|
||||||
|
Value::AllocatedString(s) => format!("{s}"),
|
||||||
|
Value::InternedString(s) => s.to_string(),
|
||||||
|
Value::Box(_, x) => x.borrow().interpolate(),
|
||||||
|
Value::Tuple(xs) => xs
|
||||||
|
.iter()
|
||||||
|
.map(|x| x.interpolate())
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(", "),
|
||||||
|
Value::List(xs) => xs
|
||||||
|
.iter()
|
||||||
|
.map(|x| x.interpolate())
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(", "),
|
||||||
|
Value::Dict(xs) => xs
|
||||||
|
.iter()
|
||||||
|
.map(|(k, v)| format!(":{} {}", k, v.interpolate()))
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(", "),
|
||||||
|
Value::Fn(x) => format!("fn {}", x.name.to_string()),
|
||||||
|
Value::Placeholder => unreachable!(),
|
||||||
|
Value::Args(_) => unreachable!(),
|
||||||
|
Value::Recur(_) => unreachable!(),
|
||||||
|
Value::Base(_) => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
23
src/vm.rs
23
src/vm.rs
|
@ -282,7 +282,28 @@ pub fn eval<'src, 'a>(
|
||||||
Ast::Number(n) => Ok(Value::Number(*n)),
|
Ast::Number(n) => Ok(Value::Number(*n)),
|
||||||
Ast::Keyword(k) => Ok(Value::Keyword(k)),
|
Ast::Keyword(k) => Ok(Value::Keyword(k)),
|
||||||
Ast::String(s) => Ok(Value::InternedString(s)),
|
Ast::String(s) => Ok(Value::InternedString(s)),
|
||||||
Ast::Interpolated(s) => todo!(),
|
Ast::Interpolated(parts) => {
|
||||||
|
let mut interpolated = String::new();
|
||||||
|
for part in parts {
|
||||||
|
match &part.0 {
|
||||||
|
StringPart::Data(s) => interpolated.push_str(s.as_str()),
|
||||||
|
StringPart::Word(w) => {
|
||||||
|
let val = if let Some((_, value)) =
|
||||||
|
ctx.iter().rev().find(|(name, _)| w == name)
|
||||||
|
{
|
||||||
|
value.clone()
|
||||||
|
} else {
|
||||||
|
return Err(LudusError {
|
||||||
|
msg: format!("unbound name {w}"),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
interpolated.push_str(val.interpolate().as_str())
|
||||||
|
}
|
||||||
|
StringPart::Inline(_) => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(Value::AllocatedString(Rc::new(interpolated)))
|
||||||
|
}
|
||||||
Ast::Block(exprs) => {
|
Ast::Block(exprs) => {
|
||||||
let to = ctx.len();
|
let to = ctx.len();
|
||||||
let mut result = Value::Nil;
|
let mut result = Value::Nil;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user