Skip to content

Instantly share code, notes, and snippets.

@wbbradley
Last active January 11, 2019 20:17
Show Gist options
  • Save wbbradley/0a4baa6aef9cf5fcd344166829cc9a70 to your computer and use it in GitHub Desktop.
Save wbbradley/0a4baa6aef9cf5fcd344166829cc9a70 to your computer and use it in GitHub Desktop.
Zion Intermediate Representation Example : For Loop
tests/test_for_loop.zion:1:4: test_for_loop.main = (λ_.let __v16 = (std.iter let __range_min__v13 = 1 in let __range_next__v14 = (std.+ 1 __range_min__v13) in let __range_max__v15 = 10 in (std.Range __range_min__v13 (std.- __range_next__v14 __range_min__v13) __range_max__v15)) in (while std.True match (__v16 ()) (std.Just(x) std.print x) (std.Nothing (break!)))) :: () -> std.ExitCode
src/parser.cpp:411:1: std.+ = __builtin_add_int :: Int -> Int -> Int
src/parser.cpp:393:1: std.- = __builtin_subtract_int :: Int -> Int -> Int
tests/test_for_loop.zion:2:16: std.Range = (λ__v10.return! (λ__v11.return! (λ__v12.return! ((__v10, __v11, __v12) as! std.Range Int)))) :: Int -> Int -> Int -> std.Range Int
tests/test_for_loop.zion:2:11: std.True = ((1,) as! std.Bool) :: std.Bool
tests/test_for_loop.zion:2:11: std.iter = (λri.let index = (std.Ref (std.__get_range_min ri)) in (return! (λ_.let cur_index = (std.load_value index) in (if (std.<= cur_index (std.__get_range_max ri)) then ({__builtin_store index (std.+ cur_index (std.__get_step_size ri)); return! std.Just cur_index}) else (return! std.Nothing))))) :: std.Range Int -> () -> std.Maybe Int
lib/std.zion:347:26: std.<= = __builtin_int_lte :: Int -> Int -> std.Bool
lib/std.zion:349:24: std.Just = (λ__v1.return! ((0, __v1) as! std.Maybe Int)) :: Int -> std.Maybe Int
lib/std.zion:351:24: std.Nothing = ((1,) as! std.Maybe Int) :: std.Maybe Int
lib/std.zion:344:18: std.Ref = (λ__v0.return! ((0, __v0) as! std.Ref Int)) :: Int -> std.Ref Int
lib/std.zion:347:32: std.__get_range_max = (λobj.return! (obj as! (Int, Int, Int,))[2 of 3]) :: std.Range Int -> Int
lib/std.zion:344:25: std.__get_range_min = (λobj.return! (obj as! (Int, Int, Int,))[0 of 3]) :: std.Range Int -> Int
lib/std.zion:348:40: std.__get_step_size = (λobj.return! (obj as! (Int, Int, Int,))[1 of 3]) :: std.Range Int -> Int
lib/std.zion:346:26: std.load_value = (λa.return! match a (std.Ref(a) a)) :: std.Ref Int -> Int
data Bool {
False
True
}
fn not(x) {
if x {
return False
} else {
return True
}
}
class HasDefault a {
fn new() a
}
class Show a {
fn str(a) [Char]
}
instance Show () {
fn str(a) => "()"
}
instance Show Int {
fn str(x) {
return "0"
}
}
instance Show Ref a {
fn str(a) => str(!a)
}
data Ref a {
Ref(a)
}
instance Show Ref {
fn str(x) {
s := new [Char]
concat(s, "Ref(")
concat(s, str(x))
concat(s, ")")
return s
}
}
class LoadableValue f {
fn load_value(f a) a
}
instance LoadableValue Ref {
fn load_value(a) => match a {
Ref(a) => a
}
}
instance LoadableValue * {
load_value = __builtin_ptr_load
}
class Eq a {
fn ==(a, a) Bool
fn !=(a, a) Bool
/*default {
fn ==(a, b) {
return not (a != b)
}
fn !=(a, b) {
return not (a == b)
}
}*/
}
instance Eq *a {
== = __builtin_ptr_eq
!= = __builtin_ptr_ne
}
instance Eq Ref a {
fn ==(a, b) => !a == !b
fn !=(a, b) => !a != !b
}
instance Eq Int {
== = __builtin_int_eq
!= = __builtin_int_ne
}
instance Eq Float {
== = __builtin_float_eq
!= = __builtin_float_ne
}
instance Eq Maybe a {
fn ==(a, b) => match (a, b) {
(Nothing, Nothing) => True
(Just(a), Just(b)) => a == b
_ => False
}
fn !=(a, b) => not (a == b)
}
instance Eq [a] {
fn ==(xs, ys) {
if !xs.size != !ys.size {
return False
}
size := !xs.size
var i = 0
while !i < size {
if xs[!i] != ys[!i] {
return False
}
}
return True
}
fn !=(xs, ys) {
if !xs.size != !ys.size {
return True
}
size := !(xs.size)
var i = 0
while !i < size {
if xs[!i] != ys[!i] {
return True
}
}
return False
}
}
class Num a {
has Eq
fn from_int(Int) a
fn +(a, a) a
fn *(a, a) a
fn -(a, a) a
fn /(a, a) a
fn abs(a) a
fn negate(a) a
}
class Bounded a {
fn min_bound() a
fn max_bound() a
}
data Ordering {
EQ
LT
GT
}
class Ord a {
fn compare(a, a) Ordering
fn <(a, a) Bool
fn <=(a, a) Bool
fn >(a, a) Bool
fn >=(a, a) Bool
}
instance Ord Int {
< = __builtin_int_lt
<= = __builtin_int_lte
> = __builtin_int_gt
>= = __builtin_int_gte
fn compare(a, b) {
if a < b {
return LT
} else if b < a {
return GT
} else {
return EQ
}
}
}
instance Num Int {
from_int = id
+ = __builtin_add_int
* = __builtin_multiply_int
- = __builtin_subtract_int
/ = __builtin_divide_int
negate = __builtin_negate_int
abs = __builtin_abs_int
}
instance Bounded Int {
fn min_bound() => __builtin_min_int
fn max_bound() => __builtin_max_int
}
instance Num Float {
from_int = __builtin_int_to_float
+ = __builtin_add_float
* = __builtin_multiply_float
- = __builtin_subtract_float
/ = __builtin_divide_float
negate = __builtin_negate_float
abs = __builtin_abs_float
}
data Maybe t {
Just(t)
Nothing
}
instance Show Maybe a {
fn str(ma) {
match ma {
Just(a) {
s := new [Char]
concat(s, "Just(")
concat(s, str(a))
concat(s, ")")
return s
}
Nothing {
return "Nothing"
}
}
}
}
class Functor f {
fn fmap(fn (a) b, f a) f b
}
data ExitCode {
ExitOK
ExitError(Int)
}
data Either a b {
Left(a)
Right(b)
}
struct Vector a {
array Ref (*(Ref a))
size Ref Int
capacity Ref Int
}
instance Show [a] {
fn str(xs) {
y := new [Char]
for x in xs {
concat(y, str(x))
}
return y
}
}
class HasLength a {
fn len(a) Int
}
instance HasLength [a] {
fn len(v) => !v.size
}
fn alloc(count Int) *a {
return __builtin_calloc(sizeof(a) * count)
}
fn __getptritem__(ptr, index) {
return !__builtin_add_ptr(ptr, index)
}
fn __getitem__(vec, index) {
size := len(vec)
if index < 0 {
return Nothing
} else if index >= size {
return Nothing
} else {
return Just(!__getptritem__(!vec.array, index))
}
}
fn append(vec [a], val a) {
if !vec.array == null {
vec.array = alloc(4)
vec.size = 1
vec.capacity = 4
# array := load_value(vec.array)
# (array[0]) = Ref(val)
}
}
instance HasDefault [a] {
fn new() {
return Vector(Ref(null), Ref(0), Ref(0))
}
}
class Iterable f {
fn iter(f a) fn () Maybe a
}
instance Iterable Vector {
fn iter(vec) {
index := Ref(-1)
return fn() {
index = !index + 1
return vec[!index]
}
}
}
let unit = ()
fn id(x) => x
fn print(x) => __builtin_print(str(x))
fn panic(x) {
print(x)
__builtin_exit(1)
}
fn concat(xs [a], ys [a]) {
for y in ys {
append(xs, y)
}
}
struct Range a {
range_min a
step_size a
range_max a
}
fn range(max Int) {
return Range(0, max-1, 1)
}
instance Iterable Range {
fn iter(ri) {
index := Ref(ri.range_min)
return fn () {
cur_index := !index;
if cur_index <= ri.range_max {
index = cur_index + ri.step_size
return Just(cur_index)
} else {
return Nothing
}
}
}
}
fn main() {
for x in [1..10]{
print(x)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment