aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEdvard Thörnros <edvard.thornros@gmail.com>2021-03-08 21:57:52 +0100
committerEdvard Thörnros <edvard.thornros@gmail.com>2021-03-08 21:57:52 +0100
commit4e6ef21576d9ec6a8861246464b1905819b68efe (patch)
treec0e07b88e9257783990895dfc6d3ab559e82b712
parent858d5c1756b64f4973588424b8ba375136740510 (diff)
downloadsylt-4e6ef21576d9ec6a8861246464b1905819b68efe.tar.gz
fix some nice tests for the nullable_types
-rw-r--r--progs/tests/nullable_types.sy33
-rw-r--r--src/compiler.rs10
-rw-r--r--src/lib.rs1
-rw-r--r--src/tokenizer.rs3
-rw-r--r--src/vm.rs4
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) }
};
diff --git a/src/lib.rs b/src/lib.rs
index d0a45f6..e7c4a35 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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),
diff --git a/src/vm.rs b/src/vm.rs
index 2859d83..0595639 100644
--- a/src/vm.rs
+++ b/src/vm.rs
@@ -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 => {