Skip to content

Commit eaa5835

Browse files
committed
Begin work on standard library
Unfortunately, it seems like I am walled. Manishearth/rust-gc#50 I thought the garbage collection story in Rust was more mature than it actually is, and that I could ride the coattails of those who know how the hell garbage collection actually works. Either I switch gears and learn how to situate myself in garbage, or I call this project a dead end because I'm running out of steam. :)
1 parent 165318f commit eaa5835

File tree

5 files changed

+70
-1
lines changed

5 files changed

+70
-1
lines changed

src/bin/eval.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
extern crate bean;
22

33
use bean::context::Context;
4+
use bean::std_scope;
45
use std::io::{self, Read};
56
use std::time::SystemTime;
67

78
fn main() {
89
let mut buffer = String::new();
910
io::stdin().read_to_string(&mut buffer).unwrap();
1011
let before = SystemTime::now();
11-
let result = Context::new().eval(&buffer);
12+
let mut context = Context::new();
13+
context.push_scope(std_scope::scope());
14+
let result = context.eval(&buffer);
1215
let elapsed = SystemTime::now().duration_since(before).unwrap();
1316
println!("Total execution time: {:?}", elapsed);
1417
println!("{:#?}", result);

src/context.rs

+7
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ impl Context {
122122
Context { scopes: Vec::new() }
123123
}
124124

125+
pub fn push_scope(&mut self, scope: Object) {
126+
self.scopes.push(scope);
127+
}
128+
125129
pub fn eval(&mut self, source: &str) -> Result<Value, Error> {
126130
Ok(self.eval_block(&Parser::parse_script(source)?)?)
127131
}
@@ -504,6 +508,9 @@ impl Context {
504508
// function was not defined in the current script. May have to accept a filename parameter
505509
// to disambiguate, or come up with another solution. Perhaps if no filename is supplied,
506510
// the error is "localized" to the caller's location (i.e. the line/column point to `pos`).
511+
//
512+
// Moreover, errors produced by native Rust functions are never tagged with a line/column.
513+
// Can this be improved?
507514
let func = self.eval_expr(func)?;
508515
if let Value::Function(ref func) = func {
509516
self.eval_call_inner_exprs(func, args)

src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ pub mod iter;
88
pub mod lexer;
99
pub mod parser;
1010
pub mod position;
11+
pub mod std_scope;
1112
pub mod value;

src/std_scope.rs

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
use crate::value::{Object, Value};
2+
3+
pub fn scope() -> Object {
4+
let scope = Object::new();
5+
let std = Object::new();
6+
7+
std.set("len", Value::rust_function(|_ctx, args| {
8+
match args.get(0) {
9+
Some(Value::Array(arr)) => Ok(Value::Number(arr.len() as f64)),
10+
Some(Value::Object(obj)) => Ok(Value::Number(obj.len() as f64)),
11+
_ => Err(Value::string("invalid argument")),
12+
}
13+
}));
14+
15+
std.set("iter", Value::rust_function(|_ctx, args| {
16+
match args.get(0) {
17+
Some(Value::Array(arr)) => {
18+
let iter = Object::new();
19+
let iter_clone = iter.clone();
20+
// TODO: Can `args` be destructured to prevent this clone?
21+
let arr = arr.clone();
22+
23+
// TODO: Use internal object value for this:
24+
iter.set("_index", Value::Number(0.0));
25+
26+
// TODO: Bad news, gamers. https://github.com/Manishearth/rust-gc/issues/50
27+
iter.set("next", Value::rust_function(move |_ctx, _args| {
28+
let next = Object::new();
29+
let index = match iter_clone.get("_index") {
30+
Some(Value::Number(number)) => number as usize,
31+
_ => panic!("TODO: Use internal object value for this"),
32+
};
33+
if let Some(value) = arr.get(index) {
34+
iter_clone.set("_index", Value::Number((index + 1) as f64));
35+
next.set("value", value);
36+
} else {
37+
next.set("done", Value::Boolean(true));
38+
}
39+
Ok(Value::Object(next))
40+
}));
41+
42+
Ok(Value::Object(iter))
43+
},
44+
_ => Err(Value::string("invalid argument")),
45+
}
46+
}));
47+
48+
scope.set("std", Value::Object(std));
49+
scope
50+
}

src/value.rs

+8
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,10 @@ impl Array {
179179
pub fn get(&self, index: usize) -> Option<Value> {
180180
self.0.borrow().get(index).cloned()
181181
}
182+
183+
pub fn len(&self) -> usize {
184+
self.0.borrow().len()
185+
}
182186
}
183187

184188
#[derive(Clone, Debug, Trace, Finalize)]
@@ -201,4 +205,8 @@ impl Object {
201205
pub fn contains(&self, key: &str) -> bool {
202206
self.0.borrow().contains_key(key)
203207
}
208+
209+
pub fn len(&self) -> usize {
210+
self.0.borrow().len()
211+
}
204212
}

0 commit comments

Comments
 (0)