Compare commits
4 Commits
db1eba08b8
...
ee0d649db8
| Author | SHA1 | Date | |
|---|---|---|---|
| ee0d649db8 | |||
| 100ddd9a87 | |||
| 89b9fbc988 | |||
| fb09facdda |
@@ -1,6 +1,62 @@
|
|||||||
BasedOnStyle: WebKit
|
BasedOnStyle: WebKit
|
||||||
IndentWidth: 8
|
IndentWidth: 8
|
||||||
---
|
---
|
||||||
|
Language: C
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
PointerAlignment: Right
|
||||||
|
ColumnLimit: 80
|
||||||
|
AlignAfterOpenBracket: AlwaysBreak
|
||||||
|
AlignConsecutiveAssignments: None
|
||||||
|
AlignConsecutiveBitFields: None
|
||||||
|
AlignConsecutiveDeclarations: None
|
||||||
|
AlignConsecutiveMacros: AcrossEmptyLinesAndComments
|
||||||
|
AlignEscapedNewlines: Right
|
||||||
|
AlignOperands: AlignAfterOperator
|
||||||
|
AlignTrailingComments: true
|
||||||
|
AllowAllArgumentsOnNextLine: false
|
||||||
|
AllowAllConstructorInitializersOnNextLine: false
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: false
|
||||||
|
AllowShortBlocksOnASingleLine: Empty
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
AllowShortEnumsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: false
|
||||||
|
AllowShortIfStatementsOnASingleLine: false
|
||||||
|
AllowShortLambdasOnASingleLine: false
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AlwaysBreakAfterReturnType: None
|
||||||
|
AlwaysBreakBeforeMultilineStrings: true
|
||||||
|
AlwaysBreakTemplateDeclarations: Yes
|
||||||
|
BinPackArguments: true
|
||||||
|
BinPackParameters: true
|
||||||
|
ExperimentalAutoDetectBinPacking: false
|
||||||
|
BitFieldColonSpacing: Both
|
||||||
|
BreakBeforeBraces: Linux
|
||||||
|
BreakBeforeBinaryOperators: All
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakConstructorInitializers: BeforeComma
|
||||||
|
BreakInheritanceList: BeforeComma
|
||||||
|
BreakStringLiterals: true
|
||||||
|
ContinuationIndentWidth: 8
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
IncludeBlocks: Regroup
|
||||||
|
SortIncludes: true
|
||||||
|
IndentRequires: true
|
||||||
|
NamespaceIndentation: Inner
|
||||||
|
ReflowComments: true
|
||||||
|
SpacesBeforeTrailingComments: 3
|
||||||
|
TabWidth: 8
|
||||||
|
UseTab: AlignWithSpaces
|
||||||
|
PenaltyReturnTypeOnItsOwnLine: 1000000
|
||||||
|
PenaltyExcessCharacter: 5
|
||||||
|
PenaltyBreakOpenParenthesis: 5
|
||||||
|
PenaltyBreakBeforeFirstCallParameter: 5
|
||||||
|
PenaltyIndentedWhitespace: 0
|
||||||
|
AttributeMacros:
|
||||||
|
- BLUELIB_API
|
||||||
|
ForEachMacros:
|
||||||
|
- b_btree_foreach
|
||||||
|
- b_queue_foreach
|
||||||
|
---
|
||||||
Language: Cpp
|
Language: Cpp
|
||||||
DerivePointerAlignment: false
|
DerivePointerAlignment: false
|
||||||
PointerAlignment: Right
|
PointerAlignment: Right
|
||||||
|
|||||||
7
doc/mie-passes.txt
Normal file
7
doc/mie-passes.txt
Normal file
@@ -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
|
||||||
530
doc/mie/sample/Person.2.mie
Normal file
530
doc/mie/sample/Person.2.mie
Normal file
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
535
doc/mie/sample/Person.3.mie
Normal file
535
doc/mie/sample/Person.3.mie
Normal file
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
ivy.package-ref "std.io"
|
||||||
data @StringBuffer = external global id
|
|
||||||
|
|
||||||
data @.str.0 = str "Received "
|
ivy.module {
|
||||||
data @.str.1 = str ", "
|
%cout = ivy.global-ref @cout -> ptr
|
||||||
|
|
||||||
data @.atom.0 = atom "years"
|
ivy.class @Person {
|
||||||
data @.atom.1 = atom "months"
|
%self.name = ivy.object-var @name : #ivy.id -> ptr
|
||||||
data @.atom.2 = atom "days"
|
%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 {
|
ivy.msgh.object init(name:%name, age:%age) -> void {
|
||||||
id @name,
|
ptr.store %name, %self.name : #ivy.id, ptr
|
||||||
id @age,
|
ptr.store %age, %self.age : #ivy.id, ptr
|
||||||
id @val
|
func.return : ()
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @_ZN3net9doorstuck4testC6PersonM4init4name3ageE(id %self, id %0) instance {
|
ivy.msgh.object test(param:%data, _:%extra) -> void {
|
||||||
entry:
|
%0 = ivy.string-builder.begin
|
||||||
%1 = getelementptr class @_ZN3net9doorstuck4testC6PersonE, id %self, i32 #0
|
|
||||||
store id %0, ptr %1
|
ivy.string-builder.add %0 << "Received "
|
||||||
|
ivy.string-builder.add %0 << %data : #ivy.id
|
||||||
%2 = getelementptr class @_ZN33net9doorstuck4testC6PersonE, id %self, i32 #1
|
ivy.string-builder.add %0 << ", "
|
||||||
store id %1, ptr %2
|
ivy.string-builder.add %0 << %extra : #ivy.id
|
||||||
|
|
||||||
ret void
|
%1 = ivy.string-builder.end %0 -> #ivy.id
|
||||||
}
|
|
||||||
|
%2 = ptr.load %cout : ptr -> #ivy.id
|
||||||
define void @_ZN3net9doorstuck4testC6PersonM4test5param0E(id %0, id %1) instance {
|
ivy.msg.send to %2, put:%1 -> void
|
||||||
entry:
|
func.return : ()
|
||||||
%2 = load id, ptr @cout
|
}
|
||||||
|
|
||||||
; %4 = StringBuilder new
|
ivy.msgh.object name -> #ivy.id {
|
||||||
%3 = load id, ptr @StringBuilder
|
%0 = ptr.load %self.name : ptr -> #ivy.id
|
||||||
%4 = msg id %3, @_M3newE
|
func.return %0 : #ivy.id
|
||||||
|
}
|
||||||
; (void) tempstr append:'Received '
|
|
||||||
%5 = load id, ptr @.str.0
|
ivy.msgh.object age -> #ivy.id {
|
||||||
msg void, id %3, @_M06appendE [id %5]
|
%0 = ptr.load %self.age : ptr -> #ivy.id
|
||||||
|
func.return %0 : #ivy.id
|
||||||
; (void) tempstr append:data (param 0)
|
}
|
||||||
msg void, id %3, @_M06appendE [id %0]
|
|
||||||
|
ivy.msgh.object age-in-months -> #ivy.id {
|
||||||
; (void) tempstr append:', '
|
%0 = ptr.load %self.age : ptr -> #ivy.id
|
||||||
%6 = load id, ptr @.str.1
|
%1 = i32.constant 12
|
||||||
msg void, id %3, @_M06appendE [id %6]
|
%multmp = ivy.mul %0, %1 : (#ivy.id, i32) -> #ivy.id
|
||||||
|
func.return %multmp : #ivy.id
|
||||||
; [void] tempstr append:extra (param 1)
|
}
|
||||||
msg void, id %3, @_M06appendE [id %1]
|
|
||||||
|
ivy.msgh.object set-name:%name -> void {
|
||||||
; %7 = tempstr toString
|
ptr.store %name, %self.name : #ivy.id, ptr
|
||||||
%7 = msg id, id %3, @_M8toStringE
|
func.return : ()
|
||||||
|
}
|
||||||
; cout put:'Received {data}, {extra}'
|
|
||||||
msg void, id %2, @_M03put [id %7]
|
ivy.msgh.object set-age:%age -> void {
|
||||||
|
ptr.store %age, %self.age : #ivy.id, ptr
|
||||||
ret void
|
func.return : ()
|
||||||
}
|
}
|
||||||
|
|
||||||
define id @_ZN3net9doorstuck4testC6PersonM4nameE(id %self) instance {
|
ivy.msgh.object set-age:%age in-units:%units -> void {
|
||||||
entry:
|
scf.switch : () -> void
|
||||||
%0 = getelementptr class @_ZN33net9doorstuck4testC6PersonE, id %self, i32 #0
|
case {
|
||||||
%1 = load id, ptr %0
|
%0 = ivy.atom "years"
|
||||||
ret id %1
|
%cmptmp.0 = ivy.cmp eq %age, %0 : (#ivy.id, #ivy.atom) -> i1
|
||||||
}
|
scf.switch-condition %cmptmp.0
|
||||||
|
} then {
|
||||||
define id @_ZN3net9doorstuck4testC6PersonM3ageE(id %self) instance {
|
ptr.store %age, %self.age : #ivy.id, ptr
|
||||||
entry:
|
scf.switch-break : ()
|
||||||
%0 = getelementptr class @_ZN33net9doorstuck4testC6PersonE, id %self, i32 #1
|
} case {
|
||||||
%1 = load id, ptr %0
|
%1 = ivy.atom "months"
|
||||||
ret id %1
|
%cmptmp.1 = ivy.cmp eq %age, %1 : (#ivy.id, #ivy.atom) -> i1
|
||||||
}
|
scf.condition %cmptmp.1
|
||||||
|
} then {
|
||||||
define id @_ZN3net9doorstuck4testC6PersonM11ageInMonthsE(id %self, id %0) instance {
|
%d0 = i32.constant 12
|
||||||
entry:
|
%divtmp.0 = ivy.div %age, %d0 : (#ivy.id, i32) -> #ivy.id
|
||||||
%1 = getelementptr class @_ZN33net9doorstuck4testC6PersonE, id %self, i32 #1
|
ptr.store %divtmp.0, %self.age : #ivy.id, ptr
|
||||||
%2 = load id, ptr %1
|
scf.switch-break : ()
|
||||||
ret id %1
|
} case {
|
||||||
}
|
%2 = ivy.atom "days"
|
||||||
|
%cmptmp.2 = ivy.cmp eq %age, %2 : (#ivy.id, #ivy.atom) -> i1
|
||||||
define void @_ZN3net9doorstuck4testC6PersonM07setNameE(id %self, id %1) instance {
|
scf.condition %cmptmp.2
|
||||||
entry:
|
} then {
|
||||||
%2 = getelementptr class @_ZN33net9doorstuck4testC6PersonE, id %self, i32 #1
|
%d1 = i32.constant 365
|
||||||
store id %1, ptr %2
|
%divtmp.1 = ivy.div %age, %d1 : (#ivy.id, i32) -> #ivy.id
|
||||||
ret void
|
ptr.store %divtmp.1, %self.age : #ivy.id, ptr
|
||||||
}
|
scf.switch-break : ()
|
||||||
|
} default {
|
||||||
define void @_ZN3net9doorstuck4testC6PersonM06setAge6inUnitE(id %self, i32 %1, id %2) instance {
|
%d2 = i32.constant 0
|
||||||
entry:
|
scf.switch-break : ()
|
||||||
%3 = load atom, ptr @.atom.0
|
}
|
||||||
%4 = load atom, ptr @.atom.1
|
|
||||||
%5 = load atom, ptr @.atom.2
|
func.return : ()
|
||||||
|
}
|
||||||
switch id %2, label %default [
|
|
||||||
atom %3, label %years
|
ivy.msgh.object get-age-in-units:%units -> #ivy.id {
|
||||||
atom %4, label %months
|
%result = scf.switch : () -> #ivy.id
|
||||||
atom %5, label %days
|
case {
|
||||||
]
|
%0 = ivy.atom "years"
|
||||||
|
%cmptmp.0 = ivy.cmp eq %age, %0 : (#ivy.id, #ivy.atom) -> i1
|
||||||
years:
|
scf.switch-condition %cmptmp.0
|
||||||
%6 = getelementptr class @_ZN33net9doorstuck4testC6PersonE, id %self, i32 #1
|
} then {
|
||||||
store i32 %2, ptr %6
|
%v0 = ptr.load %self.age : ptr -> #ivy.id
|
||||||
br label %end
|
scf.switch-break %v0 : #ivy.id
|
||||||
|
} case {
|
||||||
months:
|
%1 = ivy.atom "months"
|
||||||
%7 = getelementptr class @_ZN33net9doorstuck4testC6PersonE, id %self, i32 #1
|
%cmptmp.1 = ivy.cmp eq %age, %1 : (#ivy.id, #ivy.atom) -> i1
|
||||||
%8 = div i32 %2, #12
|
scf.condition %cmptmp.1
|
||||||
store i32 %8, ptr %7
|
} then {
|
||||||
br label %end
|
%v0 = ptr.load %self.age : ptr -> #ivy.id
|
||||||
|
%d0 = i32.constant 12
|
||||||
days:
|
%divtmp.0 = ivy.div %v0, %d0 : (#ivy.id, i32) -> #ivy.id
|
||||||
%9 = getelementptr class @_ZN33net9doorstuck4testC6PersonE, id %self, i32 #1
|
scf.switch-break %divtmp.0 : #ivy.id
|
||||||
%10 = div i32 %2, #365
|
} case {
|
||||||
store i32 %10, ptr %9
|
%2 = ivy.atom "days"
|
||||||
br label %end
|
%cmptmp.2 = ivy.cmp eq %age, %2 : (#ivy.id, #ivy.atom) -> i1
|
||||||
|
scf.condition %cmptmp.2
|
||||||
default:
|
} then {
|
||||||
%11 = getelementptr class @_ZN33net9doorstuck4testC6PersonE, id %self, i32 #1
|
%v1 = ptr.load %self.age : ptr -> #ivy.id
|
||||||
store i32 #0, ptr %11
|
%d1 = i32.constant 365
|
||||||
br label %end
|
%divtmp.1 = ivy.div %v1, %d1 : (#ivy.id, i32) -> #ivy.id
|
||||||
|
scf.switch-break %divtmp.1 : #ivy.id
|
||||||
end:
|
} default {
|
||||||
ret void
|
%d2 = i32.constant 0
|
||||||
}
|
scf.switch-break %d2 : #ivy.id
|
||||||
|
}
|
||||||
define id @_ZN3net9doorstuck4testC6PersonM012getAgeInUnitE(id %0, id %1) instance {
|
|
||||||
entry:
|
func.return %result : #ivy.id
|
||||||
|
}
|
||||||
}
|
|
||||||
|
ivy.object-prop example-property
|
||||||
define id @_ZN3net9doorstuck4testC6PersonP15examplePropertyG(id %self) instance {
|
get {
|
||||||
entry:
|
%0 = ptr.load %self.val : ptr -> #ivy.id
|
||||||
%0 = getelementptr class @_ZN33net9doorstuck4testC6PersonE, id %self, i32 #2
|
func.return %0 : #ivy.id
|
||||||
%1 = load id, ptr %0
|
}
|
||||||
ret id %1
|
set (%value: #ivy.id) {
|
||||||
}
|
ptr.store %value, %self.val : #ivy.id, ptr
|
||||||
|
func.return : ()
|
||||||
define void @_ZN3net9doorstuck4testC6PersonP15examplePropertyS(id %self, id %0) instance {
|
}
|
||||||
entry:
|
|
||||||
%1 = getelementptr class @_ZN33net9doorstuck4testC6PersonE, id %self, i32 #2
|
ivy.object-prop example-property-2 get {
|
||||||
store id %0, ptr %1
|
%0 = ptr.load %self.val : ptr -> #ivy.id
|
||||||
ret void
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
46
doc/mie/sample/Simple.1.mie
Normal file
46
doc/mie/sample/Simple.1.mie
Normal file
@@ -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 : ()
|
||||||
|
}
|
||||||
|
}
|
||||||
50
doc/mie/sample/Simple.2.mie
Normal file
50
doc/mie/sample/Simple.2.mie
Normal file
@@ -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 : ()
|
||||||
|
}
|
||||||
|
}
|
||||||
63
doc/mie/sample/Simple.3.mie
Normal file
63
doc/mie/sample/Simple.3.mie
Normal file
@@ -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 : ()
|
||||||
|
}
|
||||||
|
}
|
||||||
62
doc/mie/sample/Simple.4.mie
Normal file
62
doc/mie/sample/Simple.4.mie
Normal file
@@ -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 : ()
|
||||||
|
}
|
||||||
|
}
|
||||||
68
doc/mie/sample/Simple.5.mie
Normal file
68
doc/mie/sample/Simple.5.mie
Normal file
@@ -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 : ()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
@@ -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.
|
z = w = 2 + 3 multiply-by:2.
|
||||||
x = (((1 + 2 * 3) multiply-by:3) add: 5) + 2.
|
x = (((1 + 2 * 3) multiply-by:3) add: 5) + 2.
|
||||||
x = ((1 + 2 * 3) multiply-by:3).
|
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.
|
m = xz multiply(by:3 add:2); squared.
|
||||||
|
|
||||||
x = OrderedCollection new
|
x = Ordered-Collection new
|
||||||
add: 2;
|
add: 2;
|
||||||
add: 4;
|
add: 4;
|
||||||
add: 6;
|
add: 6;
|
||||||
@@ -21,7 +21,7 @@ x = OrderedCollection new
|
|||||||
|
|
||||||
age = Person new(name:"John Doe", age:34)
|
age = Person new(name:"John Doe", age:34)
|
||||||
set-age:144 in-unit:"months";
|
set-age:144 in-unit:"months";
|
||||||
ageInMonths.
|
age-in-months.
|
||||||
|
|
||||||
x = 5.
|
x = 5.
|
||||||
q = 10 if x > 2 else 20.
|
q = 10 if x > 2 else 20.
|
||||||
|
|||||||
@@ -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 {
|
ivy.for-each %c in %str {
|
||||||
entry:
|
ivy.msg to %cout, -put:%c
|
||||||
%0 = load str, ptr @.str.0
|
}
|
||||||
%str = alloca id
|
|
||||||
store str %0, ptr %str
|
|
||||||
|
|
||||||
%1 = load id, ptr %str
|
ivy.msg to %cout, -put:%.str.0
|
||||||
%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
|
|
||||||
|
|
||||||
%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
|
|
||||||
}
|
}
|
||||||
|
|||||||
562
doc/sample/Person.2.im
Normal file
562
doc/sample/Person.2.im
Normal file
@@ -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. */
|
||||||
|
|
||||||
@@ -48,7 +48,6 @@ class Person
|
|||||||
compatibility with lambdas.
|
compatibility with lambdas.
|
||||||
**/
|
**/
|
||||||
- init(name:name age:age)
|
- init(name:name age:age)
|
||||||
var x.
|
|
||||||
self::name = name.
|
self::name = name.
|
||||||
self::age = age!
|
self::age = age!
|
||||||
|
|
||||||
@@ -80,7 +79,7 @@ class Person
|
|||||||
_ => 0
|
_ => 0
|
||||||
end!
|
end!
|
||||||
|
|
||||||
/* Properties are defined using the $ symbol.
|
/* Properties are defined using the -> symbol.
|
||||||
They accomplish two things:
|
They accomplish two things:
|
||||||
1) they make it easy to synthesize the -get: and -put:at: messages
|
1) they make it easy to synthesize the -get: and -put:at: messages
|
||||||
that the package dot syntax requires.
|
that the package dot syntax requires.
|
||||||
@@ -109,7 +108,7 @@ class Person
|
|||||||
/* Without the lambda synthesis, the property would look like this:
|
/* Without the lambda synthesis, the property would look like this:
|
||||||
Note that this is the only time it is legal to access private fields
|
Note that this is the only time it is legal to access private fields
|
||||||
via `self` from a lambda. */
|
via `self` from a lambda. */
|
||||||
-> example-property |
|
-> example-property-2 |
|
||||||
get => [ ^self::val ],
|
get => [ ^self::val ],
|
||||||
set => [ :x | self::val = x ].
|
set => [ :x | self::val = x ].
|
||||||
|
|
||||||
@@ -119,23 +118,23 @@ class Person
|
|||||||
|
|
||||||
If either the `set` or `get` elements are not provided, the property
|
If either the `set` or `get` elements are not provided, the property
|
||||||
becomes read-only or write-only respectively */
|
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,
|
/* A property can also be configured to act just like a regular variable,
|
||||||
by setting the getter and setters to default implementations.
|
by setting the getter and setters to default implementations.
|
||||||
|
|
||||||
The default getter will return the value of a private member variable
|
The default getter will return the value of a private member variable
|
||||||
named by prepending two underscores to the property name
|
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
|
Similarly, the default setter will set the value of a private member
|
||||||
variable named by prepending two underscores to the property name
|
variable named by prepending two underscores to the property name
|
||||||
(__exampleProperty3 in this case) to the value provided to the setter. */
|
(__example-property-4 in this case) to the value provided to the setter. */
|
||||||
-> example-property-3 (get, set)
|
-> example-property-4 (get, set)
|
||||||
|
|
||||||
/* Just like in the earlier examples, either `get` or `set` can be omitted
|
/* Just like in the earlier examples, either `get` or `set` can be omitted
|
||||||
to create a write-only or read-only property respectively */
|
to create a write-only or read-only property respectively */
|
||||||
-> example-property-4 (get)
|
-> example-property-5 (get)
|
||||||
end
|
end
|
||||||
|
|
||||||
p1 = Person new(name:'John Doe', age:34).
|
p1 = Person new(name:'John Doe', age:34).
|
||||||
@@ -151,8 +150,8 @@ while i < 100 do
|
|||||||
i += 2
|
i += 2
|
||||||
end
|
end
|
||||||
|
|
||||||
for i in 0 to:100 step:2 do
|
for x in 0 to:100 step:2 do
|
||||||
cout put:'Count is {i}'
|
cout put:'Count is {x}'
|
||||||
end
|
end
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -223,11 +222,11 @@ pkg[0] = 16.
|
|||||||
/* All of these accesses are equivalent */
|
/* All of these accesses are equivalent */
|
||||||
pkg['x'] = 32.
|
pkg['x'] = 32.
|
||||||
pkg->x = 32.
|
pkg->x = 32.
|
||||||
pkg put:32 at:'x'.
|
pkg at:'x' put:32.
|
||||||
|
|
||||||
index = 'x'.
|
index = 'x'.
|
||||||
pkg[index] = 32.
|
pkg[index] = 32.
|
||||||
pkg put:32 at:index.
|
pkg at:index put:32.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
this syntax, and the pkg.* instructions that it translates to, is
|
this syntax, and the pkg.* instructions that it translates to, is
|
||||||
@@ -274,7 +273,7 @@ end
|
|||||||
following criteria:
|
following criteria:
|
||||||
a) is an Iterator object; or
|
a) is an Iterator object; or
|
||||||
b) implements the Iterator protocol; 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)
|
conforms to a) or b)
|
||||||
**/
|
**/
|
||||||
|
|
||||||
@@ -311,7 +310,7 @@ end
|
|||||||
on:$err:number-format do:[ :err :data |
|
on:$err:number-format do:[ :err :data |
|
||||||
cout put:'Cannot parse integer string ({err})'
|
cout put:'Cannot parse integer string ({err})'
|
||||||
];
|
];
|
||||||
onError:[ :err :data |
|
on-error:[ :err :data |
|
||||||
cout put:'Error {err} occurred ({data})'
|
cout put:'Error {err} occurred ({data})'
|
||||||
];
|
];
|
||||||
call.
|
call.
|
||||||
|
|||||||
@@ -1,36 +1,9 @@
|
|||||||
y = -1 + 2 * 3 / 4 * 5 - 6 + 7 multiply-by:2.
|
package net.doorstuck.test
|
||||||
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.
|
|
||||||
|
|
||||||
p1
|
use std.io
|
||||||
set-age:2 squared squared + 4 squared multiply(by:2, add:4 + 1 * 3)
|
|
||||||
in:"mon" + "ths".
|
|
||||||
|
|
||||||
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.
|
cout put:'Answer: {x}'
|
||||||
|
|
||||||
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
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package net.doorstuck.test
|
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 ]
|
s3 = s1 map:[ :c | ^((c ordinal) + 1) to-char ]
|
||||||
|
|||||||
96
doc/sample/Sum.2.mie
Normal file
96
doc/sample/Sum.2.mie
Normal file
@@ -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 : ()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,9 @@
|
|||||||
var x = 2 + 3.
|
|
||||||
var y = x.
|
x = 3.
|
||||||
var z.
|
y = 0.
|
||||||
var (x, y) = (3, 4).
|
|
||||||
|
if x > 10 then
|
||||||
|
y = 4
|
||||||
|
else
|
||||||
|
y = 2
|
||||||
|
end
|
||||||
|
|||||||
@@ -229,6 +229,9 @@ static b_result generate_mie_ir(struct compile_ctx *ctx)
|
|||||||
static b_result build_block_isel_graph(
|
static b_result build_block_isel_graph(
|
||||||
struct compile_ctx *ctx, struct mie_func *func, struct mie_block *block)
|
struct compile_ctx *ctx, struct mie_func *func, struct mie_block *block)
|
||||||
{
|
{
|
||||||
|
printf("selecting %s.%s...\n", func->f_base.v_name.n_str,
|
||||||
|
block->b_base.v_name.n_str);
|
||||||
|
|
||||||
b_queue_entry *entry = b_queue_first(&block->b_phi);
|
b_queue_entry *entry = b_queue_first(&block->b_phi);
|
||||||
while (entry) {
|
while (entry) {
|
||||||
struct mie_value *instr_v
|
struct mie_value *instr_v
|
||||||
@@ -254,9 +257,13 @@ static b_result build_block_isel_graph(
|
|||||||
struct mie_select_graph *graph = mie_select_builder_finish(ctx->select);
|
struct mie_select_graph *graph = mie_select_builder_finish(ctx->select);
|
||||||
|
|
||||||
if (ctx->flags & FLAG_SHOW_PRE_SELECT_GRAPH) {
|
if (ctx->flags & FLAG_SHOW_PRE_SELECT_GRAPH) {
|
||||||
|
char name[128];
|
||||||
|
snprintf(
|
||||||
|
name, sizeof name, "%s.%s.dot",
|
||||||
|
func->f_base.v_name.n_str, block->b_base.v_name.n_str);
|
||||||
printf("%s.%s instruction graph:\n", func->f_base.v_name.n_str,
|
printf("%s.%s instruction graph:\n", func->f_base.v_name.n_str,
|
||||||
block->b_base.v_name.n_str);
|
block->b_base.v_name.n_str);
|
||||||
mie_select_graph_dump_dot(graph);
|
mie_select_graph_dump_dot(graph, name);
|
||||||
mie_select_graph_destroy(graph);
|
mie_select_graph_destroy(graph);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,25 +9,32 @@ setlocal iskeyword+=-
|
|||||||
syn match ivyType /\<[A-Z]\{1,2}[a-z0-9]\+\(-\?[A-Z]\{1,2}[a-z0-9]\+\)*\>/
|
syn match ivyType /\<[A-Z]\{1,2}[a-z0-9]\+\(-\?[A-Z]\{1,2}[a-z0-9]\+\)*\>/
|
||||||
|
|
||||||
syn match ivySelectorLabel /\<[a-z][A-Za-z0-9-_]*\:/
|
syn match ivySelectorLabel /\<[a-z][A-Za-z0-9-_]*\:/
|
||||||
|
syn match ivySelectorLabel /\-[a-z][A-Za-z0-9-_]*\:/
|
||||||
|
syn match ivySelectorLabel /+[a-z][A-Za-z0-9-_]*\:/
|
||||||
"syn match ivySelectorLabel /\<\([a-z]\([A-Za-z0-9_]\+\)\:\(\:\)\@!\)\+/
|
"syn match ivySelectorLabel /\<\([a-z]\([A-Za-z0-9_]\+\)\:\(\:\)\@!\)\+/
|
||||||
syn match ivyUnnamedVariable /\<_\>/
|
|
||||||
|
|
||||||
syn match ivyAtomName /\$[a-z][a-z0-9_:/-]*\>/
|
syn match ivyAtomName /\$[a-z][a-z0-9_:/-]*\>/
|
||||||
syn match ivyWord /\<[a-z_][a-zA-Z0-9_]*\(-\?[a-zA-Z][a-zA-Z0-9_]*\)*\>\(\:\)\@!/
|
syn match ivyWord /\<[a-z_][a-zA-Z0-9_]*\(-\?[a-zA-Z][a-zA-Z0-9_]*\)*\>\(\:\)\@!/
|
||||||
|
|
||||||
|
syn match ivyUnnamedLabel /\s*(\?_:/
|
||||||
|
syn match ivyUnnamedVariable /\<_\>/
|
||||||
|
|
||||||
syn match ivyComplexMessageName /\<\zs[A-Za-z][A-Za-z0-9-_]\+\ze(/
|
syn match ivyComplexMessageName /\<\zs[A-Za-z][A-Za-z0-9-_]\+\ze(/
|
||||||
|
syn match ivyComplexMessageName /\-[A-Za-z][A-Za-z0-9-_]\+\ze(/
|
||||||
|
syn match ivyComplexMessageName /+[A-Za-z][A-Za-z0-9-_]\+\ze(/
|
||||||
"syn match ivyUnaryMessageName /-\s*[a-zA-z][a-zA-Z0-9_]\+\s*\n/
|
"syn match ivyUnaryMessageName /-\s*[a-zA-z][a-zA-Z0-9_]\+\s*\n/
|
||||||
syn match ivyUnaryMessageName /\(-\s*\)\@<=[a-z][A-Za-z0-9-_]*\(\s*\n\)\@=/
|
syn match ivyUnaryMessageName /\(-\s*\)\@<=[a-z][A-Za-z0-9-_]*\(\s*\n\)\@=/
|
||||||
syn match ivyUnaryMessageName /\(-\s*\)\@<=[a-z][A-Za-z0-9-_]*\(\s*|\)\@=/
|
syn match ivyUnaryMessageName /\(-\s*\)\@<=[a-z][A-Za-z0-9-_]*\(\s*|\)\@=/
|
||||||
syn match ivyUnaryMessageName /\(+\s*\)\@<=[a-z][A-Za-z0-9-_]*\(\s*\n\)\@=/
|
syn match ivyUnaryMessageName /\(+\s*\)\@<=[a-z][A-Za-z0-9-_]*\(\s*\n\)\@=/
|
||||||
syn match ivyUnaryMessageName /\(+\s*\)\@<=[a-z][A-Za-z0-9-_]*\(\s*|\)\@=/
|
syn match ivyUnaryMessageName /\(+\s*\)\@<=[a-z][A-Za-z0-9-_]*\(\s*|\)\@=/
|
||||||
|
syn match ivyUnaryMessageName /\-[a-z][A-Za-z0-9-_]*\(\s*[\|\[]\)\@=/
|
||||||
|
syn match ivyUnaryMessageName /+[a-z][A-Za-z0-9-_]*\(\s*[\|\[]\)\@=/
|
||||||
syn match ivyPropertyName /\(->\s*\)\@<=[a-z][A-Za-z0-9-_]*/
|
syn match ivyPropertyName /\(->\s*\)\@<=[a-z][A-Za-z0-9-_]*/
|
||||||
|
|
||||||
syn match ivyLineContinuation /\\\n/
|
syn match ivyLineContinuation /\\\n/
|
||||||
|
|
||||||
" Modifiers
|
" Modifiers
|
||||||
|
|
||||||
syn match ivySelfVar /\<self\([^a-zA-Z0-9-_]\)\@=/
|
syn match ivySelfVar /\<self\([^a-zA-Z0-9_]\)\@=/
|
||||||
|
|
||||||
" we have to use syn match for keywords because any keyword can be used as a
|
" we have to use syn match for keywords because any keyword can be used as a
|
||||||
" label by adding : to the end, and adding : to iskeyword causes more problems
|
" label by adding : to the end, and adding : to iskeyword causes more problems
|
||||||
@@ -44,19 +51,23 @@ syn match ivyUseStmtIdentifier /\(use \)\@<=\([A-Za-z_][A-Za-z0-9_]*\)\(.\([A-Za
|
|||||||
|
|
||||||
" Operators/Punctuation
|
" Operators/Punctuation
|
||||||
syn match ivyBraces "[{}]" display
|
syn match ivyBraces "[{}]" display
|
||||||
syn match ivyBrackets "[[\]]" display
|
|
||||||
syn match ivyParens "[()]" display
|
syn match ivyParens "[()]" display
|
||||||
|
syn match ivyControlSymbols "[[\]]" display
|
||||||
|
syn match ivyControlSymbols "|" display
|
||||||
|
syn match ivyControlSymbols "\^" display
|
||||||
syn match ivyOpSymbols "\*" display
|
syn match ivyOpSymbols "\*" display
|
||||||
syn match ivyOpSymbols "::" display
|
|
||||||
syn match ivyOpSymbols "=\{1,2}" display
|
syn match ivyOpSymbols "=\{1,2}" display
|
||||||
syn match ivyOpSymbols ">\{1,2}" display
|
syn match ivyOpSymbols ">\{1,2}" display
|
||||||
syn match ivyOpSymbols "<\{1,2}" display
|
syn match ivyOpSymbols "<\{1,2}" display
|
||||||
syn match ivyOpSymbols "[+\-/*%&^!|<>;,]" display
|
syn match ivyOpSymbols "[\/*%&!<>;,]" display
|
||||||
syn match ivyOpSymbols "[+\-/*%&^!|<>]=" display
|
syn match ivyOpSymbols "[+\-/*%&!<>]=" display
|
||||||
|
syn match ivyOpSymbols "\s\+[\-+]\s\+" display
|
||||||
|
syn match ivyOpSymbols "\->" display
|
||||||
syn match ivyOtherSymbols "=>" display
|
syn match ivyOtherSymbols "=>" display
|
||||||
syn match ivyLogicSymbols "&&" display
|
syn match ivyLogicSymbols "&&" display
|
||||||
syn match ivyLogicSymbols "||" display
|
syn match ivyLogicSymbols "||" display
|
||||||
syn match ivyStatementSeparator "\.\s*" display
|
syn match ivyPackageAccessOperator "\." display
|
||||||
|
syn match ivyStatementSeparator "\.\s*\n" display
|
||||||
syn match ivyMessageTerminator "\![\s\n]\+" display
|
syn match ivyMessageTerminator "\![\s\n]\+" display
|
||||||
syn keyword ivyWordOperator is not understands and or
|
syn keyword ivyWordOperator is not understands and or
|
||||||
|
|
||||||
@@ -147,15 +158,14 @@ hi def link ivyStatement Statement
|
|||||||
hi def link ivyRepeat Repeat
|
hi def link ivyRepeat Repeat
|
||||||
hi def link ivyConditional Conditional
|
hi def link ivyConditional Conditional
|
||||||
hi def link ivySelectorLabel Tag
|
hi def link ivySelectorLabel Tag
|
||||||
hi def link ivyUnnamedLabel @variable.builtin
|
hi def link ivyUnnamedLabel Comment
|
||||||
hi def link ivyUnnamedVariable @variable.builtin
|
hi def link ivyUnnamedVariable Comment
|
||||||
hi def link ivyLambdaParameter @variable.builtin
|
hi def link ivyLambdaParameter @variable.builtin
|
||||||
hi def link ivyException Exception
|
hi def link ivyException Exception
|
||||||
|
|
||||||
hi def link ivyParens Delimiter
|
hi def link ivyParens Delimiter
|
||||||
hi def link ivyBraces Structure
|
hi def link ivyBraces Structure
|
||||||
hi def link ivyBrackets Define
|
hi def link ivyControlSymbols Keyword
|
||||||
hi def link ivyLambdaSymbols Define
|
|
||||||
|
|
||||||
hi def link ivyModifier StorageClass
|
hi def link ivyModifier StorageClass
|
||||||
hi def link ivyAccessModifier ivyModifier
|
hi def link ivyAccessModifier ivyModifier
|
||||||
@@ -176,6 +186,7 @@ hi def link ivyTypeOf ivyKeywordOperator
|
|||||||
hi def link ivyTypeOfOperand Typedef
|
hi def link ivyTypeOfOperand Typedef
|
||||||
hi def link ivyTypeOfError Error
|
hi def link ivyTypeOfError Error
|
||||||
hi def link ivyOpSymbols Operator
|
hi def link ivyOpSymbols Operator
|
||||||
|
hi def link ivyPackageAccessOperator Operator
|
||||||
hi def link ivyOtherSymbols Structure
|
hi def link ivyOtherSymbols Structure
|
||||||
hi def link ivyLogicSymbols Operator
|
hi def link ivyLogicSymbols Operator
|
||||||
hi def link ivyWordOperator Operator
|
hi def link ivyWordOperator Operator
|
||||||
|
|||||||
Reference in New Issue
Block a user