Skip to content

Commit

Permalink
[lang] Better tuple syntax (#1122)
Browse files Browse the repository at this point in the history
Close #1101
  • Loading branch information
SamChou19815 authored Oct 30, 2023
1 parent 8daf329 commit 65c6a39
Show file tree
Hide file tree
Showing 14 changed files with 291 additions and 142 deletions.
64 changes: 32 additions & 32 deletions crates/samlang-core/src/checker/checker_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -714,39 +714,39 @@ Found 1 error.
assert_errors_full_customization(
heap,
r#"{
let _: int = [1, 1].e1;
let _: int = [1, 1, 1].e2;
let _: int = [1, 1, 1, 1].e3;
let _: int = [1, 1, 1, 1, 1].e4;
let _: int = [1, 1, 1, 1, 1, 1].e5;
let _: int = [1, 1, 1, 1, 1, 1, 1].e6;
let _: int = [1, 1, 1, 1, 1, 1, 1, 1].e7;
let _: int = [1, 1, 1, 1, 1, 1, 1, 1, 1].e8;
let _: int = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1].e9;
let _: int = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1].e10;
let _: int = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1].e11;
let _: int = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1].e12;
let _: int = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1].e13;
let _: bool = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1].e14;
let _: int = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1].e15;
let _: int = (1, 1).e1;
let _: int = (1, 1, 1).e2;
let _: int = (1, 1, 1, 1).e3;
let _: int = (1, 1, 1, 1, 1).e4;
let _: int = (1, 1, 1, 1, 1, 1).e5;
let _: int = (1, 1, 1, 1, 1, 1, 1).e6;
let _: int = (1, 1, 1, 1, 1, 1, 1, 1).e7;
let _: int = (1, 1, 1, 1, 1, 1, 1, 1, 1).e8;
let _: int = (1, 1, 1, 1, 1, 1, 1, 1, 1, 1).e9;
let _: int = (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1).e10;
let _: int = (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1).e11;
let _: int = (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1).e12;
let _: int = (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1).e13;
let _: bool = (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1).e14;
let _: int = (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1).e15;
}"#,
&builder.unit_type(),
r#"
Error --------------------------------- DUMMY.sam:15:3-15:67
`int` [1] is incompatible with `bool` [2].
15| let _: bool = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1].e14;
15| let _: bool = (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1).e14;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[1] DUMMY.sam:15:17-15:66
-------------------------
15| let _: bool = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1].e14;
15| let _: bool = (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1).e14;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[2] DUMMY.sam:15:10-15:14
-------------------------
15| let _: bool = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1].e14;
15| let _: bool = (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1).e14;
^^^^
Expand Down Expand Up @@ -2755,22 +2755,22 @@ Found 1 error.
);
assert_errors_full_customization(
heap,
"{ let _ = (t: Test) -> if let [a, b, _] = [1, 2] then 1 else 2; }",
"{ let _ = (t: Test) -> if let (a, b, _) = (1, 2) then 1 else 2; }",
&builder.unit_type(),
r#"
Error ---------------------------------- DUMMY.sam:1:31-1:40
The pattern is irrefutable.
1| { let _ = (t: Test) -> if let [a, b, _] = [1, 2] then 1 else 2; }
1| { let _ = (t: Test) -> if let (a, b, _) = (1, 2) then 1 else 2; }
^^^^^^^^^
Error ---------------------------------- DUMMY.sam:1:38-1:39
Cannot access member of `Pair<int, int>` at index 2.
1| { let _ = (t: Test) -> if let [a, b, _] = [1, 2] then 1 else 2; }
1| { let _ = (t: Test) -> if let (a, b, _) = (1, 2) then 1 else 2; }
^
Expand All @@ -2782,11 +2782,11 @@ Found 2 errors.
assert_errors_full_customization(
heap,
r#"{ let _ = (t: Test) -> if let {bar, boo} = t then 1 else 2;
let _ = (t: Test) -> if let [_, bar] = t then 1 else 2;
let _ = (t: Test) -> if let (_, bar) = t then 1 else 2;
let _ = (t: Test2) -> if let Foo(_) = t then 1 else 2;
let _ = (t: Test2) -> if let Foo(_, _) = t then 1 else 2;
let _ = (t: Test2) -> if let Foo111(_) = t then 1 else 2;
let _ = (t: Test2) -> if let Foo111(_, a, {bar as baz, b}, [eee, fff]) = t then 1 else 2;
let _ = (t: Test2) -> if let Foo111(_, a, {bar as baz, b}, (eee, fff)) = t then 1 else 2;
let _ = (t: Test2) -> if let {s} = t then 1 else 2;
let _ = if let F = 1 then 1 else 2;
}"#,
Expand Down Expand Up @@ -2830,23 +2830,23 @@ Error ---------------------------------- DUMMY.sam:2:29-2:37
The pattern does not bind all fields. Expected number of elements: 3, actual number of elements: 2.
2| let _ = (t: Test) -> if let [_, bar] = t then 1 else 2;
2| let _ = (t: Test) -> if let (_, bar) = t then 1 else 2;
^^^^^^^^
Error ---------------------------------- DUMMY.sam:2:29-2:37
The pattern is irrefutable.
2| let _ = (t: Test) -> if let [_, bar] = t then 1 else 2;
2| let _ = (t: Test) -> if let (_, bar) = t then 1 else 2;
^^^^^^^^
Error ---------------------------------- DUMMY.sam:2:33-2:36
Cannot access member of `Test` at index 1.
2| let _ = (t: Test) -> if let [_, bar] = t then 1 else 2;
2| let _ = (t: Test) -> if let (_, bar) = t then 1 else 2;
^^^
Expand All @@ -2870,7 +2870,7 @@ Error ---------------------------------- DUMMY.sam:6:30-6:36
Cannot resolve member `Foo111` on `Test2`.
6| let _ = (t: Test2) -> if let Foo111(_, a, {bar as baz, b}, [eee, fff]) = t then 1 else 2;
6| let _ = (t: Test2) -> if let Foo111(_, a, {bar as baz, b}, (eee, fff)) = t then 1 else 2;
^^^^^^
Expand Down Expand Up @@ -3074,22 +3074,22 @@ Found 2 errors.

assert_errors(
heap,
"{let [a, b, c] = A.init();}",
"{let (a, b, c) = A.init();}",
&builder.unit_type(),
r#"
Error ---------------------------------- DUMMY.sam:1:10-1:11
Cannot access member of `A` at index 1.
1| {let [a, b, c] = A.init();}
1| {let (a, b, c) = A.init();}
^
Error ---------------------------------- DUMMY.sam:1:13-1:14
Cannot access member of `A` at index 2.
1| {let [a, b, c] = A.init();}
1| {let (a, b, c) = A.init();}
^
Expand Down Expand Up @@ -3187,14 +3187,14 @@ Found 2 errors.
);
assert_errors(
heap,
"{let [_]= A.init();}",
"{let (_)= A.init();}",
&builder.unit_type(),
r#"
Error ------------------------------------ DUMMY.sam:1:6-1:9
The pattern does not bind all fields. Expected number of elements: 2, actual number of elements: 1.
1| {let [_]= A.init();}
1| {let (_)= A.init();}
^^^
Expand Down
2 changes: 1 addition & 1 deletion crates/samlang-core/src/checker/ssa_analysis_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ mod tests {
} else {
(p1: Foo, p2) -> Baz.ouch<Foo>(p2).ahha<Foo>(p1) + a
};
let _ = if let {pat1 as {pat2 as [Fizz(pat3), Buzz, _], pat4}} = true then 1 else 2;
let _ = if let {pat1 as {pat2 as (Fizz(pat3), Buzz, _), pat4}} = true then 1 else 2;
let a = 3;
let {o1, o2 as o3} = {};
o1 + o3
Expand Down
24 changes: 12 additions & 12 deletions crates/samlang-core/src/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1365,10 +1365,10 @@ class Main {
import {Pair} from std.tuples;
class List(Nil(unit), Cons(Pair<int, List>)) {
function of(i: int): List = List.Cons([
function of(i: int): List = List.Cons((
i,
List.Nil({ })
])
))
}
class Main { function main(): unit = { let _: List = List.of(1); Process.println("hello") } }
Expand Down Expand Up @@ -2109,15 +2109,15 @@ class BoxedInt(val i: int): Comparable<BoxedInt> {
class List<T: Comparable<T>>(Nil(unit), Cons(Pair<T, List<T>>)) {
function <T: Comparable<T>> nil(): List<T> = List.Nil<T>({ })
function <T: Comparable<T>> of(t: T): List<T> = List.Cons([t, List.Nil<T>({ })])
function <T: Comparable<T>> of(t: T): List<T> = List.Cons((t, List.Nil<T>({ })))
method cons(t: T): List<T> = List.Cons([t, this])
method cons(t: T): List<T> = List.Cons((t, this))
method iter(f: (T) -> unit): unit =
match (this) {
Nil(_) -> { }
Cons(pair) -> {
let [v, rest] = pair;
let (v, rest) = pair;
let _ = f(v);
rest.iter(f)
}
Expand All @@ -2129,7 +2129,7 @@ class List<T: Comparable<T>>(Nil(unit), Cons(Pair<T, List<T>>)) {
Cons(pair) -> match (pair.e1) {
Nil(_) -> this,
Cons(_) -> {
let [l1, l2] = this.split(List.nil<T>(), List.nil<T>());
let (l1, l2) = this.split(List.nil<T>(), List.nil<T>());
l1.sort().merge(l2.sort())
}
}
Expand All @@ -2141,8 +2141,8 @@ class List<T: Comparable<T>>(Nil(unit), Cons(Pair<T, List<T>>)) {
Cons(pair1) -> match (other) {
Nil(_) -> this,
Cons(pair2) -> {
let [h1, t1] = pair1;
let [h2, t2] = pair2;
let (h1, t1) = pair1;
let (h2, t2) = pair2;
if (h1.compare(h2) < 0) then t1.merge(other).cons(h1) else t2.merge(this).cons(h2)
}
}
Expand All @@ -2152,7 +2152,7 @@ class List<T: Comparable<T>>(Nil(unit), Cons(Pair<T, List<T>>)) {
match (this) {
Nil(_) -> Pair.init(y, z),
Cons(pair) -> {
let [x, rest] = pair;
let (x, rest) = pair;
rest.split(z, y.cons(x))
}
}
Expand Down Expand Up @@ -2261,11 +2261,11 @@ class Main {
import {Pair, Triple} from std.tuples;
class Clazz(val t: Pair<Triple<int, int, bool>, Str>) {
function of(): Clazz = Clazz.init([[42, 2, false], ""])
function of(): Clazz = Clazz.init(((42, 2, false), ""))
method thisTest(): int = {
let [[i, _, _], _] = this.t;
let {t as {e0 as [j, _, _], e1}} = this;
let ((i, _, _), _) = this.t;
let {t as {e0 as (j, _, _), e1}} = this;
i + j
}
}
Expand Down
12 changes: 8 additions & 4 deletions crates/samlang-core/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,16 @@ mod tests {
expect_good_expr("false || true");
expect_good_expr("\"hello\"::\"world\"");
expect_good_expr("if (true) then 3 else bar");
expect_good_expr("if let {foo as {bar as [Fizz(baz), Buzz, _], boo}} = true then 3 else bar");
expect_good_expr("if let {foo as {bar as (Fizz(baz), Buzz, _), boo}} = true then 3 else bar");
expect_good_expr("match (this) { None(_) -> 0, Some(d) -> d }");
expect_good_expr("match (this) { None(_) -> match this { None(_) -> 1 } Some(d) -> d }");
expect_good_expr("match (this) { None(_) -> {}, Some(d) -> d }");
expect_good_expr("match (this) { None(_) -> 0, Some(d) -> d, }");
expect_good_expr("(a, b: int, c: Type) -> 3");
expect_good_expr("(a, b: () -> int, c: Type) -> 3");
expect_good_expr("(a, b, c: () -> int, d: Type) -> 3");
expect_good_expr("(a, b: () -> int, c, d: Type) -> 3");
expect_good_expr("(a, b, c.a)");
expect_good_expr("() -> 3");
expect_good_expr("(foo) -> 3");
expect_good_expr("(foo: bool) -> 3");
Expand All @@ -117,7 +120,7 @@ mod tests {
expect_good_expr("{ let a = 3; a }");
expect_good_expr("{ let a: int = 3; }");
expect_good_expr("{ let a: unit = {}; }");
expect_good_expr("{ let [foo, _]: Type = [1, 2]; }");
expect_good_expr("{ let (foo, _): Type = (1, 2); }");
expect_good_expr("{ let {foo, bar as baz}: Type = 3; }");
expect_good_expr("{ let _: Int<bool> = 3; }");
expect_good_expr("{ let _: HAHAHA = 3; }");
Expand Down Expand Up @@ -147,9 +150,10 @@ mod tests {
expect_bad_expr("ForTests.assertIntEquals(2444a, 1)");
expect_bad_expr(".");
expect_bad_expr(",");
expect_bad_expr("[]");
expect_bad_expr("()");
expect_bad_expr("[1]");
expect_bad_expr("[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]");
expect_bad_expr("(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)");
expect_bad_expr("(a,b,c,d,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)");
expect_bad_expr("{: }");
expect_bad_expr("{ hello / }");
expect_bad_expr("{: bar}");
Expand Down
Loading

0 comments on commit 65c6a39

Please sign in to comment.