From fb09facdda328e1865eddc49262527429e204af4 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Mon, 19 Jan 2026 14:20:04 +0000 Subject: [PATCH] doc: update docs and sample files --- doc/mie-passes.txt | 7 + doc/mie/sample/Person.2.mie | 530 ++++++++++++++++++++++++++++++++ doc/mie/sample/Person.3.mie | 535 ++++++++++++++++++++++++++++++++ doc/mie/sample/Person.mie | 594 +++++++++++++++++++++++++++--------- doc/mie/sample/Simple.1.mie | 46 +++ doc/mie/sample/Simple.2.mie | 50 +++ doc/mie/sample/Simple.3.mie | 63 ++++ doc/mie/sample/Simple.4.mie | 62 ++++ doc/mie/sample/Simple.5.mie | 68 +++++ doc/mie/sample/Simple.mie | 46 --- doc/sample/Expressions.im | 6 +- doc/sample/ForLoop.mie | 36 +-- doc/sample/Person.2.im | 562 ++++++++++++++++++++++++++++++++++ doc/sample/Person.im | 27 +- doc/sample/Simple.im | 39 +-- doc/sample/String.im | 4 +- doc/sample/Sum.2.mie | 96 ++++++ doc/sample/Var.im | 13 +- 18 files changed, 2516 insertions(+), 268 deletions(-) create mode 100644 doc/mie-passes.txt create mode 100644 doc/mie/sample/Person.2.mie create mode 100644 doc/mie/sample/Person.3.mie create mode 100644 doc/mie/sample/Simple.1.mie create mode 100644 doc/mie/sample/Simple.2.mie create mode 100644 doc/mie/sample/Simple.3.mie create mode 100644 doc/mie/sample/Simple.4.mie create mode 100644 doc/mie/sample/Simple.5.mie delete mode 100644 doc/mie/sample/Simple.mie create mode 100644 doc/sample/Person.2.im create mode 100644 doc/sample/Sum.2.mie diff --git a/doc/mie-passes.txt b/doc/mie-passes.txt new file mode 100644 index 0000000..d89456b --- /dev/null +++ b/doc/mie-passes.txt @@ -0,0 +1,7 @@ +ivy.fold-int-constants +ivy.fold-pool-constants +ivy.expand-lambdas +ivy.convert-alloca-to-bp-slot +ivy.convert-string-builder-to-msg +scf.convert-to-cf +ivy.convert-to-cf diff --git a/doc/mie/sample/Person.2.mie b/doc/mie/sample/Person.2.mie new file mode 100644 index 0000000..3be5c29 --- /dev/null +++ b/doc/mie/sample/Person.2.mie @@ -0,0 +1,530 @@ +meta.source-filename "Person.im" + +ivy.package-scope "net.doorstuck.test" + +ivy.package-ref "std.io" + +ivy.module { + %cout = ivy.global-ref @cout -> ptr + %StringBuilder = ivy.global-ref @StringBuilder : ptr + + ivy.class @Person { + %self.name = ivy.object-var @name : #ivy.id -> ptr + %self.age = ivy.object-var @age : #ivy.id -> ptr + %self.val = ivy.object-var @val : #ivy.id -> ptr + %self.__example-property-4 = ivy.object-var @val : #ivy.id -> ptr + %self.__example-property-5 = ivy.object-var @val : #ivy.id -> ptr + + %lambda.0 = ivy.lambda.body <%env> (%i: #ivy.id) -> void { + %StringBuilder = ivy.global-ref @StringBuilder -> ptr + %0 = ivy.msg.send to %StringBuilder, new -> #ivy.id + + %1 = ivy.str.constant "Count is " + ivy.msg.send to %0, append:%1 -> void + + ivy.msg.send to %0, append:%i -> void + + %2 = ivy.msg.send to %0, to-string -> #ivy.id + + %cout = ivy.global-ref @cout -> ptr + %3 = ptr.load %cout : ptr -> #ivy.id + ivy.msg.send to %3, put:%2 -> void + + func.return : () + } + + %lambda.1 = ivy.lambda.body <%env> () -> void { + %env.q = ivy.pkg.get %env[@q] : #ivy.id -> #ivy.id + + %StringBuilder = ivy.global-ref @StringBuilder -> ptr + %0 = ivy.msg.send to %StringBuilder, new -> #ivy.id + + %1 = ivy.str.constant "Value of q is " + ivy.msg.send to %0, append:%1 -> void + + ivy.msg.send to %0, append:%env.q -> void + + %2 = ivy.msg.send to %0, to-string -> #ivy.id + + %cout = ivy.global-ref @cout -> ptr + %3 = ptr.load %cout : ptr -> #ivy.id + ivy.msg.send to %3, put:%2 -> void + } + + ivy.method init(name:%name, age:%age) -> void { + ptr.store %name, %self.name : #ivy.id, ptr + ptr.store %age, %self.age : #ivy.id, ptr + func.return : () + } + + ivy.method test(param:%data, _:%extra) -> void { + %0 = ptr.load %StringBuilder : ptr -> #ivy.id + %1 = ivy.msg.send to %0, new -> #ivy.id + + %2 = ivy.str.constant "Received " + ivy.msg.send to %1, append:%2 -> void + + ivy.msg.send to %1, append:%data -> void + + %3 = ivy.str.constant ", " + ivy.msg.send to %1, append:%3 -> void + + ivy.msg.send to %1, append:%extra -> void + + %4 = ivy.msg.send to %1, to-string -> #ivy.id + + %5 = ptr.load %cout : ptr -> #ivy.id + ivy.msg.send to %5, put:%4 -> void + func.return : () + } + + ivy.method name -> #ivy.id { + %0 = ptr.load %self.name : ptr -> #ivy.id + func.return %0 : #ivy.id + } + + ivy.method age -> #ivy.id { + %0 = ptr.load %self.age : ptr -> #ivy.id + func.return %0 : #ivy.id + } + + ivy.method age-in-months -> #ivy.id { + %0 = ptr.load %self.age : ptr -> #ivy.id + %1 = i32.constant 12 + %multmp = ivy.mul %0, %1 : (#ivy.id, i32) -> #ivy.id + func.return %multmp : #ivy.id + } + + ivy.method set-name:%name -> void { + ptr.store %name, %self.name : #ivy.id, ptr + func.return : () + } + + ivy.method set-age:%age -> void { + ptr.store %age, %self.age : #ivy.id, ptr + func.return : () + } + + ivy.method set-age:%age in-units:%units -> void { + ^switch.cond.0: + %0 = ivy.atom "years" + %cmptmp.0 = ivy.cmp eq %age, %0 : (#ivy.id, #ivy.atom) -> i1 + cf.br-cond %cmptmp.0, ^switch.body.0, ^switch.cond.1 + + ^switch.body.0: + ptr.store %age, %self.age : #ivy.id, ptr + cf.br ^switch.end.0 + + ^switch.cond.1: + %1 = ivy.atom "months" + %cmptmp.1 = ivy.cmp eq %age, %1 : (#ivy.id, #ivy.atom) -> i1 + cf.br-cond %cmptmp.1, ^switch.body.1, ^switch.cond.2 + + ^switch.body.1: + %d0 = i32.constant 12 + %divtmp.0 = ivy.div %age, %d0 : (#ivy.id, i32) -> #ivy.id + ptr.store %divtmp.0, %self.age : #ivy.id, ptr + cf.br ^switch.end.0 + + ^switch.cond.2: + %2 = ivy.atom "days" + %cmptmp.2 = ivy.cmp eq %age, %2 : (#ivy.id, #ivy.atom) -> i1 + cf.br-cond %cmptmp.2, ^switch.body.2, ^switch.default + + ^switch.body.2: + %d1 = i32.constant 365 + %divtmp.1 = ivy.div %age, %d1 : (#ivy.id, i32) -> #ivy.id + ptr.store %divtmp.1, %self.age : #ivy.id, ptr + cf.br ^switch.end.0 + + ^switch.default: + %d2 = i32.constant 0 + cf.br ^switch.end.0 + + ^switch.end: + func.return : () + } + + ivy.method get-age-in-units:%units -> #ivy.id { + ^switch.cond.0: + %0 = ivy.atom "years" + %cmptmp.0 = ivy.cmp eq %age, %0 : (#ivy.id, #ivy.atom) -> i1 + cf.br-cond %cmptmp.0, ^switch.body.0, ^switch.cond.1 + + ^switch.body.0: + %v0 = ptr.load %self.age : ptr -> #ivy.id + cf.br ^switch.end(%v0: #ivy.id) + + ^switch.cond.0: + %1 = ivy.atom "months" + %cmptmp.1 = ivy.cmp eq %age, %1 : (#ivy.id, #ivy.atom) -> i1 + cf.br-cond %cmptmp.1, ^switch.body.1, ^switch.cond.2 + + ^switch.body.0: + %v0 = ptr.load %self.age : ptr -> #ivy.id + %d0 = i32.constant 12 + %divtmp.0 = ivy.div %v0, %d0 : (#ivy.id, i32) -> #ivy.id + cf.br ^switch.end(%divtmp.0: #ivy.id) + + ^switch.cond.0: + %2 = ivy.atom "days" + %cmptmp.2 = ivy.cmp eq %age, %2 : (#ivy.id, #ivy.atom) -> i1 + cf.br-cond %cmptmp.2, ^switch.body.2, ^switch.default + + ^switch.body.0: + %v1 = ptr.load %self.age : ptr -> #ivy.id + %d1 = i32.constant 365 + %divtmp.1 = ivy.div %v1, %d1 : (#ivy.id, i32) -> #ivy.id + cf.br ^switch.end(%divtmp.1: #ivy.id) + + ^switch.default: + %d2 = i32.constant 0 + cf.br ^switch.end(%d2.1: i32) + + ^switch.end(%result: #ivy.id): + func.return %result : #ivy.id + } + + ivy.object-prop example-property + get { + %0 = ptr.load %self.val : ptr -> #ivy.id + func.return %0 : #ivy.id + } + set (%value: #ivy.id) { + ptr.store %value, %self.val : #ivy.id, ptr + func.return : () + } + + ivy.object-prop example-property-2 get { + %0 = ptr.load %self.val : ptr -> #ivy.id + func.return %0 : #ivy.id + } set (%x: #ivy.id) { + ptr.store %x, %self.val : #ivy.id, ptr + func.return : () + } + + ivy.object-prop example-property-3 get { + %0 = i32.constant 42 + func.return %0 : i32 + } + + ivy.object-prop example-property-4 get { + %0 = ptr.load %self.p-example-property-4 : ptr -> #ivy.id + func.return %0 : #ivy.id + } set (%0: #ivy.id) { + ptr.store %0, %self.p-example-property-4 : #ivy.id, ptr + func.return : () + } + + ivy.object-prop example-property-5 get { + %0 = ptr.load %self.p-example-property-5 : ptr -> #ivy.id + func.return %0 : #ivy.id + } + } + + ivy.init-text { + ; p1 = Person new(name:'John Doe', age:34). + %Person = ivy.global-ref @Person : ptr + %0 = ivy.str.constant "John Doe" + %1 = i32.constant 34 + + %2 = ivy.msg.send to %Person, new(name:%0, age:%1) -> #ivy.id + + %p1 = ptr.alloca #ivy.id -> ptr + ptr.store %2, %p1 : #ivy.id, ptr + + ; p1 set-age:100 in-unit:$months. + %3 = ptr.load %p1 : ptr -> #ivy.id + %4 = i32.constant 100 + %5 = ivy.atom "months" + ivy.msg.send to %3, set-age:%4 in-units:%5 -> void + + ; p1 test(param:'Hello', 'World'). + %6 = ptr.load %p1 : ptr -> #ivy.id + %7 = ivy.str.constant "Hello" + %8 = ivy.str.constant "World" + ivy.msg.send to %6, test(param:%7, _:%8) -> void + + ; i = 0. + %i = ptr.alloca i32 -> ptr + %9 = i32.constant 0 + ptr.store %9, %i : i32, ptr + + ; while i < 100 do + ^while.cond: + ; i < 100 + %10 = ptr.load %i : ptr -> i32 + %11 = i32.constant 100 + %cmptmp = ivy.cmp lt %10, %11 : (i32, i32) -> i1 + scf.condition(%cmptmp) + cf.br-cond %cmptmp, ^while.body, ^while.end + + ^while.body: + ; cout put:'Count is {i}'. + %12 = ivy.msg.send to %StringBuilder, new -> #ivy.id + + %13 = ivy.str.constant "Count is " + ivy.msg.send to %12, append:%13 -> void + + %14 = ptr.load %i : ptr -> i32 + ivy.msg.send to %12, append:14 -> void + + %15 = ivy.msg.send to %12, to-string -> #ivy.id + + %16 = ptr.load %cout : ptr -> #ivy.id + ivy.msg.send to %16, put:%15 -> void + + ; i += 2 + %17 = ptr.load %i : ptr -> i32 + %18 = i32.constant 2 + %addtmp = ivy.add %17, %18 : (i32, i32) -> i32 + ptr.store %addtmp, %i : i32, ptr + cf.br ^while.cond + + ^while.end: + ; 0 to:100 step:2 + %19 = i32.constant 0 + %20 = i32.constant 100 + %21 = i32.constant 2 + %22 = ivy.msg.send to %19, to:%20 step:%21 -> #ivy.id + + %for.iv.0 = ivy.msg.send to %22, value -> #ivy.id + cf.br ^for.cond(%for.iv.0: #ivy.id) + + ^for.step: + ivy.msg.send to %22, move-next -> void + %for.iv.next = ivy.msg.send to %22, value -> #ivy.id + cf.br ^for.cond(%for.iv.next: #ivy.id) + + ^for.cond(%iv: #ivy.id): + %for.valid = ivy.is-null-ref %iv : #ivy.id -> i1 + cf.br-cond %for.valid, ^for.body(%iv: #ivy.id), ^for.end + + ^for.body(%x: #ivy.id): + ; for x in 0 to:100 step:2 do + %23 = ivy.msg.send to %StringBuilder, new -> #ivy.id + + ; 'Count is {x}' + %24 = ivy.str.constant "Count is " + ivy.msg.send to %23, append:%24 -> void + + ivy.msg.send to %23, append:%x -> void + + %25 = ivy.msg.send to %23, to-string -> #ivy.id + + ; cout put:"Count is {x}" + %26 = ptr.load %cout : ptr -> #ivy.id + ivy.msg.send to %26, put:%25 -> void + + cf.br ^for.step + + ^for.end: + ; 0 to:100 step:2 do:... + %27 = i32.constant 0 + %28 = i32.constant 100 + %29 = i32.constant 2 + ; [ :i | cout put:'Count: {i}' ] + %30 = ivy.lambda.create %lambda.0 -> #ivy.id + + ; 0 to:100 step:2 do:[ :i | cout put:'Count: {i}' ]. + ivy.msg.send to %27, to:%28 step:%29 do:%30 + + ; q = 32. + %q = ptr.alloca i32 -> ptr + %31 = i32.constant 32 + ptr.store %31, %q : i32, ptr + + ; l = [ cout put:'Value of q is {q}' ]. + %l = ptr.alloca #ivy.id + %32 = ptr.load %q : ptr -> i32 + %lambda.env = ivy.pkg.create -> #ivy.id + ivy.pkg.put %lambda.env[@q] = %32 : (#ivy.id, #ivy.id) + + %33 = ivy.lambda.create <%lambda.env> %lambda.1 -> #ivy.id + + ptr.store %33, %l : #ivy.id, ptr + + ; q = 64. + %34 = i32.constant 64 + ptr.store %34, %q : i32, ptr + + ; l call. + %35 = ptr.load %l : ptr -> #ivy.id + ivy.msg.send to %35, call -> void + + %j = ptr.alloca i32 -> ptr + + %36 = i32.constant 32 + ptr.store %36, %j : i32, ptr + + %37 = ptr.load %i : ptr -> i32 + %38 = ptr.load %j : ptr -> i32 + + %cmptmp = arith.cmp lt %37, %38 : (i32, i32) -> i1 + + %39 = ivy.lambda : () -> void { + %cout = ivy.global-ref @cout -> ptr + %0 = ivy.str.constant "True!" + %1 = ptr.load %cout : ptr -> #ivy.id + ivy.msg.send to %1, put:%0 -> void + } + + %40 = ivy.lambda : () -> void { + %cout = ivy.global-ref @cout -> ptr + %0 = ivy.str.constant "False!" + %1 = ptr.load %cout : ptr -> #ivy.id + ivy.msg.send to %1, put:%0 -> void + } + + ivy.msg.send to %cmptmp, if:%39 else:%40 -> void + + %41 = ptr.load %i : ptr -> i32 + %42 = ptr.load %j : ptr -> i32 + + %cmptmp.0 = arith.cmp lt %41, %42 : (i32, i32) -> i1 + + scf.if %cmptmp.0 -> void { + %43 = ivy.str.constant "True!" + %44 = ptr.load %cout : ptr -> #ivy.id + ivy.msg.send to %44, put:%43 -> void + } + + ; pkg = {}. + %pkg = ptr.alloca #ivy.id -> ptr + + + %45 = ivy.pkg.create -> #ivy.id + ptr.store %45, %pkg : #ivy.id, ptr + + ; pkg[0] = 16. + %46 = ptr.load %pkg : ptr -> #ivy.id + %47 = i32.constant 0 + %48 = i32.constant 16 + + ivy.msg.send to %46, at:%47 put:%48 -> void + + ; tuple = (32, 'a string') + %tuple = ptr.alloca #ivy.id -> ptr + + %49 = i32.constant 32 + %50 = ivy.str.constant "a string" + + %51 = ivy.tuple.create %49, %50 : (i32, #ivy.id) -> #ivy.id + + ptr.store %51, %tuple : #ivy.id, ptr + + %52 = ptr.load %tuple : ptr -> #ivy.id + %53 = ivy.msg.send to %52, get-iterator -> #ivy.id + + ivy.for %54 in %53 -> void { + %key = ivy.tuple.get-item %54[0] : #ivy.id -> #ivy.id + %val = ivy.tuple.get-item %54[1] : #ivy.id -> #ivy.id + + ; '{key} -> {val}' + %55 = ivy.msg.send to %StringBuilder, new -> #ivy.id + + ivy.msg.send to %55, append:%key -> void + + %56 = ivy.str.constant " -> " + ivy.msg.send to %55, append:%56 -> void + + ivy.msg.send to %55, append:%val -> void + + %57 = ivy.msg.send to %23, to-string -> #ivy.id + + ; cout put:'{key} -> {val}' + %58 = ptr.load %cout : ptr -> #ivy.id + ivy.msg.send to %58, put:%57 -> void + } + + ; _ = 3 * 2. + %59 = i32.constant 3 + %60 = i32.constant 2 + %multmp = arith.mul %59, %60 : (i32, i32) -> i32 + + ; a = (32, 64). + %a = ptr.alloca #ivy.id -> ptr + + %61 = i32.constant 32 + %62 = i32.constant 64 + %63 = ivy.tuple.create %61, %62 : (i32, i32) -> #ivy.id + + ptr.store %63, %a : #ivy.id, ptr + + %v = ptr.alloca #ivy.id -> ptr + + %64 = ptr.load %a : ptr -> #ivy.id + %65 = ivy.tuple.get-item %64[1] : #ivy.id -> #ivy.id + + ptr.store %65, %v : #ivy.id, ptr + + %66 = ivy.atom "err:number-format" + + ivy.try -> void { + + } catch (%ex = %66), %data { + + } catch-all %ex, %data { + + } + + %67 = ivy.lambda : () -> void { + %v = ptr.alloca #ivy.id -> ptr + %Int = ivy.global-ref @Int -> ptr + %0 = ivy.str.constant "342" + + %1 = ivy.msg.send to %Int, parse:%0 + + ptr.store %1, %v : #ivy.id, ptr + } + + %68 = ivy.lambda %err, %data : (#ivy.id, #ivy.id) -> void { + %0 = ivy.msg.send to %StringBuilder, new -> #ivy.id + + ivy.msg.send to %0, append:%key -> void + + %1 = ivy.str.constant "Cannot parse integer string (" + ivy.msg.send to %0, append:%1 -> void + + ivy.msg.send to %0, append:%err -> void + + %2 = ivy.str.constant ")" + ivy.msg.send to %0, append:%2 -> void + + %3 = ivy.msg.send to %0, to-string -> #ivy.id + + ; cout put:'{key} -> {val}' + %4 = ptr.load %cout : ptr -> #ivy.id + ivy.msg.send to %4, put:%3 -> void + } + + %69 = ivy.lambda %err, %data : (#ivy.id, #ivy.id) -> void { + %0 = ivy.msg.send to %StringBuilder, new -> #ivy.id + + ivy.msg.send to %0, append:%key -> void + + %1 = ivy.str.constant "Error " + ivy.msg.send to %0, append:%1 -> void + + ivy.msg.send to %0, append:%err -> void + + %2 = ivy.str.constant " occurred (" + ivy.msg.send to %0, append:%2 -> void + + ivy.msg.send to %0, append:%data -> void + + %3 = ivy.str.constant ")" + + %4 = ivy.msg.send to %0, to-string -> #ivy.id + + ; cout put:'{key} -> {val}' + %5 = ptr.load %cout : ptr -> #ivy.id + ivy.msg.send to %5, put:%4 -> void + } + + %70 = ivy.atom "err:number-format" + ivy.msg.send to %67, on:%70 do:%68 -> #ivy.id + ivy.msg.send to %67, on-error:%69 -> void + ivy.msg.send to %67, call -> void + } +} diff --git a/doc/mie/sample/Person.3.mie b/doc/mie/sample/Person.3.mie new file mode 100644 index 0000000..c5096c4 --- /dev/null +++ b/doc/mie/sample/Person.3.mie @@ -0,0 +1,535 @@ +meta.source-filename "Person.im" + +ivy.package-scope "net.doorstuck.test" + +ivy.package-ref "std.io" + +ivy.module { + %cout = ivy.global-ref @cout -> ptr + %StringBuilder = ivy.global-ref @StringBuilder : ptr + + ivy.class @Person { + %self.name = ivy.object-var @name : #ivy.id -> ptr + %self.age = ivy.object-var @age : #ivy.id -> ptr + %self.val = ivy.object-var @val : #ivy.id -> ptr + %self.__example-property-4 = ivy.object-var @val : #ivy.id -> ptr + %self.__example-property-5 = ivy.object-var @val : #ivy.id -> ptr + + %lambda.0 = ivy.lambda.body <%env> (%i: #ivy.id) -> void { + %StringBuilder = ivy.global-ref @StringBuilder -> ptr + %0 = ivy.msg.send to %StringBuilder, new -> #ivy.id + + %1 = ivy.str.constant "Count is " + ivy.msg.send to %0, append:%1 -> void + + ivy.msg.send to %0, append:%i -> void + + %2 = ivy.msg.send to %0, to-string -> #ivy.id + + %cout = ivy.global-ref @cout -> ptr + %3 = ptr.load %cout : ptr -> #ivy.id + ivy.msg.send to %3, put:%2 -> void + + func.return : () + } + + %lambda.1 = ivy.lambda.body <%env> () -> void { + %env.q = ivy.pkg.get %env[@q] : #ivy.id -> #ivy.id + + %StringBuilder = ivy.global-ref @StringBuilder -> ptr + %0 = ivy.msg.send to %StringBuilder, new -> #ivy.id + + %1 = ivy.str.constant "Value of q is " + ivy.msg.send to %0, append:%1 -> void + + ivy.msg.send to %0, append:%env.q -> void + + %2 = ivy.msg.send to %0, to-string -> #ivy.id + + %cout = ivy.global-ref @cout -> ptr + %3 = ptr.load %cout : ptr -> #ivy.id + ivy.msg.send to %3, put:%2 -> void + } + + ivy.object.func init(name:%name, age:%age) -> void { + ptr.store %name, %self.name : #ivy.id, ptr + ptr.store %age, %self.age : #ivy.id, ptr + func.return : () + } + + ivy.object.func test(param:%data, _:%extra) -> void { + %0 = ptr.load %StringBuilder : ptr -> #ivy.id + %1 = ivy.msg.send to %0, new -> #ivy.id + + %2 = ivy.str.constant "Received " + ivy.msg.send to %1, append:%2 -> void + + ivy.msg.send to %1, append:%data -> void + + %3 = ivy.str.constant ", " + ivy.msg.send to %1, append:%3 -> void + + ivy.msg.send to %1, append:%extra -> void + + %4 = ivy.msg.send to %1, to-string -> #ivy.id + + %5 = ptr.load %cout : ptr -> #ivy.id + ivy.msg.send to %5, put:%4 -> void + func.return : () + } + + ivy.object.func name -> #ivy.id { + %0 = ptr.load %self.name : ptr -> #ivy.id + func.return %0 : #ivy.id + } + + ivy.object.func age -> #ivy.id { + %0 = ptr.load %self.age : ptr -> #ivy.id + func.return %0 : #ivy.id + } + + ivy.object.func age-in-months -> #ivy.id { + %0 = ptr.load %self.age : ptr -> #ivy.id + %1 = i32.constant 12 + %multmp = ivy.mul %0, %1 : (#ivy.id, i32) -> #ivy.id + func.return %multmp : #ivy.id + } + + ivy.object.func set-name:%name -> void { + ptr.store %name, %self.name : #ivy.id, ptr + func.return : () + } + + ivy.object.func set-age:%age -> void { + ptr.store %age, %self.age : #ivy.id, ptr + func.return : () + } + + ivy.object.func set-age:%age in-units:%units -> void { + ^switch.cond.0: + %0 = ivy.atom "years" + %cmptmp.0 = ivy.cmp eq %age, %0 : (#ivy.id, #ivy.atom) -> i1 + cf.br-cond %cmptmp.0, ^switch.body.0, ^switch.cond.1 + + ^switch.body.0: + ptr.store %age, %self.age : #ivy.id, ptr + cf.br ^switch.end.0 + + ^switch.cond.1: + %1 = ivy.atom "months" + %cmptmp.1 = ivy.cmp eq %age, %1 : (#ivy.id, #ivy.atom) -> i1 + cf.br-cond %cmptmp.1, ^switch.body.1, ^switch.cond.2 + + ^switch.body.1: + %d0 = i32.constant 12 + %divtmp.0 = ivy.div %age, %d0 : (#ivy.id, i32) -> #ivy.id + ptr.store %divtmp.0, %self.age : #ivy.id, ptr + cf.br ^switch.end.0 + + ^switch.cond.2: + %2 = ivy.atom "days" + %cmptmp.2 = ivy.cmp eq %age, %2 : (#ivy.id, #ivy.atom) -> i1 + cf.br-cond %cmptmp.2, ^switch.body.2, ^switch.default + + ^switch.body.2: + %d1 = i32.constant 365 + %divtmp.1 = ivy.div %age, %d1 : (#ivy.id, i32) -> #ivy.id + ptr.store %divtmp.1, %self.age : #ivy.id, ptr + cf.br ^switch.end.0 + + ^switch.default: + %d2 = i32.constant 0 + ptr.store %d2, %self.age : #ivy.id, ptr + cf.br ^switch.end.0 + + ^switch.end: + func.return : () + } + + ivy.object.func get-age-in-units:%units -> #ivy.id { + ^switch.cond.0: + %0 = ivy.atom "years" + %cmptmp.0 = ivy.cmp eq %age, %0 : (#ivy.id, #ivy.atom) -> i1 + cf.br-cond %cmptmp.0, ^switch.body.0, ^switch.cond.1 + + ^switch.body.0: + %v0 = ptr.load %self.age : ptr -> #ivy.id + cf.br ^switch.end(%v0: #ivy.id) + + ^switch.cond.1: + %1 = ivy.atom "months" + %cmptmp.1 = ivy.cmp eq %age, %1 : (#ivy.id, #ivy.atom) -> i1 + cf.br-cond %cmptmp.1, ^switch.body.1, ^switch.cond.2 + + ^switch.body.1: + %v0 = ptr.load %self.age : ptr -> #ivy.id + %d0 = i32.constant 12 + %divtmp.0 = ivy.div %v0, %d0 : (#ivy.id, i32) -> #ivy.id + cf.br ^switch.end(%divtmp.0: #ivy.id) + + ^switch.cond.2: + %2 = ivy.atom "days" + %cmptmp.2 = ivy.cmp eq %age, %2 : (#ivy.id, #ivy.atom) -> i1 + cf.br-cond %cmptmp.2, ^switch.body.2, ^switch.default + + ^switch.body.2: + %v1 = ptr.load %self.age : ptr -> #ivy.id + %d1 = i32.constant 365 + %divtmp.1 = ivy.div %v1, %d1 : (#ivy.id, i32) -> #ivy.id + cf.br ^switch.end(%divtmp.1: #ivy.id) + + ^switch.default: + %d2 = i32.constant 0 + cf.br ^switch.end(%d2.1: i32) + + ^switch.end(%result: #ivy.id): + func.return %result : #ivy.id + } + + ivy.object.prop example-property + get { + %0 = ptr.load %self.val : ptr -> #ivy.id + func.return %0 : #ivy.id + } + set (%value: #ivy.id) { + ptr.store %value, %self.val : #ivy.id, ptr + func.return : () + } + + ivy.object.prop example-property-2 get { + %0 = ptr.load %self.val : ptr -> #ivy.id + func.return %0 : #ivy.id + } set (%x: #ivy.id) { + ptr.store %x, %self.val : #ivy.id, ptr + func.return : () + } + + ivy.object.prop example-property-3 get { + %0 = i32.constant 42 + func.return %0 : i32 + } + + ivy.object.prop example-property-4 get { + %0 = ptr.load %self.p-example-property-4 : ptr -> #ivy.id + func.return %0 : #ivy.id + } set (%0: #ivy.id) { + ptr.store %0, %self.p-example-property-4 : #ivy.id, ptr + func.return : () + } + + ivy.object.prop example-property-5 get { + %0 = ptr.load %self.p-example-property-5 : ptr -> #ivy.id + func.return %0 : #ivy.id + } + } + + ivy.init-text { + ; p1 = Person new(name:'John Doe', age:34). + %Person = ivy.global-ref @Person : ptr + %0 = ivy.str.constant "John Doe" + %1 = i32.constant 34 + + %2 = ivy.msg.send to %Person, new(name:%0, age:%1) -> #ivy.id + + %p1 = ptr.alloca #ivy.id -> ptr + ptr.store %2, %p1 : #ivy.id, ptr + + ; p1 set-age:100 in-unit:$months. + %3 = ptr.load %p1 : ptr -> #ivy.id + %4 = i32.constant 100 + %5 = ivy.atom "months" + ivy.msg.send to %3, set-age:%4 in-units:%5 -> void + + ; p1 test(param:'Hello', 'World'). + %6 = ptr.load %p1 : ptr -> #ivy.id + %7 = ivy.str.constant "Hello" + %8 = ivy.str.constant "World" + ivy.msg.send to %6, test(param:%7, _:%8) -> void + + ; i = 0. + %i = ptr.alloca i32 -> ptr + %9 = i32.constant 0 + ptr.store %9, %i : i32, ptr + cf.br ^while.cond + + ; while i < 100 do + ^while.cond: + ; i < 100 + %10 = ptr.load %i : ptr -> i32 + %11 = i32.constant 100 + %cmptmp = ivy.cmp lt %10, %11 : (i32, i32) -> i1 + scf.condition(%cmptmp) + cf.br-cond %cmptmp, ^while.body, ^while.end + + ^while.body: + ; cout put:'Count is {i}'. + %12 = ivy.msg.send to %StringBuilder, new -> #ivy.id + + %13 = ivy.str.constant "Count is " + ivy.msg.send to %12, append:%13 -> void + + %14 = ptr.load %i : ptr -> i32 + ivy.msg.send to %12, append:14 -> void + + %15 = ivy.msg.send to %12, to-string -> #ivy.id + + %16 = ptr.load %cout : ptr -> #ivy.id + ivy.msg.send to %16, put:%15 -> void + + ; i += 2 + %17 = ptr.load %i : ptr -> i32 + %18 = i32.constant 2 + %addtmp = ivy.add %17, %18 : (i32, i32) -> i32 + ptr.store %addtmp, %i : i32, ptr + cf.br ^while.cond + + ^while.end: + ; 0 to:100 step:2 + %19 = i32.constant 0 + %20 = i32.constant 100 + %21 = i32.constant 2 + %22 = ivy.msg.send to %19, to:%20 step:%21 -> #ivy.id + + cf.br ^for.init(%22: #ivy.id) + + ^for.init(%it: #ivy.id): + %for.iv.0 = ivy.msg.send to %it, value -> #ivy.id + cf.br ^for.cond(%it: #ivy.id, %for.iv.0: #ivy.id) + + ^for.step(%it: #ivy.id): + ivy.msg.send to %22, move-next -> void + %for.iv.next = ivy.msg.send to %22, value -> #ivy.id + cf.br ^for.cond(%it: #ivy.id, %for.iv.next: #ivy.id) + + ^for.cond(%it: #ivy.id, %iv: #ivy.id): + %for.valid = ivy.is-null-ref %iv : #ivy.id -> i1 + cf.br-cond %for.valid, ^for.body(%it: #ivy.id, %iv: #ivy.id), ^for.end + + ^for.body(%it: #ivy.id, %x: #ivy.id): + ; for x in 0 to:100 step:2 do + %23 = ivy.msg.send to %StringBuilder, new -> #ivy.id + + ; 'Count is {x}' + %24 = ivy.str.constant "Count is " + ivy.msg.send to %23, append:%24 -> void + + ivy.msg.send to %23, append:%x -> void + + %25 = ivy.msg.send to %23, to-string -> #ivy.id + + ; cout put:"Count is {x}" + %26 = ptr.load %cout : ptr -> #ivy.id + ivy.msg.send to %26, put:%25 -> void + + cf.br ^for.step(%it: #ivy.id) + + ^for.end: + ; 0 to:100 step:2 do:... + %27 = i32.constant 0 + %28 = i32.constant 100 + %29 = i32.constant 2 + ; [ :i | cout put:'Count: {i}' ] + %30 = ivy.lambda.create %lambda.0 -> #ivy.id + + ; 0 to:100 step:2 do:[ :i | cout put:'Count: {i}' ]. + ivy.msg.send to %27, to:%28 step:%29 do:%30 + + ; q = 32. + %q = ptr.alloca i32 -> ptr + %31 = i32.constant 32 + ptr.store %31, %q : i32, ptr + + ; l = [ cout put:'Value of q is {q}' ]. + %l = ptr.alloca #ivy.id + %32 = ptr.load %q : ptr -> i32 + %lambda.env = ivy.pkg.create -> #ivy.id + ivy.pkg.put %lambda.env[@q] = %32 : (#ivy.id, #ivy.id) + + %33 = ivy.lambda.create <%lambda.env> %lambda.1 -> #ivy.id + + ptr.store %33, %l : #ivy.id, ptr + + ; q = 64. + %34 = i32.constant 64 + ptr.store %34, %q : i32, ptr + + ; l call. + %35 = ptr.load %l : ptr -> #ivy.id + ivy.msg.send to %35, call -> void + + %j = ptr.alloca i32 -> ptr + + %36 = i32.constant 32 + ptr.store %36, %j : i32, ptr + + %37 = ptr.load %i : ptr -> i32 + %38 = ptr.load %j : ptr -> i32 + + %cmptmp = arith.cmp lt %37, %38 : (i32, i32) -> i1 + + %39 = ivy.lambda : () -> void { + %cout = ivy.global-ref @cout -> ptr + %0 = ivy.str.constant "True!" + %1 = ptr.load %cout : ptr -> #ivy.id + ivy.msg.send to %1, put:%0 -> void + } + + %40 = ivy.lambda : () -> void { + %cout = ivy.global-ref @cout -> ptr + %0 = ivy.str.constant "False!" + %1 = ptr.load %cout : ptr -> #ivy.id + ivy.msg.send to %1, put:%0 -> void + } + + ivy.msg.send to %cmptmp, if:%39 else:%40 -> void + + %41 = ptr.load %i : ptr -> i32 + %42 = ptr.load %j : ptr -> i32 + + %cmptmp.0 = arith.cmp lt %41, %42 : (i32, i32) -> i1 + + scf.if %cmptmp.0 -> void { + %43 = ivy.str.constant "True!" + %44 = ptr.load %cout : ptr -> #ivy.id + ivy.msg.send to %44, put:%43 -> void + } + + ; pkg = {}. + %pkg = ptr.alloca #ivy.id -> ptr + + + %45 = ivy.pkg.create -> #ivy.id + ptr.store %45, %pkg : #ivy.id, ptr + + ; pkg[0] = 16. + %46 = ptr.load %pkg : ptr -> #ivy.id + %47 = i32.constant 0 + %48 = i32.constant 16 + + ivy.msg.send to %46, at:%47 put:%48 -> void + + ; tuple = (32, 'a string') + %tuple = ptr.alloca #ivy.id -> ptr + + %49 = i32.constant 32 + %50 = ivy.str.constant "a string" + + %51 = ivy.tuple.create %49, %50 : (i32, #ivy.id) -> #ivy.id + + ptr.store %51, %tuple : #ivy.id, ptr + + %52 = ptr.load %tuple : ptr -> #ivy.id + %53 = ivy.msg.send to %52, get-iterator -> #ivy.id + + ivy.for %54 in %53 -> void { + %key = ivy.tuple.get-item %54[0] : #ivy.id -> #ivy.id + %val = ivy.tuple.get-item %54[1] : #ivy.id -> #ivy.id + + ; '{key} -> {val}' + %55 = ivy.msg.send to %StringBuilder, new -> #ivy.id + + ivy.msg.send to %55, append:%key -> void + + %56 = ivy.str.constant " -> " + ivy.msg.send to %55, append:%56 -> void + + ivy.msg.send to %55, append:%val -> void + + %57 = ivy.msg.send to %23, to-string -> #ivy.id + + ; cout put:'{key} -> {val}' + %58 = ptr.load %cout : ptr -> #ivy.id + ivy.msg.send to %58, put:%57 -> void + } + + ; _ = 3 * 2. + %59 = i32.constant 3 + %60 = i32.constant 2 + %multmp = arith.mul %59, %60 : (i32, i32) -> i32 + + ; a = (32, 64). + %a = ptr.alloca #ivy.id -> ptr + + %61 = i32.constant 32 + %62 = i32.constant 64 + %63 = ivy.tuple.create %61, %62 : (i32, i32) -> #ivy.id + + ptr.store %63, %a : #ivy.id, ptr + + %v = ptr.alloca #ivy.id -> ptr + + %64 = ptr.load %a : ptr -> #ivy.id + %65 = ivy.tuple.get-item %64[1] : #ivy.id -> #ivy.id + + ptr.store %65, %v : #ivy.id, ptr + + %66 = ivy.atom "err:number-format" + + ivy.try -> void { + + } catch (%ex = %66), %data { + + } catch-all %ex, %data { + + } + + %67 = ivy.lambda : () -> void { + %v = ptr.alloca #ivy.id -> ptr + %Int = ivy.global-ref @Int -> ptr + %0 = ivy.str.constant "342" + + %1 = ivy.msg.send to %Int, parse:%0 + + ptr.store %1, %v : #ivy.id, ptr + } + + %68 = ivy.lambda %err, %data : (#ivy.id, #ivy.id) -> void { + %0 = ivy.msg.send to %StringBuilder, new -> #ivy.id + + ivy.msg.send to %0, append:%key -> void + + %1 = ivy.str.constant "Cannot parse integer string (" + ivy.msg.send to %0, append:%1 -> void + + ivy.msg.send to %0, append:%err -> void + + %2 = ivy.str.constant ")" + ivy.msg.send to %0, append:%2 -> void + + %3 = ivy.msg.send to %0, to-string -> #ivy.id + + ; cout put:'{key} -> {val}' + %4 = ptr.load %cout : ptr -> #ivy.id + ivy.msg.send to %4, put:%3 -> void + } + + %69 = ivy.lambda %err, %data : (#ivy.id, #ivy.id) -> void { + %0 = ivy.msg.send to %StringBuilder, new -> #ivy.id + + ivy.msg.send to %0, append:%key -> void + + %1 = ivy.str.constant "Error " + ivy.msg.send to %0, append:%1 -> void + + ivy.msg.send to %0, append:%err -> void + + %2 = ivy.str.constant " occurred (" + ivy.msg.send to %0, append:%2 -> void + + ivy.msg.send to %0, append:%data -> void + + %3 = ivy.str.constant ")" + + %4 = ivy.msg.send to %0, to-string -> #ivy.id + + ; cout put:'{key} -> {val}' + %5 = ptr.load %cout : ptr -> #ivy.id + ivy.msg.send to %5, put:%4 -> void + } + + %70 = ivy.atom "err:number-format" + ivy.msg.send to %67, on:%70 do:%68 -> #ivy.id + ivy.msg.send to %67, on-error:%69 -> void + ivy.msg.send to %67, call -> void + } +} diff --git a/doc/mie/sample/Person.mie b/doc/mie/sample/Person.mie index 43ce410..5f7a731 100644 --- a/doc/mie/sample/Person.mie +++ b/doc/mie/sample/Person.mie @@ -1,146 +1,460 @@ -record package_scope = str "net.doorstuck.test" +meta.source-filename "Person.im" -record import = { str "std.io" } +ivy.package-scope "net.doorstuck.test" -data @cout = external global id -data @StringBuffer = external global id +ivy.package-ref "std.io" -data @.str.0 = str "Received " -data @.str.1 = str ", " +ivy.module { + %cout = ivy.global-ref @cout -> ptr -data @.atom.0 = atom "years" -data @.atom.1 = atom "months" -data @.atom.2 = atom "days" + ivy.class @Person { + %self.name = ivy.object-var @name : #ivy.id -> ptr + %self.age = ivy.object-var @age : #ivy.id -> ptr + %self.val = ivy.object-var @val : #ivy.id -> ptr + %self.__example-property-4 = ivy.object-var @val : #ivy.id -> ptr + %self.__example-property-5 = ivy.object-var @val : #ivy.id -> ptr -type @_ZN3net9doorstuck4testC6PersonE = class { - id @name, - id @age, - id @val -} - -define void @_ZN3net9doorstuck4testC6PersonM4init4name3ageE(id %self, id %0) instance { -entry: - %1 = getelementptr class @_ZN3net9doorstuck4testC6PersonE, id %self, i32 #0 - store id %0, ptr %1 - - %2 = getelementptr class @_ZN33net9doorstuck4testC6PersonE, id %self, i32 #1 - store id %1, ptr %2 - - ret void -} - -define void @_ZN3net9doorstuck4testC6PersonM4test5param0E(id %0, id %1) instance { -entry: - %2 = load id, ptr @cout - - ; %4 = StringBuilder new - %3 = load id, ptr @StringBuilder - %4 = msg id %3, @_M3newE - - ; (void) tempstr append:'Received ' - %5 = load id, ptr @.str.0 - msg void, id %3, @_M06appendE [id %5] - - ; (void) tempstr append:data (param 0) - msg void, id %3, @_M06appendE [id %0] - - ; (void) tempstr append:', ' - %6 = load id, ptr @.str.1 - msg void, id %3, @_M06appendE [id %6] - - ; [void] tempstr append:extra (param 1) - msg void, id %3, @_M06appendE [id %1] - - ; %7 = tempstr toString - %7 = msg id, id %3, @_M8toStringE - - ; cout put:'Received {data}, {extra}' - msg void, id %2, @_M03put [id %7] - - ret void -} - -define id @_ZN3net9doorstuck4testC6PersonM4nameE(id %self) instance { -entry: - %0 = getelementptr class @_ZN33net9doorstuck4testC6PersonE, id %self, i32 #0 - %1 = load id, ptr %0 - ret id %1 -} - -define id @_ZN3net9doorstuck4testC6PersonM3ageE(id %self) instance { -entry: - %0 = getelementptr class @_ZN33net9doorstuck4testC6PersonE, id %self, i32 #1 - %1 = load id, ptr %0 - ret id %1 -} - -define id @_ZN3net9doorstuck4testC6PersonM11ageInMonthsE(id %self, id %0) instance { -entry: - %1 = getelementptr class @_ZN33net9doorstuck4testC6PersonE, id %self, i32 #1 - %2 = load id, ptr %1 - ret id %1 -} - -define void @_ZN3net9doorstuck4testC6PersonM07setNameE(id %self, id %1) instance { -entry: - %2 = getelementptr class @_ZN33net9doorstuck4testC6PersonE, id %self, i32 #1 - store id %1, ptr %2 - ret void -} - -define void @_ZN3net9doorstuck4testC6PersonM06setAge6inUnitE(id %self, i32 %1, id %2) instance { -entry: - %3 = load atom, ptr @.atom.0 - %4 = load atom, ptr @.atom.1 - %5 = load atom, ptr @.atom.2 - - switch id %2, label %default [ - atom %3, label %years - atom %4, label %months - atom %5, label %days - ] - -years: - %6 = getelementptr class @_ZN33net9doorstuck4testC6PersonE, id %self, i32 #1 - store i32 %2, ptr %6 - br label %end - -months: - %7 = getelementptr class @_ZN33net9doorstuck4testC6PersonE, id %self, i32 #1 - %8 = div i32 %2, #12 - store i32 %8, ptr %7 - br label %end - -days: - %9 = getelementptr class @_ZN33net9doorstuck4testC6PersonE, id %self, i32 #1 - %10 = div i32 %2, #365 - store i32 %10, ptr %9 - br label %end - -default: - %11 = getelementptr class @_ZN33net9doorstuck4testC6PersonE, id %self, i32 #1 - store i32 #0, ptr %11 - br label %end - -end: - ret void -} - -define id @_ZN3net9doorstuck4testC6PersonM012getAgeInUnitE(id %0, id %1) instance { -entry: - -} - -define id @_ZN3net9doorstuck4testC6PersonP15examplePropertyG(id %self) instance { -entry: - %0 = getelementptr class @_ZN33net9doorstuck4testC6PersonE, id %self, i32 #2 - %1 = load id, ptr %0 - ret id %1 -} - -define void @_ZN3net9doorstuck4testC6PersonP15examplePropertyS(id %self, id %0) instance { -entry: - %1 = getelementptr class @_ZN33net9doorstuck4testC6PersonE, id %self, i32 #2 - store id %0, ptr %1 - ret void + ivy.msgh.object init(name:%name, age:%age) -> void { + ptr.store %name, %self.name : #ivy.id, ptr + ptr.store %age, %self.age : #ivy.id, ptr + func.return : () + } + + ivy.msgh.object test(param:%data, _:%extra) -> void { + %0 = ivy.string-builder.begin + + ivy.string-builder.add %0 << "Received " + ivy.string-builder.add %0 << %data : #ivy.id + ivy.string-builder.add %0 << ", " + ivy.string-builder.add %0 << %extra : #ivy.id + + %1 = ivy.string-builder.end %0 -> #ivy.id + + %2 = ptr.load %cout : ptr -> #ivy.id + ivy.msg.send to %2, put:%1 -> void + func.return : () + } + + ivy.msgh.object name -> #ivy.id { + %0 = ptr.load %self.name : ptr -> #ivy.id + func.return %0 : #ivy.id + } + + ivy.msgh.object age -> #ivy.id { + %0 = ptr.load %self.age : ptr -> #ivy.id + func.return %0 : #ivy.id + } + + ivy.msgh.object age-in-months -> #ivy.id { + %0 = ptr.load %self.age : ptr -> #ivy.id + %1 = i32.constant 12 + %multmp = ivy.mul %0, %1 : (#ivy.id, i32) -> #ivy.id + func.return %multmp : #ivy.id + } + + ivy.msgh.object set-name:%name -> void { + ptr.store %name, %self.name : #ivy.id, ptr + func.return : () + } + + ivy.msgh.object set-age:%age -> void { + ptr.store %age, %self.age : #ivy.id, ptr + func.return : () + } + + ivy.msgh.object set-age:%age in-units:%units -> void { + scf.switch : () -> void + case { + %0 = ivy.atom "years" + %cmptmp.0 = ivy.cmp eq %age, %0 : (#ivy.id, #ivy.atom) -> i1 + scf.switch-condition %cmptmp.0 + } then { + ptr.store %age, %self.age : #ivy.id, ptr + scf.switch-break : () + } case { + %1 = ivy.atom "months" + %cmptmp.1 = ivy.cmp eq %age, %1 : (#ivy.id, #ivy.atom) -> i1 + scf.condition %cmptmp.1 + } then { + %d0 = i32.constant 12 + %divtmp.0 = ivy.div %age, %d0 : (#ivy.id, i32) -> #ivy.id + ptr.store %divtmp.0, %self.age : #ivy.id, ptr + scf.switch-break : () + } case { + %2 = ivy.atom "days" + %cmptmp.2 = ivy.cmp eq %age, %2 : (#ivy.id, #ivy.atom) -> i1 + scf.condition %cmptmp.2 + } then { + %d1 = i32.constant 365 + %divtmp.1 = ivy.div %age, %d1 : (#ivy.id, i32) -> #ivy.id + ptr.store %divtmp.1, %self.age : #ivy.id, ptr + scf.switch-break : () + } default { + %d2 = i32.constant 0 + scf.switch-break : () + } + + func.return : () + } + + ivy.msgh.object get-age-in-units:%units -> #ivy.id { + %result = scf.switch : () -> #ivy.id + case { + %0 = ivy.atom "years" + %cmptmp.0 = ivy.cmp eq %age, %0 : (#ivy.id, #ivy.atom) -> i1 + scf.switch-condition %cmptmp.0 + } then { + %v0 = ptr.load %self.age : ptr -> #ivy.id + scf.switch-break %v0 : #ivy.id + } case { + %1 = ivy.atom "months" + %cmptmp.1 = ivy.cmp eq %age, %1 : (#ivy.id, #ivy.atom) -> i1 + scf.condition %cmptmp.1 + } then { + %v0 = ptr.load %self.age : ptr -> #ivy.id + %d0 = i32.constant 12 + %divtmp.0 = ivy.div %v0, %d0 : (#ivy.id, i32) -> #ivy.id + scf.switch-break %divtmp.0 : #ivy.id + } case { + %2 = ivy.atom "days" + %cmptmp.2 = ivy.cmp eq %age, %2 : (#ivy.id, #ivy.atom) -> i1 + scf.condition %cmptmp.2 + } then { + %v1 = ptr.load %self.age : ptr -> #ivy.id + %d1 = i32.constant 365 + %divtmp.1 = ivy.div %v1, %d1 : (#ivy.id, i32) -> #ivy.id + scf.switch-break %divtmp.1 : #ivy.id + } default { + %d2 = i32.constant 0 + scf.switch-break %d2 : #ivy.id + } + + func.return %result : #ivy.id + } + + ivy.object-prop example-property + get { + %0 = ptr.load %self.val : ptr -> #ivy.id + func.return %0 : #ivy.id + } + set (%value: #ivy.id) { + ptr.store %value, %self.val : #ivy.id, ptr + func.return : () + } + + ivy.object-prop example-property-2 get { + %0 = ptr.load %self.val : ptr -> #ivy.id + func.return %0 : #ivy.id + } set (%x: #ivy.id) { + ptr.store %x, %self.val : #ivy.id, ptr + func.return : () + } + + ivy.object-prop example-property-3 get { + %0 = i32.constant 42 + func.return %0 : i32 + } + + ivy.object-prop example-property-4 get { + %0 = ptr.load %self.__example-property-4 : ptr -> #ivy.id + func.return %0 : #ivy.id + } set (%0: #ivy.id) { + ptr.store %0, %self.__example-property-4 : #ivy.id, ptr + func.return : () + } + + ivy.object-prop example-property-5 get { + %0 = ptr.load %self.__example-property-5 : ptr -> #ivy.id + func.return %0 : #ivy.id + } + } + + ivy.init-text { + ; p1 = Person new(name:'John Doe', age:34). + %Person = ivy.global-ref @Person : ptr + %0 = ivy.str.constant "John Doe" + %1 = i32.constant 34 + + %2 = ivy.msg.send to %Person, new(name:%0, age:%1) -> #ivy.id + + %p1 = ptr.alloca #ivy.id -> ptr + ptr.store %2, %p1 : #ivy.id, ptr + + ; p1 set-age:100 in-unit:$months. + %3 = ptr.load %p1 : ptr -> #ivy.id + %4 = i32.constant 100 + %5 = ivy.atom "months" + ivy.msg.send to %3, set-age:%4 in-units:%5 -> void + + ; p1 test(param:'Hello', 'World'). + %6 = ptr.load %p1 : ptr -> #ivy.id + %7 = ivy.str.constant "Hello" + %8 = ivy.str.constant "World" + ivy.msg.send to %6, test(param:%7, _:%8) -> void + + ; i = 0. + %i = ptr.alloca i32 -> ptr + %9 = i32.constant 0 + ptr.store %9, %i : i32, ptr + + ; while i < 100 do + scf.while -> void { + ; i < 100 + %10 = ptr.load %i : ptr -> i32 + %11 = i32.constant 100 + %cmptmp = ivy.cmp lt %10, %11 : (i32, i32) -> i1 + scf.condition(%cmptmp) + } do { + ; cout put:'Count is {i}'. + %12 = ivy.string-builder.begin + + ivy.string-builder.add %12 << "Count is " + + %14 = ptr.load %i : ptr -> i32 + ivy.string-builder.add %12 << %14 : i32 + + %15 = ivy.string-builder.end %12 -> #ivy.id + + %16 = ptr.load %cout : ptr -> #ivy.id + ivy.msg.send to %16, put:%15 -> void + + ; i += 2 + %17 = ptr.load %i : ptr -> i32 + %18 = i32.constant 2 + %addtmp = ivy.add %17, %18 : (i32, i32) -> i32 + ptr.store %addtmp, %i : i32, ptr + } + + ; 0 to:100 step:2 + %19 = i32.constant 0 + %20 = i32.constant 100 + %21 = i32.constant 2 + %22 = ivy.msg.send to %19, to:%20 step:%21 -> #ivy.id + + ; for x in 0 to:100 step:2 do + ivy.for %x in %22 -> void { + %23 = ivy.string-builder.begin + + ; 'Count is {x}' + ivy.string-builder.add %23 << "Count is " + ivy.string-builder.add %23 << %x : #ivy.id + + %25 = ivy.string-builder.end %23 -> #ivy.id + + ; cout put:"Count is {x}" + %26 = ptr.load %cout : ptr -> #ivy.id + ivy.msg.send to %26, put:%25 -> void + } + + ; 0 to:100 step:2 do:... + %27 = i32.constant 0 + %28 = i32.constant 100 + %29 = i32.constant 2 + ; [ :i | cout put:'Count: {i}' ] + %30 = ivy.lambda %i : (#ivy.id) -> void { + %0 = ivy.string-builder.begin + + ivy.string-builder.add %0 << "Count is " + ivy.string-builder.add %0 << %i : #ivy.id + + %2 = ivy.string-builder.end %0 -> #ivy.id + + %cout = ivy.global-ref @cout -> ptr + %3 = ptr.load %cout : ptr -> #ivy.id + ivy.msg.send to %3, put:%2 -> void + } + + ; 0 to:100 step:2 do:[ :i | cout put:'Count: {i}' ]. + ivy.msg.send to %27, to:%28 step:%29 do:%30 + + ; q = 32. + %q = ptr.alloca i32 -> ptr + %31 = i32.constant 32 + ptr.store %31, %q : i32, ptr + + ; l = [ cout put:'Value of q is {q}' ]. + %l = ptr.alloca #ivy.id + %32 = ptr.load %q : ptr -> i32 + %33 = ivy.lambda (%env.q = %32) : () -> void { + %0 = ivy.string-builder.begin + + ivy.string-builder.add %0 << "Value of q is " + ivy.string-builder.add %0 << %env.q : #ivy.id + + %2 = ivy.string-builder.end %0 -> #ivy.id + + %cout = ivy.global-ref @cout -> ptr + %3 = ptr.load %cout : ptr -> #ivy.id + ivy.msg.send to %3, put:%2 -> void + } + + ptr.store %33, %l : #ivy.id, ptr + + ; q = 64. + %34 = i32.constant 64 + ptr.store %34, %q : i32, ptr + + ; l call. + %35 = ptr.load %l : ptr -> #ivy.id + ivy.msg.send to %35, call -> void + + %j = ptr.alloca i32 -> ptr + + %36 = i32.constant 32 + ptr.store %36, %j : i32, ptr + + %37 = ptr.load %i : ptr -> i32 + %38 = ptr.load %j : ptr -> i32 + + %cmptmp = arith.cmp lt %37, %38 : (i32, i32) -> i1 + + %39 = ivy.lambda : () -> void { + %cout = ivy.global-ref @cout -> ptr + %0 = ivy.str.constant "True!" + %1 = ptr.load %cout : ptr -> #ivy.id + ivy.msg.send to %1, put:%0 -> void + } + + %40 = ivy.lambda : () -> void { + %cout = ivy.global-ref @cout -> ptr + %0 = ivy.str.constant "False!" + %1 = ptr.load %cout : ptr -> #ivy.id + ivy.msg.send to %1, put:%0 -> void + } + + ivy.msg.send to %cmptmp, if:%39 else:%40 -> void + + %41 = ptr.load %i : ptr -> i32 + %42 = ptr.load %j : ptr -> i32 + + %cmptmp.0 = arith.cmp lt %41, %42 : (i32, i32) -> i1 + + scf.if %cmptmp.0 -> void { + %43 = ivy.str.constant "True!" + %44 = ptr.load %cout : ptr -> #ivy.id + ivy.msg.send to %44, put:%43 -> void + } + + ; pkg = {}. + %pkg = ptr.alloca #ivy.id -> ptr + + %Package = ivy.global-ref @std.lang.Package -> ptr + + %45 = ivy.msg.send to %Package, new -> #ivy.id + ptr.store %45, %pkg : #ivy.id, ptr + + ; pkg[0] = 16. + %46 = ptr.load %pkg : ptr -> #ivy.id + %47 = i32.constant 0 + %48 = i32.constant 16 + + ivy.msg.send to %46, at:%47 put:%48 -> void + + ; tuple = (32, 'a string') + %tuple = ptr.alloca #ivy.id -> ptr + + %49 = i32.constant 32 + %50 = ivy.str.constant "a string" + + %51 = ivy.tuple.create %49, %50 : (i32, #ivy.id) -> #ivy.id + + ptr.store %51, %tuple : #ivy.id, ptr + + %52 = ptr.load %tuple : ptr -> #ivy.id + %53 = ivy.msg.send to %52, get-iterator -> #ivy.id + + ivy.for %54 in %53 -> void { + %key = ivy.tuple.get-item %54[0] : (#ivy.id, i32) -> #ivy.id + %val = ivy.tuple.get-item %54[1] : (#ivy.id, i32) -> #ivy.id + + ; '{key} -> {val}' + %55 = ivy.string-builder.begin + + ivy.string-builder.add %55 << %key : #ivy.id + ivy.string-builder.add %55 << " -> " + ivy.string-builder.add %55 << %val : #ivy.id + + %57 = ivy.string-builder.end %55 -> #ivy.id + + ; cout put:'{key} -> {val}' + %58 = ptr.load %cout : ptr -> #ivy.id + ivy.msg.send to %58, put:%57 -> void + } + + ; _ = 3 * 2. + %59 = i32.constant 3 + %60 = i32.constant 2 + %multmp = arith.mul %59, %60 : (i32, i32) -> i32 + + ; a = (32, 64). + %a = ptr.alloca #ivy.id -> ptr + + %61 = i32.constant 32 + %62 = i32.constant 64 + %63 = ivy.tuple.create %61, %62 : (i32, i32) -> #ivy.id + + ptr.store %63, %a : #ivy.id, ptr + + %v = ptr.alloca #ivy.id -> ptr + + %64 = ptr.load %a : ptr -> #ivy.id + %65 = ivy.tuple.get-item %64[1] : #ivy.id -> #ivy.id + + ptr.store %65, %v : #ivy.id, ptr + + %66 = ivy.atom "err:number-format" + + ivy.try -> void { + + } catch (%ex = %66), %data { + + } catch-all %ex, %data { + + } + + %67 = ivy.lambda : () -> void { + %v = ptr.alloca #ivy.id -> ptr + %Int = ivy.global-ref @Int -> ptr + %0 = ivy.str.constant "342" + + %1 = ivy.msg.send to %Int, parse:%0 + + ptr.store %1, %v : #ivy.id, ptr + } + + %68 = ivy.lambda %err, %data : (#ivy.id, #ivy.id) -> void { + %0 = ivy.string-builder.begin + + ivy.string-builder.add %0 << "Cannot parse integer string (" + ivy.string-builder.add %0 << %err : #ivy.id + ivy.string-builder.add %0 << ")" + + %3 = ivy.string-builder.end %0 -> #ivy.id + + ; cout put:'{key} -> {val}' + %4 = ptr.load %cout : ptr -> #ivy.id + ivy.msg.send to %4, put:%3 -> void + } + + %69 = ivy.lambda %err, %data : (#ivy.id, #ivy.id) -> void { + %0 = ivy.string-builder.create + + ivy.string-builder.add %0 << "Error " + ivy.string-builder.add %0 << %err : #ivy.id + ivy.string-builder.add %0 << " occurred (" + ivy.string-builder.add %0 << %data : #ivy.id + ivy.string-builder.add %0 << ")" + + %4 = ivy.string-builder.end %0 -> #ivy.id + + ; cout put:'{key} -> {val}' + %5 = ptr.load %cout : ptr -> #ivy.id + ivy.msg.send to %5, put:%4 -> void + } + + %70 = ivy.atom "err:number-format" + ivy.msg.send to %67, on:%70 do:%68 -> #ivy.id + ivy.msg.send to %67, on-error:%69 -> void + ivy.msg.send to %67, call -> void + } } diff --git a/doc/mie/sample/Simple.1.mie b/doc/mie/sample/Simple.1.mie new file mode 100644 index 0000000..6330f48 --- /dev/null +++ b/doc/mie/sample/Simple.1.mie @@ -0,0 +1,46 @@ +meta.source-filename "Simple.im" + +ivy.package-scope "net.doorstuck.test" + +ivy.package-ref "std.io" + +ivy.module { + ivy.init-text { + %0 = i32.constant 32 + %1 = i32.constant 64 + %multmp = arith.mul %0, %1 : (i32, i32) -> i32 + + %y = ptr.alloca i32 + ptr.store %multmp, %y : i32, ptr + + %2 = i32.constant 64 + %3 = i32.constant 4 + %divtmp = arith.div %2, %3 : (i32, i32) -> i32 + + %z = ptr.alloca i32 + ptr.store %divtmp, %z : i32, ptr + + %4 = ptr.load %y : ptr -> i32 + %5 = ptr.load %z : ptr -> i32 + %addtmp = arith.add %4, %5 : (i32, i32) -> i32 + + %x = ptr.alloca i32 + ptr.store %addtmp, %x : i32, ptr + + %cout = ivy.global-ref @cout -> ptr + + %6 = ivy.string-builder.begin + ivy.string-builder.add %6 << "Answer: " + + %7 = ptr.load %x : ptr -> i32 + ivy.string-builder.add %6 << %7 : i32 + + %8 = ivy.string-builder.end %6 -> #ivy.id + + %9 = ptr.load %cout : ptr -> #ivy.id + + ivy.msg.send to %9, put:%8 -> void + + func.return : () + } +} diff --git a/doc/mie/sample/Simple.2.mie b/doc/mie/sample/Simple.2.mie new file mode 100644 index 0000000..2d24b77 --- /dev/null +++ b/doc/mie/sample/Simple.2.mie @@ -0,0 +1,50 @@ +meta.source-filename "Simple.im" + +ivy.package-scope "net.doorstuck.test" + +ivy.package-ref "std.io" + +ivy.module { + %cout = ivy.global-ref @cout -> ptr + %StringBuilder = ivy.global-ref @std.lang.StringBuilder -> ptr + + %.str.0 = ivy.str.constant "Answer: " + + ivy.init-text { + %0 = i32.constant 32 + %1 = i32.constant 64 + %multmp = arith.mul %0, %1 : (i32, i32) -> i32 + + %y = ptr.alloca i32 + ptr.store %multmp, %y : i32, ptr + + %2 = i32.constant 64 + %3 = i32.constant 4 + %divtmp = arith.div %2, %3 : (i32, i32) -> i32 + + %z = ptr.alloca i32 + ptr.store %divtmp, %z : i32, ptr + + %4 = ptr.load %y : ptr -> i32 + %5 = ptr.load %z : ptr -> i32 + %addtmp = arith.add %4, %5 : (i32, i32) -> i32 + + %x = ptr.alloca i32 + ptr.store %addtmp, %x : i32, ptr + + %10 = ptr.load %StringBuilder : ptr -> #ivy.id + + ivy.msg.send to %10, append:%.str.0 -> void + + %7 = ptr.load %x : ptr -> i32 + ivy.msg.send to %10, append:%7 -> void + + %8 = ivy.msg.send to %10, to-string -> #ivy.id + + %9 = ptr.load %cout : ptr -> #ivy.id + + ivy.msg.send to %9, put:%8 -> void + + func.return : () + } +} diff --git a/doc/mie/sample/Simple.3.mie b/doc/mie/sample/Simple.3.mie new file mode 100644 index 0000000..d1f7369 --- /dev/null +++ b/doc/mie/sample/Simple.3.mie @@ -0,0 +1,63 @@ +meta.source-filename "Simple.im" + +ivy.package-scope "net.doorstuck.test" + +ivy.package-ref "std.io" + +ivy.module { + %cout = ivy.pool.ident @cout -> #ivy.pool-slot + %StringBuilder = ivy.pool.ident @std.lang.StringBuilder -> #ivy.pool-slot + + %.str.0 = ivy.pool.string "Answer: " -> #ivy.pool-slot + + %.sel.o-append = ivy.pool.selector append -> #ivy.pool-slot + %.sel.o-to-string = ivy.pool.selector to-string -> #ivy.pool-slot + %.sel.o-put = ivy.pool.selector put -> #ivy.pool-slot + + ivy.init-text { + %0 = i32.constant 32 + %1 = i32.constant 64 + %multmp = *ivy.MUL %0, %1 : (i32, i32) -> i32 + + *ivy.PUSH %multmp : i32 + %y = ivy.bp-slot 0 -> #ivy.bp-slot + + %2 = i32.constant 64 + %3 = i32.constant 4 + %divtmp = *ivy.DIV %2, %3 : (i32, i32) -> i32 + + *ivy.PUSH %divtmp : i32 + %z = ivy.bp-slot 1 -> #ivy.bp-slot + + %4 = *ivy.LDR-BP %y : #ivy.bp-slot -> i32 + %5 = *ivy.LDR-BP %z : #ivy.bp-slot -> i32 + %addtmp = *ivy.ADD %4, %5 : (i32, i32) -> i32 + + *ivy.PUSH %addtmp : i32 + %x = ivy.bp-slot 2 -> #ivy.bp-slot + + %10 = *ivy.LDR-POOL %StringBuilder : #ivy.pool-slot -> #ivy.id + + %20 = *ivy.LDR-POOL %.sel.o-append : #ivy.pool-slot -> #ivy.id + %21 = *ivy.LDR-POOL %.str.0 : #ivy.pool-slot -> #ivy.id + *ivy.PUSH %21 : #ivy.id + *ivy.MSG-I %10, %20, 1 : (#ivy.id, #ivy.id, i32) -> void + + %7 = *ivy.LDR-BP %x : ptr -> i32 + *ivy.PUSH %7 : i32 + %22 = *ivy.LDR-POOL %.sel.o-append : #ivy.pool-slot -> #ivy.id + *ivy.MSG-I %10, %22, 1 : (#ivy.id, #ivy.id, i32) -> void + + %23 = *ivy.LDR-POOL %.sel.o-to-string : #ivy.pool-slot -> #ivy.id + %8 = *ivy.MSG-I %10, %23, 0 : (#ivy.id, #ivy.id, i32) -> #ivy.id + + %9 = *ivy.LDR-POOL %cout : #ivy.pool-slot -> #ivy.id + %24 = *ivy.LDR-POOL %.sel.o-put : #ivy.pool-slot -> #ivy.id + + *ivy.PUSH %8 : #ivy.id + + *ivy.MSG-I %9, %24, 1 : (#ivy.id, #ivy.id, i32) -> void + + *ivy.RET-N : () + } +} diff --git a/doc/mie/sample/Simple.4.mie b/doc/mie/sample/Simple.4.mie new file mode 100644 index 0000000..b34fa49 --- /dev/null +++ b/doc/mie/sample/Simple.4.mie @@ -0,0 +1,62 @@ +meta.source-filename "Simple.im" + +ivy.package-scope "net.doorstuck.test" + +ivy.package-ref "std.io" + +ivy.module { + %cout = ivy.pool.ident @cout -> #ivy.pool-slot + %StringBuilder = ivy.pool.ident @std.lang.StringBuilder -> #ivy.pool-slot + + %.str.0 = ivy.pool.string "Answer: " -> #ivy.pool-slot + + %.sel.o-append = ivy.pool.selector append -> #ivy.pool-slot + %.sel.o-to-string = ivy.pool.selector to-string -> #ivy.pool-slot + %.sel.o-put = ivy.pool.selector put -> #ivy.pool-slot + + ivy.init-text { + %0 = i32.constant 32 + %1 = i32.constant 64 + %multmp = *ivy.MUL %0, %1 : (i32, i32) -> i32 + + *ivy.PUSH %multmp : i32 + %y = ivy.bp-slot 0 -> #ivy.bp-slot + + %2 = i32.constant 64 + %3 = i32.constant 4 + %divtmp = *ivy.DIV %2, %3 : (i32, i32) -> i32 + + *ivy.PUSH %divtmp : i32 + %z = ivy.bp-slot 1 -> #ivy.bp-slot + + %4 = *ivy.LDR %y : #ivy.bp-slot -> i32 + %5 = *ivy.LDR %z : #ivy.bp-slot -> i32 + %addtmp = *ivy.ADD %4, %5 : (i32, i32) -> i32 + + *ivy.PUSH %addtmp : i32 + %x = ivy.bp-slot 2 -> #ivy.bp-slot + + %10 = *ivy.LDR %StringBuilder : #ivy.pool-slot -> #ivy.id + + %20 = *ivy.LDR %.sel.o-append : #ivy.pool-slot -> #ivy.id + %21 = *ivy.LDR %.str.0 : #ivy.pool-slot -> #ivy.id + *ivy.PUSH %21 : #ivy.id + *ivy.MSG %10, %20, 1 : (#ivy.id, #ivy.id, i32) -> void + + %7 = *ivy.LDR %x : ptr -> i32 + *ivy.PUSH %7 : i32 + *ivy.MSG %10, %20, 1 : (#ivy.id, #ivy.id, i32) -> void + + %23 = *ivy.LDR %.sel.o-to-string : #ivy.pool-slot -> #ivy.id + %8 = *ivy.MSG %10, %23, 0 : (#ivy.id, #ivy.id, i32) -> #ivy.id + + %9 = *ivy.LDR %cout : #ivy.pool-slot -> #ivy.id + %24 = *ivy.LDR %.sel.o-put : #ivy.pool-slot -> #ivy.id + + *ivy.PUSH %8 : #ivy.id + + *ivy.MSG %9, %24, 1 : (#ivy.id, #ivy.id, i32) -> void + + *ivy.RET-N : () + } +} diff --git a/doc/mie/sample/Simple.5.mie b/doc/mie/sample/Simple.5.mie new file mode 100644 index 0000000..89b45a8 --- /dev/null +++ b/doc/mie/sample/Simple.5.mie @@ -0,0 +1,68 @@ +meta.source-filename "Simple.im" + +ivy.package-scope "net.doorstuck.test" + +ivy.package-ref "std.io" + +ivy.module { + %cout = ivy.pool.ident @cout -> #ivy.pool-slot + %StringBuilder = ivy.pool.ident @std.lang.StringBuilder -> #ivy.pool-slot + + %.str.0 = ivy.pool.string "Answer: " -> #ivy.pool-slot + + %.sel.o-append = ivy.pool.selector append -> #ivy.pool-slot + %.sel.o-to-string = ivy.pool.selector to-string -> #ivy.pool-slot + %.sel.o-put = ivy.pool.selector put -> #ivy.pool-slot + + %.i.0 = i32.constant 0 + %.i.1 = i32.constant 1 + %.i.4 = i32.constant 4 + %.i.32 = i32.constant 32 + %.i.64 = i32.constant 64 + + ivy.init-text { + $X0 = *ivy.LDR %.i.32 -> i32 + $X1 = *ivy.LDR %.i.64 -> i32 + $X2 = *ivy.MUL $X0, $X1 : (i32, i32) -> i32 + + *ivy.PUSH $X2 : i32 + %.bp.0 = ivy.bp-slot 0 -> #ivy.bp-slot + + $X4 = *ivy.LDR %.i.64 -> i32 + $X5 = *ivy.LDR %.i.4 -> i32 + $X6 = *ivy.DIV $X4, $X5 : (i32, i32) -> i32 + + *ivy.PUSH $X6 : i32 + %.bp.1 = ivy.bp-slot 1 -> #ivy.bp-slot + + $X8 = *ivy.LDR %.bp.0 : #ivy.bp-slot -> i32 + $X9 = *ivy.LDR %.bp.1 : #ivy.bp-slot -> i32 + $X10 = *ivy.ADD $X8, $X9 : (i32, i32) -> i32 + + *ivy.PUSH $X10 : i32 + %.bp.2 = ivy.bp-slot 2 -> #ivy.bp-slot + + %10 = *ivy.LDR %StringBuilder : #ivy.pool-slot -> #ivy.id + + %20 = *ivy.LDR %.sel.o-append : #ivy.pool-slot -> #ivy.id + %21 = *ivy.LDR %.str.0 : #ivy.pool-slot -> #ivy.id + *ivy.PUSH %21 : #ivy.id + *ivy.MSG %10, %20, %.i.1 : (#ivy.id, #ivy.id, i32) -> void + + %7 = *ivy.LDR %.bp.2 : ptr -> i32 + *ivy.PUSH %7 : i32 + *ivy.MSG %10, %20, %.i.1 : (#ivy.id, #ivy.id, i32) -> void + + %23 = *ivy.LDR %.sel.o-to-string : #ivy.pool-slot -> #ivy.id + %8 = *ivy.MSG %10, %23, %.i.0 : (#ivy.id, #ivy.id, i32) -> #ivy.id + + %9 = *ivy.LDR %cout : #ivy.pool-slot -> #ivy.id + %24 = *ivy.LDR %.sel.o-put : #ivy.pool-slot -> #ivy.id + + *ivy.PUSH %8 : #ivy.id + + *ivy.MSG %9, %24, %.i.1 : (#ivy.id, #ivy.id, i32) -> void + + *ivy.RET-N : () + } +} diff --git a/doc/mie/sample/Simple.mie b/doc/mie/sample/Simple.mie deleted file mode 100644 index a4249f8..0000000 --- a/doc/mie/sample/Simple.mie +++ /dev/null @@ -1,46 +0,0 @@ -data @cout = external global id - -data @.str.0 = str "less" -data @.str.1 = str "more" -data @.str.2 = str "equal" - -define void @init(id %self, id %0) static { -entry: - %x = alloca id - store i32 #2, ptr %x - - %y = alloca id - store i32 #3, ptr %y - - %1 = load i32, ptr %x - %2 = load i32, ptr %y - %3 = cmp lt i32 %1, %2 - br i1 %3, label %if.true, label %if.false - -if.true: - %4 = load id, ptr @cout - %5 = load str, ptr @.str.0 - msg void, id %4, @_M03putE [str %5] - br label %if.end - -if.false: - %6 = load i32, ptr %x - %7 = load i32, ptr %y - %8 = cmp gt i32 %6, %7 - br i1 %8, label %if.true.0, label %if.false.0 - -if.true.0: - %9 = load id, ptr @cout - %10 = load str, ptr @.str.1 - msg void, id %9, @_M03putE [str %10] - br label %if.end - -if.false.0: - %11 = load id, ptr @cout - %12 = load str, ptr @.str.2 - msg void, id %11, @_M03putE [str %12] - br label %if.end - -if.end: - ret void -} diff --git a/doc/sample/Expressions.im b/doc/sample/Expressions.im index 419e73d..06a531f 100644 --- a/doc/sample/Expressions.im +++ b/doc/sample/Expressions.im @@ -1,4 +1,4 @@ -y = 1 + 2 * 3 / 4 * 5 - 6 + 7 multiply-by:2. +y = -1 + 2 * 3 / 4 * 5 - 6 + 7 multiply-by:2. z = w = 2 + 3 multiply-by:2. x = (((1 + 2 * 3) multiply-by:3) add: 5) + 2. x = ((1 + 2 * 3) multiply-by:3). @@ -13,7 +13,7 @@ m = xz multiply(by:3 add:2) squared. m = xz multiply(by:3 add:2); squared. -x = OrderedCollection new +x = Ordered-Collection new add: 2; add: 4; add: 6; @@ -21,7 +21,7 @@ x = OrderedCollection new age = Person new(name:"John Doe", age:34) set-age:144 in-unit:"months"; - ageInMonths. + age-in-months. x = 5. q = 10 if x > 2 else 20. diff --git a/doc/sample/ForLoop.mie b/doc/sample/ForLoop.mie index c41feda..3280706 100644 --- a/doc/sample/ForLoop.mie +++ b/doc/sample/ForLoop.mie @@ -1,31 +1,15 @@ -data @cout = external global id +ivy.module @test { + %cout = ivy.global-ref @cout -data @.str.0 = str "hello" + ivy.init-text { + %str = ivy.str.constant "hello" + %.str.0 = ivy.str.constant "done" -define void @init() static { -entry: - %0 = load str, ptr @.str.0 - %str = alloca id - store str %0, ptr %str + ivy.for-each %c in %str { + ivy.msg to %cout, -put:%c + } - %1 = load id, ptr %str - %for.it = msg id, id %1, @_M8iteratorE - br label %for.cond -for.cond: - %for.value = msg id, id %for.it, @_M5valueE - %for.finished = cmp eq id %for.value, null - br i1 %for.finished, label %for.end, label %for.body -for.body: - %c = alloca id - store id %for.value, ptr %c + ivy.msg to %cout, -put:%.str.0 - %2 = load id, ptr @cout - %3 = load id, ptr %c - msg void, id %2, @_M03putE [ id %3 ] - br label %for.inc -for.inc: - msg void, id %for.it, @_M8moveNextE - br label %for.cond -for.end: - ret void + } } diff --git a/doc/sample/Person.2.im b/doc/sample/Person.2.im new file mode 100644 index 0000000..ee910b0 --- /dev/null +++ b/doc/sample/Person.2.im @@ -0,0 +1,562 @@ +/* example.im - An example Ivy Implementation source file */ + +package net.doorstuck.test + +use std.io + +-- Anything after a double hypen is ignored by the compiler +/* + Multi + Line + Comment +*/ + +/** + classes also double up as protocols. + + any class can "pretend" to be another class by responding to the same + messages that the base class understands. + + for example, by implementing all the messages that the Package class + understands, your class is said to implement the Package protocol, + allowing package-specific syntax (i.e. indexing and dot syntax) + to be used with your class. + + there are two standard messages that complement this behaviour: + -is: takes a Class parameter, and returns true if the recipient + is an instance of the given Class. + -implements: takes a Class parameter, and returns true if the recipient + understands all of the messages that the parameter class + understands. + **/ +class Person [ + /** + A class is made up of the following components: + - a set of zero of more member variables + these can only be accessed by methods (not by functions) using the + self variable and the -> operator. member variables do not need + to be declared before they are used. assigning to a member variable + for the first time automatically "creates" it, and trying to access + a member variable that hasn't been assigned to will return null. + - a set of zero or more methods. + methods are procedure/sub-routines (a list of expressions evaluated + in order) executed in response to a particular message received by an + object. every method declares what sort of message it responds to. + - a set of zero or more functions. + functions are exactly like methods, except that they are executed in + response to messages sent to the class itself, rather than to an + instance of the class. + - a set of zero or more properties. + a property is similar to a member variable, with the following key + differences: + 1) they are accessed using the . (dot) operator rather than the -> + (arrow) operator. + 2) they can be accessed from outside the class. + 3) they can (but don't have to) invoke blocks of code in response to + attempts to read from or assign to them. + 4) they can be made read-write, read-only, or write-only. + **/ + + /** + every method and function begins with a kebab, or message signature. + So called due to the preceding hyphen (for methods) or plus + (for functions) and the kebab-case convention used for message and + parameter names. + + methods and functions are called in response to messages, and the kebab + defines exactly what message the method/function should be called for. + + a message can have: + 1) a name and zero or more parameters; or + 2) no name and one or more parameters. + + if a message has a name AND parameters, the parameters are listed + within parentheses and separated by commas. + + if a message has parameters but no name, the parameters are listed + with no surrounding symbols and are separated only by whitespace. + + every parameter has a label and an identifier. the label determines what + name needs to be specified before the parameter value when sending a + message, and forms part of the API. in contrast, the identifier is + simply the variable name that is used to access the parameter value + within the method/function, and is only used internally. + + a parameter MUST have an identifier, but a label can be omitted by + specifying an _ (underscore) as the label. + + when a method/function body has more than one expression, the + expressions must be surrounded by [] (square bracket block delimiters). + **/ + -init(name:name, age:age) [ + self->name = name. + self->age = age + ] + + /* if a method/function only has a single expression body, a | (pipe) + can be used between the kebab and body, and the body will automatically + end after one expression. */ + -test(param:data, _:extra) | cout put:'Received {data}, {extra}'. + + -name | ^self->name. + + -age | ^self->age. + + -age-in-months | ^self->age * 12. + + -set-name:name | self->name = name. + + -set-age:age | self->age = age. + + -set-age:age in-unit:units [ + match units [ + $years => self->age = age, + $months => self->age = age / 12, + $days => self->age = age / 365, + _ => self->age = 0 + ] + ] + + -get-age-in-units:units [ + ^match units [ + $years => self->age, + $months => self->age / 12, + $days => self->age / 365, + _ => 0 + ] + ] + + +create-with-name:name [ + ^Person new(name:name, age:32) + ] + + /* Properties are defined by a bare identifier (with no prefixes, so not + a kebab) followed by a pipe. + They accomplish two things: + 1) they make it easy to synthesize the -get: and -put:at: messages + that the package dot syntax requires. + 2) they allow you to implement getters and setters that are used + when someone attempts to access your object's data. + + The contents of a property looks a bit like a package, but it has a few + special rules: + 1) every value must have an associated key; and + 2) the only keys that can be used are `get` and `set` (this is the only + instance where reserved keywords can be used as keys in a package). + + In this case, the getter has been set to a variable. To facilitate this + functionality, the compiler converts this to a lambda of the form + [ ^self->val ] + that will be evaluated when the getter is invoked + + Similarly, the compiler synthesizes a lambda for the setter as well. + Here, the expression + self->val = value + is converted to the lambda + [ :x | self->val = x ] + */ + example-property-a | get => self->val, set => self->val = value. + + /* Without the lambda synthesis, the property would look like this: + Note that this is the only time it is legal to access private fields + via `self` from a lambda. */ + example-property-b | + get => [ ^self->val ], + set => [ :x | self->val = x ]. + + /* The `get` element of a property doesn't have to be a lambda, it can + be any value. When the property is accessed, the value provided will + be returned. + + If either the `set` or `get` elements are not provided, the property + becomes read-only or write-only respectively */ + example-property-c | get => 42. + + /* A property can also be configured to act just like a regular variable, + by setting the getter and setters to default implementations. + + The default getter will return the value of a private member variable + named by prepending "p-" to the property name (p-example-property-d in + this case). + + Similarly, the default setter will set the value of a private member + variable named by prepending "p-" to the property name + (p-example-property-d in this case) to the value provided to the setter. */ + example-property-d (get, set) + + /* Just like in the earlier examples, either `get` or `set` can be omitted + to create a write-only or read-only property respectively */ + example-property-e (get) +] + +p1 = Person new(name:'John Doe', age:34). +p1 set-age:100 in-unit:$months. + +p1 test(param:'Hello', 'World'). + +/******************************************************************************/ + +i = 0. +while i < 100 [ + cout put:'Count is {i}'. + i += 2 +] + +for x in 0 to:100 step:2 [ + cout put:'Count is {x}' +] + +/** + a lambda's parameters are *always* unlabeled, and the underscore (_) before + the label colon (:) is unnecessary. + **/ +0 to:100 step:2 do:[ :i | cout put:'Count: {i}' ]. + +/******************************************************************************/ + +/** + lambdas can capture state from the context in which they are created. + + a lambda can reference any local variable that is accessible at the point + it is created. if a variable from such a context is referenced, its value + is captured at the point the lambda is constructed. the value of the + variable is copied into the lambda. + + this means that, if a lambda references a variable in the outer context, + and the value of that variable changes between the lambda being created + and the lambda being executed, that change will not be reflected within + the lambda. + + because the value of captured variables is copied into the lambda, it is + safe for a method to return a lambda that references variables in its + local context. + **/ +q = 32. +l = [ cout put:'Value of q is {q}' ]. /* value of `q` is captured here */ +q = 64. +_ = l call. /* prints 'Value of q is 32' */ + +/******************************************************************************/ + +j = 32. + +/** + expressions are terminated with a newline. + an expression can be written across multiple lines by using + the _ (underscore) line continuation character. + **/ + +/** + keyword messages have a lower precedence than all non-assignment + binary operators, so (i < j) will be evaluated first, and + if:else: will be sent to the result. + **/ + +i < j + if:[ cout put:'True!' ] + else:[ cout put:'False!' ]. + +if i < j [ + cout put:'True!' +] + +/******************************************************************************/ + +pkg = {}. + +/** + Packages can be indexed via integer or string. If a package is index with a + variable, the value of the variable is used as the index. + **/ + +pkg[0] = 16. + +/* All of these accesses are equivalent */ +pkg['x'] = 32. +pkg.x = 32. +pkg at:'x' put:32. + +index = 'x'. +pkg[index] = 32. +pkg at:index put:32. + +/** + this syntax, and the pkg.* instructions that it translates to, is + implemented behind-the-scenes by sending messages to the package. + + if your custom object implements this protocol, package syntax can be used + on it too. + **/ + +/** + these are the same packages used to store Classes and global variables. + for example, the std package is a regular package object, and you can use + package syntax on it or even send it messages. + **/ + +/******************************************************************************/ + +/* integer constants can be written in all sorts of interesting formats */ +i = 100. +i = 0x100. +i = 0200. +i = 0b1010101. +i = 1_000_000_000. +i = 100.25. + +/* tuples can be used to create a set of values */ + +tuple = (32, 'a string'). + +/** + they are similar to packages, except they only support consecutive integer + indices, and you cannot specify the indices when creating a tuple. + + the main purpose of tuples is to allow unwrapping of iterator variables in + for loops. + **/ + +for (key, val) in pkg [ + cout put:'{key} -> {val}' +] + +/** + any object can be the target of a for-loop, as long as it meets one of the + following criteria: + a) is an Iterator object; or + b) implements the Iterator protocol; or + c) understands the -get-iterator message, and returns an object that itself + conforms to a) or b) + **/ + +/******************************************************************************/ + +/** + underscore (_) is used as a placeholder during assignment. + it can only appear on the left of an assignment, and anything + assigned to it is discarded. +*/ +_ = 3 * 2. + +/* it is mostly used with pattern-matching and destructuring. */ + +a = (32, 64). +(_, v) = a. + +/* v is now equal to 64 */ + + +/******************************************************************************/ + +try [ + v = Int parse:'342' +] catch ($err:number-format, err) [ + cout put:'Cannot parse integer string ({err})' +] catch (_, err) [ + cout put:'Unknown error occurred ({err})' +] + +/* equivalent 'pure' syntax */ + +[ v = Int parse:'342' ] + on:$err:number-format do:[ :err :data | + cout put:'Cannot parse integer string ({err})' + ]; + on-error:[ :err :data | + cout put:'Error {err} occurred ({data})' + ]; + call. + +v = 5 + squared + squared + squared. + +/******************************************************************************/ + +x = 32. +/* a whole bunch of ways of doing conditionals using lambdas and messages */ +[ cout put:'Hello, world!' ] if:x > 10. +[ cout put:'Hello, world!' ] unless:x <= 10. + +/* and the equivalent 'fancy' syntax */ + +cout put:'Hello, world!' if x > 10. +-- cout put:'Hello, world!' unless x <= 10. + +/** + NOTE that keywords (if, try, and so on) can still be used as message + parameter names. however, they cannot be used as message names. + **/ + +/******************************************************************************/ + +/** + Order of execution (precedence) for expression elements (listed from highest + to lowest precedence). elements that appear on the same list item have equal + precedence. in these cases, their associativity determines the order of + execution. + + - binary operators + - package-access (.) + - self-access (->) + - unary operators + - boolean NOT (not) + - bitwise NOT (~) + - binary operators + - Type check operator (is, is not) + - Protocol check operator (understands) + - unary messages, complex messages + - binary operators + - multiplication (*) + - division (/) + - modulo (%) + - addition (+) + - subtraction (-) + - bitwise shift (<<, >>) + - comparison (<, >, <=, >=) + - (in)equality (==, !=) + - bitwise AND (&) + - bitwise XOR (^) + - bitwise OR (|) + - boolean AND (and) + - boolean OR (or) + - cascade (;) + - inline if-else + - keyword messages + - binary operators + - assignment by product, quotient, and remainder (*=, /=, %=) + - assignment by sum and difference (+=, -=) + - assignment by bitwise shift (<<=, >>=) + - assignment by bitwise AND, XOR, and OR (&=, ^=, |=) + - assignment (=) + **/ + +p1 + set-age:2 squared squared + 4 squared multiply(by:2, add:4 + 1 * 3) + in:'mon' + 'ths'. +(p1 + set-age:(((2 squared) squared) + ((4 squared) multiply(by:2, add:(4 + (1 * 3))))) + in:('mon' + 'ths')). + +/******************************************************************************/ + +/* how about package comprehension? */ + +/** + these two lines both construct a package containing all even numbers between + 0 and 100 incremented by 1 + + the first one uses fancy list/package comprehension syntax. + the second one uses pure message/lambda syntax. + **/ +data = { x + 1 for x in 0 to:100 if (x % 2) == 0 }. +data = (0 to: 100) select:[ :x | ^(x % 2) == 0 ] collect:[ :x | ^x + 1 ]. + +/** + for a package comprehension that follows this template: + EXPRESSION for VARIABLE in COLLECTION if CONDITION + the equivalent -select:collect: message would look something like this: + COLLECTION select:[ VARIABLE | CONDITION ] collect:[ VARIABLE | EXPRESSION ] + + -select:collect: is used to create a new package by filtering and + transforming an existing package. + + To apply a filter without a subsequent transform, you can use -select: + To apply a transformation with a filter beforehand, you can use -map: + **/ + +/******************************************************************************/ + +/** + packages also support a -map: message for constructing a new package by + manipulating an existing one. + **/ + +/** + this example creates a package of all ints between 1 and 5 using a regular + collection literal, and then uses -map: to create a second package by + doubling each of the numbers in the fist package. + **/ +pkg1 = { 1, 2, 3, 4, 5 }. +pkg2 = { x * 2 for x in pkg1 }. +pkg2 = pkg1 map:[ :x | ^x * 2 ]. + +/******************************************************************************/ + +/** + semicolon (;) is the cascade operator. it returns the recipient of the + previously sent message. it can be used to send multiple messages to a + single recipient. + **/ + +age = Person new(name:'John Doe', age:34); + set-age:144 in-unit:$months; + ageInMonths. + +-- age now has the value 144 +-- the same behaviour can be achieved by using do[...] + +age = do [ + x = Person new(name:'John Doe', age:34). + x set-age:144 in-unit:$months. + x ageInMonths +]. + +/** + this allows messages to be easily chained, without relying on the message + handler returning `self`. + **/ + +/** + NOTE that cascade is a binary operator, and cannot be used without a + right-hand operand. otherwise, simply adding a semicolon to the end of an + expression would change the behaviour (and result) of the expression. + + however, because cascade is a binary operator, it also supports implicit + line continuations. + + for situations where you want to return the recipient after a chain of + cascaded messages, you can use the -yourself message, which is understood by + all objects by default and always returns the object itself-> + **/ + +p1 = Person new(name:'John Doe', age:34); + set-age:100 in-unit:$months; + yourself. + +/* p1 now contains the Person object */ +/* again, with do[...] */ + +p1 = do [ + x = Person new(name:'John Doe', age:34). + x set-age:100 in-unit:$months. + x +]. + + +v = "Hello". +if v is String [ + cout put:"v is a string!" +] + +/******************************************************************************/ + +/** + Blocks are a bit like lambdas, except they are part of the context of the + code that uses them. They are essentially a way of evaluating multiple + statements in a place where a single statement is usually expected. + **/ + +/* Blocks are delimited by do[...], and the return operator can be used within + them. When it is, the value that is 'returned' will become the value that + the block as a whole evaluates to. also, the result of the last expression + evaluated in a block will be taken as its overall value. */ +val = do [ + x = 3. + y = 2. + x * y +]. + +/* after this statement is executed, `val` will be equal to 6. */ + diff --git a/doc/sample/Person.im b/doc/sample/Person.im index 18bbf65..60dcd77 100644 --- a/doc/sample/Person.im +++ b/doc/sample/Person.im @@ -48,7 +48,6 @@ class Person compatibility with lambdas. **/ - init(name:name age:age) - var x. self::name = name. self::age = age! @@ -80,7 +79,7 @@ class Person _ => 0 end! - /* Properties are defined using the $ symbol. + /* Properties are defined using the -> symbol. They accomplish two things: 1) they make it easy to synthesize the -get: and -put:at: messages that the package dot syntax requires. @@ -109,7 +108,7 @@ class Person /* Without the lambda synthesis, the property would look like this: Note that this is the only time it is legal to access private fields via `self` from a lambda. */ - -> example-property | + -> example-property-2 | get => [ ^self::val ], set => [ :x | self::val = x ]. @@ -119,23 +118,23 @@ class Person If either the `set` or `get` elements are not provided, the property becomes read-only or write-only respectively */ - -> example-property-2 | get => 42. + -> example-property-3 | get => 42. /* A property can also be configured to act just like a regular variable, by setting the getter and setters to default implementations. The default getter will return the value of a private member variable named by prepending two underscores to the property name - (__exampleProperty3 in this case). + (__example-property-4 in this case). Similarly, the default setter will set the value of a private member variable named by prepending two underscores to the property name - (__exampleProperty3 in this case) to the value provided to the setter. */ - -> example-property-3 (get, set) + (__example-property-4 in this case) to the value provided to the setter. */ + -> example-property-4 (get, set) /* Just like in the earlier examples, either `get` or `set` can be omitted to create a write-only or read-only property respectively */ - -> example-property-4 (get) + -> example-property-5 (get) end p1 = Person new(name:'John Doe', age:34). @@ -151,8 +150,8 @@ while i < 100 do i += 2 end -for i in 0 to:100 step:2 do - cout put:'Count is {i}' +for x in 0 to:100 step:2 do + cout put:'Count is {x}' end /** @@ -223,11 +222,11 @@ pkg[0] = 16. /* All of these accesses are equivalent */ pkg['x'] = 32. pkg->x = 32. -pkg put:32 at:'x'. +pkg at:'x' put:32. index = 'x'. pkg[index] = 32. -pkg put:32 at:index. +pkg at:index put:32. /** this syntax, and the pkg.* instructions that it translates to, is @@ -274,7 +273,7 @@ end following criteria: a) is an Iterator object; or b) implements the Iterator protocol; or - c) understands the -iterator message, and returns an object that itself + c) understands the -get-iterator message, and returns an object that itself conforms to a) or b) **/ @@ -311,7 +310,7 @@ end on:$err:number-format do:[ :err :data | cout put:'Cannot parse integer string ({err})' ]; - onError:[ :err :data | + on-error:[ :err :data | cout put:'Error {err} occurred ({data})' ]; call. diff --git a/doc/sample/Simple.im b/doc/sample/Simple.im index bdb432c..679a0a5 100644 --- a/doc/sample/Simple.im +++ b/doc/sample/Simple.im @@ -1,36 +1,9 @@ -y = -1 + 2 * 3 / 4 * 5 - 6 + 7 multiply-by:2. -z = w = 2 + 3 multiply-by:2. -x = (((1 + 2 * 3) multiply-by:3) add: 5) + 2. -x = ((1 + 2 * 3) multiply-by:3). -p = 5 multiply(by:3, add:(2 + 1)). -q = 10 squared squared. +package net.doorstuck.test -p1 - set-age:2 squared squared + 4 squared multiply(by:2, add:4 + 1 * 3) - in:"mon" + "ths". +use std.io -m = xz multiply(by:3 add:2) squared. +y = 32 * 64. +z = 64 / 4. +x = y + z. -m = xz multiply(by:3 add:2); squared. - -x = Ordered-Collection new - add: 2; - add: 4; - add: 6; - yourself. - -age = Person new(name:"John Doe", age:34) - set-age:144 in-unit:"months"; - age-in-months. - -x = 5. -q = 10 if x > 2 else 20. -q = if x > 2 then 10 else 20 end. - -cout put:5 multiply(by:5, add:2) if x > 2. - -if x > 2 then - cout put:"Greater" -else - cout put:"Less" -end +cout put:'Answer: {x}' diff --git a/doc/sample/String.im b/doc/sample/String.im index 81bbe1e..b78bc60 100644 --- a/doc/sample/String.im +++ b/doc/sample/String.im @@ -1,6 +1,6 @@ package net.doorstuck.test -s1 = 'hello world' +s1 = 'hello world'. -s2 = s1 map:[ :c | ^c uppercase ] +s2 = s1 map:[ :c | ^c uppercase ]. s3 = s1 map:[ :c | ^((c ordinal) + 1) to-char ] diff --git a/doc/sample/Sum.2.mie b/doc/sample/Sum.2.mie new file mode 100644 index 0000000..72afca6 --- /dev/null +++ b/doc/sample/Sum.2.mie @@ -0,0 +1,96 @@ +meta.source-filename "Sum.im" + +ivy.package-scope "net.doorstuck.test" + +ivy.module { + ivy.init-text { + %0 = ivy.str.constant "Finds the sum of a set of numbers." + + %cout = ivy.global-ref @cout -> ptr + %1 = ptr.load %cout : ptr -> #ivy.id + + ivy.send-msg to %1, put:%0 -> void + + %sum = ptr.alloca i32 -> ptr + %sum.0 = i32.constant 0 + + ptr.store %sum.0, %sum : i32, ptr + + scf.loop() -> void { + %2 = ivy.str.constant "Number (blank to finish): " + + %3 = ptr.load %cout : ptr -> #ivy.id + + ivy.send-msg to %3, put:%2 -> void + + %4 = ptr.load %cout : ptr -> #ivy.id + ivy.send-msg to %3, flush -> void + + %v = ptr.alloca i32 -> ptr + %5 = i32.constant 0 + + ptr.store %5, %v : i32, ptr + + %input = ptr.alloca #ivy.id -> ptr + %cin = ivy.global-ref @cin -> ptr + + %7 = ptr.load %cin : ptr -> #ivy.id + + %8 = ivy.send-msg to %7, read-line -> #ivy.id + ptr.store %8, %input : #ivy.id, ptr + + %9 = ptr.load %input : ptr -> #ivy.id + + %String = ivy.global-ref @String -> ptr + %10 = ptr.load %String : ptr -> #ivy.id + + %11 = ivy.send-msg to %10, new -> #ivy.id + + %12 = ivy.cmp eq %9, %11 : (#ivy.id, #ivy.id) -> i1 + scf.if %12 -> void { + scf.loop-break : () + } + + %v = ptr.alloca #ivy.id -> ptr + + %Int = ivy.global-ref @Int -> ptr + + %13 = ptr.load %Int : ptr -> #ivy.id + %14 = ptr.load %input : ptr -> #ivy.id + %15 = ivy.send-msg to %12, parse:%14 -> #ivy.id + + ptr.store %15, %v : #ivy.id, ptr + + %16 = ptr.load %v : ptr -> #ivy.id + %17 = ivy.null-id : #ivy.id + + %18 = ivy.cmp eq %16, %17 : (#ivy.id, #ivy.id) -> i1 + + scf.if %1 -> void { + %19 = ptr.load %cout : ptr -> #ivy.id + + %StringBuilder = ivy.global-ref @StringBuilder -> ptr + %20 = ptr.load %StringBuilder : ptr -> #ivy.id + %21 = ivy.send-msg to %20, new -> #ivy.id + + %22 = ptr.load %input : ptr -> #ivy.id + ivy.send-msg to %21, append:%22 -> void + + %23 = ivy.str.constant " is not a valid number." + ivy.send-msg to %21, append:%23 -> void + + %24 = ivy.send-msg to %21, to-string -> #ivy.id + ivy.send-msg to %19, put:%24 -> void + + scf.loop-continue : () + } + + %25 = ptr.load %sum : ptr -> i32 + %26 = ptr.load %v : ptr -> #ivy.id + %addtmp = ivy.add %25, %26 : (i32, #ivy.id) -> #ivy.id + ptr.store %addtmp, %sum : #ivy.id, ptr + + scf.loop-continue : () + } + } +} diff --git a/doc/sample/Var.im b/doc/sample/Var.im index a396ce4..c8ed9b0 100644 --- a/doc/sample/Var.im +++ b/doc/sample/Var.im @@ -1,4 +1,9 @@ -var x = 2 + 3. -var y = x. -var z. -var (x, y) = (3, 4). + +x = 3. +y = 0. + +if x > 10 then + y = 4 +else + y = 2 +end