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, Return,
// Calls // Calls
FCall, FCall,
// TypeSystem
Typ,
// Runtime hooks // Runtime hooks
Runtime(Hook), Runtime(Hook),
// TODO(jwall): TRACE instruction // TODO(jwall): TRACE instruction

View File

@ -18,7 +18,7 @@ use super::Composite::{List, Tuple};
use super::Op::{ use super::Op::{
Add, Bang, Bind, Cp, DeRef, Div, Element, Equal, FCall, Field, Func, Index, InitList, Add, Bang, Bind, Cp, DeRef, Div, Element, Equal, FCall, Field, Func, Index, InitList,
InitThunk, InitTuple, Jump, JumpIfFalse, JumpIfTrue, Module, Mul, Noop, Pop, Return, 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::Primitive::{Bool, Empty, Float, Int, Str};
use super::Value::{C, P}; 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] #[test]
fn scope_stacks() { fn scope_stacks() {
let mut stack = Stack::new(); let mut stack = Stack::new();
@ -557,6 +597,7 @@ fn simple_binary_expr() {
"2<1;" => P(Bool(false)), "2<1;" => P(Bool(false)),
"1!=1;" => P(Bool(false)), "1!=1;" => P(Bool(false)),
"\"foo\" ~ \"bar\";" => P(Bool(false)), "\"foo\" ~ \"bar\";" => P(Bool(false)),
"\"foo\" is \"str\";" => P(Bool(true)),
//"true && false;" => P(Bool(false)), //"true && false;" => P(Bool(false)),
) )
} }

View File

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

View File

@ -22,7 +22,7 @@ use super::{Error, Op, Primitive, Value};
use super::Composite::{List, Tuple}; use super::Composite::{List, Tuple};
use super::Hook; 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::Value::{C, F, M, P, S, T};
use super::{Func, Module}; use super::{Func, Module};
@ -118,12 +118,34 @@ impl<'a> VM {
Op::Pop => { Op::Pop => {
self.pop()?; self.pop()?;
} }
Op::Typ => self.op_typ()?,
Op::Runtime(h) => self.op_runtime(h)?, Op::Runtime(h) => self.op_runtime(h)?,
}; };
} }
Ok(()) 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> { fn op_deref(&mut self, name: String) -> Result<(), Error> {
let val = dbg!(self.get_binding(&name)?.clone()); let val = dbg!(self.get_binding(&name)?.clone());
self.push(val) self.push(val)