d854b22006
Phase 1-3: 基础VM架构 - 新增 Runtime trait: 抽象树遍历解释器和VM的共同接口 - NativeFn 改为接受 &mut dyn Runtime - 重构所有内置函数使用新签名 - vm/opcode.rs: 33个字节码指令 + 编码/解码辅助函数 - vm/compiler.rs: AST→字节码编译器,支持变量解析、跳转回填、作用域 - vm/vm.rs: 栈式VM执行循环,支持全局变量、原生函数调用 - lib.rs: 新增 run_file_vm() + --vm CLI标志 - 修复: 跳转偏移计算、对象字面量编译 工作特性: 算术、变量、while/for循环、条件、数组、对象、字符串 待完成: 用户定义函数调用、闭包/upvalue捕获、完整require支持 Release模式: 1M算术循环 VM 0.44s vs 树遍历 0.89s (2.0x加速)
85 lines
2.7 KiB
Rust
85 lines
2.7 KiB
Rust
//! 标准库:core(len, typeof, push, pop)
|
||
|
||
use crate::error::RuntimeError;
|
||
use crate::interpreter::{Runtime, Value};
|
||
|
||
pub fn len(_runtime: &mut dyn Runtime, args: Vec<Value>) -> Result<Value, RuntimeError> {
|
||
if args.is_empty() {
|
||
return Err(RuntimeError::RuntimeError {
|
||
message: "len() expects 1 argument".into(),
|
||
token: None,
|
||
});
|
||
}
|
||
match &args[0] {
|
||
Value::String(s) => Ok(Value::Number(s.chars().count() as f64)),
|
||
Value::Array(arr) => Ok(Value::Number(arr.borrow().len() as f64)),
|
||
Value::Object(obj) => Ok(Value::Number(obj.borrow().len() as f64)),
|
||
_ => Err(RuntimeError::RuntimeError {
|
||
message: "len() expects a string, array, or object".into(),
|
||
token: None,
|
||
}),
|
||
}
|
||
}
|
||
|
||
pub fn typeof_fn(_interp: &mut dyn Runtime, args: Vec<Value>) -> Result<Value, RuntimeError> {
|
||
if args.is_empty() {
|
||
return Err(RuntimeError::RuntimeError {
|
||
message: "typeof() expects 1 argument".into(),
|
||
token: None,
|
||
});
|
||
}
|
||
let s = match &args[0] {
|
||
Value::Number(_) => "number",
|
||
Value::String(_) => "string",
|
||
Value::Bool(_) => "bool",
|
||
Value::Nil => "nil",
|
||
Value::Object(_) => "object",
|
||
Value::Array(_) => "array",
|
||
Value::Function(_) => "function",
|
||
Value::NativeFunction(_) => "native_function",
|
||
};
|
||
Ok(Value::String(s.into()))
|
||
}
|
||
|
||
pub fn push(_interp: &mut dyn Runtime, args: Vec<Value>) -> Result<Value, RuntimeError> {
|
||
if args.len() < 2 {
|
||
return Err(RuntimeError::RuntimeError {
|
||
message: "push() expects 2 arguments (array, value)".into(),
|
||
token: None,
|
||
});
|
||
}
|
||
let val = args[1].clone();
|
||
match &args[0] {
|
||
Value::Array(arr) => {
|
||
arr.borrow_mut().push(val.clone());
|
||
Ok(val)
|
||
}
|
||
_ => Err(RuntimeError::RuntimeError {
|
||
message: "push() expects an array as first argument".into(),
|
||
token: None,
|
||
}),
|
||
}
|
||
}
|
||
|
||
pub fn pop(_interp: &mut dyn Runtime, args: Vec<Value>) -> Result<Value, RuntimeError> {
|
||
if args.is_empty() {
|
||
return Err(RuntimeError::RuntimeError {
|
||
message: "pop() expects 1 argument (array)".into(),
|
||
token: None,
|
||
});
|
||
}
|
||
match &args[0] {
|
||
Value::Array(arr) => arr
|
||
.borrow_mut()
|
||
.pop()
|
||
.ok_or_else(|| RuntimeError::RuntimeError {
|
||
message: "pop() on empty array".into(),
|
||
token: None,
|
||
}),
|
||
_ => Err(RuntimeError::RuntimeError {
|
||
message: "pop() expects an array as first argument".into(),
|
||
token: None,
|
||
}),
|
||
}
|
||
}
|