bdffe9e3c5
**Workspace 拆分** - aster-core: 纯库,zero-dependency,包含 lexer/parser/ast/interpreter/error/analysis - aster: REPL 二进制,薄封装 aster-core - aster-lsp: LSP 语言服务器 **VS Code 扩展 (vscode-ext/)** - TextMate 语法高亮 (.ast 文件) - 语言配置 (注释切换、括号配对、自动缩进) - LSP 客户端 (extension.js) **LSP 服务端功能** - Diagnostics: 实时显示 lex/parse 错误红色波浪线 - Completion: 关键字 + 内置函数 + 用户定义符号补全 - Hover: 悬停显示变量/函数信息 - Signature Help: 函数参数提示 - Goto Definition: Ctrl+Click 跳转到声明处 - Find References: 查找所有引用位置 - Rename: F2 重命名符号 **新增 analysis 模块** - collect_symbols: AST 遍历收集符号 - find_declaration/find_all_references: Token 扫描定位声明和引用
85 lines
2.7 KiB
Rust
85 lines
2.7 KiB
Rust
//! 标准库:core(len, typeof, push, pop)
|
||
|
||
use crate::error::RuntimeError;
|
||
use crate::interpreter::{Interpreter, Value};
|
||
|
||
pub fn len(_interp: &mut Interpreter, 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 Interpreter, 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 Interpreter, 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 Interpreter, 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,
|
||
}),
|
||
}
|
||
}
|