Simplify "run" function
This commit is contained in:
parent
de30f241a8
commit
f2c0786bfb
@ -10,12 +10,10 @@ use crate::{
|
|||||||
ValueError,
|
ValueError,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn run<'src>(
|
pub fn run(source: &str) -> Result<Option<Value>, DustError> {
|
||||||
source: &'src str,
|
|
||||||
context: &mut Context,
|
|
||||||
) -> Result<Option<Value>, DustError<'src>> {
|
|
||||||
let abstract_syntax_tree = parse(source)?;
|
let abstract_syntax_tree = parse(source)?;
|
||||||
let mut analyzer = Analyzer::new(&abstract_syntax_tree, context);
|
let mut context = Context::new();
|
||||||
|
let mut analyzer = Analyzer::new(&abstract_syntax_tree, &mut context);
|
||||||
|
|
||||||
analyzer
|
analyzer
|
||||||
.analyze()
|
.analyze()
|
||||||
@ -26,7 +24,7 @@ pub fn run<'src>(
|
|||||||
|
|
||||||
let mut vm = Vm::new(abstract_syntax_tree);
|
let mut vm = Vm::new(abstract_syntax_tree);
|
||||||
|
|
||||||
vm.run(context)
|
vm.run(&mut context)
|
||||||
.map_err(|vm_error| DustError::VmError { vm_error, source })
|
.map_err(|vm_error| DustError::VmError { vm_error, source })
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -629,223 +627,181 @@ mod tests {
|
|||||||
fn to_string() {
|
fn to_string() {
|
||||||
let input = "to_string(42)";
|
let input = "to_string(42)";
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(run(input), Ok(Some(Value::string("42".to_string()))));
|
||||||
run(input, &mut Context::new()),
|
|
||||||
Ok(Some(Value::string("42".to_string())))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn r#if() {
|
fn r#if() {
|
||||||
let input = "if true { 1 }";
|
let input = "if true { 1 }";
|
||||||
|
|
||||||
assert_eq!(run(input, &mut Context::new()), Ok(None));
|
assert_eq!(run(input), Ok(None));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn if_else() {
|
fn if_else() {
|
||||||
let input = "if false { 1 } else { 2 }";
|
let input = "if false { 1 } else { 2 }";
|
||||||
|
|
||||||
assert_eq!(run(input, &mut Context::new()), Ok(Some(Value::integer(2))));
|
assert_eq!(run(input), Ok(Some(Value::integer(2))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn if_else_if() {
|
fn if_else_if() {
|
||||||
let input = "if false { 1 } else if true { 2 }";
|
let input = "if false { 1 } else if true { 2 }";
|
||||||
|
|
||||||
assert_eq!(run(input, &mut Context::new()), Ok(None));
|
assert_eq!(run(input), Ok(None));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn if_else_if_else() {
|
fn if_else_if_else() {
|
||||||
let input = "if false { 1 } else if false { 2 } else { 3 }";
|
let input = "if false { 1 } else if false { 2 } else { 3 }";
|
||||||
|
|
||||||
assert_eq!(run(input, &mut Context::new()), Ok(Some(Value::integer(3))));
|
assert_eq!(run(input), Ok(Some(Value::integer(3))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn while_loop() {
|
fn while_loop() {
|
||||||
let input = "x = 0; while x < 5 { x += 1; } x";
|
let input = "x = 0; while x < 5 { x += 1; } x";
|
||||||
|
|
||||||
assert_eq!(run(input, &mut Context::new()), Ok(Some(Value::integer(5))));
|
assert_eq!(run(input), Ok(Some(Value::integer(5))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add_assign() {
|
fn add_assign() {
|
||||||
let input = "x = 1; x += 1; x";
|
let input = "x = 1; x += 1; x";
|
||||||
|
|
||||||
assert_eq!(run(input, &mut Context::new()), Ok(Some(Value::integer(2))));
|
assert_eq!(run(input), Ok(Some(Value::integer(2))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn or() {
|
fn or() {
|
||||||
let input = "true || false";
|
let input = "true || false";
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(run(input), Ok(Some(Value::boolean(true))));
|
||||||
run(input, &mut Context::new()),
|
|
||||||
Ok(Some(Value::boolean(true)))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn map_equal() {
|
fn map_equal() {
|
||||||
let input = "{ y = 'foo' } == { y = 'foo' }";
|
let input = "{ y = 'foo' } == { y = 'foo' }";
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(run(input), Ok(Some(Value::boolean(true))));
|
||||||
run(input, &mut Context::new()),
|
|
||||||
Ok(Some(Value::boolean(true)))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn integer_equal() {
|
fn integer_equal() {
|
||||||
let input = "42 == 42";
|
let input = "42 == 42";
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(run(input), Ok(Some(Value::boolean(true))));
|
||||||
run(input, &mut Context::new()),
|
|
||||||
Ok(Some(Value::boolean(true)))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn modulo() {
|
fn modulo() {
|
||||||
let input = "42 % 2";
|
let input = "42 % 2";
|
||||||
|
|
||||||
assert_eq!(run(input, &mut Context::new()), Ok(Some(Value::integer(0))));
|
assert_eq!(run(input), Ok(Some(Value::integer(0))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn divide() {
|
fn divide() {
|
||||||
let input = "42 / 2";
|
let input = "42 / 2";
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(run(input), Ok(Some(Value::integer(21))));
|
||||||
run(input, &mut Context::new()),
|
|
||||||
Ok(Some(Value::integer(21)))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn less_than() {
|
fn less_than() {
|
||||||
let input = "2 < 3";
|
let input = "2 < 3";
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(run(input), Ok(Some(Value::boolean(true))));
|
||||||
run(input, &mut Context::new()),
|
|
||||||
Ok(Some(Value::boolean(true)))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn less_than_or_equal() {
|
fn less_than_or_equal() {
|
||||||
let input = "42 <= 42";
|
let input = "42 <= 42";
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(run(input), Ok(Some(Value::boolean(true))));
|
||||||
run(input, &mut Context::new()),
|
|
||||||
Ok(Some(Value::boolean(true)))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn greater_than() {
|
fn greater_than() {
|
||||||
let input = "2 > 3";
|
let input = "2 > 3";
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(run(input), Ok(Some(Value::boolean(false))));
|
||||||
run(input, &mut Context::new()),
|
|
||||||
Ok(Some(Value::boolean(false)))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn greater_than_or_equal() {
|
fn greater_than_or_equal() {
|
||||||
let input = "42 >= 42";
|
let input = "42 >= 42";
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(run(input), Ok(Some(Value::boolean(true))));
|
||||||
run(input, &mut Context::new()),
|
|
||||||
Ok(Some(Value::boolean(true)))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn integer_saturating_add() {
|
fn integer_saturating_add() {
|
||||||
let input = "9223372036854775807 + 1";
|
let input = "9223372036854775807 + 1";
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(run(input), Ok(Some(Value::integer(i64::MAX))));
|
||||||
run(input, &mut Context::new()),
|
|
||||||
Ok(Some(Value::integer(i64::MAX)))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn integer_saturating_sub() {
|
fn integer_saturating_sub() {
|
||||||
let input = "-9223372036854775808 - 1";
|
let input = "-9223372036854775808 - 1";
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(run(input), Ok(Some(Value::integer(i64::MIN))));
|
||||||
run(input, &mut Context::new()),
|
|
||||||
Ok(Some(Value::integer(i64::MIN)))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn multiply() {
|
fn multiply() {
|
||||||
let input = "2 * 3";
|
let input = "2 * 3";
|
||||||
|
|
||||||
assert_eq!(run(input, &mut Context::new()), Ok(Some(Value::integer(6))));
|
assert_eq!(run(input), Ok(Some(Value::integer(6))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn boolean() {
|
fn boolean() {
|
||||||
let input = "true";
|
let input = "true";
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(run(input), Ok(Some(Value::boolean(true))));
|
||||||
run(input, &mut Context::new()),
|
|
||||||
Ok(Some(Value::boolean(true)))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn is_even() {
|
fn is_even() {
|
||||||
let input = "is_even(42)";
|
let input = "is_even(42)";
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(run(input), Ok(Some(Value::boolean(true))));
|
||||||
run(input, &mut Context::new()),
|
|
||||||
Ok(Some(Value::boolean(true)))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn is_odd() {
|
fn is_odd() {
|
||||||
let input = "is_odd(42)";
|
let input = "is_odd(42)";
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(run(input), Ok(Some(Value::boolean(false))));
|
||||||
run(input, &mut Context::new()),
|
|
||||||
Ok(Some(Value::boolean(false)))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn length() {
|
fn length() {
|
||||||
let input = "length([1, 2, 3])";
|
let input = "length([1, 2, 3])";
|
||||||
|
|
||||||
assert_eq!(run(input, &mut Context::new()), Ok(Some(Value::integer(3))));
|
assert_eq!(run(input), Ok(Some(Value::integer(3))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn list_access() {
|
fn list_access() {
|
||||||
let input = "[1, 2, 3].1";
|
let input = "[1, 2, 3].1";
|
||||||
|
|
||||||
assert_eq!(run(input, &mut Context::new()), Ok(Some(Value::integer(2))));
|
assert_eq!(run(input), Ok(Some(Value::integer(2))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add() {
|
fn add() {
|
||||||
let input = "1 + 2";
|
let input = "1 + 2";
|
||||||
|
|
||||||
assert_eq!(run(input, &mut Context::new()), Ok(Some(Value::integer(3))));
|
assert_eq!(run(input), Ok(Some(Value::integer(3))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add_multiple() {
|
fn add_multiple() {
|
||||||
let input = "1 + 2 + 3";
|
let input = "1 + 2 + 3";
|
||||||
|
|
||||||
assert_eq!(run(input, &mut Context::new()), Ok(Some(Value::integer(6))));
|
assert_eq!(run(input), Ok(Some(Value::integer(6))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use std::fs::read_to_string;
|
use std::fs::read_to_string;
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use dust_lang::{run, Context};
|
use dust_lang::run;
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
struct Cli {
|
struct Cli {
|
||||||
@ -13,21 +13,20 @@ struct Cli {
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let args = Cli::parse();
|
let args = Cli::parse();
|
||||||
let mut context = Context::new();
|
|
||||||
|
|
||||||
if let Some(command) = &args.command {
|
if let Some(command) = &args.command {
|
||||||
run_and_display_errors(command, &mut context);
|
run_and_display_errors(command);
|
||||||
} else if let Some(path) = &args.path {
|
} else if let Some(path) = &args.path {
|
||||||
let source = read_to_string(path).expect("Failed to read file");
|
let source = read_to_string(path).expect("Failed to read file");
|
||||||
|
|
||||||
run_and_display_errors(&source, &mut context)
|
run_and_display_errors(&source)
|
||||||
} else {
|
} else {
|
||||||
panic!("No command or path provided");
|
panic!("No command or path provided");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_and_display_errors(source: &str, variables: &mut Context) {
|
fn run_and_display_errors(source: &str) {
|
||||||
match run(source, variables) {
|
match run(source) {
|
||||||
Ok(return_value) => {
|
Ok(return_value) => {
|
||||||
if let Some(value) = return_value {
|
if let Some(value) = return_value {
|
||||||
println!("{}", value);
|
println!("{}", value);
|
||||||
|
Loading…
Reference in New Issue
Block a user