From 519a9e5360f2cf0438dd09cfa3070bb9c8819f40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edvard=20Th=C3=B6rnros?= Date: Mon, 15 Feb 2021 18:50:28 +0100 Subject: BlobInstance -> Instance --- src/lib.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/lib.rs') diff --git a/src/lib.rs b/src/lib.rs index ee176e5..c2aee90 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -85,14 +85,14 @@ pub enum Type { Tuple(Vec), Function(Vec, Box), Blob(usize), - BlobInstance(usize), + Instance(usize), } impl PartialEq for Type { fn eq(&self, other: &Self) -> bool { match (self, other) { (Type::Void, Type::Void) => true, - (Type::BlobInstance(a), Type::BlobInstance(b)) => a == b, + (Type::Instance(a), Type::Instance(b)) => a == b, (Type::Blob(a), Type::Blob(b)) => a == b, (Type::Int, Type::Int) => true, (Type::Float, Type::Float) => true, @@ -111,7 +111,7 @@ impl PartialEq for Type { impl From<&Value> for Type { fn from(value: &Value) -> Type { match value { - Value::BlobInstance(i, _) => Type::BlobInstance(*i), + Value::Instance(i, _) => Type::Instance(*i), Value::Blob(i) => Type::Blob(*i), Value::Tuple(v) => { Type::Tuple(v.iter().map(|x| Type::from(x)).collect()) @@ -137,7 +137,7 @@ impl From<&Type> for Value { match ty { Type::Void => Value::Nil, Type::Blob(i) => Value::Blob(*i), - Type::BlobInstance(i) => Value::BlobInstance(*i, Rc::new(RefCell::new(Vec::new()))), + Type::Instance(i) => Value::Instance(*i, Rc::new(RefCell::new(Vec::new()))), Type::Tuple(fields) => { Value::Tuple(Rc::new(fields.iter().map(Value::from).collect())) } @@ -164,7 +164,7 @@ impl From for Value { pub enum Value { Ty(Type), Blob(usize), - BlobInstance(usize, Rc>>), + Instance(usize, Rc>>), Tuple(Rc>), Float(f64), Int(i64), @@ -181,7 +181,7 @@ impl Debug for Value { match self { Value::Ty(ty) => write!(fmt, "(type {:?})", ty), Value::Blob(i) => write!(fmt, "(blob {})", i), - Value::BlobInstance(i, v) => write!(fmt, "(inst {} {:?})", i, v), + Value::Instance(i, v) => write!(fmt, "(inst {} {:?})", i, v), Value::Float(f) => write!(fmt, "(float {})", f), Value::Int(i) => write!(fmt, "(int {})", i), Value::Bool(b) => write!(fmt, "(bool {})", b), -- cgit v1.2.1 From f098c32e89626f75d83118d4d95d209299d28587 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edvard=20Th=C3=B6rnros?= Date: Mon, 15 Feb 2021 19:18:25 +0100 Subject: change how blobs are stored --- src/lib.rs | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) (limited to 'src/lib.rs') diff --git a/src/lib.rs b/src/lib.rs index c2aee90..497dba3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -84,16 +84,16 @@ pub enum Type { String, Tuple(Vec), Function(Vec, Box), - Blob(usize), - Instance(usize), + Blob(Rc), + Instance(Rc), } impl PartialEq for Type { fn eq(&self, other: &Self) -> bool { match (self, other) { (Type::Void, Type::Void) => true, - (Type::Instance(a), Type::Instance(b)) => a == b, - (Type::Blob(a), Type::Blob(b)) => a == b, + (Type::Instance(a), Type::Instance(b)) => *a == *b, + (Type::Blob(a), Type::Blob(b)) => *a == *b, (Type::Int, Type::Int) => true, (Type::Float, Type::Float) => true, (Type::Bool, Type::Bool) => true, @@ -111,8 +111,8 @@ impl PartialEq for Type { impl From<&Value> for Type { fn from(value: &Value) -> Type { match value { - Value::Instance(i, _) => Type::Instance(*i), - Value::Blob(i) => Type::Blob(*i), + Value::Instance(b, _) => Type::Instance(Rc::clone(b)), + Value::Blob(b) => Type::Blob(Rc::clone(b)), Value::Tuple(v) => { Type::Tuple(v.iter().map(|x| Type::from(x)).collect()) } @@ -136,8 +136,11 @@ impl From<&Type> for Value { fn from(ty: &Type) -> Self { match ty { Type::Void => Value::Nil, - Type::Blob(i) => Value::Blob(*i), - Type::Instance(i) => Value::Instance(*i, Rc::new(RefCell::new(Vec::new()))), + Type::Blob(b) => Value::Blob(Rc::clone(b)), + Type::Instance(b) => { + Value::Instance(Rc::clone(b), + Rc::new(RefCell::new(Vec::new()))) + } Type::Tuple(fields) => { Value::Tuple(Rc::new(fields.iter().map(Value::from).collect())) } @@ -163,8 +166,8 @@ impl From for Value { #[derive(Clone)] pub enum Value { Ty(Type), - Blob(usize), - Instance(usize, Rc>>), + Blob(Rc), + Instance(Rc, Rc>>), Tuple(Rc>), Float(f64), Int(i64), @@ -180,8 +183,8 @@ impl Debug for Value { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Value::Ty(ty) => write!(fmt, "(type {:?})", ty), - Value::Blob(i) => write!(fmt, "(blob {})", i), - Value::Instance(i, v) => write!(fmt, "(inst {} {:?})", i, v), + Value::Blob(b) => write!(fmt, "(blob {})", b.name), + Value::Instance(b, v) => write!(fmt, "(inst {} {:?})", b.name, v), Value::Float(f) => write!(fmt, "(float {})", f), Value::Int(i) => write!(fmt, "(int {})", i), Value::Bool(b) => write!(fmt, "(bool {})", b), @@ -257,14 +260,22 @@ impl UpValue { #[derive(Debug, Clone)] pub struct Blob { + pub id: usize, pub name: String, /// Maps field names to their slot and type. pub fields: HashMap, } +impl PartialEq for Blob { + fn eq(&self, other: &Self) -> bool { + self.id == other.id + } +} + impl Blob { - fn new(name: &str) -> Self { + fn new(id: usize, name: &str) -> Self { Self { + id: id, name: String::from(name), fields: HashMap::new(), } @@ -713,7 +724,6 @@ impl Block { #[derive(Clone)] pub struct Prog { pub blocks: Vec>>, - pub blobs: Vec>, pub functions: Vec, pub constants: Vec, pub strings: Vec, -- cgit v1.2.1 From 4d2121c548492c591d3366f6a3b919b098c349d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edvard=20Th=C3=B6rnros?= Date: Mon, 15 Feb 2021 22:23:11 +0100 Subject: allow usages of blobs before definition --- src/lib.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src/lib.rs') diff --git a/src/lib.rs b/src/lib.rs index 497dba3..7253141 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1183,4 +1183,15 @@ a := 0 a <=> -1 ", ); + test_multiple!( + declaration_order, + simple: " +a := A() + +blob A { + a: int +} +", + + ); } -- cgit v1.2.1 From 42b6130e649b41671620134ed73fa2ae7b0990a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edvard=20Th=C3=B6rnros?= Date: Mon, 15 Feb 2021 22:36:32 +0100 Subject: add more tests --- src/lib.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'src/lib.rs') diff --git a/src/lib.rs b/src/lib.rs index 7253141..907a1cd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -833,6 +833,12 @@ mod tests { assert_errs!(run_string("a :: 2\nq :: fn { a = 2 }\n", true, Vec::new()), [ErrorKind::SyntaxError(_, _)]); } + #[test] + fn undefined_blob() { + assert_errs!(run_string("a :: B()\n", true, Vec::new()), [ErrorKind::SyntaxError(_, _)]); + } + + macro_rules! test_multiple { ($mod:ident, $( $fn:ident : $prog:literal ),+ $( , )? ) => { mod $mod { @@ -1183,6 +1189,7 @@ a := 0 a <=> -1 ", ); + test_multiple!( declaration_order, simple: " @@ -1193,5 +1200,15 @@ blob A { } ", + complex: " +a := A() +b := B() +c := C() +b2 := B() + +blob A { } +blob C { } +blob B { } +", ); } -- cgit v1.2.1 From f93bb0b3bf8cf26dfa337b643c90f321bd67520c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edvard=20Th=C3=B6rnros?= Date: Mon, 15 Feb 2021 23:33:52 +0100 Subject: sexy constant functions --- src/lib.rs | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) (limited to 'src/lib.rs') diff --git a/src/lib.rs b/src/lib.rs index 907a1cd..1fa6368 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1192,7 +1192,7 @@ a <=> -1 test_multiple!( declaration_order, - simple: " + blob_simple: " a := A() blob A { @@ -1200,15 +1200,42 @@ blob A { } ", - complex: " + blob_complex: " a := A() b := B() c := C() b2 := B() -blob A { } +blob A { + c: C +} blob C { } blob B { } +", + + constant_function: " +a() +a :: fn {} +", + + constant_function_complex: " +h :: fn -> int { + ret 3 +} + +a() <=> 3 + +k :: fn -> int { + ret h() +} + +a :: fn -> int { + ret q() +} + +q :: fn -> int { + ret k() +} ", ); } -- cgit v1.2.1 From 2a8020706c6309ac23755839cfdb13cf4e11d303 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edvard=20Th=C3=B6rnros?= Date: Mon, 15 Feb 2021 23:49:42 +0100 Subject: add magic blob inference --- src/lib.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'src/lib.rs') diff --git a/src/lib.rs b/src/lib.rs index 1fa6368..146e534 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1045,7 +1045,11 @@ a() <=> 4 a.a = 2 a.b = 3 a.a + a.b <=> 5 - 5 <=> a.a + a.b" + 5 <=> a.a + a.b", + blob_infer: " +blob A { } +a : A = A() +", ); test_multiple!(tuples, @@ -1213,6 +1217,13 @@ blob C { } blob B { } ", + blob_infer: " +blob A { } + +a : A = A() +", + + constant_function: " a() a :: fn {} -- cgit v1.2.1 From 1a6fd93e49c01f8291cc594445ef63b407375b1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edvard=20Th=C3=B6rnros?= Date: Mon, 15 Feb 2021 23:54:19 +0100 Subject: add test for upvalues --- src/lib.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src/lib.rs') diff --git a/src/lib.rs b/src/lib.rs index 146e534..b1bae9f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1248,5 +1248,20 @@ q :: fn -> int { ret k() } ", + + constant_function_closure: " +q := 1 + +f :: fn -> int { + q += 1 + ret q +} + +f() <=> 2 +f() <=> 3 +f() <=> 4 +f() <=> 5 +", + ); } -- cgit v1.2.1 From ecc84fc8259ab0f2f5754718ed70e3a57048a540 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edvard=20Th=C3=B6rnros?= Date: Tue, 16 Feb 2021 00:02:23 +0100 Subject: add test that should work --- src/lib.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'src/lib.rs') diff --git a/src/lib.rs b/src/lib.rs index b1bae9f..8821710 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1261,6 +1261,25 @@ f() <=> 2 f() <=> 3 f() <=> 4 f() <=> 5 +", + + constants_in_inner_functions: " +q : int = 0 + +f :: fn -> fn -> { + g :: fn { + q += 1 + } + ret g +} + +g := f() +g() +q <=> 3 +g() +q <=> 4 +g() +q <=> 5 ", ); -- cgit v1.2.1 From e86b1be782c2c2f57e968557d7f91bbcc7b8b27f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edvard=20Th=C3=B6rnros?= Date: Tue, 16 Feb 2021 21:10:03 +0100 Subject: fix the failing testcase --- src/lib.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src/lib.rs') diff --git a/src/lib.rs b/src/lib.rs index 8821710..b39b4bb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -480,6 +480,12 @@ pub enum Op { /// Does not affect the stack. Define(usize), + /// Links the upvalues for the given constant + /// function. This updates the constant stack. + /// + /// Does not affect the stack. + Link(usize), + /// Calls "something" with the given number /// of arguments. The callable value is /// then replaced with the result. @@ -1275,11 +1281,11 @@ f :: fn -> fn -> { g := f() g() -q <=> 3 +q <=> 1 g() -q <=> 4 +q <=> 2 g() -q <=> 5 +q <=> 3 ", ); -- cgit v1.2.1 From ef47ba4e8bdec20a57f325efd129cc3e183e0b98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edvard=20Th=C3=B6rnros?= Date: Tue, 16 Feb 2021 21:10:26 +0100 Subject: clearer test output --- src/lib.rs | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'src/lib.rs') diff --git a/src/lib.rs b/src/lib.rs index b39b4bb..c838743 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -694,6 +694,8 @@ impl Block { pub fn debug_print(&self) { println!(" === {} ===", self.name.blue()); for (i, s) in self.ops.iter().enumerate() { + // TODO(ed): This print should only do one call to print. + // Otherwise we can get race conditions in a single line. if self.line_offsets.contains_key(&i) { print!("{:5} ", self.line_offsets[&i].red()); } else { @@ -763,6 +765,7 @@ mod tests { use std::time::Duration; use std::sync::mpsc; use std::thread; + use owo_colors::OwoColorize; // Shamelessly stolen from https://github.com/rust-lang/rfcs/issues/2798 pub fn panic_after(d: Duration, f: F) -> T @@ -778,10 +781,19 @@ mod tests { val }); - match done_rx.recv_timeout(d) { - Ok(_) => handle.join().expect("Thread panicked"), - Err(_) => panic!("Thread took too long"), - } + let msg = match done_rx.recv_timeout(d) { + Ok(_) => { + return handle.join().expect("Thread panicked"); + } + Err(mpsc::RecvTimeoutError::Timeout) => { + "Test took too long to complete" + }, + Err(mpsc::RecvTimeoutError::Disconnected) => { + "Test produced incorrect result" + }, + }; + println!(" #### {} ####", msg.red()); + panic!(msg); } #[macro_export] @@ -1010,10 +1022,9 @@ b() <=> 2 b() <=> 3 a() <=> 4 -" +", //TODO this tests doesn't terminate in proper time if we print blocks and ops - /* fibonacci: "fibonacci : fn int -> int = fn n: int -> int { if n == 0 { ret 0 @@ -1024,9 +1035,7 @@ a() <=> 4 } ret fibonacci(n - 1) + fibonacci(n - 2) } - fibonacci(10) <=> 55 - fibonacci(20) <=> 6765" - */ + fibonacci(10) <=> 55", ); test_multiple!( -- cgit v1.2.1 From 299981e74e625b7dc85ebfe2adbd066f6c68c0d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edvard=20Th=C3=B6rnros?= Date: Tue, 16 Feb 2021 21:35:38 +0100 Subject: remove long test --- src/lib.rs | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'src/lib.rs') diff --git a/src/lib.rs b/src/lib.rs index c838743..77176c4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1023,19 +1023,6 @@ b() <=> 3 a() <=> 4 ", - - //TODO this tests doesn't terminate in proper time if we print blocks and ops - fibonacci: "fibonacci : fn int -> int = fn n: int -> int { - if n == 0 { - ret 0 - } else if n == 1 { - ret 1 - } else if n < 0 { - - } - ret fibonacci(n - 1) + fibonacci(n - 2) - } - fibonacci(10) <=> 55", ); test_multiple!( -- cgit v1.2.1