feat: 新增对象字面量和属性访问表达式
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
use crate::ast::*;
|
||||
use crate::error::RuntimeError;
|
||||
use super::{Value, Env, Function};
|
||||
use std::collections::HashMap;
|
||||
use std::rc::Rc;
|
||||
use std::cell::RefCell;
|
||||
|
||||
@@ -11,27 +12,13 @@ pub struct Interpreter {
|
||||
impl Interpreter {
|
||||
pub fn new() -> Self {
|
||||
let env = Rc::new(RefCell::new(Env::new(None)));
|
||||
|
||||
let mut env_mut = env.borrow_mut();
|
||||
|
||||
// 注册内置函数
|
||||
env_mut.define("print".to_string(), Value::NativeFunction(native_print));
|
||||
env_mut.define("input".to_string(), Value::NativeFunction(native_input));
|
||||
env_mut.define("clock".to_string(), Value::NativeFunction(native_clock));
|
||||
|
||||
drop(env_mut);
|
||||
|
||||
super::builtins::register_all(&env);
|
||||
Self { env }
|
||||
}
|
||||
|
||||
pub fn interpret(&mut self, statements: Vec<Stmt>) -> Result<(), RuntimeError> {
|
||||
for stmt in statements {
|
||||
if let Some(val) = self.execute(stmt.clone())? {
|
||||
// 如果是表达式语句且结果不是 Nil,打印结果
|
||||
if matches!(stmt, Stmt::ExprStmt(_)) && !matches!(val, Value::Nil) {
|
||||
println!("{}", val);
|
||||
}
|
||||
}
|
||||
self.execute(stmt)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -124,6 +111,46 @@ impl Interpreter {
|
||||
}
|
||||
Ok(val)
|
||||
}
|
||||
Expr::Get { object, name } => {
|
||||
let obj = self.evaluate(*object)?;
|
||||
match obj {
|
||||
Value::Object(map) => {
|
||||
match map.borrow().get(&name) {
|
||||
Some(val) => Ok(val.clone()),
|
||||
None => Err(RuntimeError::RuntimeError {
|
||||
message: format!("Undefined property '{}'", name),
|
||||
token: None,
|
||||
}),
|
||||
}
|
||||
}
|
||||
_ => Err(RuntimeError::RuntimeError {
|
||||
message: "Only objects have properties".to_string(),
|
||||
token: None,
|
||||
}),
|
||||
}
|
||||
}
|
||||
Expr::Set { object, name, value } => {
|
||||
let obj = self.evaluate(*object)?;
|
||||
match obj {
|
||||
Value::Object(map) => {
|
||||
let val = self.evaluate(*value)?;
|
||||
map.borrow_mut().insert(name, val.clone());
|
||||
Ok(val)
|
||||
}
|
||||
_ => Err(RuntimeError::RuntimeError {
|
||||
message: "Only objects have properties".to_string(),
|
||||
token: None,
|
||||
}),
|
||||
}
|
||||
}
|
||||
Expr::ObjectLiteral { properties } => {
|
||||
let mut map = HashMap::new();
|
||||
for (key, value_expr) in properties {
|
||||
let value = self.evaluate(value_expr)?;
|
||||
map.insert(key, value);
|
||||
}
|
||||
Ok(Value::Object(Rc::new(RefCell::new(map))))
|
||||
}
|
||||
Expr::Unary { op, right } => {
|
||||
let val = self.evaluate(*right)?;
|
||||
match op {
|
||||
@@ -276,30 +303,3 @@ impl Interpreter {
|
||||
}
|
||||
}
|
||||
|
||||
// 内置函数实现
|
||||
fn native_print(args: Vec<Value>) -> Value {
|
||||
for (i, arg) in args.iter().enumerate() {
|
||||
if i > 0 {
|
||||
print!(" ");
|
||||
}
|
||||
print!("{}", arg);
|
||||
}
|
||||
println!();
|
||||
Value::Nil
|
||||
}
|
||||
|
||||
fn native_input(args: Vec<Value>) -> Value {
|
||||
if let Some(prompt) = args.get(0) {
|
||||
print!("{}", prompt);
|
||||
use std::io::Write;
|
||||
std::io::stdout().flush().unwrap();
|
||||
}
|
||||
let mut buffer = String::new();
|
||||
std::io::stdin().read_line(&mut buffer).unwrap();
|
||||
Value::String(buffer.trim_end().to_string())
|
||||
}
|
||||
|
||||
// 获取当前时间
|
||||
fn native_clock(_args: Vec<Value>) -> Value {
|
||||
Value::Number(std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_secs_f64())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user