Skip to content

Commit

Permalink
Merge pull request ValeLang#619 from Verdagon/regionsmerge14
Browse files Browse the repository at this point in the history
Regions merge: tuples, function returns, incremental solves
  • Loading branch information
Verdagon authored Jul 14, 2023
2 parents 57b2698 + 7ec8adb commit 08f3120
Show file tree
Hide file tree
Showing 38 changed files with 422 additions and 231 deletions.
5 changes: 4 additions & 1 deletion Frontend/Builtins/src/dev/vale/Builtins.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ object Builtins {
"mainargs" -> "mainargs.vale",
"as" -> "as.vale",
"print" -> "print.vale",
"tup" -> "tup.vale",
"tup0" -> "tup0.vale",
"tup1" -> "tup1.vale",
"tup2" -> "tup2.vale",
"tupN" -> "tupN.vale",
"streq" -> "streq.vale",
"panic" -> "panic.vale",
"panicutils" -> "panicutils.vale",
Expand Down
16 changes: 0 additions & 16 deletions Frontend/Builtins/src/dev/vale/resources/tup.vale

This file was deleted.

2 changes: 2 additions & 0 deletions Frontend/Builtins/src/dev/vale/resources/tup0.vale
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

struct Tup0 { }
10 changes: 10 additions & 0 deletions Frontend/Builtins/src/dev/vale/resources/tup1.vale
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

// See TAVWG for what it would take to re-enable variadic tuples.
// struct Tup<T RefList> {
// _ ..T;
// }

#!DeriveStructDrop
struct Tup1<T0> { 0 T0; }
func drop<T0>(tup Tup1<T0>)
where func drop(T0)void { [a] = tup; }
12 changes: 12 additions & 0 deletions Frontend/Builtins/src/dev/vale/resources/tup2.vale
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

// See TAVWG for what it would take to re-enable variadic tuples.
// struct Tup<T RefList> {
// _ ..T;
// }

#!DeriveStructDrop
struct Tup2<T0, T1> { 0 T0; 1 T1; }
func drop<T0, T1>(tup Tup2<T0, T1>)
where func drop(T0)void,
func drop(T1)void
{ [a, b] = tup; }
83 changes: 83 additions & 0 deletions Frontend/Builtins/src/dev/vale/resources/tupN.vale
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@

// See TAVWG for what it would take to re-enable variadic tuples.
// struct Tup<T RefList> {
// _ ..T;
// }

#!DeriveStructDrop
struct Tup3<T0, T1, T2> { 0 T0; 1 T1; 2 T2; }
func drop<T0, T1, T2>(tup Tup3<T0, T1, T2>)
where func drop(T0)void,
func drop(T1)void,
func drop(T2)void
{ [a, b, c] = tup; }

// #!DeriveStructDrop
// struct Tup4<T0, T1, T2, T3> { 0 T0; 1 T1; 2 T2; 3 T3; }
// func drop<T0, T1, T2, T3>(tup Tup4<T0, T1, T2, T3>)
// where func drop(T0)void,
// func drop(T1)void,
// func drop(T2)void,
// func drop(T3)void
// { [a, b, c, d] = tup; }
//
// #!DeriveStructDrop
// struct Tup5<T0, T1, T2, T3, T4> { 0 T0; 1 T1; 2 T2; 3 T3; 4 T4; }
// func drop<T0, T1, T2, T3, T4>(tup Tup5<T0, T1, T2, T3, T4>)
// where func drop(T0)void,
// func drop(T1)void,
// func drop(T2)void,
// func drop(T3)void,
// func drop(T4)void
// { [a, b, c, d, e] = tup; }
//
// #!DeriveStructDrop
// struct Tup6<T0, T1, T2, T3, T4, T5> { 0 T0; 1 T1; 2 T2; 3 T3; 4 T4; 5 T5; }
// func drop<T0, T1, T2, T3, T4, T5>(tup Tup6<T0, T1, T2, T3, T4, T5>)
// where func drop(T0)void,
// func drop(T1)void,
// func drop(T2)void,
// func drop(T3)void,
// func drop(T4)void,
// func drop(T5)void
// { [a, b, c, d, e, f] = tup; }
//
// #!DeriveStructDrop
// struct Tup7<T0, T1, T2, T3, T4, T5, T6> { 0 T0; 1 T1; 2 T2; 3 T3; 4 T4; 5 T5; 6 T6; }
// func drop<T0, T1, T2, T3, T4, T5, T6>(tup Tup7<T0, T1, T2, T3, T4, T5, T6>)
// where func drop(T0)void,
// func drop(T1)void,
// func drop(T2)void,
// func drop(T3)void,
// func drop(T4)void,
// func drop(T5)void,
// func drop(T6)void
// { [a, b, c, d, e, f, g] = tup; }
//
// #!DeriveStructDrop
// struct Tup8<T0, T1, T2, T3, T4, T5, T6, T7> { 0 T0; 1 T1; 2 T2; 3 T3; 4 T4; 5 T5; 6 T6; 7 T7; }
// func drop<T0, T1, T2, T3, T4, T5, T6, T7>(tup Tup8<T0, T1, T2, T3, T4, T5, T6, T7>)
// where func drop(T0)void,
// func drop(T1)void,
// func drop(T2)void,
// func drop(T3)void,
// func drop(T4)void,
// func drop(T5)void,
// func drop(T6)void,
// func drop(T7)void
// { [a, b, c, d, e, f, g, h] = tup; }
//
// #!DeriveStructDrop
// struct Tup9<T0, T1, T2, T3, T4, T5, T6, T7, T8> { 0 T0; 1 T1; 2 T2; 3 T3; 4 T4; 5 T5; 6 T6; 7 T7; 8 T8; }
// func drop<T0, T1, T2, T3, T4, T5, T6, T7, T8>(tup Tup9<T0, T1, T2, T3, T4, T5, T6, T7, T8>)
// where func drop(T0)void,
// func drop(T1)void,
// func drop(T2)void,
// func drop(T3)void,
// func drop(T4)void,
// func drop(T5)void,
// func drop(T6)void,
// func drop(T7)void,
// func drop(T8)void
// { [a, b, c, d, e, f, g, h, i] = tup; }
//
Original file line number Diff line number Diff line change
Expand Up @@ -2072,7 +2072,7 @@ class Instantiator(
case VoidLiteralTE(_) => {
(CoordI[sI](MutableShareI, VoidIT()), VoidLiteralIE())
}
case FunctionCallTE(prototypeT, args) => {
case FunctionCallTE(prototypeT, args, returnType) => {
val innersCE =
args.map(argTE => {
val (argIT, argCE) =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,25 +85,14 @@ class AfterRegionsIntegrationTests extends FunSuite with Matchers {
|import array.each.*;
|func myfunc(i int) { }
|exported func main() int {
| mylist = [#][1, 3, 3, 7];
| mylist = [#](1, 3, 3, 7);
| mylist.each(myfunc);
| 42
|}
|""".stripMargin)
compile.evalForKind(Vector()) match { case VonInt(42) => }
}

test("Simple tuple with one int") {
val compile = RunCompilation.test( "exported func main() int { return (9,).0; }")

val coutputs = compile.expectCompilerOutputs()
coutputs.lookupFunction("main").header.returnType.kind shouldEqual IntT.i32
// Funny story, theres no such thing as a one element tuple! It becomes a one element array.
Collector.only(coutputs.lookupFunction("main"), { case TupleTE(_, _) => })

compile.evalForKind(Vector()) match { case VonInt(9) => }
}

test("Upcasting in a generic function") {
// This is testing two things:
// - Upcasting inside a generic function
Expand Down Expand Up @@ -321,17 +310,4 @@ class AfterRegionsIntegrationTests extends FunSuite with Matchers {
compile.evalForKind(Vector()) match { case VonInt(8) => }
}


test("Ignoring receiver") {
val compile = RunCompilation.test(
"""
|struct Marine { hp int; }
|exported func main() int { [_, y] = (Marine(6), Marine(8)); return y.hp; }
|
""".stripMargin)
val coutputs = compile.expectCompilerOutputs()
val main = coutputs.lookupFunction("main");
main.header.returnType shouldEqual CoordT(ShareT, RegionT(), IntT.i32)
compile.evalForKind(Vector()) match { case VonInt(8) => }
}
}
2 changes: 1 addition & 1 deletion Frontend/IntegrationTests/test/dev/vale/ClosureTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ class ClosureTests extends FunSuite with Matchers {
Collector.all(
coutputs.lookupFunction("main"),
{
case FunctionCallTE(p @ PrototypeT(IdT(_, _, LambdaCallFunctionNameT(_, _, _)), _), _) => p
case FunctionCallTE(p @ PrototypeT(IdT(_, _, LambdaCallFunctionNameT(_, _, _)), _), _, _) => p
}))
params.head match {
case CoordT(ShareT, _, StructTT(IdT(_, Vector(FunctionNameT(FunctionTemplateNameT(StrI("main"), _),Vector(),Vector())),LambdaCitizenNameT(_)))) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class InferTemplateTests extends FunSuite with Matchers {
}
val main = compile.expectCompilerOutputs().lookupFunction("main")
Collector.only(main, {
case FunctionCallTE(PrototypeT(IdT(_, _, FunctionNameT(FunctionTemplateNameT(StrI("moo"), _), templateArgs, _)), _), _) => {
case FunctionCallTE(PrototypeT(IdT(_, _, FunctionNameT(FunctionTemplateNameT(StrI("moo"), _), templateArgs, _)), _), _, _) => {
templateArgs match {
case Vector(CoordTemplataT(CoordT(OwnT, _, StructTT(IdT(x, Vector(), StructNameT(StructTemplateNameT(StrI("Muta")), Vector())))))) => {
vassert(x.isTest)
Expand Down
18 changes: 17 additions & 1 deletion Frontend/IntegrationTests/test/dev/vale/IntegrationTestsA.scala
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ class IntegrationTestsA extends FunSuite with Matchers {
compile.evalForKind(Vector()) match { case VonInt(3) => }
}
test("Simple program with tup") {
val compile = RunCompilation.test("import v.builtins.tup.*; exported func main() int { return 3; }", false)
val compile = RunCompilation.test("import v.builtins.tup2.*; exported func main() int { return 3; }", false)
compile.evalForKind(Vector()) match { case VonInt(3) => }
}
test("Simple program with panic") {
Expand Down Expand Up @@ -1004,4 +1004,20 @@ class IntegrationTestsA extends FunSuite with Matchers {
case VonInt(42) =>
}
}

test("Ignoring receiver") {
val compile = RunCompilation.test(
"""
|struct Marine { hp int; }
|exported func main() int { [_, y] = (Marine(6), Marine(8)); return y.hp; }
|
""".stripMargin)
val coutputs = compile.expectCompilerOutputs()
val main = coutputs.lookupFunction("main");
main.header.returnType shouldEqual CoordT(ShareT, RegionT(), IntT.i32)
compile.evalForKind(Vector()) match {
case VonInt(8) =>
}
}

}
28 changes: 14 additions & 14 deletions Frontend/IntegrationTests/test/dev/vale/OwnershipTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ class OwnershipTests extends FunSuite with Matchers {
""".stripMargin)

val main = compile.expectCompilerOutputs().lookupFunction("main")
Collector.only(main, { case FunctionCallTE(functionNameT("drop"), _) => })
Collector.all(main, { case FunctionCallTE(_, _) => }).size shouldEqual 2
Collector.only(main, { case FunctionCallTE(functionNameT("drop"), _, _) => })
Collector.all(main, { case FunctionCallTE(_, _, _) => }).size shouldEqual 2

compile.evalForKind(Vector())
}
Expand All @@ -94,8 +94,8 @@ class OwnershipTests extends FunSuite with Matchers {
""".stripMargin)

val main = compile.expectCompilerOutputs().lookupFunction("main")
Collector.only(main, { case FunctionCallTE(functionNameT("drop"), _) => })
Collector.all(main, { case FunctionCallTE(_, _) => }).size shouldEqual 2
Collector.only(main, { case FunctionCallTE(functionNameT("drop"), _, _) => })
Collector.all(main, { case FunctionCallTE(_, _, _) => }).size shouldEqual 2

compile.evalForStdout(Vector()) shouldEqual "Destroying!\n"
}
Expand All @@ -119,7 +119,7 @@ class OwnershipTests extends FunSuite with Matchers {
""".stripMargin)

val main = compile.expectCompilerOutputs().lookupFunction("main")
Collector.only(main, { case FunctionCallTE(functionNameT("drop"), _) => })
Collector.only(main, { case FunctionCallTE(functionNameT("drop"), _, _) => })

compile.evalForKindAndStdout(Vector()) match { case (VonInt(10), "Destroying!\n") => }
}
Expand All @@ -143,8 +143,8 @@ class OwnershipTests extends FunSuite with Matchers {
""".stripMargin)

val main = compile.expectCompilerOutputs().lookupFunction("main")
Collector.only(main, { case FunctionCallTE(functionNameT("drop"), _) => })
Collector.all(main, { case FunctionCallTE(_, _) => }).size shouldEqual 2
Collector.only(main, { case FunctionCallTE(functionNameT("drop"), _, _) => })
Collector.all(main, { case FunctionCallTE(_, _, _) => }).size shouldEqual 2

compile.evalForStdout(Vector()) shouldEqual "Destroying!\n"
}
Expand Down Expand Up @@ -184,18 +184,18 @@ class OwnershipTests extends FunSuite with Matchers {
}
}))
// The only function lookup should be println
Collector.only(destructor, { case FunctionCallTE(functionNameT("println"), _) => })
Collector.only(destructor, { case FunctionCallTE(functionNameT("println"), _, _) => })
// Only one call (the above println)
Collector.all(destructor, { case FunctionCallTE(_, _) => }).size shouldEqual 1
Collector.all(destructor, { case FunctionCallTE(_, _, _) => }).size shouldEqual 1

// moo should be calling the destructor
val moo = coutputs.lookupFunction("moo")
Collector.only(moo, { case FunctionCallTE(functionNameT("drop"), _) => })
Collector.only(moo, { case FunctionCallTE(_, _) => })
Collector.only(moo, { case FunctionCallTE(functionNameT("drop"), _, _) => })
Collector.only(moo, { case FunctionCallTE(_, _, _) => })

// main should not be calling the destructor
val main = coutputs.lookupFunction("main")
Collector.all(main, { case FunctionCallTE(functionNameT("drop"), _) => true }).size shouldEqual 0
Collector.all(main, { case FunctionCallTE(functionNameT("drop"), _, _) => true }).size shouldEqual 0

compile.evalForStdout(Vector()) shouldEqual "Destroying!\n"
}
Expand All @@ -220,8 +220,8 @@ class OwnershipTests extends FunSuite with Matchers {
""".stripMargin)

val main = compile.expectCompilerOutputs().lookupFunction("main")
Collector.only(main, { case FunctionCallTE(functionNameT("drop"), _) => })
Collector.all(main, { case FunctionCallTE(_, _) => }).size shouldEqual 2
Collector.only(main, { case FunctionCallTE(functionNameT("drop"), _, _) => })
Collector.all(main, { case FunctionCallTE(_, _, _) => }).size shouldEqual 2

compile.evalForKindAndStdout(Vector()) match { case (VonInt(10), "Destroying!\n") => }
}
Expand Down
3 changes: 2 additions & 1 deletion Frontend/IntegrationTests/test/dev/vale/PatternTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class PatternTests extends FunSuite with Matchers {
coutputs.functions.head.header.returnType == CoordT(ShareT, RegionT(), IntT.i32)

val monouts = compile.getMonouts()
val tupDef = monouts.lookupStruct("Tup")
val tupDef = monouts.lookupStruct("Tup2")
val tupDefMemberTypes =
tupDef.members.collect({ case StructMemberI(_, _, tyype) => tyype.reference })
tupDefMemberTypes match {
Expand Down Expand Up @@ -159,4 +159,5 @@ class PatternTests extends FunSuite with Matchers {
// coutputs.functions.head.header.returnType == CoordT(ShareT, IntT.i32)
// compile.evalForKind(Vector()) match { case VonInt(8) => }
// }

}
34 changes: 29 additions & 5 deletions Frontend/IntegrationTests/test/dev/vale/TupleTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,32 +10,56 @@ class TupleTests extends FunSuite with Matchers {
test("Returning tuple from function and dotting it") {
val compile = RunCompilation.test(
"""
|import v.builtins.tup2.*;
|import v.builtins.drop.*;
|
|func makeTup() (int, int) { return (2, 3); }
|exported func main() int {
| return makeTup().1;
|}
""".stripMargin)
""".stripMargin, false)

compile.evalForKind(Vector()) match { case VonInt(3) => }
}

test("Tuple with two things") {
val compile = RunCompilation.test( "exported func main() bool { return (9, true).1; }")
val compile = RunCompilation.test(
"""
|import v.builtins.tup2.*;
|import v.builtins.drop.*;
|
|exported func main() bool {
| return (9, true).1;
|}
|""".stripMargin, false)
compile.evalForKind(Vector()) match { case VonBool(true) => }
}


test("Tuple type") {
val compile = RunCompilation.test(
"""
|import v.builtins.tup2.*;
|import v.builtins.drop.*;
|
|func moo(a (int, int)) int { return a.1; }
|
|exported func main() int {
| return moo((3, 4));
|}
|""".stripMargin)
|""".stripMargin, false)
compile.evalForKind(Vector()) match { case VonInt(4) => }
}

// todo: indexing into it with a variable, to get a union type
test("Simple tuple with one int") {
val compile = RunCompilation.test("exported func main() int { return (9,).0; }")

val coutputs = compile.expectCompilerOutputs()
coutputs.lookupFunction("main").header.returnType.kind shouldEqual IntT.i32
// Funny story, theres no such thing as a one element tuple! It becomes a one element array.
Collector.only(coutputs.lookupFunction("main"), { case TupleTE(_, _) => })

compile.evalForKind(Vector()) match {
case VonInt(9) =>
}
}
}
Loading

0 comments on commit 08f3120

Please sign in to comment.