Add first working pipeline of parse -> ast -> instr -> render
Signed-off-by: Marcel Müller <neikos@neikos.email>
This commit is contained in:
parent
f5050e369e
commit
1ea15f0e49
5 changed files with 234 additions and 6 deletions
|
|
@ -1,7 +1,70 @@
|
|||
pub struct EvalStack {
|
||||
stack: Vec<Evaluation>,
|
||||
use std::collections::HashMap;
|
||||
|
||||
use displaydoc::Display;
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::Context;
|
||||
use crate::emit::Instruction;
|
||||
|
||||
#[derive(Debug, Error, Display)]
|
||||
enum EvalError {
|
||||
/// An unknown variable was encountered: .0
|
||||
UnknownVariable(String),
|
||||
/// An explicit abort was requested
|
||||
ExplicitAbort,
|
||||
}
|
||||
|
||||
pub enum Evaluation {
|
||||
AppendContent { content: String },
|
||||
fn execute(instructions: &[Instruction], global_context: &Context) -> Result<String, EvalError> {
|
||||
let mut output = String::new();
|
||||
|
||||
let mut scopes: HashMap<crate::emit::VariableSlot, serde_json::Value> = HashMap::new();
|
||||
|
||||
for instr in instructions {
|
||||
match instr {
|
||||
Instruction::AppendContent { content } => output.push_str(content),
|
||||
Instruction::LoadFromContextToSlot { name, slot } => {
|
||||
let value = global_context
|
||||
.values
|
||||
.get(name)
|
||||
.ok_or(EvalError::UnknownVariable(name.clone()))?;
|
||||
|
||||
scopes.insert(*slot, value.clone());
|
||||
}
|
||||
Instruction::EmitFromSlot { slot } => {
|
||||
let value = scopes.get(slot).unwrap().as_str().unwrap();
|
||||
output.push_str(value);
|
||||
}
|
||||
Instruction::PushScope { inherit_parent: _ } => todo!(),
|
||||
Instruction::Abort => return Err(EvalError::ExplicitAbort),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(output)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::Context;
|
||||
use crate::eval::execute;
|
||||
|
||||
#[test]
|
||||
fn check_simple_variable_interpolation() {
|
||||
let input = "Hello {{= world }}";
|
||||
|
||||
let parsed = crate::parser::parse(input).unwrap();
|
||||
|
||||
let ast = crate::ast::parse(parsed.tokens()).unwrap();
|
||||
|
||||
let emit = crate::emit::emit_machine(ast);
|
||||
|
||||
let mut context = Context::new();
|
||||
context.insert("world", "World");
|
||||
let output = execute(&emit, &context);
|
||||
|
||||
insta::assert_debug_snapshot!(output, @r#"
|
||||
Ok(
|
||||
"Hello World",
|
||||
)
|
||||
"#);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue