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() {
|
||||
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();
|
||||
if !lex_errs.is_empty() {
|
||||
|
@ -73,13 +78,13 @@ pub fn main() {
|
|||
let (ast, _) = parser()
|
||||
.parse(Stream::from_iter(to_parse).map((0..src.len()).into(), |(t, s)| (t, s)))
|
||||
.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::<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 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::Keyword(k) => Ok(Value::Keyword(k)),
|
||||
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) => {
|
||||
let to = ctx.len();
|
||||
let mut result = Value::Nil;
|
||||
|
|
Loading…
Reference in New Issue
Block a user