Compare commits

...

4 Commits

21 changed files with 2603 additions and 281 deletions

View File

@@ -1,6 +1,62 @@
BasedOnStyle: WebKit
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
DerivePointerAlignment: false
PointerAlignment: Right

7
doc/mie-passes.txt Normal file
View 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
View 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
View 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
}
}

View File

@@ -1,146 +1,460 @@
record package_scope = str "net.doorstuck.test"
meta.source-filename "Person.im"
record import = { str "std.io" }
ivy.package-scope "net.doorstuck.test"
data @cout = external global id
data @StringBuffer = external global id
ivy.package-ref "std.io"
data @.str.0 = str "Received "
data @.str.1 = str ", "
ivy.module {
%cout = ivy.global-ref @cout -> ptr
data @.atom.0 = atom "years"
data @.atom.1 = atom "months"
data @.atom.2 = atom "days"
ivy.class @Person {
%self.name = ivy.object-var @name : #ivy.id -> ptr
%self.age = ivy.object-var @age : #ivy.id -> ptr
%self.val = ivy.object-var @val : #ivy.id -> ptr
%self.__example-property-4 = ivy.object-var @val : #ivy.id -> ptr
%self.__example-property-5 = ivy.object-var @val : #ivy.id -> ptr
type @_ZN3net9doorstuck4testC6PersonE = class {
id @name,
id @age,
id @val
ivy.msgh.object init(name:%name, age:%age) -> void {
ptr.store %name, %self.name : #ivy.id, ptr
ptr.store %age, %self.age : #ivy.id, ptr
func.return : ()
}
define void @_ZN3net9doorstuck4testC6PersonM4init4name3ageE(id %self, id %0) instance {
entry:
%1 = getelementptr class @_ZN3net9doorstuck4testC6PersonE, id %self, i32 #0
store id %0, ptr %1
ivy.msgh.object test(param:%data, _:%extra) -> void {
%0 = ivy.string-builder.begin
%2 = getelementptr class @_ZN33net9doorstuck4testC6PersonE, id %self, i32 #1
store id %1, ptr %2
ivy.string-builder.add %0 << "Received "
ivy.string-builder.add %0 << %data : #ivy.id
ivy.string-builder.add %0 << ", "
ivy.string-builder.add %0 << %extra : #ivy.id
ret void
%1 = ivy.string-builder.end %0 -> #ivy.id
%2 = ptr.load %cout : ptr -> #ivy.id
ivy.msg.send to %2, put:%1 -> void
func.return : ()
}
define void @_ZN3net9doorstuck4testC6PersonM4test5param0E(id %0, id %1) instance {
entry:
%2 = load id, ptr @cout
; %4 = StringBuilder new
%3 = load id, ptr @StringBuilder
%4 = msg id %3, @_M3newE
; (void) tempstr append:'Received '
%5 = load id, ptr @.str.0
msg void, id %3, @_M06appendE [id %5]
; (void) tempstr append:data (param 0)
msg void, id %3, @_M06appendE [id %0]
; (void) tempstr append:', '
%6 = load id, ptr @.str.1
msg void, id %3, @_M06appendE [id %6]
; [void] tempstr append:extra (param 1)
msg void, id %3, @_M06appendE [id %1]
; %7 = tempstr toString
%7 = msg id, id %3, @_M8toStringE
; cout put:'Received {data}, {extra}'
msg void, id %2, @_M03put [id %7]
ret void
ivy.msgh.object name -> #ivy.id {
%0 = ptr.load %self.name : ptr -> #ivy.id
func.return %0 : #ivy.id
}
define id @_ZN3net9doorstuck4testC6PersonM4nameE(id %self) instance {
entry:
%0 = getelementptr class @_ZN33net9doorstuck4testC6PersonE, id %self, i32 #0
%1 = load id, ptr %0
ret id %1
ivy.msgh.object age -> #ivy.id {
%0 = ptr.load %self.age : ptr -> #ivy.id
func.return %0 : #ivy.id
}
define id @_ZN3net9doorstuck4testC6PersonM3ageE(id %self) instance {
entry:
%0 = getelementptr class @_ZN33net9doorstuck4testC6PersonE, id %self, i32 #1
%1 = load id, ptr %0
ret id %1
ivy.msgh.object age-in-months -> #ivy.id {
%0 = ptr.load %self.age : ptr -> #ivy.id
%1 = i32.constant 12
%multmp = ivy.mul %0, %1 : (#ivy.id, i32) -> #ivy.id
func.return %multmp : #ivy.id
}
define id @_ZN3net9doorstuck4testC6PersonM11ageInMonthsE(id %self, id %0) instance {
entry:
%1 = getelementptr class @_ZN33net9doorstuck4testC6PersonE, id %self, i32 #1
%2 = load id, ptr %1
ret id %1
ivy.msgh.object set-name:%name -> void {
ptr.store %name, %self.name : #ivy.id, ptr
func.return : ()
}
define void @_ZN3net9doorstuck4testC6PersonM07setNameE(id %self, id %1) instance {
entry:
%2 = getelementptr class @_ZN33net9doorstuck4testC6PersonE, id %self, i32 #1
store id %1, ptr %2
ret void
ivy.msgh.object set-age:%age -> void {
ptr.store %age, %self.age : #ivy.id, ptr
func.return : ()
}
define void @_ZN3net9doorstuck4testC6PersonM06setAge6inUnitE(id %self, i32 %1, id %2) instance {
entry:
%3 = load atom, ptr @.atom.0
%4 = load atom, ptr @.atom.1
%5 = load atom, ptr @.atom.2
switch id %2, label %default [
atom %3, label %years
atom %4, label %months
atom %5, label %days
]
years:
%6 = getelementptr class @_ZN33net9doorstuck4testC6PersonE, id %self, i32 #1
store i32 %2, ptr %6
br label %end
months:
%7 = getelementptr class @_ZN33net9doorstuck4testC6PersonE, id %self, i32 #1
%8 = div i32 %2, #12
store i32 %8, ptr %7
br label %end
days:
%9 = getelementptr class @_ZN33net9doorstuck4testC6PersonE, id %self, i32 #1
%10 = div i32 %2, #365
store i32 %10, ptr %9
br label %end
default:
%11 = getelementptr class @_ZN33net9doorstuck4testC6PersonE, id %self, i32 #1
store i32 #0, ptr %11
br label %end
end:
ret void
ivy.msgh.object set-age:%age in-units:%units -> void {
scf.switch : () -> void
case {
%0 = ivy.atom "years"
%cmptmp.0 = ivy.cmp eq %age, %0 : (#ivy.id, #ivy.atom) -> i1
scf.switch-condition %cmptmp.0
} then {
ptr.store %age, %self.age : #ivy.id, ptr
scf.switch-break : ()
} case {
%1 = ivy.atom "months"
%cmptmp.1 = ivy.cmp eq %age, %1 : (#ivy.id, #ivy.atom) -> i1
scf.condition %cmptmp.1
} then {
%d0 = i32.constant 12
%divtmp.0 = ivy.div %age, %d0 : (#ivy.id, i32) -> #ivy.id
ptr.store %divtmp.0, %self.age : #ivy.id, ptr
scf.switch-break : ()
} case {
%2 = ivy.atom "days"
%cmptmp.2 = ivy.cmp eq %age, %2 : (#ivy.id, #ivy.atom) -> i1
scf.condition %cmptmp.2
} then {
%d1 = i32.constant 365
%divtmp.1 = ivy.div %age, %d1 : (#ivy.id, i32) -> #ivy.id
ptr.store %divtmp.1, %self.age : #ivy.id, ptr
scf.switch-break : ()
} default {
%d2 = i32.constant 0
scf.switch-break : ()
}
define id @_ZN3net9doorstuck4testC6PersonM012getAgeInUnitE(id %0, id %1) instance {
entry:
func.return : ()
}
ivy.msgh.object get-age-in-units:%units -> #ivy.id {
%result = scf.switch : () -> #ivy.id
case {
%0 = ivy.atom "years"
%cmptmp.0 = ivy.cmp eq %age, %0 : (#ivy.id, #ivy.atom) -> i1
scf.switch-condition %cmptmp.0
} then {
%v0 = ptr.load %self.age : ptr -> #ivy.id
scf.switch-break %v0 : #ivy.id
} case {
%1 = ivy.atom "months"
%cmptmp.1 = ivy.cmp eq %age, %1 : (#ivy.id, #ivy.atom) -> i1
scf.condition %cmptmp.1
} then {
%v0 = ptr.load %self.age : ptr -> #ivy.id
%d0 = i32.constant 12
%divtmp.0 = ivy.div %v0, %d0 : (#ivy.id, i32) -> #ivy.id
scf.switch-break %divtmp.0 : #ivy.id
} case {
%2 = ivy.atom "days"
%cmptmp.2 = ivy.cmp eq %age, %2 : (#ivy.id, #ivy.atom) -> i1
scf.condition %cmptmp.2
} then {
%v1 = ptr.load %self.age : ptr -> #ivy.id
%d1 = i32.constant 365
%divtmp.1 = ivy.div %v1, %d1 : (#ivy.id, i32) -> #ivy.id
scf.switch-break %divtmp.1 : #ivy.id
} default {
%d2 = i32.constant 0
scf.switch-break %d2 : #ivy.id
}
func.return %result : #ivy.id
}
ivy.object-prop example-property
get {
%0 = ptr.load %self.val : ptr -> #ivy.id
func.return %0 : #ivy.id
}
set (%value: #ivy.id) {
ptr.store %value, %self.val : #ivy.id, ptr
func.return : ()
}
ivy.object-prop example-property-2 get {
%0 = ptr.load %self.val : ptr -> #ivy.id
func.return %0 : #ivy.id
} set (%x: #ivy.id) {
ptr.store %x, %self.val : #ivy.id, ptr
func.return : ()
}
ivy.object-prop example-property-3 get {
%0 = i32.constant 42
func.return %0 : i32
}
ivy.object-prop example-property-4 get {
%0 = ptr.load %self.__example-property-4 : ptr -> #ivy.id
func.return %0 : #ivy.id
} set (%0: #ivy.id) {
ptr.store %0, %self.__example-property-4 : #ivy.id, ptr
func.return : ()
}
ivy.object-prop example-property-5 get {
%0 = ptr.load %self.__example-property-5 : ptr -> #ivy.id
func.return %0 : #ivy.id
}
}
ivy.init-text {
; p1 = Person new(name:'John Doe', age:34).
%Person = ivy.global-ref @Person : ptr
%0 = ivy.str.constant "John Doe"
%1 = i32.constant 34
%2 = ivy.msg.send to %Person, new(name:%0, age:%1) -> #ivy.id
%p1 = ptr.alloca #ivy.id -> ptr
ptr.store %2, %p1 : #ivy.id, ptr
; p1 set-age:100 in-unit:$months.
%3 = ptr.load %p1 : ptr -> #ivy.id
%4 = i32.constant 100
%5 = ivy.atom "months"
ivy.msg.send to %3, set-age:%4 in-units:%5 -> void
; p1 test(param:'Hello', 'World').
%6 = ptr.load %p1 : ptr -> #ivy.id
%7 = ivy.str.constant "Hello"
%8 = ivy.str.constant "World"
ivy.msg.send to %6, test(param:%7, _:%8) -> void
; i = 0.
%i = ptr.alloca i32 -> ptr
%9 = i32.constant 0
ptr.store %9, %i : i32, ptr
; while i < 100 do
scf.while -> void {
; i < 100
%10 = ptr.load %i : ptr -> i32
%11 = i32.constant 100
%cmptmp = ivy.cmp lt %10, %11 : (i32, i32) -> i1
scf.condition(%cmptmp)
} do {
; cout put:'Count is {i}'.
%12 = ivy.string-builder.begin
ivy.string-builder.add %12 << "Count is "
%14 = ptr.load %i : ptr -> i32
ivy.string-builder.add %12 << %14 : i32
%15 = ivy.string-builder.end %12 -> #ivy.id
%16 = ptr.load %cout : ptr -> #ivy.id
ivy.msg.send to %16, put:%15 -> void
; i += 2
%17 = ptr.load %i : ptr -> i32
%18 = i32.constant 2
%addtmp = ivy.add %17, %18 : (i32, i32) -> i32
ptr.store %addtmp, %i : i32, ptr
}
; 0 to:100 step:2
%19 = i32.constant 0
%20 = i32.constant 100
%21 = i32.constant 2
%22 = ivy.msg.send to %19, to:%20 step:%21 -> #ivy.id
; for x in 0 to:100 step:2 do
ivy.for %x in %22 -> void {
%23 = ivy.string-builder.begin
; 'Count is {x}'
ivy.string-builder.add %23 << "Count is "
ivy.string-builder.add %23 << %x : #ivy.id
%25 = ivy.string-builder.end %23 -> #ivy.id
; cout put:"Count is {x}"
%26 = ptr.load %cout : ptr -> #ivy.id
ivy.msg.send to %26, put:%25 -> void
}
; 0 to:100 step:2 do:...
%27 = i32.constant 0
%28 = i32.constant 100
%29 = i32.constant 2
; [ :i | cout put:'Count: {i}' ]
%30 = ivy.lambda %i : (#ivy.id) -> void {
%0 = ivy.string-builder.begin
ivy.string-builder.add %0 << "Count is "
ivy.string-builder.add %0 << %i : #ivy.id
%2 = ivy.string-builder.end %0 -> #ivy.id
%cout = ivy.global-ref @cout -> ptr
%3 = ptr.load %cout : ptr -> #ivy.id
ivy.msg.send to %3, put:%2 -> void
}
; 0 to:100 step:2 do:[ :i | cout put:'Count: {i}' ].
ivy.msg.send to %27, to:%28 step:%29 do:%30
; q = 32.
%q = ptr.alloca i32 -> ptr
%31 = i32.constant 32
ptr.store %31, %q : i32, ptr
; l = [ cout put:'Value of q is {q}' ].
%l = ptr.alloca #ivy.id
%32 = ptr.load %q : ptr -> i32
%33 = ivy.lambda (%env.q = %32) : () -> void {
%0 = ivy.string-builder.begin
ivy.string-builder.add %0 << "Value of q is "
ivy.string-builder.add %0 << %env.q : #ivy.id
%2 = ivy.string-builder.end %0 -> #ivy.id
%cout = ivy.global-ref @cout -> ptr
%3 = ptr.load %cout : ptr -> #ivy.id
ivy.msg.send to %3, put:%2 -> void
}
ptr.store %33, %l : #ivy.id, ptr
; q = 64.
%34 = i32.constant 64
ptr.store %34, %q : i32, ptr
; l call.
%35 = ptr.load %l : ptr -> #ivy.id
ivy.msg.send to %35, call -> void
%j = ptr.alloca i32 -> ptr
%36 = i32.constant 32
ptr.store %36, %j : i32, ptr
%37 = ptr.load %i : ptr -> i32
%38 = ptr.load %j : ptr -> i32
%cmptmp = arith.cmp lt %37, %38 : (i32, i32) -> i1
%39 = ivy.lambda : () -> void {
%cout = ivy.global-ref @cout -> ptr
%0 = ivy.str.constant "True!"
%1 = ptr.load %cout : ptr -> #ivy.id
ivy.msg.send to %1, put:%0 -> void
}
%40 = ivy.lambda : () -> void {
%cout = ivy.global-ref @cout -> ptr
%0 = ivy.str.constant "False!"
%1 = ptr.load %cout : ptr -> #ivy.id
ivy.msg.send to %1, put:%0 -> void
}
ivy.msg.send to %cmptmp, if:%39 else:%40 -> void
%41 = ptr.load %i : ptr -> i32
%42 = ptr.load %j : ptr -> i32
%cmptmp.0 = arith.cmp lt %41, %42 : (i32, i32) -> i1
scf.if %cmptmp.0 -> void {
%43 = ivy.str.constant "True!"
%44 = ptr.load %cout : ptr -> #ivy.id
ivy.msg.send to %44, put:%43 -> void
}
; pkg = {}.
%pkg = ptr.alloca #ivy.id -> ptr
%Package = ivy.global-ref @std.lang.Package -> ptr
%45 = ivy.msg.send to %Package, new -> #ivy.id
ptr.store %45, %pkg : #ivy.id, ptr
; pkg[0] = 16.
%46 = ptr.load %pkg : ptr -> #ivy.id
%47 = i32.constant 0
%48 = i32.constant 16
ivy.msg.send to %46, at:%47 put:%48 -> void
; tuple = (32, 'a string')
%tuple = ptr.alloca #ivy.id -> ptr
%49 = i32.constant 32
%50 = ivy.str.constant "a string"
%51 = ivy.tuple.create %49, %50 : (i32, #ivy.id) -> #ivy.id
ptr.store %51, %tuple : #ivy.id, ptr
%52 = ptr.load %tuple : ptr -> #ivy.id
%53 = ivy.msg.send to %52, get-iterator -> #ivy.id
ivy.for %54 in %53 -> void {
%key = ivy.tuple.get-item %54[0] : (#ivy.id, i32) -> #ivy.id
%val = ivy.tuple.get-item %54[1] : (#ivy.id, i32) -> #ivy.id
; '{key} -> {val}'
%55 = ivy.string-builder.begin
ivy.string-builder.add %55 << %key : #ivy.id
ivy.string-builder.add %55 << " -> "
ivy.string-builder.add %55 << %val : #ivy.id
%57 = ivy.string-builder.end %55 -> #ivy.id
; cout put:'{key} -> {val}'
%58 = ptr.load %cout : ptr -> #ivy.id
ivy.msg.send to %58, put:%57 -> void
}
; _ = 3 * 2.
%59 = i32.constant 3
%60 = i32.constant 2
%multmp = arith.mul %59, %60 : (i32, i32) -> i32
; a = (32, 64).
%a = ptr.alloca #ivy.id -> ptr
%61 = i32.constant 32
%62 = i32.constant 64
%63 = ivy.tuple.create %61, %62 : (i32, i32) -> #ivy.id
ptr.store %63, %a : #ivy.id, ptr
%v = ptr.alloca #ivy.id -> ptr
%64 = ptr.load %a : ptr -> #ivy.id
%65 = ivy.tuple.get-item %64[1] : #ivy.id -> #ivy.id
ptr.store %65, %v : #ivy.id, ptr
%66 = ivy.atom "err:number-format"
ivy.try -> void {
} catch (%ex = %66), %data {
} catch-all %ex, %data {
}
define id @_ZN3net9doorstuck4testC6PersonP15examplePropertyG(id %self) instance {
entry:
%0 = getelementptr class @_ZN33net9doorstuck4testC6PersonE, id %self, i32 #2
%1 = load id, ptr %0
ret id %1
%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
}
define void @_ZN3net9doorstuck4testC6PersonP15examplePropertyS(id %self, id %0) instance {
entry:
%1 = getelementptr class @_ZN33net9doorstuck4testC6PersonE, id %self, i32 #2
store id %0, ptr %1
ret void
%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
}
}

View 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 : ()
}
}

View 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 : ()
}
}

View 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 : ()
}
}

View 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 : ()
}
}

View 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 : ()
}
}

View File

@@ -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
}

View File

@@ -1,4 +1,4 @@
y = 1 + 2 * 3 / 4 * 5 - 6 + 7 multiply-by:2.
y = -1 + 2 * 3 / 4 * 5 - 6 + 7 multiply-by:2.
z = w = 2 + 3 multiply-by:2.
x = (((1 + 2 * 3) multiply-by:3) add: 5) + 2.
x = ((1 + 2 * 3) multiply-by:3).
@@ -13,7 +13,7 @@ m = xz multiply(by:3 add:2) squared.
m = xz multiply(by:3 add:2); squared.
x = OrderedCollection new
x = Ordered-Collection new
add: 2;
add: 4;
add: 6;
@@ -21,7 +21,7 @@ x = OrderedCollection new
age = Person new(name:"John Doe", age:34)
set-age:144 in-unit:"months";
ageInMonths.
age-in-months.
x = 5.
q = 10 if x > 2 else 20.

View File

@@ -1,31 +1,15 @@
data @cout = external global id
ivy.module @test {
%cout = ivy.global-ref @cout
data @.str.0 = str "hello"
ivy.init-text {
%str = ivy.str.constant "hello"
%.str.0 = ivy.str.constant "done"
define void @init() static {
entry:
%0 = load str, ptr @.str.0
%str = alloca id
store str %0, ptr %str
%1 = load id, ptr %str
%for.it = msg id, id %1, @_M8iteratorE
br label %for.cond
for.cond:
%for.value = msg id, id %for.it, @_M5valueE
%for.finished = cmp eq id %for.value, null
br i1 %for.finished, label %for.end, label %for.body
for.body:
%c = alloca id
store id %for.value, ptr %c
%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
ivy.for-each %c in %str {
ivy.msg to %cout, -put:%c
}
ivy.msg to %cout, -put:%.str.0
}
}

562
doc/sample/Person.2.im Normal file
View 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. */

View File

@@ -48,7 +48,6 @@ class Person
compatibility with lambdas.
**/
- init(name:name age:age)
var x.
self::name = name.
self::age = age!
@@ -80,7 +79,7 @@ class Person
_ => 0
end!
/* Properties are defined using the $ symbol.
/* Properties are defined using the -> symbol.
They accomplish two things:
1) they make it easy to synthesize the -get: and -put:at: messages
that the package dot syntax requires.
@@ -109,7 +108,7 @@ class Person
/* Without the lambda synthesis, the property would look like this:
Note that this is the only time it is legal to access private fields
via `self` from a lambda. */
-> example-property |
-> example-property-2 |
get => [ ^self::val ],
set => [ :x | self::val = x ].
@@ -119,23 +118,23 @@ class Person
If either the `set` or `get` elements are not provided, the property
becomes read-only or write-only respectively */
-> example-property-2 | get => 42.
-> example-property-3 | get => 42.
/* A property can also be configured to act just like a regular variable,
by setting the getter and setters to default implementations.
The default getter will return the value of a private member variable
named by prepending two underscores to the property name
(__exampleProperty3 in this case).
(__example-property-4 in this case).
Similarly, the default setter will set the value of a private member
variable named by prepending two underscores to the property name
(__exampleProperty3 in this case) to the value provided to the setter. */
-> example-property-3 (get, set)
(__example-property-4 in this case) to the value provided to the setter. */
-> example-property-4 (get, set)
/* Just like in the earlier examples, either `get` or `set` can be omitted
to create a write-only or read-only property respectively */
-> example-property-4 (get)
-> example-property-5 (get)
end
p1 = Person new(name:'John Doe', age:34).
@@ -151,8 +150,8 @@ while i < 100 do
i += 2
end
for i in 0 to:100 step:2 do
cout put:'Count is {i}'
for x in 0 to:100 step:2 do
cout put:'Count is {x}'
end
/**
@@ -223,11 +222,11 @@ pkg[0] = 16.
/* All of these accesses are equivalent */
pkg['x'] = 32.
pkg->x = 32.
pkg put:32 at:'x'.
pkg at:'x' put:32.
index = 'x'.
pkg[index] = 32.
pkg put:32 at:index.
pkg at:index put:32.
/**
this syntax, and the pkg.* instructions that it translates to, is
@@ -274,7 +273,7 @@ end
following criteria:
a) is an Iterator object; or
b) implements the Iterator protocol; or
c) understands the -iterator message, and returns an object that itself
c) understands the -get-iterator message, and returns an object that itself
conforms to a) or b)
**/
@@ -311,7 +310,7 @@ end
on:$err:number-format do:[ :err :data |
cout put:'Cannot parse integer string ({err})'
];
onError:[ :err :data |
on-error:[ :err :data |
cout put:'Error {err} occurred ({data})'
];
call.

View File

@@ -1,36 +1,9 @@
y = -1 + 2 * 3 / 4 * 5 - 6 + 7 multiply-by:2.
z = w = 2 + 3 multiply-by:2.
x = (((1 + 2 * 3) multiply-by:3) add: 5) + 2.
x = ((1 + 2 * 3) multiply-by:3).
p = 5 multiply(by:3, add:(2 + 1)).
q = 10 squared squared.
package net.doorstuck.test
p1
set-age:2 squared squared + 4 squared multiply(by:2, add:4 + 1 * 3)
in:"mon" + "ths".
use std.io
m = xz multiply(by:3 add:2) squared.
y = 32 * 64.
z = 64 / 4.
x = y + z.
m = xz multiply(by:3 add:2); squared.
x = Ordered-Collection new
add: 2;
add: 4;
add: 6;
yourself.
age = Person new(name:"John Doe", age:34)
set-age:144 in-unit:"months";
age-in-months.
x = 5.
q = 10 if x > 2 else 20.
q = if x > 2 then 10 else 20 end.
cout put:5 multiply(by:5, add:2) if x > 2.
if x > 2 then
cout put:"Greater"
else
cout put:"Less"
end
cout put:'Answer: {x}'

View File

@@ -1,6 +1,6 @@
package net.doorstuck.test
s1 = 'hello world'
s1 = 'hello world'.
s2 = s1 map:[ :c | ^c uppercase ]
s2 = s1 map:[ :c | ^c uppercase ].
s3 = s1 map:[ :c | ^((c ordinal) + 1) to-char ]

96
doc/sample/Sum.2.mie Normal file
View 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 : ()
}
}
}

View File

@@ -1,4 +1,9 @@
var x = 2 + 3.
var y = x.
var z.
var (x, y) = (3, 4).
x = 3.
y = 0.
if x > 10 then
y = 4
else
y = 2
end

View File

@@ -229,6 +229,9 @@ static b_result generate_mie_ir(struct compile_ctx *ctx)
static b_result build_block_isel_graph(
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);
while (entry) {
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);
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,
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);
}

View File

@@ -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 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 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 /\-[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-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*\n\)\@=/
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 ivyLineContinuation /\\\n/
" 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
" 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
syn match ivyBraces "[{}]" display
syn match ivyBrackets "[[\]]" 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 "=\{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 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 keyword ivyWordOperator is not understands and or
@@ -147,15 +158,14 @@ hi def link ivyStatement Statement
hi def link ivyRepeat Repeat
hi def link ivyConditional Conditional
hi def link ivySelectorLabel Tag
hi def link ivyUnnamedLabel @variable.builtin
hi def link ivyUnnamedVariable @variable.builtin
hi def link ivyUnnamedLabel Comment
hi def link ivyUnnamedVariable Comment
hi def link ivyLambdaParameter @variable.builtin
hi def link ivyException Exception
hi def link ivyParens Delimiter
hi def link ivyBraces Structure
hi def link ivyBrackets Define
hi def link ivyLambdaSymbols Define
hi def link ivyControlSymbols Keyword
hi def link ivyModifier StorageClass
hi def link ivyAccessModifier ivyModifier
@@ -176,6 +186,7 @@ hi def link ivyTypeOf ivyKeywordOperator
hi def link ivyTypeOfOperand Typedef
hi def link ivyTypeOfError Error
hi def link ivyOpSymbols Operator
hi def link ivyPackageAccessOperator Operator
hi def link ivyOtherSymbols Structure
hi def link ivyLogicSymbols Operator
hi def link ivyWordOperator Operator