From 48ea8b30ef75d35295123ba3f662b658b77a8e03 Mon Sep 17 00:00:00 2001 From: Jeremy Wall Date: Wed, 31 Jul 2019 20:08:05 -0500 Subject: [PATCH] DEV: Type check expressions work. --- src/build/opcode/mod.rs | 2 ++ src/build/opcode/test.rs | 43 ++++++++++++++++++++++++++++++++++- src/build/opcode/translate.rs | 5 +++- src/build/opcode/vm.rs | 24 ++++++++++++++++++- 4 files changed, 71 insertions(+), 3 deletions(-) diff --git a/src/build/opcode/mod.rs b/src/build/opcode/mod.rs index 7737c0c..b925f9e 100644 --- a/src/build/opcode/mod.rs +++ b/src/build/opcode/mod.rs @@ -143,6 +143,8 @@ pub enum Op { Return, // Calls FCall, + // TypeSystem + Typ, // Runtime hooks Runtime(Hook), // TODO(jwall): TRACE instruction diff --git a/src/build/opcode/test.rs b/src/build/opcode/test.rs index 88942fb..93fd9b7 100644 --- a/src/build/opcode/test.rs +++ b/src/build/opcode/test.rs @@ -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)), ) } diff --git a/src/build/opcode/translate.rs b/src/build/opcode/translate.rs index 64a7912..44c6679 100644 --- a/src/build/opcode/translate.rs +++ b/src/build/opcode/translate.rs @@ -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 diff --git a/src/build/opcode/vm.rs b/src/build/opcode/vm.rs index 2753734..fe9b09c 100644 --- a/src/build/opcode/vm.rs +++ b/src/build/opcode/vm.rs @@ -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)