Skip to content

Commit

Permalink
Merge pull request #12 from calcit-lang/call-main
Browse files Browse the repository at this point in the history
pass values and return value from main
  • Loading branch information
NoEgAm authored Jul 20, 2022
2 parents 66b1f6c + cf569b5 commit fb8a1fd
Show file tree
Hide file tree
Showing 13 changed files with 309 additions and 150 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/publish.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ jobs:
- run: cargo run -- -S examples/sum.cirru
- run: cargo run -- -S examples/assert.cirru
- run: cargo run -- -S examples/nested.cirru
- run: cargo run -- -S examples/named.cirru
- run: cargo run -- --emit-binary target/a.calx examples/named.cirru && cargo run -- --eval-binary target/a.calx

# - run: cargo test

Expand Down
9 changes: 8 additions & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,21 @@ jobs:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
toolchain: nightly
components: clippy
override: true

- run: cargo run -- -S examples/hello.cirru
- run: cargo run -- -S examples/sum.cirru
- run: cargo run -- -S examples/assert.cirru
- run: cargo run -- -S examples/nested.cirru
- run: cargo run -- -S examples/named.cirru
- run: cargo run -- --emit-binary target/a.calx examples/named.cirru && cargo run -- --eval-binary target/a.calx

- uses: actions-rs/clippy-check@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --all-features

- uses: actions-rs/clippy-check@v1
with:
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "calx_vm"
version = "0.1.3"
version = "0.1.4"
authors = ["jiyinyiyong <[email protected]>"]
edition = "2018"
license = "MIT"
Expand Down
103 changes: 53 additions & 50 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,57 +80,60 @@ Highly inspired by:

For binary op, top value puts on right.

| Code | Usage | Note |
| -------------------- | -------------------------------------------------------- | ----------------- |
| `local.set $idx` | set value at `$idx` | |
| `local.tee $idx` | set value at `$idx`, and also load it | |
| `local.get $idx` | get value at `$idx` load on stack | |
| `local.new` | increase size of array of locals | |
| `global.set $idx` | set global value at `$idx` | |
| `global.get $idx` | get global value at `$idx` | |
| `local.new` | increase size of array of globals | |
| `const $v` | push value `$v` on stack | |
| `dup` | duplicate top value on stack | |
| `drop` | drop top value from stack | |
| `i.add` | add two i64 numbers on stack into one | |
| `i.mul` | multiply two i64 numbers on stack into one | |
| `i.div` | divide two i64 numbers on stack into one | |
| `i.rem` | calculate reminder two i64 numbers on stack into one | |
| `i.neg` | negate i64 numbers on top of stack | |
| `i.shr $bits` | call SHR `$bits` bits on i64 numbers on top of stack | |
| `i.shl $bits` | call SHL `$bits` bits on i64 numbers on top of stack | |
| `i.eq` | detects if two i64 numbers on stack equal | |
| `i.ne` | detects if two i64 numbers on stack not equal | |
| `i.lt` | litter than, compares two i64 numbers on stack | |
| `i.gt` | greater than, compares two i64 numbers on stack | |
| `i.le` | litter/equal than, compares two i64 numbers on stack | |
| `i.ge` | greater/equal than, compares two i64 numbers on stack | |
| `add` | add two f64 numbers on stack into one | |
| `mul` | multiply two f64 numbers on stack into one | |
| `div` | divide two f64 numbers on stack into one | |
| `neg` | negate f64 numbers on top of stack | |
| `list.new` | | TODO |
| `list.get` | | TODO |
| `list.set` | | TODO |
| `link.new` | | TODO |
| `and` | | TODO |
| `or` | | TODO |
| `br $n` | branch `$n` level of block, 0 means end of current block | |
| `br-if $n` | like `br $n` but detects top value on stack first | Internal |
| (JMP `$l`) | jump to line `$l` | Internal |
Calx Binary Edition `0.1`:

| Code | Usage | Note |
| -------------------- | -------------------------------------------------------- | -------------------------------------- |
| `local.set $idx` | pop from stack, set value at `$idx` | |
| `local.tee $idx` | set value at `$idx`, and also load it | |
| `local.get $idx` | get value at `$idx` load on stack | |
| `local.new $name` | increase size of array of locals | name is optional, defaults to `$<idx>` |
| `global.set $idx` | set global value at `$idx` | |
| `global.get $idx` | get global value at `$idx` | |
| `global.new` | increase size of array of globals | |
| `const $v` | push value `$v` on stack | |
| `dup` | duplicate top value on stack | |
| `drop` | drop top value from stack | |
| `i.add` | add two i64 numbers on stack into one | |
| `i.mul` | multiply two i64 numbers on stack into one | |
| `i.div` | divide two i64 numbers on stack into one | |
| `i.rem` | calculate reminder two i64 numbers on stack into one | |
| `i.neg` | negate i64 numbers on top of stack | |
| `i.shr $bits` | call SHR `$bits` bits on i64 numbers on top of stack | |
| `i.shl $bits` | call SHL `$bits` bits on i64 numbers on top of stack | |
| `i.eq` | detects if two i64 numbers on stack equal | |
| `i.ne` | detects if two i64 numbers on stack not equal | |
| `i.lt` | litter than, compares two i64 numbers on stack | |
| `i.gt` | greater than, compares two i64 numbers on stack | |
| `i.le` | litter/equal than, compares two i64 numbers on stack | |
| `i.ge` | greater/equal than, compares two i64 numbers on stack | |
| `add` | add two f64 numbers on stack into one | |
| `mul` | multiply two f64 numbers on stack into one | |
| `div` | divide two f64 numbers on stack into one | |
| `neg` | negate f64 numbers on top of stack | |
| `list.new` | | TODO |
| `list.get` | | TODO |
| `list.set` | | TODO |
| `link.new` | | TODO |
| `and` | | TODO |
| `or` | | TODO |
| `not` | | TODO |
| `br $n` | branch `$n` level of block, 0 means end of current block | |
| `br-if $n` | like `br $n` but detects top value on stack first | Internal |
| (JMP `$l`) | jump to line `$l` | Internal |
| (JMP_IF `$l`) | conditional jump to `$l` |
| `block $types $body` | declare a block | |
| `loop $types $body` | declare a loop block | |
| (BlockEnd) | internal mark for ending a block | Internal |
| `echo` | pop value from stack and print | |
| `call $f` | call function `$f` | |
| `call-import $f` | call imported function `$f` | |
| `unreachable` | throw unreachable panic | |
| `nop` | No op | |
| `quit $code` | quit program and return exit code `$code` | |
| `return` | | TODO |
| `fn $types $body` | | Global definition |
| `assert` | `quit(1)` if not `true` | for testing |
| `block $types $body` | declare a block | |
| `loop $types $body` | declare a loop block | |
| (BlockEnd) | internal mark for ending a block | Internal |
| `echo` | pop value from stack and print | |
| `call $f` | call function `$f` | |
| `call-import $f` | call imported function `$f` | |
| `unreachable` | throw unreachable panic | |
| `nop` | No op | |
| `quit $code` | quit program and return exit code `$code` | |
| `return` | | TODO |
| `fn $types $body` | | Global definition |
| `assert` | `quit(1)` if not `true` | for testing |

For `$types`, it can be `($t1 $t2 -> $t3 $t4)`, where supported types are:

Expand Down
18 changes: 18 additions & 0 deletions examples/named.cirru
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

fn f-add (($a i64) ($b i64) -> i64)
local.new $c
const 100
local.set $c
i.add
i.add
local.get $a
local.get $b
local.get $c
dup
echo

fn main ()
const 1
const 2
call f-add
drop
6 changes: 4 additions & 2 deletions examples/sum.cirru
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ fn blocks (-> i64)
, (const "|demo of string") (echo)
const 0

fn sum ()
fn sum (-> i64)
local.new
block (-> i64)
const 0
Expand Down Expand Up @@ -48,6 +48,7 @@ fn sum ()
const "|check sum"
echo
local.get 0
dup
echo

fn echos (-> i64)
Expand All @@ -64,5 +65,6 @@ fn echos (-> i64)
return


fn main ()
fn main (-> i64)
call sum
return
30 changes: 19 additions & 11 deletions src/bin/calx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::time::Instant;
use cirru_parser::{parse, Cirru};
use clap::{Arg, Command};

use calx_vm::{parse_function, Calx, CalxError, CalxFunc, CalxImportsDict, CalxVM};
use calx_vm::{log_calx_value, parse_function, Calx, CalxBinaryProgram, CalxFunc, CalxImportsDict, CalxVM, CALX_BINARY_EDITION};

fn main() -> Result<(), String> {
let matches = Command::new("Calx VM")
Expand Down Expand Up @@ -55,9 +55,18 @@ fn main() -> Result<(), String> {

if eval_binary {
let code = fs::read(source).expect("read binar from source file");
fns = bincode::decode_from_slice(&code, bincode::config::standard())
let program: CalxBinaryProgram = bincode::decode_from_slice(&code, bincode::config::standard())
.expect("decode functions from binary")
.0;
if program.edition == CALX_BINARY_EDITION {
println!("Calx Edition: {}", program.edition);
fns = program.fns;
} else {
return Err(format!(
"Runner uses binary edition {}, binary encoded in {}",
CALX_BINARY_EDITION, program.edition
));
}
} else {
let contents = fs::read_to_string(source).expect("Cirru file for instructions");
let xs = parse(&contents).expect("Some Cirru content");
Expand All @@ -74,7 +83,11 @@ fn main() -> Result<(), String> {

if emit_binary {
let mut slice = [0u8; 10000];
let length = match bincode::encode_into_slice(&fns, &mut slice, bincode::config::standard()) {
let program = CalxBinaryProgram {
edition: CALX_BINARY_EDITION.to_string(),
fns,
};
let length = match bincode::encode_into_slice(&program, &mut slice, bincode::config::standard()) {
Ok(l) => {
println!("encoded binary length: {}", l);
l
Expand Down Expand Up @@ -117,11 +130,11 @@ fn main() -> Result<(), String> {
}
}

match vm.run() {
Ok(()) => {
match vm.run(vec![Calx::I64(1)]) {
Ok(ret) => {
let elapsed = now.elapsed();

println!("Took {:.3?}: {:?}", elapsed, vm.stack);
println!("Took {:.3?}: {:?}", elapsed, ret);
Ok(())
}
Err(e) => {
Expand All @@ -131,8 +144,3 @@ fn main() -> Result<(), String> {
}
}
}

fn log_calx_value(xs: Vec<Calx>) -> Result<Calx, CalxError> {
println!("log: {:?}", xs);
Ok(Calx::Nil)
}
4 changes: 3 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
mod parser;
mod primes;
mod util;
mod vm;

pub use parser::{extract_nested, parse_function};
pub use primes::{Calx, CalxError, CalxFrame, CalxFunc};
pub use primes::{Calx, CalxBinaryProgram, CalxError, CalxFrame, CalxFunc, CALX_BINARY_EDITION};
pub use util::log_calx_value;
pub use vm::{CalxImportsDict, CalxVM};
Loading

0 comments on commit fb8a1fd

Please sign in to comment.