DEV: Type check expressions work.

This commit is contained in:
Jeremy Wall 2019-07-31 20:08:05 -05:00
parent 2bfb1ee6fe
commit 48ea8b30ef
4 changed files with 71 additions and 3 deletions

View File

@ -143,6 +143,8 @@ pub enum Op {
Return,
// Calls
FCall,
// TypeSystem
Typ,
// Runtime hooks
Runtime(Hook),
// TODO(jwall): TRACE instruction

View File

@ -18,7 +18,7 @@ use super::Composite::{List, Tuple};
use super::Op::{
Add, Bang, Bind, Cp, DeRef, Div, Element, Equal, FCall, Field, Func, Index, InitList,
InitThunk, InitTuple, Jump, JumpIfFalse, JumpIfTrue, Module, Mul, Noop, Pop, Return,
SelectJump, Sub, Sym, Val,
SelectJump, Sub, Sym, Typ, Val,
};
use super::Primitive::{Bool, Empty, Float, Int, Str};
use super::Value::{C, P};
@ -490,6 +490,46 @@ fn index_operation() {
];
}
#[test]
fn type_comparisons() {
assert_cases![
vec![
Val(Str("foo".to_owned())),
Typ,
] => P(Str("str".to_owned())),
vec![
Val(Int(1)),
Typ,
] => P(Str("int".to_owned())),
vec![
Val(Float(1.0)),
Typ,
] => P(Str("float".to_owned())),
vec![
Val(Bool(true)),
Typ,
] => P(Str("bool".to_owned())),
vec![
Val(Empty),
Typ,
] => P(Str("null".to_owned())),
vec![
InitTuple,
Typ,
] => P(Str("tuple".to_owned())),
vec![
InitList,
Typ,
] => P(Str("list".to_owned())),
vec![
Val(Str("str".to_owned())),
Val(Str("foo".to_owned())),
Typ,
Equal,
] => P(Bool(true)),
];
}
#[test]
fn scope_stacks() {
let mut stack = Stack::new();
@ -557,6 +597,7 @@ fn simple_binary_expr() {
"2<1;" => P(Bool(false)),
"1!=1;" => P(Bool(false)),
"\"foo\" ~ \"bar\";" => P(Bool(false)),
"\"foo\" is \"str\";" => P(Bool(true)),
//"true && false;" => P(Bool(false)),
)
}

View File

@ -89,8 +89,11 @@ impl AST {
ops.push(Op::Runtime(Hook::Regex));
ops.push(Op::Not);
}
BinaryExprType::IS => {
ops.push(Op::Typ);
ops.push(Op::Equal);
}
BinaryExprType::IN
| BinaryExprType::IS
| BinaryExprType::Mod
| BinaryExprType::OR
| BinaryExprType::AND

View File

@ -22,7 +22,7 @@ use super::{Error, Op, Primitive, Value};
use super::Composite::{List, Tuple};
use super::Hook;
use super::Primitive::{Bool, Float, Int, Str};
use super::Primitive::{Bool, Empty, Float, Int, Str};
use super::Value::{C, F, M, P, S, T};
use super::{Func, Module};
@ -118,12 +118,34 @@ impl<'a> VM {
Op::Pop => {
self.pop()?;
}
Op::Typ => self.op_typ()?,
Op::Runtime(h) => self.op_runtime(h)?,
};
}
Ok(())
}
fn op_typ(&mut self) -> Result<(), Error> {
let val = dbg!(self.pop())?;
let typ_name = match val.as_ref() {
P(Int(_)) => "int",
P(Float(_)) => "float",
P(Bool(_)) => "bool",
P(Str(_)) => "str",
P(Empty) => "null",
C(Tuple(_)) => "tuple",
C(List(_)) => "list",
F(_) => "func",
M(_) => "module",
S(_) | T(_) => {
return Err(dbg!(Error {}));
}
}
.to_owned();
self.push(Rc::new(P(Str(typ_name))))?;
Ok(())
}
fn op_deref(&mut self, name: String) -> Result<(), Error> {
let val = dbg!(self.get_binding(&name)?.clone());
self.push(val)