add argument reading for lox
This commit is contained in:
parent
98dfbc8503
commit
97fdc89316
6 changed files with 60 additions and 8 deletions
|
@ -96,5 +96,6 @@ class Interpreter {
|
|||
}
|
||||
}
|
||||
|
||||
var interpreter = Interpreter("bf/game_of_life.bf");
|
||||
var bfScript = args(0);
|
||||
var interpreter = Interpreter(bfScript);
|
||||
interpreter.run();
|
||||
|
|
|
@ -19,6 +19,9 @@ pub struct RunConfig {
|
|||
/// Path to Lox source file.
|
||||
#[arg(short, long)]
|
||||
pub source: PathBuf,
|
||||
/// Arguments to pass to the Lox script (must be after '--').
|
||||
#[arg(last = true)]
|
||||
pub script_args: Vec<String>,
|
||||
}
|
||||
|
||||
/// Available commands for the Lox interpreter
|
||||
|
|
|
@ -60,12 +60,18 @@ pub struct Interpreter {
|
|||
/// Default configuration for the interpreter, with builtin native functions.
|
||||
impl Default for Interpreter {
|
||||
fn default() -> Self {
|
||||
Interpreter::new(Vec::new())
|
||||
}
|
||||
}
|
||||
|
||||
impl Interpreter {
|
||||
pub fn new(cli_args: Vec<String>) -> Self {
|
||||
let env: Rc<RefCell<Environment>> = Default::default();
|
||||
|
||||
{
|
||||
// add all native functions to global environment
|
||||
let mut env = env.borrow_mut();
|
||||
for (name, fun) in native_functions::all() {
|
||||
for (name, fun) in native_functions::all(cli_args) {
|
||||
env.define(name, fun);
|
||||
}
|
||||
}
|
||||
|
@ -76,9 +82,7 @@ impl Default for Interpreter {
|
|||
locals: HashMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Interpreter {
|
||||
/// Execute a list of statements in sequence.
|
||||
/// Log errors but continue execution.
|
||||
pub fn run(&mut self, statements: Vec<Statement>) -> Result<(), InterpreterError> {
|
||||
|
|
|
@ -53,9 +53,9 @@ pub enum RoxError {
|
|||
}
|
||||
|
||||
/// Read the source code in a file and scan it to tokens.
|
||||
pub fn compile(source: &Path) -> Result<(), io::Error> {
|
||||
pub fn compile(source: &Path, cli_args: Vec<String>) -> Result<(), io::Error> {
|
||||
let input = fs::read_to_string(source)?;
|
||||
let mut interpreter = Interpreter::default();
|
||||
let mut interpreter = Interpreter::new(cli_args);
|
||||
|
||||
run(&input, &mut interpreter);
|
||||
|
||||
|
|
|
@ -23,7 +23,8 @@ fn main() {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
if let Err(e) = rox::compile(&compile_config.source) {
|
||||
if let Err(e) = rox::compile(&compile_config.source, compile_config.script_args.clone())
|
||||
{
|
||||
error!(
|
||||
"failed to compile {}: {}",
|
||||
&compile_config.source.to_string_lossy(),
|
||||
|
|
|
@ -224,8 +224,47 @@ impl Callable for PromptAscii {
|
|||
}
|
||||
}
|
||||
|
||||
struct CliArgs {
|
||||
cli_args: Vec<String>,
|
||||
}
|
||||
impl Callable for CliArgs {
|
||||
fn name(&self) -> String {
|
||||
"args".into()
|
||||
}
|
||||
|
||||
fn arity(&self) -> usize {
|
||||
1
|
||||
}
|
||||
|
||||
fn call(
|
||||
&self,
|
||||
_interpreter: &mut Interpreter,
|
||||
args: Vec<Value>,
|
||||
) -> Result<Value, CallingError> {
|
||||
if args.len() != self.arity() {
|
||||
return Err(CallingError::ArgumentMismatch(self.arity(), args.len()));
|
||||
}
|
||||
|
||||
let idx = args
|
||||
.first()
|
||||
.ok_or(CallingError::CallFailed("arg not readable".into()))?;
|
||||
if let Value::Number(idx) = idx {
|
||||
let idx: usize = idx.0 as usize;
|
||||
Ok(self
|
||||
.cli_args
|
||||
.get(idx)
|
||||
.map(|x| Value::String(x.clone()))
|
||||
.unwrap_or(Value::Nil))
|
||||
} else {
|
||||
Err(CallingError::CallFailed(
|
||||
"arg index must be a number".into(),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Return all native functions available to the Lox interpreter
|
||||
pub fn all() -> Vec<(String, Value)> {
|
||||
pub fn all(cli_args: Vec<String>) -> Vec<(String, Value)> {
|
||||
vec![
|
||||
(
|
||||
"asciiOut".into(),
|
||||
|
@ -247,5 +286,9 @@ pub fn all() -> Vec<(String, Value)> {
|
|||
"promptAscii".into(),
|
||||
Value::Callable((Rc::new(PromptAscii {}), CallableType::Function)),
|
||||
),
|
||||
(
|
||||
"args".into(),
|
||||
Value::Callable((Rc::new(CliArgs { cli_args }), CallableType::Function)),
|
||||
),
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue