Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,25 @@ keywords = ["interpreter", "scripting"]

[features]
default = ["async"]
async = ["futures", "tokio"]

async = [ "futures", "parking_lot" ]

[dependencies]
futures = { version = "0.3", optional = true }
log = "0.4"
parking_lot = { version = "0.12", optional = true }
pest = "2"
pest_derive = "2"
petgraph = "0.8"
tokio = { version = "1", features = ["full"], optional = true }


[dev-dependencies]
criterion = "0.6"
env_logger = "0.11"
reqwest = { version = "0.12", features = ["rustls-tls"] }
hyper = { version = "1", features = ["full"] }
hyper-util = { version = "0.1", features = ["full"] }
tokio = { version = "1", features = ["full"] }


[[bench]]
name = "vm_benchmark"
harness = false
65 changes: 56 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,53 +63,100 @@ float number, f64.

string quote by `"`


## variable

variable name is a string, start with `_` or letter, and can contain letter, number, `_`.

```rust
let a;
let a = 1;
```

## expression

```rust
1 + 2 * 3;
```

### operator


| operator | description |
| -------- | ----------- |
| `+` | add |
| `-` | subtract |
| `*` | multiply |
| `/` | divide |
| `%` | remainder |
| `==` | equal |
| `!=` | not equal |
| `<` | less than |
| `<=` | less than or equal |
| `>` | greater than |
| `>=` | greater than or equal |
| `&&` | and |
| `\|\|` | or |
| `!` | not |
| `=` | assign |
| `+=` | add assign |
| `-=` | subtract assign |
| `*=` | multiply assign |
| `/=` | divide assign |
| `%=` | remainder assign |
| `[]` | index |
| `.` | member |
| `()` | call |
| `..` | range |


## control flow

### loop
### loop statement

`loop` to repeat.

```rust
loop {}
```

### while
### while statement

`while` to repeat.
`while` to conditional repeat.

```rust
while condition {}
```

### for
### for statement

`for` to iterate.

```rust
for i in 0..=10 {}
```

### if
### if statement

`if` to choose branch.

```rust
if condition {} else {}
```

### break
### break statement

`break` to exist loop.

### continue
### continue statement

`continue` to finish one iterate.

### return
### return statement

`return` to return value.

## fn
## fn item

### user defined function

Expand Down
1 change: 1 addition & 0 deletions benches/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod vm_benchmark;
114 changes: 114 additions & 0 deletions benches/vm_benchmark.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
use std::sync::Arc;

use criterion::{Criterion, criterion_group, criterion_main};
use evalit::{Environment, Interpreter, Module, Object, VM, compile};

fn run_script(code: &str) -> Result<(), String> {
Interpreter::eval(code, Environment::new());

Ok(())
}

fn run_vm<T: Object>(program: Arc<Module>, env: Environment) -> T {
let mut vm = VM::new(program, env);

#[cfg(not(feature = "async"))]
return vm.run().unwrap().unwrap().take().into_inner().unwrap();

#[cfg(feature = "async")]
return futures::executor::block_on(async {
vm.run()
.await
.unwrap()
.unwrap()
.take()
.into_inner()
.unwrap()
});
}

fn bench_simple_math(c: &mut Criterion) {
c.bench_function("simple math", |b| {
b.iter(|| {
run_script("1 + 2 * 3 - 4 / 5;").unwrap();
})
});
}

fn bench_function_call(c: &mut Criterion) {
let script = r#"
fn inc(x) { x + 1; }
for i in 0..1000 {
inc(i);
}
"#;

c.bench_function("function call", |b| {
b.iter(|| {
run_script(script).unwrap();
})
});
}

fn bench_array_index_access(c: &mut Criterion) {
let script = r#"
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
for i in 0..1000 {
arr[i % 10] = arr[(i + 1) % 10];
}
"#;

c.bench_function("array index access", |b| {
b.iter(|| {
run_script(script).unwrap();
})
});
}

fn bench_fibonacci(c: &mut Criterion) {
let script = r#"
fn fib(n) {
if n <= 1 {
return n;
}
return fib(n - 1) + fib(n - 2);
}
return fib(10);
"#;

let env = Environment::new();
let module = compile(script, &env).map_err(|e| e.to_string()).unwrap();

c.bench_function("fibonacci", |b| {
b.iter(|| {
let ret = run_vm::<i64>(module.clone(), env.clone());
assert_eq!(ret, 55);
})
});
}

fn bench_native_fibonacci(c: &mut Criterion) {
fn fib(n: i64) -> i64 {
if n <= 1 {
return n;
}
return fib(n - 1) + fib(n - 2);
}

c.bench_function("native fibonacci", |b| {
b.iter(|| {
fib(10);
})
});
}

// 注册新的 benchmark 到 criterion_group!
criterion_group!(
benches,
bench_simple_math,
bench_function_call,
bench_array_index_access,
bench_fibonacci,
bench_native_fibonacci,
);
criterion_main!(benches);
34 changes: 34 additions & 0 deletions examples/eval.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use evalit::{Environment, ValueRef, eval};

fn main() {
let mut env = Environment::new();

env.define_function("println", println);

let script = r#"
println("hello, world");

let sum = 0;
for i in 0..=10 {
sum += i;
}

return sum;
"#;

let retval = eval::<i64>(script, env).unwrap();

println!("ret: {retval:?}");

assert_eq!(retval, Some(55));
}

fn println(args: &[ValueRef]) {
let s = args
.iter()
.map(|v| format!("{v}"))
.collect::<Vec<String>>()
.join("");

println!("{s}");
}
83 changes: 0 additions & 83 deletions examples/hello.rs

This file was deleted.

Loading
Loading