instantly refreshable code. untested, but it compiles
This commit is contained in:
parent
f1f32af113
commit
24a852f125
9 changed files with 193 additions and 40 deletions
96
Cargo.lock
generated
96
Cargo.lock
generated
|
|
@ -154,6 +154,12 @@ version = "0.22.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.9.4"
|
||||
|
|
@ -291,12 +297,14 @@ dependencies = [
|
|||
name = "crudlang"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"arc-swap",
|
||||
"axum",
|
||||
"chrono",
|
||||
"clap",
|
||||
"dotenv",
|
||||
"log",
|
||||
"log4rs",
|
||||
"notify",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"thiserror",
|
||||
|
|
@ -449,6 +457,15 @@ dependencies = [
|
|||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fsevent-sys"
|
||||
version = "4.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.31"
|
||||
|
|
@ -843,6 +860,26 @@ dependencies = [
|
|||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inotify"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3"
|
||||
dependencies = [
|
||||
"bitflags 2.9.4",
|
||||
"inotify-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inotify-sys"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ipnet"
|
||||
version = "2.11.0"
|
||||
|
|
@ -881,6 +918,26 @@ dependencies = [
|
|||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kqueue"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eac30106d7dce88daf4a3fcb4879ea939476d5074a9b7ddd0fb97fa4bed5596a"
|
||||
dependencies = [
|
||||
"kqueue-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kqueue-sys"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.5.0"
|
||||
|
|
@ -899,7 +956,7 @@ version = "0.1.10"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 2.9.4",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
]
|
||||
|
|
@ -1014,6 +1071,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"wasi 0.11.1+wasi-snapshot-preview1",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
|
@ -1041,6 +1099,30 @@ dependencies = [
|
|||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "notify"
|
||||
version = "8.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3"
|
||||
dependencies = [
|
||||
"bitflags 2.9.4",
|
||||
"fsevent-sys",
|
||||
"inotify",
|
||||
"kqueue",
|
||||
"libc",
|
||||
"log",
|
||||
"mio",
|
||||
"notify-types",
|
||||
"walkdir",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "notify-types"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e0826a989adedc2a244799e823aece04662b66609d96af8dff7ac6df9a8925d"
|
||||
|
||||
[[package]]
|
||||
name = "nu-ansi-term"
|
||||
version = "0.50.3"
|
||||
|
|
@ -1077,7 +1159,7 @@ version = "0.10.73"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 2.9.4",
|
||||
"cfg-if",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
|
|
@ -1296,7 +1378,7 @@ version = "0.5.18"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 2.9.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1361,7 +1443,7 @@ version = "1.1.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 2.9.4",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
|
|
@ -1443,7 +1525,7 @@ version = "2.11.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 2.9.4",
|
||||
"core-foundation",
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
|
|
@ -1678,7 +1760,7 @@ version = "0.6.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 2.9.4",
|
||||
"core-foundation",
|
||||
"system-configuration-sys",
|
||||
]
|
||||
|
|
@ -1879,7 +1961,7 @@ version = "0.6.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 2.9.4",
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
|
|
|
|||
|
|
@ -23,3 +23,5 @@ walkdir = "2.5.0"
|
|||
thiserror = "2.0.17"
|
||||
url = "2.5.7"
|
||||
clap = { version = "4.5.51", features = ["derive"] }
|
||||
notify = "8.2.0"
|
||||
arc-swap = "1.7.1"
|
||||
|
|
|
|||
|
|
@ -2,4 +2,4 @@ fn get(path: string) -> string:
|
|||
add("hello", path)
|
||||
|
||||
fn add(a: string, b: string) -> string:
|
||||
a + " " + b
|
||||
a + " " + b
|
||||
|
|
@ -5,11 +5,11 @@ use crate::errors::CompilerError::{
|
|||
};
|
||||
use crate::errors::CompilerErrorAtLine;
|
||||
use crate::tokens::TokenType::{
|
||||
Bang, Bool, Char, Colon, Date, Eof, Eol, Equal, F32, F64, False, FloatingPoint, Fn, Greater,
|
||||
GreaterEqual, GreaterGreater, I32, I64, Identifier, Indent, Integer, LeftBrace, LeftBracket,
|
||||
LeftParen, Less, LessEqual, LessLess, Let, ListType, MapType, Minus, Object, Plus, Print,
|
||||
RightBrace, RightBracket, RightParen, SignedInteger, SingleRightArrow, Slash, Star, StringType,
|
||||
True, U32, U64, UnsignedInteger,
|
||||
Bang, Bool, Char, Colon, Date, Eof, Eol, Equal, False, FloatingPoint, Fn, Greater, GreaterEqual, GreaterGreater,
|
||||
Identifier, Indent, Integer, LeftBrace, LeftBracket, LeftParen, Less, LessEqual, LessLess,
|
||||
Let, ListType, MapType, Minus, Object, Plus, Print, RightBrace, RightBracket, RightParen, SignedInteger,
|
||||
SingleRightArrow, Slash, Star, StringType, True, UnsignedInteger, F32, F64,
|
||||
I32, I64, U32, U64,
|
||||
};
|
||||
use crate::tokens::{Token, TokenType};
|
||||
use crate::value::Value;
|
||||
|
|
|
|||
54
src/file_watch.rs
Normal file
54
src/file_watch.rs
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
use crate::chunk::Chunk;
|
||||
use crate::compile_sourcedir;
|
||||
use log4rs::append::Append;
|
||||
use notify::{RecursiveMode, Watcher};
|
||||
use std::collections::HashMap;
|
||||
use std::hash::Hash;
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
use std::sync::mpsc::channel;
|
||||
use std::thread;
|
||||
use std::time::{Duration, SystemTime};
|
||||
use arc_swap::ArcSwap;
|
||||
|
||||
const ONE_SEC: Duration = Duration::from_secs(1);
|
||||
|
||||
pub fn start_watch_daemon(source: &str, registry: Arc<ArcSwap<HashMap<String, Chunk>>>) {
|
||||
let source = source.to_string();
|
||||
let s = source.to_string();
|
||||
let (tx, rx) = channel();
|
||||
thread::spawn(move || {
|
||||
println!("-- File watch started --");
|
||||
let path = Path::new(&source);
|
||||
if !path.exists() {
|
||||
panic!("source directory {} does not exist", &source);
|
||||
}
|
||||
let mut watcher = notify::recommended_watcher(tx).expect("Failed to create watcher");
|
||||
watcher
|
||||
.watch(path, RecursiveMode::Recursive)
|
||||
.expect("Failed to watch");
|
||||
loop {
|
||||
thread::sleep(Duration::from_secs(1));
|
||||
}
|
||||
});
|
||||
thread::spawn(move || {
|
||||
let mut file_changed = false;
|
||||
loop {
|
||||
let start = SystemTime::now();
|
||||
loop {
|
||||
thread::sleep(Duration::from_millis(50));
|
||||
if let Ok(_) = rx.recv() {
|
||||
file_changed = true;
|
||||
}
|
||||
if file_changed && SystemTime::now().duration_since(start).unwrap() > ONE_SEC {
|
||||
break;
|
||||
}
|
||||
}
|
||||
println!("refresh"); // TODO implement refresh source
|
||||
let new_registry = Arc::new(compile_sourcedir(&s).unwrap());
|
||||
|
||||
registry.store(new_registry.clone());
|
||||
file_changed = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
11
src/lib.rs
11
src/lib.rs
|
|
@ -6,6 +6,8 @@ use crate::value::Value;
|
|||
use crate::vm::interpret;
|
||||
use std::collections::HashMap;
|
||||
use std::fs;
|
||||
use std::sync::Arc;
|
||||
use arc_swap::ArcSwap;
|
||||
use walkdir::WalkDir;
|
||||
|
||||
pub mod ast_compiler;
|
||||
|
|
@ -19,6 +21,7 @@ mod tokens;
|
|||
mod value;
|
||||
pub mod vm;
|
||||
pub mod repl;
|
||||
pub mod file_watch;
|
||||
|
||||
pub fn compile_sourcedir(source_dir: &str) -> Result<HashMap<String, Chunk>, CrudLangError> {
|
||||
let mut registry = HashMap::new();
|
||||
|
|
@ -26,12 +29,13 @@ pub fn compile_sourcedir(source_dir: &str) -> Result<HashMap<String, Chunk>, Cru
|
|||
for entry in WalkDir::new(source_dir).into_iter().filter_map(|e| e.ok()) {
|
||||
let path = entry.path().to_str().unwrap();
|
||||
if path.ends_with(".crud") {
|
||||
print!("compiling {:?}: ", path);
|
||||
print!("-- Compiling ");
|
||||
let source = fs::read_to_string(path).map_err(map_underlying())?;
|
||||
let tokens = scan(&source)?;
|
||||
match ast_compiler::compile(Some(&path), tokens) {
|
||||
Ok(statements) => {
|
||||
let path = path.strip_prefix("source/").unwrap().replace(".crud", "");
|
||||
println!("{}",path);
|
||||
let path = path.strip_prefix(source_dir).unwrap().replace(".crud", "");
|
||||
bytecode_compiler::compile(Some(&path), &statements, &mut registry)?;
|
||||
}
|
||||
Err(e) => {
|
||||
|
|
@ -62,5 +66,6 @@ fn run(src: &str) -> Result<Value, CrudLangError> {
|
|||
let mut registry = HashMap::new();
|
||||
let ast = ast_compiler::compile(None, tokens)?;
|
||||
bytecode_compiler::compile(None, &ast, &mut registry)?;
|
||||
interpret(®istry, "main").map_err(CrudLangError::from)
|
||||
let registry = ArcSwap::from(Arc::new(registry));
|
||||
interpret(registry.load(), "main").map_err(CrudLangError::from)
|
||||
}
|
||||
|
|
|
|||
35
src/main.rs
35
src/main.rs
|
|
@ -8,8 +8,10 @@ use crudlang::errors::CrudLangError;
|
|||
use crudlang::errors::CrudLangError::Platform;
|
||||
use crudlang::vm::interpret_async;
|
||||
use crudlang::{compile_sourcedir, map_underlying};
|
||||
use notify::Watcher;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use arc_swap::ArcSwap;
|
||||
|
||||
/// A simple CLI tool to greet users
|
||||
#[derive(Parser, Debug)]
|
||||
|
|
@ -19,6 +21,9 @@ struct Args {
|
|||
|
||||
#[arg(short, long)]
|
||||
source: Option<String>,
|
||||
|
||||
#[arg(short, long)]
|
||||
watch: bool,
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
|
|
@ -26,17 +31,19 @@ async fn main() -> Result<(), CrudLangError> {
|
|||
println!("-- Crudlang --");
|
||||
tracing_subscriber::fmt::init();
|
||||
let args = Args::parse();
|
||||
let source = args.source.unwrap_or("source".to_string());
|
||||
let source = args.source.unwrap_or("./source".to_string());
|
||||
let registry = compile_sourcedir(&source)?;
|
||||
|
||||
let registry = Arc::new(registry);
|
||||
|
||||
if !registry.is_empty() {
|
||||
println!("-- Compilation successful -- Starting server --");
|
||||
let state = Arc::new(AppState {
|
||||
registry: registry.clone(),
|
||||
});
|
||||
|
||||
let swap = Arc::new(ArcSwap::from(Arc::new(registry)));
|
||||
if args.watch {
|
||||
crudlang::file_watch::start_watch_daemon(&source, swap.clone());
|
||||
}
|
||||
println!("-- Compilation successful --");
|
||||
let state =AppState {
|
||||
registry: swap.clone(),
|
||||
};
|
||||
let app = Router::new()
|
||||
.route("/", any(handle_any).with_state(state.clone()))
|
||||
.route("/{*path}", any(handle_any).with_state(state.clone()));
|
||||
|
|
@ -46,12 +53,12 @@ async fn main() -> Result<(), CrudLangError> {
|
|||
.map_err(map_underlying())?;
|
||||
|
||||
println!(
|
||||
"listening on {}\n",
|
||||
"-- Listening on {} --\n",
|
||||
listener.local_addr().map_err(map_underlying())?
|
||||
);
|
||||
|
||||
if args.repl {
|
||||
std::thread::spawn(move || crudlang::repl::start(registry).unwrap());
|
||||
std::thread::spawn(move || crudlang::repl::start(swap.load()).unwrap());
|
||||
}
|
||||
|
||||
axum::serve(listener, app).await.map_err(map_underlying())?;
|
||||
|
|
@ -65,11 +72,11 @@ async fn main() -> Result<(), CrudLangError> {
|
|||
|
||||
#[derive(Clone)]
|
||||
struct AppState {
|
||||
registry: Arc<HashMap<String, Chunk>>,
|
||||
registry: Arc<ArcSwap<HashMap<String, Chunk>>>,
|
||||
}
|
||||
|
||||
async fn handle_any(
|
||||
State(state): State<Arc<AppState>>,
|
||||
State(state): State<AppState>,
|
||||
req: Request,
|
||||
) -> Result<Json<String>, StatusCode> {
|
||||
let method = req.method().to_string().to_ascii_lowercase();
|
||||
|
|
@ -84,7 +91,7 @@ async fn handle_any(
|
|||
.collect()
|
||||
})
|
||||
.unwrap_or_default();
|
||||
let component = format!("{}/web", &uri.path()[1..]);
|
||||
let component = format!("{}/web", &uri.path());
|
||||
let function_qname = format!("{}.{}", component, method);
|
||||
|
||||
let mut headers = HashMap::new();
|
||||
|
|
@ -93,7 +100,7 @@ async fn handle_any(
|
|||
}
|
||||
let path = &req.uri().to_string();
|
||||
match interpret_async(
|
||||
&state.registry,
|
||||
state.registry.load(),
|
||||
&function_qname,
|
||||
path,
|
||||
query_params,
|
||||
|
|
@ -104,7 +111,7 @@ async fn handle_any(
|
|||
Ok(value) => Ok(Json(value.to_string())),
|
||||
Err(e) => {
|
||||
// url checks out but function for method not found
|
||||
if state.registry.get(&format!("{}.main", component)).is_some() {
|
||||
if state.registry.load().get(&format!("{}.main", component)).is_some() {
|
||||
Err(StatusCode::METHOD_NOT_ALLOWED)
|
||||
} else {
|
||||
Err(StatusCode::NOT_FOUND)
|
||||
|
|
|
|||
|
|
@ -5,8 +5,9 @@ use std::collections::HashMap;
|
|||
use std::io;
|
||||
use std::io::Write;
|
||||
use std::sync::Arc;
|
||||
use arc_swap::{ArcSwap, Guard};
|
||||
|
||||
pub fn start(registry: Arc<HashMap<String, Chunk>>) -> Result<(), CrudLangError> {
|
||||
pub fn start(registry: Guard<Arc<HashMap<String, Chunk>>>) -> Result<(), CrudLangError> {
|
||||
println!("REPL started -- Type ctrl-c to exit (both the repl and the server)");
|
||||
println!(":h for help");
|
||||
loop {
|
||||
|
|
@ -20,7 +21,7 @@ pub fn start(registry: Arc<HashMap<String, Chunk>>) -> Result<(), CrudLangError>
|
|||
match input {
|
||||
":h" => help(),
|
||||
":le" => list_endpoints(registry.clone()),
|
||||
":lf" => list_functions(registry.clone()),
|
||||
":lf" => list_endpoints(registry.clone()),
|
||||
_ => {}
|
||||
}
|
||||
// println!("[{}]",input);
|
||||
|
|
|
|||
18
src/vm.rs
18
src/vm.rs
|
|
@ -5,17 +5,19 @@ use crate::tokens::TokenType;
|
|||
use crate::value::Value;
|
||||
use axum::http::{Uri};
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use arc_swap::Guard;
|
||||
use tracing::debug;
|
||||
|
||||
pub struct Vm<'a> {
|
||||
pub struct Vm {
|
||||
ip: usize,
|
||||
stack: Vec<Value>,
|
||||
local_vars: HashMap<String, Value>,
|
||||
error_occurred: bool,
|
||||
registry: &'a HashMap<String, Chunk>,
|
||||
registry: Arc<HashMap<String, Chunk>>,
|
||||
}
|
||||
|
||||
pub fn interpret(registry: &HashMap<String, Chunk>, function: &str) -> Result<Value, RuntimeError> {
|
||||
pub fn interpret(registry: Guard<Arc<HashMap<String, Chunk>>>, function: &str) -> Result<Value, RuntimeError> {
|
||||
let chunk = registry.get(function).unwrap().clone();
|
||||
// for (key,value) in registry.iter() {
|
||||
// println!("{}", key);
|
||||
|
|
@ -26,13 +28,13 @@ pub fn interpret(registry: &HashMap<String, Chunk>, function: &str) -> Result<Va
|
|||
stack: vec![],
|
||||
local_vars: HashMap::new(),
|
||||
error_occurred: false,
|
||||
registry,
|
||||
registry: registry.clone(),
|
||||
};
|
||||
vm.run(&chunk)
|
||||
}
|
||||
|
||||
pub async fn interpret_async(
|
||||
registry: &HashMap<String, Chunk>,
|
||||
registry: Guard<Arc<HashMap<String, Chunk>>>,
|
||||
function: &str,
|
||||
uri: &str,
|
||||
query_params: HashMap<String, String>,
|
||||
|
|
@ -46,7 +48,7 @@ pub async fn interpret_async(
|
|||
stack: vec![],
|
||||
local_vars: HashMap::new(),
|
||||
error_occurred: false,
|
||||
registry,
|
||||
registry:registry.clone(),
|
||||
};
|
||||
vm.local_vars
|
||||
.insert("path".to_string(), Value::String(uri.into()));
|
||||
|
|
@ -73,13 +75,13 @@ pub fn interpret_function(chunk: &Chunk, args: Vec<Value>) -> Result<Value, Runt
|
|||
stack: vec![],
|
||||
local_vars: HashMap::new(),
|
||||
error_occurred: false,
|
||||
registry: &HashMap::new(),
|
||||
registry: Arc::new(HashMap::new()),
|
||||
};
|
||||
|
||||
vm.run_function(chunk, args)
|
||||
}
|
||||
|
||||
impl<'a> Vm<'a> {
|
||||
impl Vm {
|
||||
fn run_function(&mut self, chunk: &Chunk, mut args: Vec<Value>) -> Result<Value, RuntimeError> {
|
||||
// arguments -> locals
|
||||
for (_, name) in chunk.vars.iter() {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue