diff options
Diffstat (limited to 'crates/rebel-lang/examples/repl.rs')
-rw-r--r-- | crates/rebel-lang/examples/repl.rs | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/crates/rebel-lang/examples/repl.rs b/crates/rebel-lang/examples/repl.rs new file mode 100644 index 0000000..0163c6b --- /dev/null +++ b/crates/rebel-lang/examples/repl.rs @@ -0,0 +1,78 @@ +use rebel_lang::{ + func::{Func, FuncDef, FuncType}, + typing::{ArrayLen, Type, TypeFamily}, + value::{Context, EvalError, Result, Value}, +}; +use rebel_parse::{recipe, tokenize}; + +fn intrinsic_array_len(params: &[Value]) -> Result<Value> { + assert!(params.len() == 1); + let Value::Array(array) = ¶ms[0] else { + panic!(); + }; + Ok(Value::Integer(array.len().try_into().or(Err(EvalError))?)) +} +fn intrinsic_string_len(params: &[Value]) -> Result<Value> { + assert!(params.len() == 1); + let Value::Str(string) = ¶ms[0] else { + panic!(); + }; + Ok(Value::Integer( + string.chars().count().try_into().or(Err(EvalError))?, + )) +} + +fn main() -> rustyline::Result<()> { + let mut ctx = Context::default(); + + ctx.methods.entry(TypeFamily::Array).or_default().insert( + "len", + Func { + typ: FuncType { + params: vec![Type::Array(Box::new(Type::Free), ArrayLen::Dynamic)], + ret: Type::Int, + }, + def: FuncDef::Intrinsic(intrinsic_array_len), + }, + ); + ctx.methods.entry(TypeFamily::Str).or_default().insert( + "len", + Func { + typ: FuncType { + params: vec![Type::Str], + ret: Type::Int, + }, + def: FuncDef::Intrinsic(intrinsic_string_len), + }, + ); + + let mut rl = rustyline::DefaultEditor::new()?; + + while let Ok(line) = rl.readline("> ") { + rl.add_history_entry(line.as_str())?; + let tokens = match tokenize::token_stream(&line) { + Ok(value) => value, + Err(err) => { + println!("Tokenize error: {err}"); + continue; + } + }; + let expr = match recipe::expr(&tokens) { + Ok(value) => value, + Err(err) => { + println!("Parse error: {err}"); + continue; + } + }; + let value = match ctx.eval(&expr) { + Ok(value) => value, + Err(err) => { + println!("Eval error: {err:?}"); + continue; + } + }; + println!("{value}"); + } + + Ok(()) +} |