Skip to content

Commit

Permalink
Refactoring how optional params work (#505)
Browse files Browse the repository at this point in the history
Previously, functions with optional parameters would have an additional
"mask" parameter at the end which would indicate to if-statements
contained within the body of the function whether or not to reassign
parameters to their default values if they were omitted. This resulted
in a lot of bloated logic within the compiler, and also a performance
cost since each time a function with optional parameters was called,
those if-statements would run even if all values were passed.

The new approach is to compile a separate function instance for each
combination of optional parameters, which ultimately calls the base
function and passes in the default values for the missing parameters.
This allows all decisions to happen at compile-time rather than at
runtime, and it's also a LOT simpler to reason about within the compiler
itself.

The change was also made for types with optional fields, and I also
updated enum variants to be able to have optional fields as well. This
also has the added benefit of being able to remove the `Pointer.null()`
default field value for `String#_buf` (which is a relic of a previous
version of the prelude).
  • Loading branch information
kengorab authored Nov 20, 2024
1 parent 74771e2 commit cbeb86b
Show file tree
Hide file tree
Showing 5 changed files with 387 additions and 450 deletions.
90 changes: 74 additions & 16 deletions projects/compiler/example.abra
Original file line number Diff line number Diff line change
@@ -1,21 +1,79 @@
import "process" as process
// // enum Foo {
// // Bar(a: Int, b: String = "default")
// // }

func foo() {
print("hello ")
bar()
}
// // val f = Foo.Bar(a: 123)
// // println(f)

func bar() {
print("world")
baz()
}
// func foo(a: Int, b = "asdf", c = 123) {
// println(a, b, c)
// }

// foo(a: 1)
// foo(a: 1, c: 456)
// foo(a: 1, b: "456")
// foo(a: 1, b: "456", c: 456)

// type Foo {
// func bar(self, a: Int, b = "asdf", c = 123) {
// println(a, b, c)
// }

// func baz(a: Int, b = "asdf", c = 123) {
// println(a, b, c)
// }
// }

// // Foo.baz(a: 1)
// // Foo.baz(a: 1, c: 456)
// // Foo.baz(a: 1, b: "456")
// // Foo.baz(a: 1, b: "456", c: 456)

// val f = Foo()
// // f.bar(a: 1)
// // f.bar(a: 1, c: 456)
// // f.bar(a: 1, b: "456")
// // f.bar(a: 1, b: "456", c: 456)


// func callFn2(fn: (Int, String) => Unit) {
// fn(24, "foo")
// }

// func callFn3(fn: (Int, String, Int, String) => Unit) {
// fn(24, "foo", 24, "foo")
// }

// callFn1(foo)
// callFn2(foo)
// callFn3(foo)

// callFn1(f.bar)
// callFn2(f.bar)
// callFn3(f.bar)

// callFn1(Foo.baz)
// callFn2(Foo.baz)
// callFn3(Foo.baz)

func baz() {
println("!")
println(process.callstack())
enum Color {
Red
Green
Blue
RGB(r: Int = 0, g: Int = 0, b: Int = 0)
}

val arr = [1].map((i, _) => {
foo()
i + 1
})
val black = Color.RGB()
println(black)
val white = Color.RGB(r: 255, g: 255, b: 255)
println(white)
val red = Color.RGB(r: 255)
println(red)
val green = Color.RGB(g: 255)
println(green)
val pink = Color.RGB(r: 255, b: 255)
println(pink)
val cyan = Color.RGB(g: 255, b: 255)
println(cyan)
val yellow = Color.RGB(r: 255, g: 255)
println(yellow)
Loading

0 comments on commit cbeb86b

Please sign in to comment.