feat: 新增对象字面量和属性访问表达式

This commit is contained in:
0264408
2026-02-10 17:13:40 +08:00
parent 5c5ca8600a
commit 521c7006d9
11 changed files with 188 additions and 66 deletions
+24
View File
@@ -0,0 +1,24 @@
//! 标准库:ioprint, input
use crate::interpreter::Value;
pub fn print(args: Vec<Value>) -> Value {
for (i, arg) in args.iter().enumerate() {
if i > 0 {
print!(" ");
}
print!("{}", arg);
}
println!();
Value::Nil
}
pub fn input(args: Vec<Value>) -> Value {
if let Some(prompt) = args.get(0) {
print!("{}", prompt);
std::io::Write::flush(&mut std::io::stdout()).unwrap();
}
let mut buffer = String::new();
std::io::stdin().read_line(&mut buffer).unwrap();
Value::String(buffer.trim_end().to_string())
}
+28
View File
@@ -0,0 +1,28 @@
//! 内置函数模块:按功能分组注册,便于扩展和维护。
mod io;
mod os;
use crate::interpreter::{Env, Value};
use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
/// 向全局环境注册所有标准库(io、os 等)
pub fn register_all(env: &Rc<RefCell<Env>>) {
let mut e = env.borrow_mut();
// io
let mut io = HashMap::new();
io.insert("print".into(), Value::NativeFunction(io::print));
io.insert("input".into(), Value::NativeFunction(io::input));
e.define("io".into(), Value::Object(Rc::new(RefCell::new(io))));
// input and print can be used as global functions for convenience
e.define("print".into(), Value::NativeFunction(io::print));
e.define("input".into(), Value::NativeFunction(io::input));
// os
let mut os = HashMap::new();
os.insert("clock".into(), Value::NativeFunction(os::clock));
e.define("os".into(), Value::Object(Rc::new(RefCell::new(os))));
}
+12
View File
@@ -0,0 +1,12 @@
//! 标准库:osclock
use crate::interpreter::Value;
pub fn clock(_args: Vec<Value>) -> Value {
Value::Number(
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_secs_f64(),
)
}
+43 -43
View File
@@ -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())
}
+5
View File
@@ -1,9 +1,11 @@
pub mod builtins;
pub mod env;
pub mod interpreter;
pub use env::Env;
pub use interpreter::Interpreter;
use std::collections::HashMap;
use std::rc::Rc;
use std::cell::RefCell;
use std::fmt;
@@ -16,6 +18,7 @@ pub enum Value {
String(String),
Bool(bool),
Nil,
Object(Rc<RefCell<HashMap<String, Value>>>),
Function(Rc<Function>),
NativeFunction(NativeFn),
}
@@ -27,6 +30,7 @@ impl std::fmt::Debug for Value {
Value::String(s) => write!(f, "String({:?})", s),
Value::Bool(b) => write!(f, "Bool({:?})", b),
Value::Nil => write!(f, "Nil"),
Value::Object(_) => write!(f, "Object(...)"),
Value::Function(_) => write!(f, "Function(...)"),
Value::NativeFunction(_) => write!(f, "NativeFunction(...)"),
}
@@ -40,6 +44,7 @@ impl fmt::Display for Value {
Value::String(s) => write!(f, "{}", s),
Value::Bool(b) => write!(f, "{}", b),
Value::Nil => write!(f, "nil"),
Value::Object(_) => write!(f, "<object>"),
Value::Function(_) => write!(f, "<function>"),
Value::NativeFunction(_) => write!(f, "<native function>"),
}