Skip to content

Commit

Permalink
Merge pull request #16 from calcit-lang/reuse-methods
Browse files Browse the repository at this point in the history
Reuse methods
  • Loading branch information
NoEgAm authored Jan 22, 2024
2 parents f8892ad + 9f7769c commit ea753f1
Show file tree
Hide file tree
Showing 20 changed files with 1,516 additions and 1,031 deletions.
7 changes: 6 additions & 1 deletion .github/workflows/publish.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,17 @@ jobs:
toolchain: nightly
components: clippy

- run: cargo test

- run: cargo run -- -s demos/hello.cirru
- run: cargo run -- -s demos/sum.cirru
- run: cargo run -- -s demos/assert.cirru
- run: cargo run -- -s demos/nested.cirru
- run: cargo run -- -s demos/named.cirru
- run: cargo run -- demos/recur.cirru
- run: cargo run -- -s demos/recur.cirru
- run: cargo run -- -s demos/fibonacci.cirru
- run: cargo run -- -s demos/if.cirru
- run: cargo run -- -s demos/fibo-if.cirru
- run: cargo run -- --emit-binary target/a.calx demos/named.cirru && cargo run -- --eval-binary target/a.calx

# - run: cargo test
Expand Down
8 changes: 6 additions & 2 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,20 @@ jobs:
toolchain: nightly
components: clippy

- run: cargo test

- run: cargo run -- -s demos/hello.cirru
- run: cargo run -- -s demos/sum.cirru
- run: cargo run -- -s demos/assert.cirru
- run: cargo run -- -s demos/nested.cirru
- run: cargo run -- -s demos/named.cirru
- run: cargo run -- demos/recur.cirru
- run: cargo run -- -s demos/recur.cirru
- run: cargo run -- -s demos/fibonacci.cirru
- run: cargo run -- -s demos/if.cirru
- run: cargo run -- -s demos/fibo-if.cirru
- run: cargo run -- --emit-binary target/a.calx demos/named.cirru && cargo run -- --eval-binary target/a.calx

- uses: giraffate/clippy-action@v1
with:
reporter: 'github-pr-review'
github_token: ${{ secrets.GITHUB_TOKEN }}

10 changes: 7 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "calx_vm"
version = "0.1.6"
version = "0.2.0-a1"
authors = ["jiyinyiyong <[email protected]>"]
edition = "2021"
license = "MIT"
Expand All @@ -11,13 +11,17 @@ repository = "https://github.com/calcit-lang/calx-vm.rs"
readme = "README.md"
exclude = []

[[bin]]
name = "calx"
path = "src/bin/cli.rs"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
cirru_parser = "0.1.25"
cirru_parser = "0.1.26"
regex = "1.10.2"
lazy_static = "1.4.0"
clap = { version = "4.4.13", features = ["derive"] }
clap = { version = "4.4.18", features = ["derive"] }
bincode = "2.0.0-rc.3"

[profile.release]
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ fn main ()

### Instructions

> _TODO_ update to `0.2.x`...
Highly inspired by:

- WASM https://github.com/WebAssembly/design/blob/main/Semantics.md
Expand Down Expand Up @@ -135,7 +137,7 @@ Calx Binary Edition `0.1`:
| `return` | | TODO |
| `fn $types $body` | | Global definition |
| `assert` | `quit(1)` if not `true` | for testing |
| `inspect | println inspection information | |
| `inspect` | println inspection information | |

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

Expand Down
25 changes: 25 additions & 0 deletions demos/fibo-if.cirru
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

fn main ()
call fibo
const 34
echo

fn fibo (($x i64) -> i64)
local.get $x
const 3
i.lt
if (->)
do
const 1
return
do
local.get $x
const -1
i.add
call fibo
local.get $x
const -2
i.add
call fibo
i.add
return
19 changes: 19 additions & 0 deletions demos/if.cirru
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

fn main ()
const 1
call demo
const 0
call demo

fn demo (($a i64) ->)
local.get $a

if (->)
do
const 11
echo
do
const 20
echo
const 3
echo
33 changes: 20 additions & 13 deletions src/bin/calx.rs → src/bin/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,18 @@ use std::time::Instant;
use cirru_parser::{parse, Cirru};
use clap::{arg, Parser};

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

use bincode::{Decode, Encode};

/// binary format for saving calx program
/// TODO this is not a valid file format that requires magic code
#[derive(Debug, Clone, PartialEq, PartialOrd, Encode, Decode)]
pub struct CalxBinaryProgram {
/// updates as instructions update
pub edition: String,
pub fns: Vec<CalxFunc>,
}

/// Simple program to greet a person
#[derive(Parser, Debug)]
Expand All @@ -16,8 +27,6 @@ use calx_vm::{log_calx_value, parse_function, Calx, CalxBinaryProgram, CalxFunc,
struct Args {
#[arg(short, long, value_name = "SHOW_CODE")]
show_code: bool,
#[arg(short, long, value_name = "DISABLE_PRE")]
disable_pre: bool,
#[arg(short, long, value_name = "EMIT_BINARY")]
emit_binary: Option<String>,
#[arg(short, long, value_name = "VERBOSE")]
Expand All @@ -33,7 +42,6 @@ fn main() -> Result<(), String> {

let source = args.source;
let show_code = args.show_code;
let disable_pre = args.disable_pre;
let emit_binary = args.emit_binary;
let eval_binary = args.eval_binary;

Expand All @@ -44,13 +52,13 @@ fn main() -> Result<(), String> {
let program: CalxBinaryProgram = bincode::decode_from_slice(&code, bincode::config::standard())
.expect("decode functions from binary")
.0;
if program.edition == CALX_BINARY_EDITION {
if program.edition == CALX_INSTR_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
CALX_INSTR_EDITION, program.edition
));
}
} else {
Expand All @@ -69,7 +77,7 @@ fn main() -> Result<(), String> {

if emit_binary.is_some() {
let program = CalxBinaryProgram {
edition: CALX_BINARY_EDITION.to_string(),
edition: CALX_INSTR_EDITION.to_string(),
fns,
};
let buf = bincode::encode_to_vec(program, bincode::config::standard()).map_err(|e| e.to_string())?;
Expand All @@ -93,12 +101,11 @@ fn main() -> Result<(), String> {
// }

let now = Instant::now();
if !disable_pre {
println!("[calx] start preprocessing");
vm.preprocess(args.verbose)?;
} else {
println!("Preprocess disabled.")
}

println!("[calx] start preprocessing");
vm.preprocess(args.verbose)?;

vm.setup_top_frame()?;

if show_code {
for func in &vm.funcs {
Expand Down
112 changes: 112 additions & 0 deletions src/calx.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
mod types;

use bincode::{Decode, Encode};
use core::fmt;
use lazy_static::lazy_static;
use regex::Regex;
use std::str::FromStr;

pub use types::CalxType;

/// Simplied from Calcit, but trying to be basic and mutable
#[derive(Debug, Clone, PartialEq, PartialOrd, Decode, Encode)]
pub enum Calx {
Nil,
Bool(bool),
I64(i64),
F64(f64),
Str(String),
List(Vec<Calx>),
// to simultate linked structures
// Link(Box<Calx>, Box<Calx>, Box<Calx>),
}

impl FromStr for Calx {
type Err = String;

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"nil" => Ok(Calx::Nil),
"true" => Ok(Calx::Bool(true)),
"false" => Ok(Calx::Bool(false)),
"" => Err(String::from("unknown empty string")),
_ => {
let s0 = s.chars().next().unwrap();
if s0 == '|' || s0 == ':' {
Ok(Calx::Str(s[1..s.len()].to_owned()))
} else if FLOAT_PATTERN.is_match(s) {
match s.parse::<f64>() {
Ok(u) => Ok(Calx::F64(u)),
Err(e) => Err(format!("failed to parse: {}", e)),
}
} else if INT_PATTERN.is_match(s) {
match s.parse::<i64>() {
Ok(u) => Ok(Calx::I64(u)),
Err(e) => Err(format!("failed to parse: {}", e)),
}
} else {
Err(format!("unknown value: {}", s))
}
}
}
}
}

impl Calx {
// for runtime type checking
pub fn typed_as(&self, t: CalxType) -> bool {
match self {
Calx::Nil => t == CalxType::Nil,
Calx::Bool(_) => t == CalxType::Bool,
Calx::I64(_) => t == CalxType::I64,
Calx::F64(_) => t == CalxType::F64,
Calx::Str(_) => t == CalxType::Str,
Calx::List(_) => t == CalxType::List,
// Calx::Link(_, _, _) => t == CalxType::Link,
}
}

pub fn truthy(&self) -> bool {
match self {
Calx::Nil => false,
Calx::Bool(b) => *b,
Calx::I64(n) => *n != 0,
Calx::F64(n) => *n != 0.0,
Calx::Str(_) => false,
Calx::List(_) => false,
// Calx::Link(_, _, _) => true,
}
}
}

impl fmt::Display for Calx {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Calx::Nil => f.write_str("nil"),
Calx::Bool(b) => f.write_str(&b.to_string()),
Calx::I64(n) => f.write_str(&n.to_string()),
Calx::F64(n) => f.write_str(&n.to_string()),
Calx::Str(s) => f.write_str(s),
Calx::List(xs) => {
f.write_str("(")?;
let mut at_head = true;
for x in xs {
if at_head {
at_head = false
} else {
f.write_str(" ")?;
}
x.fmt(f)?;
}
f.write_str(")")?;
Ok(())
} // Calx::Link(..) => f.write_str("TODO LINK"),
}
}
}

lazy_static! {
static ref FLOAT_PATTERN: Regex = Regex::new("^-?\\d+\\.(\\d+)?$").unwrap();
static ref INT_PATTERN: Regex = Regex::new("^-?\\d+$").unwrap();
static ref USIZE_PATTERN: Regex = Regex::new("^\\d+$").unwrap();
}
30 changes: 30 additions & 0 deletions src/calx/types.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use bincode::{Decode, Encode};
use std::str::FromStr;

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Decode, Encode)]
pub enum CalxType {
Nil,
Bool,
I64,
F64,
Str,
List,
Link,
}

impl FromStr for CalxType {
type Err = String;

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"nil" => Ok(CalxType::Nil),
"bool" => Ok(CalxType::Bool),
"i64" => Ok(CalxType::I64),
"f64" => Ok(CalxType::F64),
"str" => Ok(CalxType::Str),
"list" => Ok(CalxType::List),
"link" => Ok(CalxType::Link),
_ => Err(format!("unknown type: {}", s)),
}
}
}
7 changes: 4 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
mod calx;
mod parser;
mod primes;
mod syntax;
mod util;
mod vm;

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

0 comments on commit ea753f1

Please sign in to comment.