Skip to content

Commit

Permalink
extra stack check for block; tag 0.1.4
Browse files Browse the repository at this point in the history
  • Loading branch information
tiye committed Jul 19, 2022
1 parent 629287a commit cf569b5
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 15 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
7 changes: 6 additions & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
toolchain: nightly
components: clippy
override: true

Expand All @@ -35,3 +35,8 @@ jobs:
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --all-features

- uses: actions-rs/clippy-check@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --all-features
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
10 changes: 4 additions & 6 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,9 +271,7 @@ fn parse_local_idx(x: &Cirru, collector: &mut LocalsCollector) -> Result<usize,
}
None => Err(String::from("invalid empty name")),
},
Cirru::List(_) => {
return Err(format!("expected token, got {}", x));
}
Cirru::List(_) => Err(format!("expected token, got {}", x)),
}
}

Expand Down Expand Up @@ -358,7 +356,7 @@ pub fn parse_fn_types(xs: &Cirru, collector: &mut LocalsCollector) -> Result<(Ve
if &**t == "->" {
ret_mode = true;
} else {
let ty = parse_type_name(&**t)?;
let ty = parse_type_name(t)?;
if ret_mode {
returns.push(ty);
} else {
Expand All @@ -382,7 +380,7 @@ pub fn parse_fn_types(xs: &Cirru, collector: &mut LocalsCollector) -> Result<(Ve
Cirru::List(_) => return Err(format!("invalid syntax, expected name, got {:?}", x)),
};
let ty = match &zs[1] {
Cirru::Leaf(s) => parse_type_name(&**s)?,
Cirru::Leaf(s) => parse_type_name(s)?,
Cirru::List(_) => return Err(format!("invalid syntax, expected type, got {:?}", x)),
};
collector.track(&name_str);
Expand Down Expand Up @@ -410,7 +408,7 @@ pub fn parse_block_types(xs: &Cirru) -> Result<(Vec<CalxType>, Vec<CalxType>), S
if &**t == "->" {
ret_mode = true;
} else {
let ty = parse_type_name(&**t)?;
let ty = parse_type_name(t)?;
if ret_mode {
returns.push(ty);
} else {
Expand Down
20 changes: 18 additions & 2 deletions src/primes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,28 @@ pub enum Calx {
// Link(Box<Calx>, Box<Calx>, Box<Calx>),
}

#[derive(Debug, Clone, PartialEq, PartialOrd, Decode, Encode)]
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,
}
}
}

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Decode, Encode)]
pub enum CalxType {
Nil,
Bool,
I64,
F64,
Str,
List,
Link,
}
Expand Down Expand Up @@ -193,7 +209,7 @@ impl CalxError {
}
}

#[derive(Debug, Clone, PartialEq, PartialOrd)]
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd)]
pub struct BlockData {
pub looped: bool,
pub ret_types: Vec<CalxType>,
Expand Down
21 changes: 16 additions & 5 deletions src/vm.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::primes::{BlockData, Calx, CalxError, CalxFrame, CalxFunc, CalxInstr};
use crate::primes::{BlockData, Calx, CalxError, CalxFrame, CalxFunc, CalxInstr, CalxType};
use std::collections::hash_map::HashMap;
use std::fmt;
use std::ops::Rem;
Expand Down Expand Up @@ -118,7 +118,7 @@ impl CalxVM {
to,
initial_stack_size: self.stack.len() - params_types.len(),
});
println!("TODO check params type: {:?}", params_types);
self.check_stack_for_block(&params_types)?;
}
CalxInstr::BlockEnd(looped) => {
if looped {
Expand Down Expand Up @@ -391,9 +391,6 @@ impl CalxVM {
ret_types: f.ret_types,
};

// TODO check params type
println!("TODO check args: {:?}", f.params_types);

// start in new frame
continue;
}
Expand Down Expand Up @@ -579,6 +576,20 @@ impl CalxVM {
Ok(())
}

/// checks is given parameters on stack top
fn check_stack_for_block(&self, params: &[CalxType]) -> Result<(), CalxError> {
if self.stack.len() < params.len() {
return Err(self.gen_err(format!("stack size does not match given params: {:?} {:?}", self.stack, params)));
}
for (idx, t) in params.iter().enumerate() {
if self.stack[self.stack.len() - params.len() - 1 + idx].typed_as(t.to_owned()) {
continue;
}
return Err(self.gen_err(format!("stack type does not match given params: {:?} {:?}", self.stack, params)));
}
Ok(())
}

#[inline(always)]
fn check_func_return(&mut self) -> Result<(), CalxError> {
if self.stack.len() != self.top_frame.initial_stack_size + self.top_frame.ret_types.len() {
Expand Down

0 comments on commit cf569b5

Please sign in to comment.