oakc
oakc copied to clipboard
Add a new, top-level IR?
Right now, Oak's type system is a bit weird compared to other languages. Take for example, C++ structures:
struct Date {
Date() {}
int get_day() { return day; }
int month, day, year;
};
They have explicit distinctions between members and methods, and it's simple to read. Now, see the equivalent Oak code.
// For use in other type definitions
const DATE_SIZE = 3;
type Date(DATE_SIZE) {
fn new() -> Date {
return [0, 0, 0];
}
fn get_day(self: &Date) -> num { return self->day }
// members as methods
fn month(self: &Date) -> &num { return self as # }
fn day(self: &Date) -> &num { return (self + 1) as # }
fn year(self: &Date) -> &num { return (self + 2) as # }
}
See anything significant? The Oak code accomplishes exactly the same thing, but it's utterly massive in comparison.
How about tagged unions? Here is some example rust code.
enum Value {
Int(i32),
IntPair(i32, i32),
Boolean(bool)
}
To simulate something like tagged unions in Oak, its significantly more difficult.
const INT = 0;
const INT_PAIR = 1;
const BOOLEAN = 2;
type Value(3) {
fn new_int(n: num) -> Value {
return [INT, n, 0];
}
fn new_int_pair(a: num, b: num) -> Value {
return [INT_PAIR, a, b];
}
fn new_boolean(x: bool) -> Value {
return [BOOLEAN, x, 0];
}
fn is_int(self: &Value) -> bool { return self->tag == INT }
fn is_int_pair(self: &Value) -> bool { return self->tag == INT_PAIR }
fn is_boolean(self: &Value) -> bool { return self->tag == BOOLEAN }
fn tag(self: &Value) -> &num { return self as &num }
fn int(self: &Value) -> &num { return (self + 1) as &num }
fn int_first(self: &Value) -> &num { return (self + 1) as &num }
fn int_second(self: &Value) -> &num { return (self + 2) as &num }
fn boolean(self: &Value) -> &bool { return (self + 1) as &bool }
}
Another HUGE problem in Oak is the lack of static dispatch: there's absolutely no support for template or type parameters.
These things could easily be abstracted away by a new top-level IR at compile time. The syntax of Oak would be completely changed by this.
Here is some example potential new Oak syntax and its expansion to the current top level IR code.
struct Date {
let month: num,
day: num,
year: num;
fn new(m: num, d: num, y: num) -> Self {
return [m, d, y];
}
fn tomorrow(&self) -> Self {
let result = *self;
result->month = result->month + 1;
return result;
}
}
Becomes:
const NUM_SIZE = 1;
type Date(NUM_SIZE + NUM_SIZE + NUM_SIZE) {
fn new(m: num, d: num, y: num) -> Date {
return [m, d, y];
}
fn tomorrow(self: &Date) -> Date {
let result = *self;
result->month = result->month + 1;
return result;
}
fn month(self: &Date) -> &num { return self as &num }
fn day(self: &Date) -> &num { return (self + NUM_SIZE) as &num }
fn year(self: &Date) -> &num { return (self + NUM_SIZE + NUM_SIZE) as &num }
}
Of course, there would have to be a lot of accommodations for copy and drop methods when they are added, but they could definitely still be supported with structures and enums.