diff options
| author | Edvard Thörnros <edvard.thornros@gmail.com> | 2021-03-08 21:57:52 +0100 |
|---|---|---|
| committer | Edvard Thörnros <edvard.thornros@gmail.com> | 2021-03-08 21:57:52 +0100 |
| commit | 4e6ef21576d9ec6a8861246464b1905819b68efe (patch) | |
| tree | c0e07b88e9257783990895dfc6d3ab559e82b712 | |
| parent | 858d5c1756b64f4973588424b8ba375136740510 (diff) | |
| download | sylt-4e6ef21576d9ec6a8861246464b1905819b68efe.tar.gz | |
fix some nice tests for the nullable_types
| -rw-r--r-- | progs/tests/nullable_types.sy | 33 | ||||
| -rw-r--r-- | src/compiler.rs | 10 | ||||
| -rw-r--r-- | src/lib.rs | 1 | ||||
| -rw-r--r-- | src/tokenizer.rs | 3 | ||||
| -rw-r--r-- | src/vm.rs | 4 |
5 files changed, 47 insertions, 4 deletions
diff --git a/progs/tests/nullable_types.sy b/progs/tests/nullable_types.sy new file mode 100644 index 0000000..2088c53 --- /dev/null +++ b/progs/tests/nullable_types.sy @@ -0,0 +1,33 @@ +test001 :: fn -> int { + a : int? = nil + a = 2 + ret a +} + +test002 :: fn b:bool -> int? { + if b { + ret nil + } else { + ret 0 + } +} + +// TODO(ed): Introduce type type! +test003 :: fn { + a := test002! false + a += 1 + a <=> 1 +} + + +start :: fn { + test001! + nil <=> test002! true + 0 <=> test002! false + q : bool? = true + q <=> true + q = nil + q <=> nil + test003! +} + diff --git a/src/compiler.rs b/src/compiler.rs index 47b8b84..4fdd13b 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -634,10 +634,11 @@ impl Compiler { Token::LeftParen => self.grouping_or_tuple(block), Token::Minus => self.unary(block), - Token::Float(_) => self.value(block), - Token::Int(_) => self.value(block), - Token::Bool(_) => self.value(block), - Token::String(_) => self.value(block), + Token::Float(_) + | Token::Int(_) + | Token::Bool(_) + | Token::String(_) + | Token::Nil => self.value(block), Token::Bang => self.unary(block), @@ -676,6 +677,7 @@ impl Compiler { Token::Float(f) => { Value::Float(f) }, Token::Int(i) => { Value::Int(i) } Token::Bool(b) => { Value::Bool(b) } + Token::Nil => { Value::Nil } Token::String(s) => { Value::String(Rc::from(s)) } _ => { error!(self, "Cannot parse value."); Value::Bool(false) } }; @@ -685,6 +685,7 @@ mod op { (Value::Unknown, a) | (a, Value::Unknown) if !matches!(a, Value::Unknown) => eq(a, a), (Value::Unknown, Value::Unknown) => Value::Unknown, (Value::Union(a), b) | (b, Value::Union(a)) => union_bin_op(&a, b, eq), + (Value::Nil, Value::Nil) => Value::Bool(true), _ => Value::Nil, } } diff --git a/src/tokenizer.rs b/src/tokenizer.rs index 6e142e3..664532a 100644 --- a/src/tokenizer.rs +++ b/src/tokenizer.rs @@ -15,6 +15,9 @@ pub enum Token { #[regex(r"[\d]+", |lex| lex.slice().parse())] Int(i64), + #[regex(r"nil")] + Nil, + #[regex(r"true|false", |lex| lex.slice().parse(), priority=2)] Bool(bool), @@ -669,6 +669,10 @@ impl VM { let ty = self.ty(ty); let top_type = self.stack.last().unwrap().into(); match (ty, top_type) { + (a, b) if matches!(a, Type::Union(_)) && a == &b => { + let last = self.stack.len() - 1; + self.stack[last] = Value::from(a); + } (Type::Unknown, top_type) if top_type != Type::Unknown => {} (a, b) if a != &b => { |
