Files
aster/aster-core/src/interpreter/builtins/core.rs
T
elmma bdffe9e3c5 feat: IDE支持 — workspace拆分、LSP服务器、VS Code扩展
**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 扫描定位声明和引用
2026-06-25 00:28:13 +08:00

85 lines
2.7 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! 标准库:corelen, 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,
}),
}
}