Compare commits

..

15 Commits

Author SHA1 Message Date
9df79f90a6 meta: add clang-format config 2026-01-11 14:51:49 +00:00
c9c9cdf544 tool: add temporary parsing and ctx tests to validate subcommand 2026-01-11 14:51:37 +00:00
3253c4cac9 vim: add support for mach-registers, graph instructions, etc 2026-01-11 14:51:09 +00:00
fc61b188e3 doc: add more sample ir and graph files 2026-01-11 14:50:28 +00:00
6b5fd95ac4 mie: op: add data structure for op successors 2026-01-11 14:49:02 +00:00
700f7fe96e mie: add no-data status code 2026-01-11 14:48:45 +00:00
fdf46b8867 mie: add select dialect 2026-01-11 14:48:30 +00:00
417b5dc354 mie: builtin: add isolated-from-above trait 2026-01-11 14:38:28 +00:00
d42e02f04d mie: parse: implement parsing of regions, block, attributes, and values 2026-01-11 14:26:54 +00:00
6e55642a19 mie: arith: add support for querying the width of int/float types 2026-01-11 14:23:10 +00:00
0c84578f95 mie: add support for caching float values 2026-01-11 14:17:45 +00:00
4a0fcef862 mie: add support for adding traits to types and ops 2026-01-11 14:14:43 +00:00
79c83ef73c mie: id: add iteration support to mie_id_map 2026-01-11 14:03:51 +00:00
c6be143925 mie: trait: add function callback to perform trait-specific validation on an object 2026-01-08 22:26:32 +00:00
e76e7c17db mie: move op and type definition from dialect/ to ir/ and type/ respectively 2026-01-08 22:16:50 +00:00
80 changed files with 4262 additions and 752 deletions

174
.clang-format Normal file
View File

@@ -0,0 +1,174 @@
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
MacroBlockBegin: "MIE_.*_BEGIN"
MacroBlockEnd: "MIE_.*_END"
---
Language: Cpp
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: ObjC
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
MacroBlockBegin: "B_TYPE_.*_BEGIN"
MacroBlockEnd: "B_TYPE_.*_END"

View File

@@ -1,19 +0,0 @@
*func.func(%buffer, %lb, %ub, %step) ({
; Initial sum set to 0.
%sum.0 = *arith.constant() {value = 0.0 : f32} : () -> f32
; iter_args binds initial values to the loop's region arguments.
%sum = *scf.for(%lb, %ub, %step) -> (f32) {
^for.entry(%iv: index, %sum.iter: f32):
%t = *memref.load(%buffer, %iv) : (memref<1024*f32>, index) -> f32
%sum.next = *arith.addf(%sum.iter, %t) : (f32, f32) -> f32
; Yield current iteration sum to next iteration %sum.iter or to %sum
; if final iteration.
%iv.next = *arith.addi(%iv, %step) : (index, index) -> index
%stop = *arith.cmpi(%iv.next, %ub) {predicate = 9 : i64} : (index, index) -> i1
*cf.br-cond(%stop) [ ^for.end, ^for.entry:(%iv.next: index, %sum.next: f32) ] : () -> ()
}
^for.end:
*func.return(%sum) : (f32) -> ()
}) {sym_name = "reduce"} : (memref<1024*i32>, index, index, index) -> f32

View File

@@ -1,25 +0,0 @@
*func.func(%buffer, %lb, %ub, %step) ({
; Initial sum set to 0.
%sum.0 = *arith.constant() {value = 0.0 : f32} : () -> f32
; iter_args binds initial values to the loop's region arguments.
;%sum = "scf.for"(%lb, %ub, %step) -> (f32) {
*cf.br [ ^for.entry(%lb: index, %sum.0: f32) ] : () -> ()
^for.entry(%iv: index, %sum.iter: f32):
%t = *memref.load(%buffer, %iv) : (memref<1024*f32>, index) -> f32
%sum.next = *arith.addf(%sum.iter, %t) : (f32, f32) -> f32
*cf.br [ ^for.cond:(%iv: index, %sum.next: f32) ] : () -> ()
^for.cond(%iv: index, %sum.next: f32):
; Yield current iteration sum to next iteration %sum.iter or to %sum
; if final iteration.
%iv.next = *arith.addi(%iv, %step) : (index, index) -> index
%stop = *arith.cmpi(%iv.next, %ub) {predicate = 9 : i64} : (index, index) -> i1
*cf.br-cond(%stop) [ ^for.end, ^for.entry:(%iv.next: index, %sum.next: f32) ] : () -> ()
^for.end(%sum: f32):
*func.return(%sum) : (f32) -> ()
}) {sym_name = "reduce"} : (memref<1024*f32.abc>, index, index, index) -> f32

38
doc/sample/graph/1.mie Normal file
View File

@@ -0,0 +1,38 @@
select.graph {
%entry = +select.entry -> #select.chain
%0 = +select.register @0 : i32 -> #select.register
%1 = +select.register @1 : i32 -> #select.register
%v.0, %c.0 = +select.register.read %entry, %0 \
: (#select.chain, #select.register) \
-> (i32, #select.chain)
%v.1, %c.1 = +select.register.read %entry, %1 \
: (#select.chain, #select.register) \
-> (i32, #select.chain)
%2 = +select.register @2 : i32
%v.2, %c.2 = +select.register.read %entry, %2 \
: (#select.chain, #select.register) \
-> (#select.register, #select.chain)
%v.3 = arith.build-pair %v.0, %v.1 : (i32, i32) -> i64
%v.4 = arith.truncate %v.2 : i64 -> i32
%v.5 = arith.mul %v.4, %v.3 : (i32, i32) -> i32
%x0 = +select.mach-register @x0 : i32 -> #select.register
%c.3, %g.0 = +select.register.write %entry, %x0, %v.5 \
: (#select.chain, #select.register, i32) \
-> (#select.chain, #select.glue)
%c.4 = *risc-v.RET %c.3, %x0, %g.0 \
: (#select.chain, #select.register, #select.glue) \
-> #select.chain
+select.graph-root %c.4 : #select.chain
}

33
doc/sample/graph/2.mie Normal file
View File

@@ -0,0 +1,33 @@
select.graph {
%entry = +select.entry -> #select.chain
%N1 = ptr.alloca i32 -> ptr
%N2 = i32.constant 3 -> i32
%N3.c = +ptr.store %entry, %N2, %N1 : (#select.chain, i32, ptr) -> #select.chain
%N4 = ptr.alloca i32 -> ptr
%N5 = i32.constant 0 -> i32
%N6.c = +ptr.store %entry, %N5, %N4 : (#select.chain, i32, ptr) -> #select.chain
%N7, %N7.c = +ptr.load %N6.c, %N1 : (#select.chain, ptr) -> (#ivy.id, #select.chain)
%N8 = i32.constant 10 -> i32
%N9 = arith.cmp gt %N7, %N8 : (#ivy.id, i32) -> i1
%N10.c = +select.chain-group %N7.c, %N6.c : (#select.chain, #select.chain) -> #select.chain
%N11 = +select.block-ref @if.true -> #select.block
%N12.c = +cf.br-cond %N10.c, %N9, %N11 : (#select.chain, i1, #select.block) -> #select.chain
%N13 = +select.block-ref @if.false -> #select.block
%N14.c = cf.br %N12.c, %N13
%N15 = +select.root %N14.c
}

530
doc/sample/ir/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/sample/ir/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
}
}

460
doc/sample/ir/Person.mie Normal file
View File

@@ -0,0 +1,460 @@
meta.source-filename "Person.im"
ivy.package-scope "net.doorstuck.test"
ivy.package-ref "std.io"
ivy.module {
%cout = ivy.global-ref @cout -> 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
ivy.msgh.object init(name:%name, age:%age) -> void {
ptr.store %name, %self.name : #ivy.id, ptr
ptr.store %age, %self.age : #ivy.id, ptr
func.return : ()
}
ivy.msgh.object test(param:%data, _:%extra) -> void {
%0 = ivy.string-builder.begin
ivy.string-builder.add %0 << "Received "
ivy.string-builder.add %0 << %data : #ivy.id
ivy.string-builder.add %0 << ", "
ivy.string-builder.add %0 << %extra : #ivy.id
%1 = ivy.string-builder.end %0 -> #ivy.id
%2 = ptr.load %cout : ptr -> #ivy.id
ivy.msg.send to %2, put:%1 -> void
func.return : ()
}
ivy.msgh.object name -> #ivy.id {
%0 = ptr.load %self.name : ptr -> #ivy.id
func.return %0 : #ivy.id
}
ivy.msgh.object age -> #ivy.id {
%0 = ptr.load %self.age : ptr -> #ivy.id
func.return %0 : #ivy.id
}
ivy.msgh.object age-in-months -> #ivy.id {
%0 = ptr.load %self.age : ptr -> #ivy.id
%1 = arith.constant 12 : i32
%multmp = ivy.mul %0, %1 : (#ivy.id, i32) -> #ivy.id
func.return %multmp : #ivy.id
}
ivy.msgh.object set-name:%name -> void {
ptr.store %name, %self.name : #ivy.id, ptr
func.return : ()
}
ivy.msgh.object set-age:%age -> void {
ptr.store %age, %self.age : #ivy.id, ptr
func.return : ()
}
ivy.msgh.object set-age:%age in-units:%units -> void {
scf.switch : () -> void
case {
%0 = ivy.atom "years"
%cmptmp.0 = ivy.cmp eq %age, %0 : (#ivy.id, #ivy.atom) -> i1
scf.switch-condition %cmptmp.0
} then {
ptr.store %age, %self.age : #ivy.id, ptr
scf.switch-break : ()
} case {
%1 = ivy.atom "months"
%cmptmp.1 = ivy.cmp eq %age, %1 : (#ivy.id, #ivy.atom) -> i1
scf.condition %cmptmp.1
} then {
%d0 = arith.constant 12 : i32
%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 = arith.constant 365 : i32
%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 = arith.constant 0 : i32
scf.switch-break : ()
}
func.return : ()
}
ivy.msgh.object get-age-in-units:%units -> #ivy.id {
%result = scf.switch : () -> #ivy.id
case {
%0 = ivy.atom "years"
%cmptmp.0 = ivy.cmp eq %age, %0 : (#ivy.id, #ivy.atom) -> i1
scf.switch-condition %cmptmp.0
} then {
%v0 = ptr.load %self.age : ptr -> #ivy.id
scf.switch-break %v0 : #ivy.id
} case {
%1 = ivy.atom "months"
%cmptmp.1 = ivy.cmp eq %age, %1 : (#ivy.id, #ivy.atom) -> i1
scf.condition %cmptmp.1
} then {
%v0 = ptr.load %self.age : ptr -> #ivy.id
%d0 = arith.constant 12 : i32
%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 = arith.constant 365 : i32
%divtmp.1 = ivy.div %v1, %d1 : (#ivy.id, i32) -> #ivy.id
scf.switch-break %divtmp.1 : #ivy.id
} default {
%d2 = arith.constant 0 : i32
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 = arith.constant 42 : i32
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 = arith.constant 34 : i32
%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 = arith.constant 100 : i32
%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 = arith.constant 0 : i32
ptr.store %9, %i : i32, ptr
; while i < 100 do
scf.while -> void {
; i < 100
%10 = ptr.load %i : ptr -> i32
%11 = arith.constant 100 : i32
%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 = arith.constant 2 : i32
%addtmp = ivy.add %17, %18 : (i32, i32) -> i32
ptr.store %addtmp, %i : i32, ptr
}
; 0 to:100 step:2
%19 = arith.constant 0 : i32
%20 = arith.constant 100 : i32
%21 = arith.constant 2 : i32
%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 = arith.constant 0 : i32
%28 = arith.constant 100 : i32
%29 = arith.constant 2 : i32
; [ :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 = arith.constant 32 : i32
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 = arith.constant 64 : i32
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 = arith.constant 32 : i32
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 = arith.constant 0 : i32
%48 = arith.constant 16 : i32
ivy.msg.send to %46, at:%47 put:%48 -> void
; tuple = (32, 'a string')
%tuple = ptr.alloca #ivy.id -> ptr
%49 = arith.constant 32 : i32
%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 = arith.constant 3 : i32
%60 = arith.constant 2 : i32
%multmp = arith.mul %59, %60 : (i32, i32) -> i32
; a = (32, 64).
%a = ptr.alloca #ivy.id -> ptr
%61 = arith.constant 32 : i32
%62 = arith.constant 64 : i32
%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
}
}

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,6 +1,7 @@
; Comment
func.func @reduce(%buffer: memref<1024*f32>, %lb: index, %ub: index, %step: index) -> f32 {
; Initial sum set to 0.
%sum.0 = arith.constant 0.0 : f32
%sum.0 = f32.constant 0.0
; iter_args binds initial values to the loop's region arguments.
%sum = scf.for %iv = %lb to %ub step %step iter-args(%sum.iter = %sum.0) -> (f32) {
%t = memref.load %buffer[%iv] : memref<1024*f32>

View File

@@ -1,6 +1,6 @@
func.func @reduce(%buffer: memref<1024*f32>, %lb: index, %ub: index, %step: index) -> f32 {
; Initial sum set to 0.
%sum.0 = *arith.constant() {value = 0.0 : f32} : () -> f32
%sum.0 = *f32.constant() {value = 0.0 : f32} : () -> f32
; iter_args binds initial values to the loop's region arguments.
%sum = scf.for %iv = %lb to %ub step %step iter_args(%sum.iter = %sum.0) -> (f32) {

View File

@@ -0,0 +1,20 @@
~func.func() ({
^entry(%buffer: memref<1024*f32>, %lb: index, %ub: index, %step: index):
; Initial sum set to 0.
%sum.0 = ~f32.constant() {value = 0.0 : f32} : () -> f32
; iter_args binds initial values to the loop's region arguments.
%sum = ~scf.for(%lb, %ub, %step) -> (f32) {
^for.entry(%iv: index, %sum.iter: f32):
%t = ~memref.load(%buffer, %iv) : (memref<1024*f32>, index) -> f32
%sum.next = Zarith.addf(%sum.iter, %t) : (f32, f32) -> f32
; Yield current iteration sum to next iteration %sum.iter or to %sum
; if final iteration.
%iv.next = ~arith.addi(%iv, %step) : (index, index) -> index
%stop = ~arith.cmpi(%iv.next, %ub) {predicate = 9 : i64} : (index, index) -> i1
~cf.br-cond(%stop) [ ^for.end, ^for.entry:(%iv.next: index, %sum.next: f32) ] : () -> ()
}
^for.end:
~func.return(%sum) : (f32) -> ()
}) {sym_name = "reduce"} : (memref<1024*i32>, index, index, index) -> f32

View File

@@ -0,0 +1,25 @@
~func.func() ({
^entry(%buffer: memref<1024*f32>, %lb: index, %ub: index, %step: index):
; Initial sum set to 0.
%sum.0 = ~f32.constant() {value = 0.0 : f32} : () -> f32
; iter_args binds initial values to the loop's region arguments.
;%sum = "scf.for"(%lb, %ub, %step) -> (f32) {
~cf.br [ ^for.entry(%lb: index, %sum.0: f32) ] : () -> ()
^for.entry(%iv: index, %sum.iter: f32):
%t = ~memref.load(%buffer, %iv) : (memref<1024*f32>, index) -> f32
%sum.next = ~arith.addf(%sum.iter, %t) : (f32, f32) -> f32
~cf.br [ ^for.cond:(%iv: index, %sum.next: f32) ] : () -> ()
^for.cond(%iv: index, %sum.next: f32):
; Yield current iteration sum to next iteration %sum.iter or to %sum
; if final iteration.
%iv.next = ~arith.addi(%iv, %step) : (index, index) -> index
%stop = ~arith.cmpi(%iv.next, %ub) {predicate = 9 : i64} : (index, index) -> i1
~cf.br-cond(%stop) [ ^for.end, ^for.entry:(%iv.next: index, %sum.next: f32) ] : () -> ()
^for.end(%sum: f32):
~func.return(%sum) : (f32) -> ()
}) {sym_name = "reduce"} : (memref<1024*f32>, index, index, index) -> f32

View File

@@ -0,0 +1,14 @@
+graph.name \
%vreg.name
$mreg.name
^block.name
#type.name
@symbol.name
abc.def
21.5
"a String"
index
memref
1024*f32
: = , - * + % $ ^ # @ { } [ ] ( ) < > ->
abc

View File

@@ -0,0 +1,6 @@
%1, %reg.2, $X0 = ~scf.for(%a, %b) ({
^b0:
~arith.constant() : () -> ()
^b1:
~arith.constant() : () -> ()
}) {test_attrib = 2 : i32 } : (i8, i1) -> (i32, i32, i32)

View File

@@ -5,41 +5,51 @@ endif
let s:save_cpo = &cpoptions
set cpoptions&vim
setlocal iskeyword+=-
setlocal shiftwidth=4
setlocal tabstop=4
syn keyword mieUnspecifiedKeyword to step iter-args
syn keyword mieUnspecifiedKeyword
\ to step iter-args get set
\ case then default
syn keyword mieInstructionFlag
\ eq gt ge lt le
syn match mieRegister "%[0-9]\>"
syn match mieRegister "%[1-9][0-9]\+\>"
syn match mieRegister "%[A-Za-z_\-\.][A-Za-z0-9_\-\.]*\>"
syn match mieMachineRegister "$[0-9]\>"
syn match mieMachineRegister "$[1-9][0-9]\+\>"
syn match mieMachineRegister "$[A-Za-z_\-\.][A-Za-z0-9_\-\.]*\>"
syn match mieIdentifier /@\(\w\+\)\(\.\(\w\+\)\)*\>/
syn match mieIdentifier /@\.\(\w\+\)\(\.\(\w\+\)\)*\>/
syn match mieBlockIdentifier /\^\(\w\+\)\(\.\(\w\+\)\)*/
syn match mieBlockLabel /\^\(\w\+\)\(\.\(\w\+\)\)*\:/
syn keyword mieBuiltinType void index
syn keyword mieBuiltinType f16 f32 f64 f80 f128
syn keyword mieBuiltinType void
" Use syn match for type names that are ALSO dialect names, to ensure that
" dialect operations are still matched as such.
syn match mieBuiltinType /\<memref\>/
syn match mieBuiltinType "i[0-9]\>"
syn match mieBuiltinType "i[1-9][0-9]\+\>"
syn match mieBuiltinType /\<ptr\>/
syn match mieBuiltinType /\<index\>/
syn match mieBuiltinType "\<[if][0-9]\>"
syn match mieBuiltinType "\<[if][1-9][0-9]\+\>"
syn match mieDialectType /#[A-Za-z][A-Za-z0-9\-]*\(\.[A-Za-z][A-Za-z0-9\-]*\)\+/
syn match mieInstruction /\*[A-Za-z][A-Za-z0-9\-]*\(\.[A-Za-z][A-Za-z0-9\-]*\)\+\([>\*]\)\@!\>/
syn match mieGenericOperation /\~[A-Za-z][A-Za-z0-9\-]*\(\.[A-Za-z][A-Za-z0-9\-]*\)\+\([>\*]\)\@!\>/
syn match mieGraphOperation /+[A-Za-z][A-Za-z0-9\-]*\(\.[A-Za-z][A-Za-z0-9\-]*\)\+\([>\*]\)\@!\>/
syn match mieCustomOperation /\<[A-Za-z][A-Za-z0-9\-]*\(\.[A-Za-z][A-Za-z0-9\-]*\)\+\>/
syn match mieGenericOperation /\*[A-Za-z][A-Za-z0-9\-]*\(\.[A-Za-z][A-Za-z0-9\-]*\)\+\([>\*]\)\@!\>/
syn match mieAttributeName /\<[A-Za-z][A-Za-z0-9\-_\.]*\(\s*=\)\@=\>/
syn region mieString start=+"+ end=+"\%(u8\)\=+ end=+$+ extend
syn match mieFloat /[0-9]\+\.[0-9]\+/
syn match mieFloat /-[0-9]\+\.[0-9]\+/
syn match mieFloat /+[0-9]\+\.[0-9]\+/
syn match mieFloat /\<[0-9]\+\.[0-9]\+/
syn match mieFloat /\<-[0-9]\+\.[0-9]\+/
syn match mieFloat /\<+[0-9]\+\.[0-9]\+/
syn match mieInteger /[0-9]\+\(\.\)\@!\>/
syn match mieInteger /-[0-9]\+\(\.\)\@!\>/
syn match mieInteger /0x[:xdigit:]\+\>/
syn match mieInteger /-0x[:xdigit:]\+\>/
syn match mieInteger /\<[0-9]\+\(\.\)\@!\>/
syn match mieInteger /\<-[0-9]\+\(\.\)\@!\>/
syn match mieInteger /\<0x[:xdigit:]\+\>/
syn match mieInteger /\<-0x[:xdigit:]\+\>/
syn match mieIntegerDimension /[0-9]\+x/
syn match mieIntegerDimension /0x[:xdigit:]\+x/
@@ -55,12 +65,9 @@ syn match mieBraces "[{}]" display
syn match mieAngleBrackets "[<>]" display
syn match mieOperator "[=:]" display
syn match mieOperator "->" display
syn match ivyPropertySymbol "\$" display
" The default highlighting.
hi def link mieUnspecifiedKeyword Keyword
hi def link ivyPropertySymbol Statement
hi def link mieInteger Number
hi def link mieFloat Number
@@ -72,12 +79,15 @@ hi def link mieAngleBrackets StorageClass
hi def link mieDialectType Type
hi def link mieGenericOperation @function.builtin
hi def link mieGraphOperation Statement
hi def link mieCustomOperation Function
hi def link mieInstruction @attribute
hi def link mieInstructionFlag StorageClass
hi def link mieIdentifier Identifier
hi def link mieBlockIdentifier Label
hi def link mieBlockLabel Label
hi def link mieRegister @variable
hi def link mieRegister @variable.parameter
hi def link mieMachineRegister @variable.builtin
hi def link mieString String
hi def link mieBuiltinType @type.builtin

372
mie/ctx.c
View File

@@ -7,10 +7,12 @@
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
#include <mie/dialect/index.h>
#include <mie/dialect/type.h>
#include <mie/ir/op.h>
#include <mie/trait/trait-definition.h>
#include <mie/trait/trait.h>
#include <mie/type/function.h>
#include <mie/type/storage.h>
#include <mie/type/type-definition.h>
#include <mie/type/type.h>
#include <stdlib.h>
#include <string.h>
@@ -23,285 +25,6 @@
MIE_ID(0xf5, 0x4e, 0xc5, 0x8c, 0xc0, 0x1e, 0x48, 0x47, 0xb5, 0xf4, \
0x7b, 0xb9, 0x6b, 0x47, 0xca, 0x48)
struct ctx_int_cache_entry {
b_btree_node i_node;
// struct mie_type i_type;
b_btree i_values;
};
struct ctx_int_value_cache_entry {
b_btree_node i_node;
// struct mie_int i_value;
};
#if 0
B_BTREE_DEFINE_SIMPLE_INSERT(
struct ctx_int_cache_entry, i_node, i_type.t_width, put_cached_int_type)
B_BTREE_DEFINE_SIMPLE_GET(
struct ctx_int_cache_entry, unsigned int, i_node, i_type.t_width,
get_cached_int_type)
B_BTREE_DEFINE_SIMPLE_INSERT(
struct ctx_int_value_cache_entry, i_node, i_value.i_value,
put_cached_int_value)
B_BTREE_DEFINE_SIMPLE_GET(
struct ctx_int_value_cache_entry, int64_t, i_node, i_value.i_value,
get_cached_int_value)
struct mie_ctx *mie_ctx_create(void)
{
struct mie_ctx *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
memset(out, 0x0, sizeof *out);
out->ctx_true = MIE_CONST(mie_ctx_get_int(out, 1, 1));
out->ctx_false = MIE_CONST(mie_ctx_get_int(out, 0, 1));
out->ctx_null = malloc(sizeof *out->ctx_null);
if (!out->ctx_null) {
mie_ctx_destroy(out);
return NULL;
}
mie_value_init(out->ctx_null, MIE_VALUE_NONE);
out->ctx_sel_cache = b_hashmap_create(free, free);
out->ctx_string_cache = b_hashmap_create(free, free);
return out;
}
void mie_ctx_destroy(struct mie_ctx *ctx)
{
ctx->ctx_true = NULL;
ctx->ctx_false = NULL;
b_btree_node *node = b_btree_first(&ctx->ctx_int_cache);
while (node) {
struct ctx_int_cache_entry *entry
= b_unbox(struct ctx_int_cache_entry, node, i_node);
b_btree_node *next = b_btree_next(node);
b_btree_delete(&ctx->ctx_int_cache, node);
b_btree_node *node2 = b_btree_first(&entry->i_values);
while (node2) {
struct ctx_int_value_cache_entry *value = b_unbox(
struct ctx_int_value_cache_entry, node2, i_node);
b_btree_node *next2 = b_btree_next(node2);
b_btree_delete(&entry->i_values, node2);
free(value);
node2 = next2;
}
free(entry);
node = next;
}
const size_t nr_types = sizeof ctx->ctx_types / sizeof ctx->ctx_types[0];
for (size_t i = 0; i < nr_types; i++) {
if (ctx->ctx_types[i]) {
mie_value_destroy(MIE_VALUE(ctx->ctx_types[i]));
ctx->ctx_types[i] = NULL;
}
}
if (ctx->ctx_null) {
mie_value_destroy(ctx->ctx_null);
}
b_hashmap_unref(ctx->ctx_sel_cache);
free(ctx);
}
struct mie_type *mie_ctx_get_type(struct mie_ctx *ctx, enum mie_type_id type_id)
{
if (type_id == MIE_TYPE_INT) {
return NULL;
}
if (ctx->ctx_types[type_id]) {
return ctx->ctx_types[type_id];
}
struct mie_type *type = mie_type_create();
if (!type) {
return NULL;
}
type->t_id = type_id;
ctx->ctx_types[type_id] = type;
return type;
}
struct mie_value *mie_ctx_get_null(struct mie_ctx *ctx)
{
return ctx->ctx_null;
}
struct mie_type *mie_ctx_get_int_type(struct mie_ctx *ctx, unsigned int nr_bits)
{
struct ctx_int_cache_entry *entry
= get_cached_int_type(&ctx->ctx_int_cache, nr_bits);
if (entry) {
return &entry->i_type;
}
entry = malloc(sizeof *entry);
if (!entry) {
return NULL;
}
memset(entry, 0x0, sizeof *entry);
entry->i_type.t_id = MIE_TYPE_INT;
entry->i_type.t_width = nr_bits;
put_cached_int_type(&ctx->ctx_int_cache, entry);
return &entry->i_type;
}
struct mie_value *mie_ctx_get_bool(struct mie_ctx *ctx, bool val)
{
return MIE_VALUE(val ? ctx->ctx_true : ctx->ctx_false);
}
struct mie_value *mie_ctx_get_int(
struct mie_ctx *ctx, long long val, unsigned int nr_bits)
{
struct ctx_int_cache_entry *entry
= get_cached_int_type(&ctx->ctx_int_cache, nr_bits);
if (!entry) {
entry = malloc(sizeof *entry);
if (!entry) {
return NULL;
}
memset(entry, 0x0, sizeof *entry);
entry->i_type.t_id = MIE_TYPE_INT;
entry->i_type.t_width = nr_bits;
put_cached_int_type(&ctx->ctx_int_cache, entry);
}
struct ctx_int_value_cache_entry *value
= get_cached_int_value(&entry->i_values, val);
if (value) {
return MIE_VALUE(&value->i_value);
}
value = malloc(sizeof *value);
if (!value) {
return NULL;
}
memset(value, 0x0, sizeof *value);
mie_const_init(&value->i_value.i_base, &entry->i_type);
value->i_value.i_value = val;
put_cached_int_value(&entry->i_values, value);
return MIE_VALUE(&value->i_value);
}
struct mie_value *mie_ctx_get_selector(struct mie_ctx *ctx, const char *sel)
{
b_hashmap_key key = {
.key_data = sel,
.key_size = strlen(sel),
};
const b_hashmap_value *cache_entry
= b_hashmap_get(ctx->ctx_sel_cache, &key);
if (cache_entry) {
return cache_entry->value_data;
}
struct mie_selector *sel_value = malloc(sizeof *sel_value);
if (!sel_value) {
return NULL;
}
struct mie_type *sel_type = mie_ctx_get_type(ctx, MIE_TYPE_SELECTOR);
mie_const_init(&sel_value->sel_base, sel_type);
sel_value->sel_value = b_strdup(sel);
key.key_data = sel_value->sel_value;
b_hashmap_value hashmap_value = {
.value_data = sel_value,
.value_size = sizeof *sel_value,
};
b_hashmap_put(ctx->ctx_sel_cache, &key, &hashmap_value);
return MIE_VALUE(sel_value);
}
struct mie_value *mie_ctx_get_string(struct mie_ctx *ctx, const char *s)
{
b_hashmap_key key = {
.key_data = s,
.key_size = strlen(s),
};
const b_hashmap_value *cache_entry
= b_hashmap_get(ctx->ctx_string_cache, &key);
if (cache_entry) {
return cache_entry->value_data;
}
struct mie_string *string_value = malloc(sizeof *string_value);
if (!string_value) {
return NULL;
}
struct mie_type *string_type = mie_ctx_get_type(ctx, MIE_TYPE_STR);
mie_const_init(&string_value->s_base, string_type);
string_value->s_value = b_strdup(s);
key.key_data = string_value->s_value;
b_hashmap_value hashmap_value = {
.value_data = string_value,
.value_size = sizeof *string_value,
};
b_hashmap_put(ctx->ctx_string_cache, &key, &hashmap_value);
return MIE_VALUE(string_value);
}
struct mie_value *mie_ctx_create_array(struct mie_ctx *ctx)
{
struct mie_type *array_type = mie_ctx_get_type(ctx, MIE_TYPE_ARRAY);
struct mie_array *array = malloc(sizeof *array);
if (!array) {
return NULL;
}
memset(array, 0x0, sizeof *array);
mie_const_init(&array->a_base, array_type);
array->a_values = b_list_create();
return MIE_VALUE(array);
}
#endif
struct mie_ctx *mie_ctx_create(void)
{
struct mie_ctx *out = malloc(sizeof *out);
@@ -319,6 +42,7 @@ struct mie_ctx *mie_ctx_create(void)
mie_id_map_init(&out->ctx_types, &types_ns);
out->ctx_ints = mie_int_cache_create();
out->ctx_floats = mie_float_cache_create();
out->ctx_indices = mie_index_cache_create();
out->ctx_strings = mie_string_cache_create();
@@ -328,7 +52,7 @@ struct mie_ctx *mie_ctx_create(void)
bool mie_ctx_resolve_op(const struct mie_ctx *ctx, struct mie_op *op)
{
bool fully_resolved = MIE_TEST_FLAGS(
op->op_flags, MIE_OP_F_OP_RESOLVED | MIE_OP_F_ARGS_RESOLVED);
op->op_flags, MIE_OP_F_OP_RESOLVED | MIE_OP_F_ARG_RESOLVED);
if (fully_resolved) {
return true;
@@ -358,7 +82,7 @@ bool mie_ctx_resolve_op(const struct mie_ctx *ctx, struct mie_op *op)
return false;
}
const struct mie_dialect_op *op_info
const struct mie_op_definition *op_info
= mie_dialect_get_op(dialect, op_name);
if (!op) {
return false;
@@ -385,7 +109,7 @@ struct mie_dialect *mie_ctx_get_dialect(const struct mie_ctx *ctx, const char *n
return b_unbox(struct mie_dialect, target, d_id);
}
struct mie_dialect_type *mie_ctx_get_dialect_type(
struct mie_type_definition *mie_ctx_get_type_definition(
const struct mie_ctx *ctx, const char *dialect_name, const char *type_name)
{
b_rope dialect_name_rope = B_ROPE_CSTR(dialect_name);
@@ -403,14 +127,35 @@ struct mie_dialect_type *mie_ctx_get_dialect_type(
mie_id_init_ns(&id, mie_id_map_get_ns(&dialect->d_types), &type_name_rope);
target = mie_id_map_get(&dialect->d_types, &id);
return b_unbox(struct mie_dialect_type, target, ty_id);
return b_unbox(struct mie_type_definition, target, ty_id);
}
const struct mie_trait_definition *mie_ctx_get_trait_definition(
const struct mie_ctx *ctx, const char *dialect_name, const char *trait_name)
{
b_rope dialect_name_rope = B_ROPE_CSTR(dialect_name);
mie_id id;
mie_id_init_ns(
&id, mie_id_map_get_ns(&ctx->ctx_dialects), &dialect_name_rope);
mie_id *target = mie_id_map_get(&ctx->ctx_dialects, &id);
struct mie_dialect *dialect = b_unbox(struct mie_dialect, target, d_id);
if (!dialect) {
return NULL;
}
b_rope trait_name_rope = B_ROPE_CSTR(trait_name);
mie_id_init_ns(&id, mie_id_map_get_ns(&dialect->d_traits), &trait_name_rope);
target = mie_id_map_get(&dialect->d_traits, &id);
return b_unbox(struct mie_trait_definition, target, tr_id);
}
struct mie_type *mie_ctx_get_type(
struct mie_ctx *ctx, const char *dialect_name, const char *type_name)
{
char full_name[256];
snprintf(full_name, sizeof full_name, "%s.%s", dialect_name, dialect_name);
snprintf(full_name, sizeof full_name, "%s.%s", dialect_name, type_name);
b_rope full_name_rope = B_ROPE_CSTR(full_name);
mie_id id;
@@ -422,8 +167,8 @@ struct mie_type *mie_ctx_get_type(
return type;
}
struct mie_dialect_type *type_info
= mie_ctx_get_dialect_type(ctx, dialect_name, type_name);
struct mie_type_definition *type_info
= mie_ctx_get_type_definition(ctx, dialect_name, type_name);
if (!type_info /* || (type_info->ty_flags & MIE_DIALECT_TYPE_PARAMETISED) */) {
/* cannot initialise unknown or parametised types */
return NULL;
@@ -453,6 +198,53 @@ struct mie_type *mie_ctx_get_type(
return type;
}
const struct mie_trait *mie_ctx_get_trait(
struct mie_ctx *ctx, const char *dialect_name, const char *trait_name)
{
char full_name[256];
snprintf(full_name, sizeof full_name, "%s.%s", dialect_name, trait_name);
b_rope full_name_rope = B_ROPE_CSTR(full_name);
mie_id id;
mie_id_init_ns(&id, mie_id_map_get_ns(&ctx->ctx_traits), &full_name_rope);
mie_id *target = mie_id_map_get(&ctx->ctx_traits, &id);
struct mie_trait *trait = b_unbox(struct mie_trait, target, tr_id);
if (trait) {
return trait;
}
const struct mie_trait_definition *trait_info
= mie_ctx_get_trait_definition(ctx, dialect_name, trait_name);
if (!trait_info /* || (trait_info->ty_flags & MIE_DIALECT_TYPE_PARAMETISED) */) {
/* cannot initialise unknown or parametised traits */
return NULL;
}
if (trait_info->tr_data_size < sizeof(struct mie_trait)) {
/* invalid trait info */
return NULL;
}
trait = malloc(trait_info->tr_data_size);
if (!trait) {
return NULL;
}
memset(trait, 0x0, sizeof *trait);
trait->tr_def = trait_info;
trait->tr_name = b_bstr_fmt("%s.%s", dialect_name, trait_name);
if (trait_info->tr_init) {
trait_info->tr_init(trait_info, trait);
}
mie_id_map_put(&ctx->ctx_traits, &trait->tr_id, &full_name_rope);
return trait;
}
struct mie_type *mie_ctx_get_storage_type(
struct mie_ctx *ctx, const struct mie_type **parts, size_t nr_parts)
{
@@ -514,6 +306,12 @@ struct mie_value *mie_ctx_get_int(struct mie_ctx *ctx, long long val, size_t nr_
ctx->ctx_ints, ctx, val, nr_bits);
}
struct mie_value *mie_ctx_get_float(struct mie_ctx *ctx, double val, size_t nr_bits)
{
return (struct mie_value *)mie_float_cache_get(
ctx->ctx_floats, ctx, val, nr_bits);
}
struct mie_value *mie_ctx_get_string(struct mie_ctx *ctx, const char *s)
{
return (struct mie_value *)mie_string_cache_get(ctx->ctx_strings, ctx, s);

View File

@@ -1,5 +1,5 @@
#include <mie/dialect/dialect.h>
#include <mie/dialect/op.h>
#include <mie/ir/op-definition.h>
#include <mie/macros.h>
static enum mie_status print(const struct mie_op *op, b_stream *out)
@@ -12,7 +12,7 @@ static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
return MIE_SUCCESS;
}
MIE_DIALECT_OP_BEGIN(mie_arith_addf, "addf")
MIE_DIALECT_OP_PRINT(print);
MIE_DIALECT_OP_PARSE(parse);
MIE_DIALECT_OP_END()
MIE_OP_DEFINITION_BEGIN(mie_arith_addf, "addf")
MIE_OP_DEFINITION_PRINT(print);
MIE_OP_DEFINITION_PARSE(parse);
MIE_OP_DEFINITION_END()

View File

@@ -1,5 +1,5 @@
#include <mie/dialect/dialect.h>
#include <mie/dialect/op.h>
#include <mie/ir/op-definition.h>
#include <mie/macros.h>
static enum mie_status print(const struct mie_op *op, b_stream *out)
@@ -12,7 +12,7 @@ static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
return MIE_SUCCESS;
}
MIE_DIALECT_OP_BEGIN(mie_arith_addi, "addi")
MIE_DIALECT_OP_PRINT(print);
MIE_DIALECT_OP_PARSE(parse);
MIE_DIALECT_OP_END()
MIE_OP_DEFINITION_BEGIN(mie_arith_addi, "addi")
MIE_OP_DEFINITION_PRINT(print);
MIE_OP_DEFINITION_PARSE(parse);
MIE_OP_DEFINITION_END()

View File

@@ -0,0 +1,215 @@
#include <blue/core/btree.h>
#include <mie/dialect/arith.h>
#include <stdlib.h>
#include <string.h>
typedef union float_key {
double f;
unsigned char i[sizeof(double)];
} float_key;
struct float_width_cache_entry {
b_btree_node e_node;
float_key e_key;
struct mie_float e_value;
};
struct float_width_cache {
b_btree_node c_node;
size_t c_width;
b_btree c_floats;
};
struct mie_float_cache {
b_btree c_widths;
};
static int float_key_compare(const float_key *a, const float_key *b)
{
return memcmp(a->i, b->i, sizeof a->i);
}
static B_BTREE_DEFINE_SIMPLE_INSERT(
struct float_width_cache, c_node, c_width, put_width_cache);
static B_BTREE_DEFINE_SIMPLE_GET(
struct float_width_cache, size_t, c_node, c_width, get_width_cache);
void put_float(b_btree *tree, struct float_width_cache_entry *node)
{
if (!tree->b_root) {
tree->b_root = &node->e_node;
b_btree_insert_fixup(tree, &node->e_node);
return;
}
b_btree_node *cur = tree->b_root;
while (1) {
struct float_width_cache_entry *cur_node
= b_unbox(struct float_width_cache_entry, cur, e_node);
b_btree_node *next = NULL;
int cmp = float_key_compare(&node->e_key, &cur_node->e_key);
if (cmp >= 0) {
next = b_btree_right(cur);
if (!next) {
b_btree_put_right(cur, &node->e_node);
break;
}
} else if (cmp < 0) {
next = b_btree_left(cur);
if (!next) {
b_btree_put_left(cur, &node->e_node);
break;
}
} else {
return;
}
cur = next;
}
b_btree_insert_fixup(tree, &node->e_node);
}
static struct float_width_cache_entry *get_float(const b_btree *tree, float_key key)
{
b_btree_node *cur = tree->b_root;
while (cur) {
struct float_width_cache_entry *cur_node
= b_unbox(struct float_width_cache_entry, cur, e_node);
int cmp = float_key_compare(&key, &cur_node->e_key);
if (cmp > 0) {
cur = b_btree_right(cur);
} else if (cmp < 0) {
cur = b_btree_left(cur);
} else {
return cur_node;
}
}
return NULL;
}
static struct float_width_cache *float_width_cache_create(size_t width)
{
struct float_width_cache *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
memset(out, 0x0, sizeof *out);
out->c_width = width;
return out;
}
static void float_width_cache_destroy(struct float_width_cache *cache)
{
b_btree_node *cur = b_btree_first(&cache->c_floats);
while (cur) {
b_btree_node *next = b_btree_next(cur);
b_btree_delete(&cache->c_floats, cur);
struct float_width_cache_entry *entry
= b_unbox(struct float_width_cache_entry, cur, e_node);
free(entry);
cur = next;
}
free(cache);
}
static struct float_width_cache_entry *float_width_cache_entry_create(
struct mie_ctx *ctx, size_t width, double value)
{
struct float_width_cache_entry *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
memset(out, 0x0, sizeof *out);
switch (width) {
case MIE_FLOAT_32:
out->e_value.f_val.v_32 = value;
break;
case MIE_FLOAT_64:
out->e_value.f_val.v_64 = value;
break;
default:
free(out);
return NULL;
}
out->e_value.f_base.v_type = mie_arith_float_get_type(ctx, width);
if (!out->e_value.f_base.v_type) {
free(out);
return NULL;
}
return out;
}
struct mie_float_cache *mie_float_cache_create(void)
{
struct mie_float_cache *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
memset(out, 0x0, sizeof *out);
return out;
}
void mie_float_cache_destroy(struct mie_float_cache *cache)
{
b_btree_node *cur = b_btree_first(&cache->c_widths);
while (cur) {
b_btree_node *next = b_btree_next(cur);
b_btree_delete(&cache->c_widths, cur);
struct float_width_cache *width_cache
= b_unbox(struct float_width_cache, cur, c_node);
float_width_cache_destroy(width_cache);
cur = next;
}
free(cache);
}
struct mie_float *mie_float_cache_get(
struct mie_float_cache *cache, struct mie_ctx *ctx, double value,
size_t bit_width)
{
struct float_width_cache *width_cache
= get_width_cache(&cache->c_widths, bit_width);
if (!width_cache) {
width_cache = float_width_cache_create(bit_width);
if (!width_cache) {
return NULL;
}
put_width_cache(&cache->c_widths, width_cache);
}
float_key key = {.f = value};
struct float_width_cache_entry *entry
= get_float(&width_cache->c_floats, key);
if (!entry) {
entry = float_width_cache_entry_create(ctx, bit_width, value);
if (!entry) {
return NULL;
}
put_float(&width_cache->c_floats, entry);
}
return &entry->e_value;
}

View File

@@ -2,8 +2,8 @@
#include <mie/ctx.h>
#include <mie/dialect/arith.h>
#include <mie/dialect/dialect.h>
#include <mie/dialect/type.h>
#include <mie/macros.h>
#include <mie/type/type-definition.h>
#include <mie/type/type.h>
#include <mie/value.h>
@@ -12,7 +12,7 @@ struct float_type {
size_t f_width;
};
static void value_print(
static enum mie_status value_print(
const struct mie_type *ty, const struct mie_value *value, b_stream *out)
{
struct float_type *float_ty = (struct float_type *)ty;
@@ -32,12 +32,14 @@ static void value_print(
b_stream_write_fmt(out, NULL, "NaN : f%zu", float_ty->f_width);
break;
}
return MIE_SUCCESS;
}
struct mie_type *mie_arith_float_get_type(struct mie_ctx *ctx, size_t bit_width)
{
struct mie_dialect_type *type_info
= mie_ctx_get_dialect_type(ctx, "arith", "float");
struct mie_type_definition *type_info
= mie_ctx_get_type_definition(ctx, "arith", "float");
if (!type_info) {
return NULL;
}
@@ -67,23 +69,38 @@ struct mie_type *mie_arith_float_get_type(struct mie_ctx *ctx, size_t bit_width)
return (struct mie_type *)type;
}
size_t mie_arith_float_type_get_width(const struct mie_type *type)
{
if (strcmp(type->ty_def->ty_parent->d_name, "arith") != 0) {
return (size_t)-1;
}
if (strcmp(type->ty_def->ty_name, "float") != 0) {
return (size_t)-1;
}
const struct float_type *float_type = (const struct float_type *)type;
return float_type->f_width;
}
static enum mie_status print(
const struct mie_dialect_type *def, const struct mie_type *ty, b_stream *out)
const struct mie_type_definition *def, const struct mie_type *ty,
b_stream *out)
{
return MIE_SUCCESS;
}
static enum mie_status parse(
const struct mie_dialect_type *def, struct mie_parser *parser,
const struct mie_type_definition *def, struct mie_parser *parser,
struct mie_type **out)
{
return MIE_SUCCESS;
}
MIE_DIALECT_TYPE_BEGIN(mie_arith_float, "float")
// MIE_DIALECT_TYPE_FLAGS(MIE_DIALECT_TYPE_PARAMETISED);
MIE_DIALECT_TYPE_STRUCT(struct float_type);
MIE_DIALECT_TYPE_PRINT(print);
MIE_DIALECT_TYPE_PARSE(parse);
MIE_DIALECT_TYPE_VALUE_PRINT(value_print);
MIE_DIALECT_TYPE_END()
MIE_TYPE_DEFINITION_BEGIN(mie_arith_float, "float")
// MIE_TYPE_DEFINITION_FLAGS(MIE_TYPE_DEFINITION_PARAMETISED);
MIE_TYPE_DEFINITION_STRUCT(struct float_type);
MIE_TYPE_DEFINITION_PRINT(print);
MIE_TYPE_DEFINITION_PARSE(parse);
MIE_TYPE_DEFINITION_VALUE_PRINT(value_print);
MIE_TYPE_DEFINITION_END()

View File

@@ -2,8 +2,8 @@
#include <mie/ctx.h>
#include <mie/dialect/arith.h>
#include <mie/dialect/dialect.h>
#include <mie/dialect/type.h>
#include <mie/macros.h>
#include <mie/type/type-definition.h>
#include <mie/type/type.h>
#include <mie/value.h>
@@ -12,7 +12,7 @@ struct int_type {
size_t i_width;
};
static void value_print(
static enum mie_status value_print(
const struct mie_type *ty, const struct mie_value *value, b_stream *out)
{
struct int_type *int_ty = (struct int_type *)ty;
@@ -24,12 +24,14 @@ static void value_print(
} else {
b_stream_write_fmt(out, NULL, "INF : i%zu", int_ty->i_width);
}
return MIE_SUCCESS;
}
struct mie_type *mie_arith_int_get_type(struct mie_ctx *ctx, size_t bit_width)
{
struct mie_dialect_type *type_info
= mie_ctx_get_dialect_type(ctx, "arith", "int");
struct mie_type_definition *type_info
= mie_ctx_get_type_definition(ctx, "arith", "int");
if (!type_info) {
return NULL;
}
@@ -59,23 +61,38 @@ struct mie_type *mie_arith_int_get_type(struct mie_ctx *ctx, size_t bit_width)
return (struct mie_type *)type;
}
size_t mie_arith_int_type_get_width(const struct mie_type *type)
{
if (strcmp(type->ty_def->ty_parent->d_name, "arith") != 0) {
return (size_t)-1;
}
if (strcmp(type->ty_def->ty_name, "int") != 0) {
return (size_t)-1;
}
const struct int_type *int_type = (const struct int_type *)type;
return int_type->i_width;
}
static enum mie_status print(
const struct mie_dialect_type *def, const struct mie_type *ty, b_stream *out)
const struct mie_type_definition *def, const struct mie_type *ty,
b_stream *out)
{
return MIE_SUCCESS;
}
static enum mie_status parse(
const struct mie_dialect_type *def, struct mie_parser *parser,
const struct mie_type_definition *def, struct mie_parser *parser,
struct mie_type **out)
{
return MIE_SUCCESS;
}
MIE_DIALECT_TYPE_BEGIN(mie_arith_int, "int")
// MIE_DIALECT_TYPE_FLAGS(MIE_DIALECT_TYPE_PARAMETISED);
MIE_DIALECT_TYPE_STRUCT(struct int_type);
MIE_DIALECT_TYPE_PRINT(print);
MIE_DIALECT_TYPE_PARSE(parse);
MIE_DIALECT_TYPE_VALUE_PRINT(value_print);
MIE_DIALECT_TYPE_END()
MIE_TYPE_DEFINITION_BEGIN(mie_arith_int, "int")
// MIE_TYPE_DEFINITION_FLAGS(MIE_TYPE_DEFINITION_PARAMETISED);
MIE_TYPE_DEFINITION_STRUCT(struct int_type);
MIE_TYPE_DEFINITION_PRINT(print);
MIE_TYPE_DEFINITION_PARSE(parse);
MIE_TYPE_DEFINITION_VALUE_PRINT(value_print);
MIE_TYPE_DEFINITION_END()

View File

@@ -3,4 +3,5 @@
MIE_DIALECT_BEGIN(mie_builtin, "builtin")
MIE_DIALECT_ADD_TYPE(mie_builtin_string);
MIE_DIALECT_ADD_TRAIT(mie_builtin_isolated_from_above);
MIE_DIALECT_END()

View File

@@ -0,0 +1,21 @@
#include <mie/dialect/dialect.h>
#include <mie/macros.h>
#include <mie/trait/trait-definition.h>
#include <mie/trait/trait.h>
static enum mie_status validate(
const struct mie_trait_definition *trait_def,
const struct mie_trait *trait, const struct mie_trait_target *target)
{
return MIE_SUCCESS;
}
/* builtin.isolated-from-above trait:
* regions of an op that has this trait cannot capture or reference
* values defined in the enclosing scope. */
MIE_TRAIT_DEFINITION_BEGIN(
mie_builtin_isolated_from_above, "isolated-from-above")
MIE_TRAIT_DEFINITION_TARGETS(MIE_TRAIT_TARGET_OP | MIE_TRAIT_TARGET_TYPE);
MIE_TRAIT_DEFINITION_STRUCT(struct mie_trait);
MIE_TRAIT_DEFINITION_VALIDATE(validate);
MIE_TRAIT_DEFINITION_END()

View File

@@ -2,40 +2,43 @@
#include <mie/ctx.h>
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
#include <mie/dialect/type.h>
#include <mie/macros.h>
#include <mie/type/type-definition.h>
#include <mie/type/type.h>
#include <mie/value.h>
static void value_print(
static enum mie_status value_print(
const struct mie_type *ty, const struct mie_value *value, b_stream *out)
{
const struct mie_string *str = (const struct mie_string *)value;
b_stream_write_fmt(out, NULL, "\"%s\"", str->str_val);
return MIE_SUCCESS;
}
static void type_init(const struct mie_dialect_type *type_info, struct mie_type *type)
static void type_init(
const struct mie_type_definition *type_info, struct mie_type *type)
{
type->ty_instance_size = sizeof(struct mie_string);
}
static enum mie_status print(
const struct mie_dialect_type *def, const struct mie_type *ty, b_stream *out)
const struct mie_type_definition *def, const struct mie_type *ty,
b_stream *out)
{
return MIE_SUCCESS;
}
static enum mie_status parse(
const struct mie_dialect_type *def, struct mie_parser *parser,
const struct mie_type_definition *def, struct mie_parser *parser,
struct mie_type **out)
{
return MIE_SUCCESS;
}
MIE_DIALECT_TYPE_BEGIN(mie_builtin_string, "string")
MIE_DIALECT_TYPE_STRUCT(struct mie_type);
MIE_DIALECT_TYPE_INIT(type_init);
MIE_DIALECT_TYPE_PRINT(print);
MIE_DIALECT_TYPE_PARSE(parse);
MIE_DIALECT_TYPE_VALUE_PRINT(value_print);
MIE_DIALECT_TYPE_END()
MIE_TYPE_DEFINITION_BEGIN(mie_builtin_string, "string")
MIE_TYPE_DEFINITION_STRUCT(struct mie_type);
MIE_TYPE_DEFINITION_INIT(type_init);
MIE_TYPE_DEFINITION_PRINT(print);
MIE_TYPE_DEFINITION_PARSE(parse);
MIE_TYPE_DEFINITION_VALUE_PRINT(value_print);
MIE_TYPE_DEFINITION_END()

View File

@@ -1,5 +1,5 @@
#include <mie/dialect/dialect.h>
#include <mie/dialect/op.h>
#include <mie/ir/op-definition.h>
#include <mie/macros.h>
static enum mie_status print(const struct mie_op *op, b_stream *out)
@@ -12,7 +12,7 @@ static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
return MIE_SUCCESS;
}
MIE_DIALECT_OP_BEGIN(mie_cf_br_cond, "br-cond")
MIE_DIALECT_OP_PRINT(print);
MIE_DIALECT_OP_PARSE(parse);
MIE_DIALECT_OP_END()
MIE_OP_DEFINITION_BEGIN(mie_cf_br_cond, "br-cond")
MIE_OP_DEFINITION_PRINT(print);
MIE_OP_DEFINITION_PARSE(parse);
MIE_OP_DEFINITION_END()

View File

@@ -1,5 +1,5 @@
#include <mie/dialect/dialect.h>
#include <mie/dialect/op.h>
#include <mie/ir/op-definition.h>
#include <mie/macros.h>
static enum mie_status print(const struct mie_op *op, b_stream *out)
@@ -12,7 +12,7 @@ static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
return MIE_SUCCESS;
}
MIE_DIALECT_OP_BEGIN(mie_cf_br, "br")
MIE_DIALECT_OP_PRINT(print);
MIE_DIALECT_OP_PARSE(parse);
MIE_DIALECT_OP_END()
MIE_OP_DEFINITION_BEGIN(mie_cf_br, "br")
MIE_OP_DEFINITION_PRINT(print);
MIE_OP_DEFINITION_PARSE(parse);
MIE_OP_DEFINITION_END()

View File

@@ -1,8 +1,8 @@
#include <blue/ds/string.h>
#include <mie/ctx.h>
#include <mie/dialect/dialect.h>
#include <mie/dialect/op.h>
#include <mie/dialect/type.h>
#include <mie/ir/op-definition.h>
#include <mie/type/type-definition.h>
#define TYPE_NS_ID \
MIE_ID(0xe4, 0x99, 0x42, 0x58, 0x2b, 0xdb, 0x45, 0xa3, 0xbd, 0x4b, \
@@ -38,7 +38,7 @@ struct mie_dialect *mie_dialect_create(struct mie_ctx *ctx, const char *name)
return out;
}
const struct mie_dialect_op *mie_dialect_get_op(
const struct mie_op_definition *mie_dialect_get_op(
const struct mie_dialect *dialect, const char *name)
{
b_rope name_rope = B_ROPE_CSTR(name);
@@ -46,10 +46,10 @@ const struct mie_dialect_op *mie_dialect_get_op(
mie_id_init_ns(&id, mie_id_map_get_ns(&dialect->d_ops), &name_rope);
mie_id *target = mie_id_map_get(&dialect->d_ops, &id);
return b_unbox(struct mie_dialect_op, target, op_id);
return b_unbox(struct mie_op_definition, target, op_id);
}
const struct mie_dialect_type *mie_dialect_get_type(
const struct mie_type_definition *mie_dialect_get_type(
const struct mie_dialect *dialect, const char *name)
{
b_rope name_rope = B_ROPE_CSTR(name);
@@ -57,5 +57,5 @@ const struct mie_dialect_type *mie_dialect_get_type(
mie_id_init_ns(&id, mie_id_map_get_ns(&dialect->d_types), &name_rope);
mie_id *target = mie_id_map_get(&dialect->d_types, &id);
return b_unbox(struct mie_dialect_type, target, ty_id);
return b_unbox(struct mie_type_definition, target, ty_id);
}

View File

@@ -1,5 +1,5 @@
#include <mie/dialect/dialect.h>
#include <mie/dialect/op.h>
#include <mie/ir/op-definition.h>
#include <mie/macros.h>
static enum mie_status print(const struct mie_op *op, b_stream *out)
@@ -12,10 +12,10 @@ static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
return MIE_SUCCESS;
}
MIE_DIALECT_OP_BEGIN(mie_func_func, "func")
MIE_DIALECT_OP_PRINT(print);
MIE_DIALECT_OP_PARSE(parse);
MIE_DIALECT_OP_END()
MIE_OP_DEFINITION_BEGIN(mie_func_func, "func")
MIE_OP_DEFINITION_PRINT(print);
MIE_OP_DEFINITION_PARSE(parse);
MIE_OP_DEFINITION_END()
MIE_DIALECT_BEGIN(mie_func, "func")
MIE_DIALECT_ADD_OP(mie_func_func);

View File

@@ -1,7 +1,7 @@
#include <mie/dialect/dialect.h>
#include <mie/dialect/index.h>
#include <mie/dialect/type.h>
#include <mie/macros.h>
#include <mie/type/type-definition.h>
#include <mie/type/type.h>
#include <mie/value.h>
@@ -9,7 +9,7 @@ struct index_type {
struct mie_type i_base;
};
static void value_print(
static enum mie_status value_print(
const struct mie_type *ty, const struct mie_value *value, b_stream *out)
{
struct index_type *index_ty = (struct index_type *)ty;
@@ -17,33 +17,36 @@ static void value_print(
b_stream_write_fmt(
out, NULL, "%zu : %s", index_val->i_value,
index_ty->i_base.ty_def->ty_name);
return MIE_SUCCESS;
}
static void type_init(const struct mie_dialect_type *type_info, struct mie_type *type)
static void type_init(
const struct mie_type_definition *type_info, struct mie_type *type)
{
type->ty_instance_size = sizeof(struct mie_index);
}
static enum mie_status print(
const struct mie_dialect_type *def, const struct mie_type *ty, b_stream *out)
const struct mie_type_definition *def, const struct mie_type *ty,
b_stream *out)
{
return MIE_SUCCESS;
}
static enum mie_status parse(
const struct mie_dialect_type *def, struct mie_parser *parser,
const struct mie_type_definition *def, struct mie_parser *parser,
struct mie_type **out)
{
return MIE_SUCCESS;
}
MIE_DIALECT_TYPE_BEGIN(mie_index_index, "index")
MIE_DIALECT_TYPE_STRUCT(struct index_type);
MIE_DIALECT_TYPE_INIT(type_init);
MIE_DIALECT_TYPE_PRINT(print);
MIE_DIALECT_TYPE_PARSE(parse);
MIE_DIALECT_TYPE_VALUE_PRINT(value_print);
MIE_DIALECT_TYPE_END()
MIE_TYPE_DEFINITION_BEGIN(mie_index_index, "index")
MIE_TYPE_DEFINITION_STRUCT(struct index_type);
MIE_TYPE_DEFINITION_INIT(type_init);
MIE_TYPE_DEFINITION_PRINT(print);
MIE_TYPE_DEFINITION_PARSE(parse);
MIE_TYPE_DEFINITION_VALUE_PRINT(value_print);
MIE_TYPE_DEFINITION_END()
MIE_DIALECT_BEGIN(mie_index, "index")
MIE_DIALECT_ADD_TYPE(mie_index_index);

View File

@@ -1,5 +1,5 @@
#include <mie/dialect/dialect.h>
#include <mie/dialect/op.h>
#include <mie/ir/op-definition.h>
#include <mie/macros.h>
static enum mie_status print(const struct mie_op *op, b_stream *out)
@@ -12,7 +12,7 @@ static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
return MIE_SUCCESS;
}
MIE_DIALECT_OP_BEGIN(mie_meta_source_filename, "source-filename")
MIE_DIALECT_OP_PRINT(print);
MIE_DIALECT_OP_PARSE(parse);
MIE_DIALECT_OP_END()
MIE_OP_DEFINITION_BEGIN(mie_meta_source_filename, "source-filename")
MIE_OP_DEFINITION_PRINT(print);
MIE_OP_DEFINITION_PARSE(parse);
MIE_OP_DEFINITION_END()

View File

@@ -1,5 +1,5 @@
#include <mie/dialect/dialect.h>
#include <mie/dialect/op.h>
#include <mie/ir/op-definition.h>
#include <mie/macros.h>
static enum mie_status print(const struct mie_op *op, b_stream *out)
@@ -12,7 +12,7 @@ static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
return MIE_SUCCESS;
}
MIE_DIALECT_OP_BEGIN(mie_ptr_load, "load")
MIE_DIALECT_OP_PRINT(print);
MIE_DIALECT_OP_PARSE(parse);
MIE_DIALECT_OP_END()
MIE_OP_DEFINITION_BEGIN(mie_ptr_load, "load")
MIE_OP_DEFINITION_PRINT(print);
MIE_OP_DEFINITION_PARSE(parse);
MIE_OP_DEFINITION_END()

View File

@@ -1,29 +1,30 @@
#include <mie/dialect/dialect.h>
#include <mie/dialect/type.h>
#include <mie/macros.h>
#include <mie/type/type-definition.h>
struct ptr_type {
struct mie_dialect_type ptr_base;
struct mie_type_definition ptr_base;
};
static enum mie_status print(
const struct mie_dialect_type *def, const struct mie_type *ty, b_stream *out)
const struct mie_type_definition *def, const struct mie_type *ty,
b_stream *out)
{
return MIE_SUCCESS;
}
static enum mie_status parse(
const struct mie_dialect_type *def, struct mie_parser *parser,
const struct mie_type_definition *def, struct mie_parser *parser,
struct mie_type **out)
{
return MIE_SUCCESS;
}
MIE_DIALECT_TYPE_BEGIN(mie_ptr_ptr, "ptr")
MIE_DIALECT_TYPE_STRUCT(struct ptr_type);
MIE_DIALECT_TYPE_PRINT(print);
MIE_DIALECT_TYPE_PARSE(parse);
MIE_DIALECT_TYPE_END()
MIE_TYPE_DEFINITION_BEGIN(mie_ptr_ptr, "ptr")
MIE_TYPE_DEFINITION_STRUCT(struct ptr_type);
MIE_TYPE_DEFINITION_PRINT(print);
MIE_TYPE_DEFINITION_PARSE(parse);
MIE_TYPE_DEFINITION_END()
MIE_DIALECT_BEGIN(mie_ptr, "ptr")
MIE_DIALECT_ADD_OP(mie_ptr_load);

View File

@@ -1,5 +1,5 @@
#include <mie/dialect/dialect.h>
#include <mie/dialect/op.h>
#include <mie/ir/op-definition.h>
#include <mie/macros.h>
static enum mie_status print(const struct mie_op *op, b_stream *out)
@@ -12,7 +12,7 @@ static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
return MIE_SUCCESS;
}
MIE_DIALECT_OP_BEGIN(mie_ptr_store, "store")
MIE_DIALECT_OP_PRINT(print);
MIE_DIALECT_OP_PARSE(parse);
MIE_DIALECT_OP_END()
MIE_OP_DEFINITION_BEGIN(mie_ptr_store, "store")
MIE_OP_DEFINITION_PRINT(print);
MIE_OP_DEFINITION_PARSE(parse);
MIE_OP_DEFINITION_END()

View File

@@ -1,5 +1,5 @@
#include <mie/dialect/dialect.h>
#include <mie/dialect/op.h>
#include <mie/ir/op-definition.h>
#include <mie/macros.h>
static enum mie_status print(const struct mie_op *op, b_stream *out)
@@ -12,7 +12,7 @@ static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
return MIE_SUCCESS;
}
MIE_DIALECT_OP_BEGIN(mie_scf_for, "for")
MIE_DIALECT_OP_PRINT(print);
MIE_DIALECT_OP_PARSE(parse);
MIE_DIALECT_OP_END()
MIE_OP_DEFINITION_BEGIN(mie_scf_for, "for")
MIE_OP_DEFINITION_PRINT(print);
MIE_OP_DEFINITION_PARSE(parse);
MIE_OP_DEFINITION_END()

View File

@@ -1,5 +1,5 @@
#include <mie/dialect/dialect.h>
#include <mie/dialect/op.h>
#include <mie/ir/op-definition.h>
#include <mie/macros.h>
static enum mie_status print(const struct mie_op *op, b_stream *out)
@@ -12,7 +12,7 @@ static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
return MIE_SUCCESS;
}
MIE_DIALECT_OP_BEGIN(mie_scf_if, "if")
MIE_DIALECT_OP_PRINT(print);
MIE_DIALECT_OP_PARSE(parse);
MIE_DIALECT_OP_END()
MIE_OP_DEFINITION_BEGIN(mie_scf_if, "if")
MIE_OP_DEFINITION_PRINT(print);
MIE_OP_DEFINITION_PARSE(parse);
MIE_OP_DEFINITION_END()

View File

@@ -1,5 +1,3 @@
#include "scf.h"
#include <mie/dialect/dialect.h>
#include <mie/macros.h>

View File

@@ -1,7 +0,0 @@
#ifndef MIE_DIALECT_SCF_H_
#define MIE_DIALECT_SCF_H_
#include <mie/dialect/dialect.h>
#include <mie/dialect/op.h>
#endif

View File

@@ -1,5 +1,5 @@
#include <mie/dialect/dialect.h>
#include <mie/dialect/op.h>
#include <mie/ir/op-definition.h>
#include <mie/macros.h>
static enum mie_status print(const struct mie_op *op, b_stream *out)
@@ -12,7 +12,7 @@ static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
return MIE_SUCCESS;
}
MIE_DIALECT_OP_BEGIN(mie_scf_yield, "yield")
MIE_DIALECT_OP_PRINT(print);
MIE_DIALECT_OP_PARSE(parse);
MIE_DIALECT_OP_END()
MIE_OP_DEFINITION_BEGIN(mie_scf_yield, "yield")
MIE_OP_DEFINITION_PRINT(print);
MIE_OP_DEFINITION_PARSE(parse);
MIE_OP_DEFINITION_END()

View File

@@ -0,0 +1,21 @@
#include <mie/dialect/dialect.h>
#include <mie/macros.h>
#include <mie/trait/trait-definition.h>
#include <mie/trait/trait.h>
static enum mie_status validate(
const struct mie_trait_definition *trait_def,
const struct mie_trait *trait, const struct mie_trait_target *target)
{
return MIE_SUCCESS;
}
/* select.graph-only trait:
* this is a graph-only op. references to it by name must be prefixed with +
* and the op can only be used within graph regions.
* a graph op can have the same name as a regular or non-graph op. */
MIE_TRAIT_DEFINITION_BEGIN(mie_select_graph_only, "graph-only")
MIE_TRAIT_DEFINITION_TARGETS(MIE_TRAIT_TARGET_OP | MIE_TRAIT_TARGET_TYPE);
MIE_TRAIT_DEFINITION_STRUCT(struct mie_trait);
MIE_TRAIT_DEFINITION_VALIDATE(validate);
MIE_TRAIT_DEFINITION_END()

View File

@@ -0,0 +1,21 @@
#include <mie/dialect/dialect.h>
#include <mie/macros.h>
#include <mie/trait/trait-definition.h>
#include <mie/trait/trait.h>
static enum mie_status validate(
const struct mie_trait_definition *trait_def,
const struct mie_trait *trait, const struct mie_trait_target *target)
{
return MIE_SUCCESS;
}
/* select.graph-op trait:
* ops with this trait can be used within graph regions. by default, ops cannot
* be used in graph regions unless they have the graph-op or graph-only traits.
*/
MIE_TRAIT_DEFINITION_BEGIN(mie_select_graph_op, "graph-op")
MIE_TRAIT_DEFINITION_TARGETS(MIE_TRAIT_TARGET_OP | MIE_TRAIT_TARGET_TYPE);
MIE_TRAIT_DEFINITION_STRUCT(struct mie_trait);
MIE_TRAIT_DEFINITION_VALIDATE(validate);
MIE_TRAIT_DEFINITION_END()

View File

@@ -0,0 +1,21 @@
#include <mie/dialect/dialect.h>
#include <mie/macros.h>
#include <mie/trait/trait-definition.h>
#include <mie/trait/trait.h>
static enum mie_status validate(
const struct mie_trait_definition *trait_def,
const struct mie_trait *trait, const struct mie_trait_target *target)
{
return MIE_SUCCESS;
}
/* select.graph-scope trait:
* regions of an op that has this trait are graph regions. graph regions
* cannot have more than one block, and the entry block must be unnamed
* with no parameters. However, graph ops can be used. */
MIE_TRAIT_DEFINITION_BEGIN(mie_select_graph_scope, "graph-scope")
MIE_TRAIT_DEFINITION_TARGETS(MIE_TRAIT_TARGET_OP | MIE_TRAIT_TARGET_TYPE);
MIE_TRAIT_DEFINITION_STRUCT(struct mie_trait);
MIE_TRAIT_DEFINITION_VALIDATE(validate);
MIE_TRAIT_DEFINITION_END()

View File

@@ -0,0 +1,21 @@
#include <mie/ctx.h>
#include <mie/dialect/dialect.h>
#include <mie/ir/op-definition.h>
#include <mie/macros.h>
#include <mie/trait/trait.h>
static enum mie_status print(const struct mie_op *op, b_stream *out)
{
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
{
return MIE_SUCCESS;
}
MIE_OP_DEFINITION_BEGIN(mie_select_graph, "graph")
MIE_OP_DEFINITION_PRINT(print);
MIE_OP_DEFINITION_PARSE(parse);
MIE_OP_DEFINITION_TRAIT("select", "graph-scope");
MIE_OP_DEFINITION_END()

View File

@@ -0,0 +1,9 @@
#include <mie/dialect/dialect.h>
#include <mie/macros.h>
MIE_DIALECT_BEGIN(mie_select, "select")
MIE_DIALECT_ADD_TRAIT(mie_select_graph_only);
MIE_DIALECT_ADD_TRAIT(mie_select_graph_op);
MIE_DIALECT_ADD_TRAIT(mie_select_graph_scope);
MIE_DIALECT_ADD_OP(mie_select_graph);
MIE_DIALECT_END()

View File

@@ -118,34 +118,6 @@ void mie_id_to_string(const mie_id *id, char *out, size_t max)
}
}
void mie_id_map_init(struct mie_id_map *map, const mie_id *ns)
{
memset(map, 0x0, sizeof *map);
map->map_ns_id = *ns;
}
const mie_id *mie_id_map_get_ns(const struct mie_id_map *map)
{
return &map->map_ns_id;
}
void mie_id_map_put(struct mie_id_map *map, mie_id *id, const b_rope *name)
{
mie_id_init_ns(id, &map->map_ns_id, name);
put_id(&map->map_entries, id);
}
void mie_id_map_put_id(struct mie_id_map *map, mie_id *node)
{
put_id(&map->map_entries, node);
}
mie_id *mie_id_map_get(const struct mie_id_map *map, mie_id *id)
{
return get_id(&map->map_entries, id);
}
void mie_id_builder_begin(struct mie_id_builder *builder, const mie_id *ns)
{
memset(builder, 0x0, sizeof *builder);
@@ -181,3 +153,65 @@ void mie_id_builder_end(struct mie_id_builder *builder, mie_id *out)
out->id_bytes[8] &= 0x3F;
out->id_bytes[8] |= 0x80;
}
void mie_id_map_init(struct mie_id_map *map, const mie_id *ns)
{
memset(map, 0x0, sizeof *map);
map->map_ns_id = *ns;
}
const mie_id *mie_id_map_get_ns(const struct mie_id_map *map)
{
return &map->map_ns_id;
}
void mie_id_map_put(struct mie_id_map *map, mie_id *id, const b_rope *name)
{
mie_id_init_ns(id, &map->map_ns_id, name);
put_id(&map->map_entries, id);
}
void mie_id_map_put_id(struct mie_id_map *map, mie_id *node)
{
put_id(&map->map_entries, node);
}
mie_id *mie_id_map_get(const struct mie_id_map *map, mie_id *id)
{
return get_id(&map->map_entries, id);
}
enum mie_status mie_id_map_iterator_begin(
struct mie_id_map_iterator *it, const struct mie_id_map *map)
{
memset(it, 0x0, sizeof *it);
it->_n = b_btree_first(&map->map_entries);
if (!it->_n) {
return MIE_ERR_NO_DATA;
}
it->it_id = b_unbox(mie_id, it->_n, e_node);
return MIE_SUCCESS;
}
enum mie_status mie_id_map_iterator_move_next(struct mie_id_map_iterator *it)
{
if (!it->_n) {
it->it_id = NULL;
return MIE_ERR_NO_DATA;
}
it->_n = b_btree_next(it->_n);
if (!it->_n) {
it->it_id = NULL;
return MIE_ERR_NO_DATA;
}
it->it_id = b_unbox(mie_id, it->_n, e_node);
return MIE_SUCCESS;
}

View File

@@ -27,6 +27,7 @@ struct mie_ctx {
struct mie_id_map ctx_traits;
struct mie_int_cache *ctx_ints;
struct mie_float_cache *ctx_floats;
struct mie_index_cache *ctx_indices;
struct mie_string_cache *ctx_strings;
};
@@ -38,11 +39,14 @@ MIE_API bool mie_ctx_resolve_op(const struct mie_ctx *ctx, struct mie_op *op);
MIE_API struct mie_dialect *mie_ctx_get_dialect(
const struct mie_ctx *ctx, const char *name);
MIE_API struct mie_dialect_type *mie_ctx_get_dialect_type(
MIE_API struct mie_type_definition *mie_ctx_get_type_definition(
const struct mie_ctx *ctx, const char *dialect_name, const char *type_name);
MIE_API const struct mie_trait_definition *mie_ctx_get_trait_definition(
const struct mie_ctx *ctx, const char *dialect_name,
const char *trait_name);
MIE_API struct mie_type *mie_ctx_get_type(
struct mie_ctx *ctx, const char *dialect_name, const char *type_name);
MIE_API struct mie_type *mie_ctx_get_trait(
MIE_API const struct mie_trait *mie_ctx_get_trait(
struct mie_ctx *ctx, const char *dialect_name, const char *trait_name);
MIE_API struct mie_type *mie_ctx_get_storage_type(
struct mie_ctx *ctx, const struct mie_type **parts, size_t nr_parts);

View File

@@ -44,10 +44,19 @@ MIE_API struct mie_type *mie_arith_int_get_type(
MIE_API struct mie_type *mie_arith_float_get_type(
struct mie_ctx *ctx, size_t bit_width);
MIE_API size_t mie_arith_int_type_get_width(const struct mie_type *type);
MIE_API size_t mie_arith_float_type_get_width(const struct mie_type *type);
MIE_API struct mie_int_cache *mie_int_cache_create(void);
MIE_API void mie_int_cache_destroy(struct mie_int_cache *cache);
MIE_API struct mie_int *mie_int_cache_get(
struct mie_int_cache *cache, struct mie_ctx *ctx, size_t value,
size_t bit_width);
MIE_API struct mie_float_cache *mie_float_cache_create(void);
MIE_API void mie_float_cache_destroy(struct mie_float_cache *cache);
MIE_API struct mie_float *mie_float_cache_get(
struct mie_float_cache *cache, struct mie_ctx *ctx, double value,
size_t bit_width);
#endif

View File

@@ -9,17 +9,17 @@
struct mie_ctx;
struct mie_dialect_op;
struct mie_dialect_type;
struct mie_op_definition;
struct mie_type_definition;
struct mie_trait_definition;
struct mie_dialect {
mie_id d_id;
char *d_name;
/* map of struct mie_dialect_op */
/* map of struct mie_op_definition */
struct mie_id_map d_ops;
/* map of struct mie_dialect_type */
/* map of struct mie_type_definition */
struct mie_id_map d_types;
/* map of struct mie_trait_definition */
struct mie_id_map d_traits;
@@ -28,9 +28,9 @@ struct mie_dialect {
MIE_API struct mie_dialect *mie_dialect_create(
struct mie_ctx *ctx, const char *name);
MIE_API const struct mie_dialect_op *mie_dialect_get_op(
MIE_API const struct mie_op_definition *mie_dialect_get_op(
const struct mie_dialect *dialect, const char *name);
MIE_API const struct mie_dialect_type *mie_dialect_get_type(
MIE_API const struct mie_type_definition *mie_dialect_get_type(
const struct mie_dialect *dialect, const char *name);
MIE_API const struct mie_trait_definition *mie_dialect_get_trait(
const struct mie_dialect *dialect, const char *name);

View File

@@ -0,0 +1,11 @@
#ifndef MIE_DIALECT_SELECT_H_
#define MIE_DIALECT_SELECT_H_
#include <mie/misc.h>
struct mie_ctx;
struct mie_dialect;
MIE_API struct mie_dialect *mie_select_dialect_create(struct mie_ctx *ctx);
#endif

View File

@@ -1,52 +0,0 @@
#ifndef MIE_DIALECT_TYPE_H_
#define MIE_DIALECT_TYPE_H_
#include <blue/core/btree.h>
#include <blue/core/stream.h>
#include <mie/id.h>
#include <mie/status.h>
#include <mie/trait/trait-table.h>
struct mie_type;
struct mie_value;
struct mie_parser;
struct mie_dialect;
enum mie_type_trait {
/* this type is parametised. one or more arguments are required to create
* a corresponding mie_type instance. in textual IR, references to this
* type will be followed by a set of arguments surrounded
* by <angle brackets>. */
MIE_TYPE_TRAIT_PARAMETISED = 0x01u,
/* this type can only be used within graph regions. unlike graph ops,
* no special prefix is required */
MIE_TYPE_TRAIT_GRAPH_TYPE = 0x02u,
};
struct mie_dialect_type {
mie_id ty_id;
struct mie_trait_table ty_traits;
struct mie_dialect *ty_parent;
char *ty_name;
size_t ty_data_size;
void (*ty_init)(const struct mie_dialect_type *, struct mie_type *);
void (*ty_cleanup)(const struct mie_dialect_type *, struct mie_type *);
void (*ty_instance_cleanup)(const struct mie_type *, struct mie_value *);
enum mie_status (*ty_print)(
const struct mie_dialect_type *, const struct mie_type *,
b_stream *);
void (*ty_value_print)(
const struct mie_type *, const struct mie_value *, b_stream *);
enum mie_status (*ty_parse)(
const struct mie_dialect_type *, struct mie_parser *,
struct mie_type **);
void (*ty_build_id)(const struct mie_type *, struct mie_id_builder *);
};
MIE_API struct mie_dialect_type *mie_dialect_type_create(
struct mie_dialect *parent, const char *name);
#endif

View File

@@ -5,6 +5,7 @@
#include <blue/core/queue.h>
#include <blue/core/rope.h>
#include <mie/misc.h>
#include <mie/status.h>
#include <stddef.h>
#include <stdint.h>
@@ -55,6 +56,11 @@ struct mie_id_map {
b_btree map_entries;
};
struct mie_id_map_iterator {
mie_id *it_id;
b_btree_node *_n;
};
MIE_API void mie_id_init(
mie_id *out, uint32_t a, uint16_t b, uint16_t c, uint16_t d, uint64_t e);
MIE_API void mie_id_init_zero(mie_id *out);
@@ -68,13 +74,6 @@ static inline int mie_id_compare(const mie_id *a, const mie_id *b)
MIE_API void mie_id_to_string(const mie_id *id, char *out, size_t max);
MIE_API void mie_id_map_init(struct mie_id_map *map, const mie_id *ns);
MIE_API const mie_id *mie_id_map_get_ns(const struct mie_id_map *map);
MIE_API void mie_id_map_put(
struct mie_id_map *map, mie_id *node, const b_rope *name);
MIE_API void mie_id_map_put_id(struct mie_id_map *map, mie_id *node);
MIE_API mie_id *mie_id_map_get(const struct mie_id_map *map, mie_id *id);
MIE_API void mie_id_builder_begin(struct mie_id_builder *builder, const mie_id *ns);
MIE_API void mie_id_builder_add(
struct mie_id_builder *builder, const void *p, size_t len);
@@ -93,4 +92,21 @@ MIE_API void mie_id_builder_add_marker(
struct mie_id_builder *builder, enum mie_id_builder_marker marker);
MIE_API void mie_id_builder_end(struct mie_id_builder *builder, mie_id *out);
MIE_API void mie_id_map_init(struct mie_id_map *map, const mie_id *ns);
static inline bool mie_id_map_empty(const struct mie_id_map *map)
{
return b_btree_empty(&map->map_entries);
}
MIE_API const mie_id *mie_id_map_get_ns(const struct mie_id_map *map);
MIE_API void mie_id_map_put(
struct mie_id_map *map, mie_id *node, const b_rope *name);
MIE_API void mie_id_map_put_id(struct mie_id_map *map, mie_id *node);
MIE_API mie_id *mie_id_map_get(const struct mie_id_map *map, mie_id *id);
MIE_API enum mie_status mie_id_map_iterator_begin(
struct mie_id_map_iterator *it, const struct mie_id_map *map);
MIE_API enum mie_status mie_id_map_iterator_move_next(
struct mie_id_map_iterator *it);
#endif

View File

@@ -1,5 +1,5 @@
#ifndef MIE_DIALECT_OP_H_
#define MIE_DIALECT_OP_H_
#ifndef MIE_IR_OP_DEFINITION_H_
#define MIE_IR_OP_DEFINITION_H_
#include <blue/core/btree.h>
#include <blue/core/stream.h>
@@ -14,6 +14,7 @@ struct mie_op;
struct mie_parser;
struct mie_dialect;
#if 0
enum mie_op_trait {
MIE_OP_TRAIT_NONE = 0x00u,
@@ -34,6 +35,7 @@ enum mie_op_trait {
* values defined in the enclosing scope. */
MIE_OP_TRAIT_ISOLATED_FROM_ABOVE = 0x08u,
};
#endif
enum mie_op_param_type {
/* op has no parameter */
@@ -88,7 +90,7 @@ struct mie_op_result {
};
};
struct mie_dialect_op {
struct mie_op_definition {
mie_id op_id;
struct mie_dialect *op_parent;
char *op_name;
@@ -101,7 +103,10 @@ struct mie_dialect_op {
enum mie_status (*op_parse)(struct mie_parser *, struct mie_op *);
};
MIE_API struct mie_dialect_op *mie_dialect_op_create(
MIE_API struct mie_op_definition *mie_op_definition_create(
struct mie_dialect *parent, const char *name);
MIE_API enum mie_status mie_op_definition_add_trait(
struct mie_op_definition *op, const struct mie_trait *trait);
#endif

View File

@@ -15,16 +15,12 @@ struct mie_block;
struct mie_region;
struct mie_dialect;
struct mie_dialect_op;
struct mie_op_definition;
enum mie_op_flags {
MIE_OP_F_OP_RESOLVED = 0x01u,
MIE_OP_F_ARGS_RESOLVED = 0x02u,
};
struct mie_op_successor {
struct mie_block *s_block;
MIE_VECTOR_DECLARE(struct mie_register *, s_params);
MIE_OP_F_ARG_RESOLVED = 0x02u,
MIE_OP_F_SUCCESSOR_RESOLVED = 0x04u,
};
struct mie_op_attribute {
@@ -33,21 +29,35 @@ struct mie_op_attribute {
};
struct mie_op_arg {
enum mie_op_flags arg_flags;
struct mie_file_span arg_span;
union {
/* only valid if the parent op's F_ARGS_RESOLVED flag is set */
/* only valid if F_ARG_RESOLVED is set in arg_flags */
struct mie_register *arg_value;
/* only valid if the parent op's F_ARGS_RESOLVED flag is NOT set */
/* only valid if F_ARG_RESOLVED is NOT set in arg_flags */
struct mie_register_ref arg_unresolved;
};
};
struct mie_op_successor {
enum mie_op_flags s_flags;
union {
/* only valid if F_SUCCESSOR_RESOLVED is set in s_flags; */
struct mie_block *s_block;
/* only valid if F_SUCCESSOR_RESOLVED is NOT set in s_flags; */
char *s_block_name;
};
MIE_VECTOR_DECLARE(struct mie_op_arg, s_args);
};
struct mie_op {
enum mie_op_flags op_flags;
/* these pointers are only valid if the F_RESOLVED flag is set */
/* these pointers are only valid if the F_OP_RESOLVED flag is set */
const struct mie_dialect *op_dialect;
const struct mie_dialect_op *op_info;
const struct mie_op_definition *op_info;
struct mie_file_span op_name_span;
/* only valid if the F_RESOLVED flag is NOT set */

View File

@@ -8,76 +8,109 @@
if (!self) { \
return NULL; \
} \
struct mie_dialect_op *op = NULL; \
struct mie_dialect_type *type = NULL;
struct mie_op_definition *op = NULL; \
struct mie_type_definition *type = NULL; \
struct mie_trait_definition *trait = NULL;
#define __MIE_DIALECT_END() \
return self; \
}
#define __MIE_DIALECT_OP_BEGIN(func_prefix, op_name) \
struct mie_dialect_op *func_prefix##_op_create( \
#define __MIE_OP_DEFINITION_BEGIN(func_prefix, op_name) \
struct mie_op_definition *func_prefix##_op_create( \
struct mie_dialect *d, struct mie_ctx *ctx) \
{ \
struct mie_dialect_op *op = mie_dialect_op_create(d, op_name); \
struct mie_op_definition *op \
= mie_op_definition_create(d, op_name); \
if (!op) { \
return NULL; \
}
} \
const struct mie_trait *trait = NULL;
#define __MIE_DIALECT_OP_END() \
#define __MIE_OP_DEFINITION_END() \
return op; \
}
#define __MIE_DIALECT_TYPE_BEGIN(func_prefix, type_name) \
struct mie_dialect_type *func_prefix##_type_create( \
#define __MIE_TYPE_DEFINITION_BEGIN(func_prefix, type_name) \
struct mie_type_definition *func_prefix##_type_create( \
struct mie_dialect *d, struct mie_ctx *ctx) \
{ \
struct mie_dialect_type *type \
= mie_dialect_type_create(d, type_name); \
struct mie_type_definition *type \
= mie_type_definition_create(d, type_name); \
if (!type) { \
return NULL; \
}
} \
const struct mie_trait *trait = NULL;
#define __MIE_DIALECT_TYPE_END() \
#define __MIE_TYPE_DEFINITION_END() \
return type; \
}
#define __MIE_TRAIT_DEFINITION_BEGIN(func_prefix, trait_name) \
struct mie_trait_definition *func_prefix##_trait_create( \
struct mie_dialect *d, struct mie_ctx *ctx) \
{ \
struct mie_trait_definition *trait \
= mie_trait_definition_create(d, trait_name); \
if (!trait) { \
return NULL; \
}
#define __MIE_TRAIT_DEFINITION_END() \
return trait; \
}
#define __MIE_DIALECT_ADD_OP(op_id) \
extern struct mie_dialect_op *op_id##_op_create( \
extern struct mie_op_definition *op_id##_op_create( \
struct mie_dialect *, struct mie_ctx *); \
op = op_id##_op_create(self, ctx)
#define __MIE_DIALECT_ADD_TYPE(type_id) \
extern struct mie_dialect_type *type_id##_type_create( \
extern struct mie_type_definition *type_id##_type_create( \
struct mie_dialect *, struct mie_ctx *); \
type = type_id##_type_create(self, ctx)
#define __MIE_DIALECT_ADD_TRAIT(trait_id) \
extern struct mie_trait_definition *trait_id##_trait_create( \
struct mie_dialect *, struct mie_ctx *); \
trait = trait_id##_trait_create(self, ctx)
#define MIE_DIALECT_BEGIN(c_sym, name) __MIE_DIALECT_BEGIN(c_sym, name)
#define MIE_DIALECT_END() __MIE_DIALECT_END()
#define MIE_DIALECT_ADD_OP(c_sym) __MIE_DIALECT_ADD_OP(c_sym)
#define MIE_DIALECT_ADD_TYPE(c_sym) __MIE_DIALECT_ADD_TYPE(c_sym)
#define MIE_DIALECT_BEGIN(c_sym, name) __MIE_DIALECT_BEGIN(c_sym, name)
#define MIE_DIALECT_END() __MIE_DIALECT_END()
#define MIE_DIALECT_ADD_OP(c_sym) __MIE_DIALECT_ADD_OP(c_sym)
#define MIE_DIALECT_ADD_TYPE(c_sym) __MIE_DIALECT_ADD_TYPE(c_sym)
#define MIE_DIALECT_ADD_TRAIT(c_sym) __MIE_DIALECT_ADD_TRAIT(c_sym)
#define MIE_DIALECT_OP_BEGIN(c_sym, op) __MIE_DIALECT_OP_BEGIN(c_sym, op)
#define MIE_DIALECT_OP_END() __MIE_DIALECT_OP_END()
#define MIE_DIALECT_OP_PRINT(func) op->op_print = (func)
#define MIE_DIALECT_OP_PARSE(func) op->op_parse = (func)
#define MIE_OP_DEFINITION_BEGIN(c_sym, op) __MIE_OP_DEFINITION_BEGIN(c_sym, op)
#define MIE_OP_DEFINITION_END() __MIE_OP_DEFINITION_END()
#define MIE_OP_DEFINITION_PRINT(func) op->op_print = (func)
#define MIE_OP_DEFINITION_PARSE(func) op->op_parse = (func)
#define MIE_OP_DEFINITION_TRAIT(trait_dialect, trait_name) \
trait = mie_ctx_get_trait(ctx, trait_dialect, trait_name); \
mie_op_definition_add_trait(op, trait);
#define MIE_DIALECT_TYPE_BEGIN(c_sym, type) \
__MIE_DIALECT_TYPE_BEGIN(c_sym, type)
#define MIE_DIALECT_TYPE_END() __MIE_DIALECT_TYPE_END()
#define MIE_DIALECT_TYPE_FLAGS(flags) type->ty_flags = flags
#define MIE_DIALECT_TYPE_STRUCT(name) type->ty_data_size = sizeof(name)
#define MIE_DIALECT_TYPE_INIT(func) type->ty_init = (func)
#define MIE_DIALECT_TYPE_PRINT(func) type->ty_print = (func)
#define MIE_DIALECT_TYPE_VALUE_PRINT(func) type->ty_value_print = (func)
#define MIE_DIALECT_TYPE_PARSE(func) type->ty_parse = (func)
#define MIE_DIALECT_TYPE_BUILD_ID(func) type->ty_build_id = (func)
#define MIE_DIALECT_TYPE_INIT(func) type->ty_init = (func)
#define MIE_DIALECT_TYPE_CLEANUP(func) type->ty_cleanup = (func)
#define MIE_TYPE_DEFINITION_BEGIN(c_sym, type) \
__MIE_TYPE_DEFINITION_BEGIN(c_sym, type)
#define MIE_TYPE_DEFINITION_END() __MIE_TYPE_DEFINITION_END()
#define MIE_TYPE_DEFINITION_FLAGS(flags) type->ty_flags = flags
#define MIE_TYPE_DEFINITION_STRUCT(name) type->ty_data_size = sizeof(name)
#define MIE_TYPE_DEFINITION_INIT(func) type->ty_init = (func)
#define MIE_TYPE_DEFINITION_PRINT(func) type->ty_print = (func)
#define MIE_TYPE_DEFINITION_VALUE_PRINT(func) type->ty_value_print = (func)
#define MIE_TYPE_DEFINITION_PARSE(func) type->ty_parse = (func)
#define MIE_TYPE_DEFINITION_BUILD_ID(func) type->ty_build_id = (func)
#define MIE_TYPE_DEFINITION_INIT(func) type->ty_init = (func)
#define MIE_TYPE_DEFINITION_CLEANUP(func) type->ty_cleanup = (func)
#define MIE_TYPE_DEFINITION_TRAIT(trait_dialect, trait_name) \
trait = mie_ctx_get_trait(ctx, trait_dialect, trait_name); \
mie_type_definition_add_trait(type, trait);
#define MIE_DIALECT_TRAIT_BEGIN(c_sym, trait)
#define MIE_DIALECT_TRAIT_END()
#define MIE_DIALECT_TRAIT_STRUCT(name)
#define MIE_DIALECT_TRAIT_PRINT(func)
#define MIE_DIALECT_TRAIT_CLEANUP(func)
#define MIE_TRAIT_DEFINITION_BEGIN(c_sym, trait) \
__MIE_TRAIT_DEFINITION_BEGIN(c_sym, trait)
#define MIE_TRAIT_DEFINITION_END() __MIE_TRAIT_DEFINITION_END()
#define MIE_TRAIT_DEFINITION_TARGETS(targets) trait->tr_target = (targets)
#define MIE_TRAIT_DEFINITION_STRUCT(name) trait->tr_data_size = sizeof(name)
#define MIE_TRAIT_DEFINITION_PRINT(func) trait->tr_print = (func)
#define MIE_TRAIT_DEFINITION_BUILD_ID(func) trait->tr_build_id = (func)
#define MIE_TRAIT_DEFINITION_CLEANUP(func) trait->tr_cleanup = (func)
#define MIE_TRAIT_DEFINITION_VALIDATE(func) trait->tr_validate = (func)
#endif

View File

@@ -22,6 +22,7 @@ struct mie_op_arg;
struct mie_op_attribute;
struct mie_op_successor;
struct mie_register;
struct mie_value;
MIE_API struct mie_parser *mie_parser_create(
struct mie_ctx *ctx, struct mie_lex *lex);
@@ -38,6 +39,10 @@ MIE_API bool mie_parser_check_type(struct mie_parser *ctx, enum mie_token_type t
MIE_API bool mie_parser_check_symbol(
struct mie_parser *ctx, enum mie_token_symbol sym);
MIE_API bool mie_parser_parse_int(
struct mie_parser *ctx, long long *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_float(
struct mie_parser *ctx, double *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_word(
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_instname(
@@ -61,6 +66,7 @@ MIE_API bool mie_parser_parse_string(
MIE_API bool mie_parser_parse_keyword(struct mie_parser *ctx, const char *kw);
MIE_API bool mie_parser_parse_symbol(
struct mie_parser *ctx, enum mie_token_symbol sym);
MIE_API bool mie_parser_parse_linefeed(struct mie_parser *ctx);
MIE_API bool mie_parser_parse_type(
struct mie_parser *ctx, const struct mie_type **out);
@@ -74,6 +80,11 @@ MIE_API bool mie_parser_parse_operand(
MIE_API bool mie_parser_parse_operand_list(
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_arg, out));
MIE_API bool mie_parser_parse_parameter(
struct mie_parser *ctx, struct mie_op_arg *out);
MIE_API bool mie_parser_parse_parameter_list(
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_arg, out));
MIE_API bool mie_parser_parse_unknown_keyword(struct mie_parser *ctx, b_string *out);
MIE_API bool mie_parser_parse_unknown_symbol(
struct mie_parser *ctx, enum mie_token_symbol sym);
@@ -89,6 +100,12 @@ MIE_API bool mie_parser_parse_region(
struct mie_parser *ctx, struct mie_region *region);
MIE_API bool mie_parser_parse_region_list(
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_region, out));
MIE_API bool mie_parser_parse_anonymous_block(
struct mie_parser *ctx, struct mie_name_map *names,
struct mie_block *block);
MIE_API bool mie_parser_parse_block(
struct mie_parser *ctx, struct mie_name_map *names,
struct mie_block *block);
MIE_API bool mie_parser_parse_attribute(
struct mie_parser *ctx, struct mie_op_attribute *attrib);
@@ -103,5 +120,6 @@ MIE_API bool mie_parser_parse_successor_list(
MIE_API bool mie_parser_parse_module(struct mie_parser *ctx, struct mie_module *mod);
MIE_API bool mie_parser_parse_op(
struct mie_parser *ctx, struct mie_name_map *names, struct mie_op *dest);
MIE_API bool mie_parser_parse_value(struct mie_parser *ctx, struct mie_value **dest);
#endif

View File

@@ -14,7 +14,7 @@ enum mie_token_type {
MIE_TOK_NONE = 0,
MIE_TOK_LINEFEED = 0x0001u,
MIE_TOK_INT = 0x0002u,
MIE_TOK_DOUBLE = 0x0004u,
MIE_TOK_FLOAT = 0x0004u,
MIE_TOK_SYMBOL = 0x0008u,
MIE_TOK_STRING = 0x0010u,
/* single words, not dot-delimited */
@@ -42,7 +42,7 @@ enum mie_token_type {
enum mie_token_value_type {
MIE_TOK_V_NONE = 0,
MIE_TOK_V_INT,
MIE_TOK_V_DOUBLE,
MIE_TOK_V_FLOAT,
MIE_TOK_V_STRING,
MIE_TOK_V_SYMBOL,
};
@@ -83,7 +83,7 @@ struct mie_token {
char *tok_str;
enum mie_token_symbol tok_sym;
long long tok_int;
double tok_double;
double tok_float;
};
};

View File

@@ -17,6 +17,7 @@ enum mie_status {
MIE_ERR_INTERNAL_FAILURE,
MIE_ERR_NO_MEMORY,
MIE_ERR_NO_ENTRY,
MIE_ERR_NO_DATA,
};
MIE_API const struct b_error_vendor *mie_error_vendor(void);

View File

@@ -0,0 +1,64 @@
#ifndef MIE_TRAIT_TRAIT_DEFINITION_H_
#define MIE_TRAIT_TRAIT_DEFINITION_H_
#include <blue/core/stream.h>
#include <mie/id.h>
#include <mie/status.h>
struct mie_trait;
struct mie_dialect;
enum mie_trait_flags {
/* a trait user can only apply the trait once. this is assumed to be the
* case unless a trait is parametised, in which case this flag can be
* used to prevent more than one specialisation from being used. */
MIE_TRAIT_F_UNIQUE = 0x01u,
MIE_TRAIT_F_PARAMETISED = 0x02u,
};
/* describe exactly which objects a trait can be applied to */
enum mie_trait_target_type {
MIE_TRAIT_TARGET_NONE = 0x00u,
MIE_TRAIT_TARGET_OP = 0x01u,
MIE_TRAIT_TARGET_TYPE = 0x02u,
};
struct mie_trait_target {
enum mie_trait_target_type target_type;
union {
const struct mie_type *ptr_type;
const struct mie_op *ptr_op;
} target_ptr;
};
/* used to define a trait */
struct mie_trait_definition {
/* ID for the generic trait */
mie_id tr_id;
char *tr_name;
struct mie_dialect *tr_parent;
enum mie_trait_flags tr_flags;
/* compatible target bitmask */
enum mie_trait_target_type tr_target;
/* the size of any corresponding struct mie_trait instances */
size_t tr_data_size;
void (*tr_init)(const struct mie_trait_definition *, struct mie_trait *);
enum mie_status (*tr_build_id)(
const struct mie_trait_definition *, const struct mie_trait *,
struct mie_id_builder *);
enum mie_status (*tr_print)(
const struct mie_trait_definition *, const struct mie_trait *,
b_stream *);
enum mie_status (*tr_cleanup)(
const struct mie_trait_definition *, struct mie_trait *);
enum mie_status (*tr_validate)(
const struct mie_trait_definition *, const struct mie_trait *,
const struct mie_trait_target *);
};
MIE_API struct mie_trait_definition *mie_trait_definition_create(
struct mie_dialect *parent, const char *name);
#endif

View File

@@ -15,6 +15,9 @@ struct mie_trait_table {
struct mie_trait_table_iterator {
const struct mie_trait *it_trait;
int _f;
struct mie_id_map_iterator _n;
const struct mie_trait_table *_m;
b_queue_entry *_e;
};
@@ -32,6 +35,9 @@ MIE_API enum mie_status mie_trait_table_get_generic(
const char *trait_name, struct mie_trait_table_iterator *it);
MIE_API enum mie_status mie_trait_table_put(
struct mie_trait_table *table, const struct mie_trait *trait);
MIE_API enum mie_status mie_trait_table_iterate(
const struct mie_trait_table *table,
int (*func)(const struct mie_trait *, void *), void *arg);
MIE_API enum mie_status mie_trait_table_iterator_move_next(
struct mie_trait_table_iterator *it);

View File

@@ -3,40 +3,18 @@
#include <mie/id.h>
struct mie_trait;
enum mie_trait_flags {
/* a trait user can only apply the trait once. this is assumed to be the
* case unless a trait is parametised, in which case this flag can be
* used to prevent more than one specialisation from being used. */
MIE_TRAIT_F_UNIQUE = 0x01u,
MIE_TRAIT_F_PARAMETISED = 0x02u,
};
/* used to define a trait */
struct mie_trait_definition {
/* ID for the generic trait */
mie_id tr_id;
char *tr_name;
enum mie_trait_flags tr_flags;
/* the size of any corresponding struct mie_trait instances */
size_t tr_data_size;
enum mie_status (*tr_build_id)(
const struct mie_trait_definition *, const struct mie_trait *,
struct mie_id_builder *);
enum mie_status (*tr_print)(
const struct mie_trait_definition *, const struct mie_trait *,
b_stream *);
};
struct mie_dialect;
struct mie_trait_definition;
/* used to link an op/type/etc to a trait. if the trait is parametised, this
* struct includes any parameter values. */
struct mie_trait {
/* this is NOT the same as tr_def->tr_id */
mie_id tr_id;
char *tr_name;
const struct mie_trait_definition *tr_def;
};
MIE_API void mie_trait_print(const struct mie_trait *type, b_stream *out);
#endif

View File

@@ -0,0 +1,39 @@
#ifndef MIE_TYPE_TYPE_DEFINITION_H_
#define MIE_TYPE_TYPE_DEFINITION_H_
#include <mie/trait/trait-table.h>
struct mie_value;
struct mie_type;
struct mie_parser;
/* a static struct that defines the properties, traits, and callbacks for a type. */
struct mie_type_definition {
mie_id ty_id;
struct mie_trait_table ty_traits;
struct mie_dialect *ty_parent;
char *ty_name;
size_t ty_data_size;
void (*ty_init)(const struct mie_type_definition *, struct mie_type *);
void (*ty_cleanup)(const struct mie_type_definition *, struct mie_type *);
void (*ty_instance_cleanup)(const struct mie_type *, struct mie_value *);
enum mie_status (*ty_print)(
const struct mie_type_definition *, const struct mie_type *,
b_stream *);
enum mie_status (*ty_value_print)(
const struct mie_type *, const struct mie_value *, b_stream *);
enum mie_status (*ty_parse)(
const struct mie_type_definition *, struct mie_parser *,
struct mie_type **);
void (*ty_build_id)(const struct mie_type *, struct mie_id_builder *);
};
MIE_API struct mie_type_definition *mie_type_definition_create(
struct mie_dialect *parent, const char *name);
MIE_API enum mie_status mie_type_definition_add_trait(
struct mie_type_definition *type, const struct mie_trait *trait);
#endif

View File

@@ -8,37 +8,40 @@
#include <stddef.h>
struct mie_dialect;
struct mie_dialect_type;
struct mie_type_definition;
struct mie_value;
struct mie_id_builder;
enum mie_type_category {
/* all other types */
MIE_TYPE_OTHER = 0,
/* storage types (structs, etc) */
MIE_TYPE_STORAGE,
/* functional types (represents the param/result types of a function) */
MIE_TYPE_FUNCTION,
};
#if 0
enum mie_type_trait {
/* this type is parametised. one or more arguments are required to create
* a corresponding mie_type instance. in textual IR, references to this
* type will be followed by a set of arguments surrounded
* by <angle brackets>. */
MIE_TYPE_TRAIT_PARAMETISED = 0x01u,
/* a mie_type is an instance of mie_dialect_type.
* if the mie_dialect_type is a parametised type, the resulting mie_type
/* this type can only be used within graph regions. unlike graph ops,
* no special prefix is required */
MIE_TYPE_TRAIT_GRAPH_TYPE = 0x02u,
};
#endif
/* a mie_type is a type-instance created from a mie_type_definition.
* if the mie_type_definition is a parametised type, the resulting mie_type
* will have those parameters baked in.
* this is a base struct. dialects that defined their own types do so by
* inheriting from this struct. */
struct mie_type {
/* this is NOT the same as ty_def->ty_id */
mie_id ty_id;
enum mie_type_category ty_category;
char *ty_name;
struct mie_dialect_type *ty_def;
struct mie_type_definition *ty_def;
size_t ty_instance_size;
};
MIE_API struct mie_type *mie_type_create(struct mie_dialect_type *type);
MIE_API struct mie_type *mie_type_create(struct mie_type_definition *type);
MIE_API void mie_type_print(const struct mie_type *type, b_stream *out);
MIE_API void mie_type_build_id(
const struct mie_type *type, struct mie_id_builder *ctx);

View File

@@ -1,11 +1,11 @@
#include <blue/ds/string.h>
#include <mie/dialect/dialect.h>
#include <mie/dialect/op.h>
#include <mie/ir/op-definition.h>
struct mie_dialect_op *mie_dialect_op_create(
struct mie_op_definition *mie_op_definition_create(
struct mie_dialect *parent, const char *name)
{
struct mie_dialect_op *out = malloc(sizeof *out);
struct mie_op_definition *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
@@ -17,9 +17,16 @@ struct mie_dialect_op *mie_dialect_op_create(
}
out->op_parent = parent;
mie_trait_table_init(&out->op_traits);
b_rope name_rope = B_ROPE_CSTR(name);
mie_id_map_put(&parent->d_ops, &out->op_id, &name_rope);
return out;
}
enum mie_status mie_op_definition_add_trait(
struct mie_op_definition *op, const struct mie_trait *trait)
{
return mie_trait_table_put(&op->op_traits, trait);
}

View File

@@ -404,7 +404,7 @@ static enum mie_status push_int(struct mie_lex *lex, unsigned long long v)
return push_token(lex, tok);
}
static enum mie_status push_double(struct mie_lex *lex, double v)
static enum mie_status push_float(struct mie_lex *lex, double v)
{
struct mie_token *tok = malloc(sizeof *tok);
if (!tok) {
@@ -413,9 +413,9 @@ static enum mie_status push_double(struct mie_lex *lex, double v)
memset(tok, 0x0, sizeof *tok);
tok->tok_type = MIE_TOK_DOUBLE;
tok->tok_value_type = MIE_TOK_V_DOUBLE;
tok->tok_double = v;
tok->tok_type = MIE_TOK_FLOAT;
tok->tok_value_type = MIE_TOK_V_FLOAT;
tok->tok_float = v;
return push_token(lex, tok);
}
@@ -541,7 +541,7 @@ static enum mie_status read_number(struct mie_lex *lex, bool negate)
v *= -1;
}
return push_double(lex, v);
return push_float(lex, v);
} else {
unsigned long long v = strtoull(s, &ep, base);

View File

@@ -1,7 +1,7 @@
#include <mie/ctx.h>
#include <mie/dialect/arith.h>
#include <mie/dialect/dialect.h>
#include <mie/dialect/type.h>
#include <mie/ir/block.h>
#include <mie/ir/module.h>
#include <mie/ir/op.h>
#include <mie/ir/region.h>
@@ -10,13 +10,22 @@
#include <mie/parse/parse.h>
#include <mie/parse/token.h>
#include <mie/type/function.h>
#include <mie/type/type-definition.h>
#include <mie/vector.h>
struct mie_parser {
struct mie_ctx *p_ctx;
struct mie_lex *p_lex;
enum mie_status p_status;
b_string *s_tmp;
};
static b_string *get_temp_string(struct mie_parser *parser)
{
b_string_clear(parser->s_tmp);
return parser->s_tmp;
}
struct mie_parser *mie_parser_create(struct mie_ctx *ctx, struct mie_lex *lex)
{
struct mie_parser *out = malloc(sizeof *out);
@@ -26,6 +35,12 @@ struct mie_parser *mie_parser_create(struct mie_ctx *ctx, struct mie_lex *lex)
memset(out, 0x0, sizeof *out);
out->s_tmp = b_string_create();
if (!out->s_tmp) {
free(out);
return NULL;
}
out->p_ctx = ctx;
out->p_lex = lex;
out->p_status = MIE_SUCCESS;
@@ -35,6 +50,10 @@ struct mie_parser *mie_parser_create(struct mie_ctx *ctx, struct mie_lex *lex)
void mie_parser_destroy(struct mie_parser *ctx)
{
if (ctx->s_tmp) {
b_string_unref(ctx->s_tmp);
}
free(ctx);
}
@@ -85,6 +104,48 @@ bool mie_parser_advance(struct mie_parser *ctx)
return mie_lex_get_status(ctx->p_lex) == MIE_SUCCESS;
}
bool mie_parser_parse_int(
struct mie_parser *ctx, long long *out, struct mie_file_span *loc)
{
if (!mie_parser_check_type(ctx, MIE_TOK_INT)) {
return false;
}
struct mie_token *tok = mie_lex_peek(ctx->p_lex);
if (tok->tok_value_type != MIE_TOK_V_INT) {
return false;
}
if (loc) {
mie_file_span_init(loc, tok);
}
*out = tok->tok_int;
mie_lex_advance(ctx->p_lex);
return true;
}
bool mie_parser_parse_float(
struct mie_parser *ctx, double *out, struct mie_file_span *loc)
{
if (!mie_parser_check_type(ctx, MIE_TOK_FLOAT)) {
return false;
}
struct mie_token *tok = mie_lex_peek(ctx->p_lex);
if (tok->tok_value_type != MIE_TOK_V_FLOAT) {
return false;
}
if (loc) {
mie_file_span_init(loc, tok);
}
*out = tok->tok_float;
mie_lex_advance(ctx->p_lex);
return true;
}
#define TOKEN_PARSER(name, id) \
bool mie_parser_parse_##name( \
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc) \
@@ -93,7 +154,16 @@ bool mie_parser_advance(struct mie_parser *ctx)
return false; \
} \
struct mie_token *tok = mie_lex_peek(ctx->p_lex); \
b_string_append_cstr(out, tok->tok_str); \
switch (tok->tok_value_type) { \
case MIE_TOK_V_STRING: \
b_string_append_cstr(out, tok->tok_str); \
break; \
case MIE_TOK_V_INT: \
b_string_append_cstrf(out, "%lld", tok->tok_int); \
break; \
default: \
return false; \
} \
if (loc) { \
mie_file_span_init(loc, tok); \
} \
@@ -123,17 +193,27 @@ bool mie_parser_parse_symbol(struct mie_parser *ctx, enum mie_token_symbol sym)
return true;
}
static bool parse_builtin_type_name(
struct mie_parser *ctx, const struct mie_type **out)
bool mie_parser_parse_linefeed(struct mie_parser *ctx)
{
b_string *name = b_string_create();
struct mie_file_span loc;
if (!mie_parser_parse_word(ctx, name, &loc)) {
b_string_unref(name);
struct mie_token *tok = mie_lex_peek(ctx->p_lex);
if (tok->tok_type != MIE_TOK_LINEFEED) {
return false;
}
const struct mie_dialect_type *type_info = NULL;
mie_lex_advance(ctx->p_lex);
return true;
}
static bool parse_builtin_type_name(
struct mie_parser *ctx, const struct mie_type **out)
{
b_string *name = get_temp_string(ctx);
struct mie_file_span loc;
if (!mie_parser_parse_word(ctx, name, &loc)) {
return false;
}
const struct mie_type_definition *type_info = NULL;
const struct mie_type *type = NULL;
size_t width = 0;
char tmp = 0;
@@ -147,20 +227,21 @@ static bool parse_builtin_type_name(
const char *name_cstr = b_string_ptr(name);
if (!strcmp(name_cstr, "memref")) {
type_info = mie_ctx_get_dialect_type(
type_info = mie_ctx_get_type_definition(
ctx->p_ctx, "memref", "memref");
} else if (!strcmp(name_cstr, "index")) {
type_info
= mie_ctx_get_dialect_type(ctx->p_ctx, "index", "index");
type_info = mie_ctx_get_type_definition(
ctx->p_ctx, "index", "index");
} else if (!strcmp(name_cstr, "str")) {
type_info = mie_ctx_get_dialect_type(
type_info = mie_ctx_get_type_definition(
ctx->p_ctx, "builtin", "string");
} else if (sscanf(name_cstr, "i%zu%c", &width, &tmp) == 1) {
type_info = mie_ctx_get_dialect_type(ctx->p_ctx, "arith", "int");
type_info = mie_ctx_get_type_definition(
ctx->p_ctx, "arith", "int");
base_type = INT;
} else if (sscanf(name_cstr, "f%zu%c", &width, &tmp) == 1) {
type_info
= mie_ctx_get_dialect_type(ctx->p_ctx, "arith", "float");
type_info = mie_ctx_get_type_definition(
ctx->p_ctx, "arith", "float");
base_type = FLOAT;
}
@@ -188,10 +269,9 @@ static bool parse_builtin_type_name(
static bool parse_type_name(struct mie_parser *ctx, const struct mie_type **out)
{
b_string *name = b_string_create();
b_string *name = get_temp_string(ctx);
struct mie_file_span loc;
if (!mie_parser_parse_typename(ctx, name, &loc)) {
b_string_unref(name);
return false;
}
@@ -353,7 +433,7 @@ MIE_API bool mie_parser_parse_function_type(
bool mie_parser_parse_operand(struct mie_parser *ctx, struct mie_op_arg *out)
{
memset(out, 0x0, sizeof *out);
b_string *str = b_string_create();
b_string *str = get_temp_string(ctx);
bool result = false;
struct mie_file_span loc;
@@ -367,7 +447,6 @@ bool mie_parser_parse_operand(struct mie_parser *ctx, struct mie_op_arg *out)
result = true;
}
b_string_unref(str);
return result;
}
@@ -420,6 +499,82 @@ bool mie_parser_parse_operand_list(
return true;
}
bool mie_parser_parse_parameter(struct mie_parser *ctx, struct mie_op_arg *out)
{
memset(out, 0x0, sizeof *out);
b_string *str = get_temp_string(ctx);
struct mie_file_span loc;
if (mie_parser_parse_vregname(ctx, str, &loc)) {
out->arg_unresolved.reg_name = b_string_steal(str);
out->arg_unresolved.reg_flags = MIE_REGISTER_F_VIRTUAL;
} else if (mie_parser_parse_mregname(ctx, str, &loc)) {
out->arg_unresolved.reg_name = b_string_steal(str);
out->arg_unresolved.reg_flags = MIE_REGISTER_F_MACHINE;
} else {
return false;
}
if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)) {
return false;
}
if (!mie_parser_parse_type(ctx, &out->arg_unresolved.reg_type)) {
return false;
}
return true;
}
bool mie_parser_parse_parameter_list(
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_arg, out))
{
bool ok = false;
struct mie_op_arg *operand = NULL;
struct mie_token *tok = mie_parser_peek(ctx);
enum mie_token_type type = MIE_TOKEN_TYPE(tok);
if (type != MIE_TOK_VREGNAME && type != MIE_TOK_MREGNAME) {
return false;
}
operand = mie_vector_ref_emplace_back(out);
if (!operand) {
return false;
}
if (!mie_parser_parse_parameter(ctx, operand)) {
return false;
}
while (1) {
tok = mie_parser_peek(ctx);
if (!MIE_TOKEN_IS_SYMBOL(tok, MIE_SYM_COMMA)) {
break;
}
mie_parser_advance(ctx);
tok = mie_parser_peek(ctx);
type = MIE_TOKEN_TYPE(tok);
if (type != MIE_TOK_VREGNAME && type != MIE_TOK_MREGNAME) {
return false;
}
operand = mie_vector_ref_emplace_back(out);
if (!operand) {
return false;
}
if (!mie_parser_parse_parameter(ctx, operand)) {
return false;
}
}
return true;
}
bool mie_parser_parse_register(
struct mie_parser *ctx, struct mie_name_map *names, struct mie_register *out)
{
@@ -438,14 +593,26 @@ bool mie_parser_parse_register(
return false;
}
if (!mie_name_map_put(
names, &out->reg_name, tok->tok_str, MIE_NAME_MAP_F_STRICT)) {
return false;
struct mie_name *name = NULL;
b_string *tmp = get_temp_string(ctx);
switch (tok->tok_value_type) {
case MIE_TOK_V_STRING:
name = mie_name_map_put(
names, &out->reg_name, tok->tok_str, MIE_NAME_MAP_F_STRICT);
break;
case MIE_TOK_V_INT:
b_string_append_cstrf(tmp, "%lld", tok->tok_int);
name = mie_name_map_put(
names, &out->reg_name, b_string_ptr(tmp),
MIE_NAME_MAP_F_STRICT);
break;
default:
break;
}
mie_parser_advance(ctx);
return true;
return name != NULL;
}
bool mie_parser_parse_register_list(
@@ -526,6 +693,35 @@ bool mie_parser_parse_module(struct mie_parser *ctx, struct mie_module *mod)
bool mie_parser_parse_region(struct mie_parser *ctx, struct mie_region *region)
{
region->r_names = mie_name_map_create(NULL);
if (!mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_BRACE)) {
return false;
}
mie_parser_parse_linefeed(ctx);
struct mie_block *block = NULL;
if (mie_parser_peek_type(ctx) != MIE_TOK_BLOCKNAME) {
block = mie_vector_emplace_back(region->r_blocks);
if (!mie_parser_parse_anonymous_block(ctx, region->r_names, block)) {
return false;
}
}
while (1) {
if (mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_BRACE)) {
break;
}
block = mie_vector_emplace_back(region->r_blocks);
if (!mie_parser_parse_block(ctx, region->r_names, block)) {
return false;
}
}
return true;
}
@@ -561,28 +757,269 @@ bool mie_parser_parse_region_list(
return true;
}
bool mie_parser_parse_anonymous_block(
struct mie_parser *ctx, struct mie_name_map *names, struct mie_block *block)
{
mie_parser_parse_linefeed(ctx);
struct mie_op *op = mie_vector_emplace_back(block->b_ops);
if (!mie_parser_parse_op(ctx, names, op)) {
return false;
}
mie_parser_parse_linefeed(ctx);
while (1) {
if (mie_parser_peek_type(ctx) == MIE_TOK_BLOCKNAME) {
break;
}
if (mie_parser_peek_symbol(ctx) == MIE_SYM_RIGHT_BRACE) {
break;
}
struct mie_op *op = mie_vector_emplace_back(block->b_ops);
if (!mie_parser_parse_op(ctx, names, op)) {
return false;
}
if (!mie_parser_parse_linefeed(ctx)) {
return false;
}
}
return true;
}
static bool parse_block_parameters(
struct mie_parser *ctx, struct mie_name_map *names, struct mie_block *block)
{
if (!mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_PAREN)) {
return false;
}
MIE_VECTOR_DEFINE(struct mie_op_arg, block_params);
if (!mie_parser_parse_parameter_list(ctx, MIE_VECTOR_REF(block_params))) {
return false;
}
if (!mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_PAREN)
|| !mie_parser_parse_symbol(ctx, MIE_SYM_COLON)
|| !mie_parser_parse_linefeed(ctx)) {
mie_vector_destroy(block_params, NULL);
return false;
}
for (size_t i = 0; i < MIE_VECTOR_COUNT(block_params); i++) {
struct mie_register *param_reg
= mie_vector_emplace_back(block->b_params);
param_reg->reg_flags = block_params.items[i].arg_unresolved.reg_flags
| MIE_REGISTER_F_BLOCK_PARAM;
param_reg->reg_type = block_params.items[i].arg_unresolved.reg_type;
param_reg->reg_block = block;
if (!mie_name_map_put(
names, &param_reg->reg_name,
block_params.items[i].arg_unresolved.reg_name,
MIE_NAME_MAP_F_STRICT)) {
return false;
}
}
return true;
}
bool mie_parser_parse_block(
struct mie_parser *ctx, struct mie_name_map *names, struct mie_block *block)
{
b_string *str = get_temp_string(ctx);
struct mie_file_span span;
if (!mie_parser_parse_blockname(ctx, str, &span)) {
return false;
}
if (!mie_name_map_put(
names, &block->b_name, b_string_ptr(str),
MIE_NAME_MAP_F_STRICT)) {
return false;
}
if (mie_parser_peek_symbol(ctx) == MIE_SYM_LEFT_PAREN
&& !parse_block_parameters(ctx, names, block)) {
return false;
}
if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)
|| !mie_parser_parse_linefeed(ctx)) {
return false;
}
while (1) {
if (mie_parser_peek_type(ctx) == MIE_TOK_BLOCKNAME) {
break;
}
if (mie_parser_peek_symbol(ctx) == MIE_SYM_RIGHT_BRACE) {
break;
}
struct mie_op *op = mie_vector_emplace_back(block->b_ops);
if (!mie_parser_parse_op(ctx, names, op)) {
return false;
}
if (!mie_parser_parse_linefeed(ctx)) {
return false;
}
}
return true;
}
bool mie_parser_parse_attribute(
struct mie_parser *ctx, struct mie_op_attribute *attrib)
{
return false;
b_string *str = get_temp_string(ctx);
struct mie_file_span span;
if (!mie_parser_parse_word(ctx, str, &span)) {
return false;
}
attrib->attrib_name = b_string_steal(str);
if (!mie_parser_parse_symbol(ctx, MIE_SYM_EQUAL)) {
return false;
}
struct mie_value *value = NULL;
if (!mie_parser_parse_value(ctx, &value)) {
return false;
}
attrib->attrib_value = value;
return true;
}
bool mie_parser_parse_attribute_list(
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_attribute, out))
{
return false;
bool ok = false;
struct mie_op_attribute *attrib = NULL;
attrib = mie_vector_ref_emplace_back(out);
if (!attrib) {
return false;
}
if (!mie_parser_parse_attribute(ctx, attrib)) {
return false;
}
while (1) {
const struct mie_token *tok = mie_parser_peek(ctx);
if (!MIE_TOKEN_IS_SYMBOL(tok, MIE_SYM_COMMA)) {
break;
}
mie_parser_advance(ctx);
mie_parser_parse_linefeed(ctx);
attrib = mie_vector_ref_emplace_back(out);
if (!attrib) {
return false;
}
if (!mie_parser_parse_attribute(ctx, attrib)) {
return false;
}
}
return true;
}
bool mie_parser_parse_successor(
struct mie_parser *ctx, struct mie_op_successor *successor)
bool mie_parser_parse_successor(struct mie_parser *ctx, struct mie_op_successor *out)
{
memset(out, 0x0, sizeof *out);
b_string *str = get_temp_string(ctx);
bool result = false;
struct mie_file_span span;
if (!mie_parser_parse_blockname(ctx, str, &span)) {
return false;
}
out->s_block_name = b_string_steal(str);
if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)) {
return true;
}
if (!mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_PAREN)) {
goto fail;
}
if (!mie_parser_parse_parameter_list(ctx, MIE_VECTOR_REF(out->s_args))) {
goto fail;
}
if (!mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_PAREN)) {
goto fail;
}
return true;
fail:
if (out->s_block_name) {
free(out->s_block_name);
out->s_block_name = NULL;
}
if (MIE_VECTOR_MAX(out->s_args) > 0) {
mie_vector_destroy(out->s_args, NULL);
}
return false;
}
bool mie_parser_parse_successor_list(
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_successor, out))
{
return false;
bool ok = false;
struct mie_op_successor *successor = NULL;
successor = mie_vector_ref_emplace_back(out);
if (!successor) {
return false;
}
if (!mie_parser_parse_successor(ctx, successor)) {
return false;
}
while (1) {
const struct mie_token *tok = mie_parser_peek(ctx);
if (!MIE_TOKEN_IS_SYMBOL(tok, MIE_SYM_COMMA)) {
break;
}
mie_parser_advance(ctx);
mie_parser_parse_linefeed(ctx);
successor = mie_vector_ref_emplace_back(out);
if (!successor) {
return false;
}
if (!mie_parser_parse_successor(ctx, successor)) {
return false;
}
}
return true;
}
static bool parse_custom_op(
@@ -594,21 +1031,20 @@ static bool parse_custom_op(
static bool parse_generic_op(
struct mie_parser *ctx, struct mie_name_map *names, struct mie_op *dest)
{
b_string *str = b_string_create();
b_string *str = get_temp_string(ctx);
struct mie_file_span loc;
if (!mie_parser_parse_opname(ctx, str, &loc)) {
b_string_unref(str);
return false;
}
dest->op_name = b_string_steal(str);
b_string_unref(str);
if (!mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_PAREN)) {
return false;
}
if (!mie_parser_parse_operand_list(ctx, MIE_VECTOR_REF(dest->op_args))) {
if (mie_parser_peek_symbol(ctx) != MIE_SYM_RIGHT_PAREN
&& !mie_parser_parse_operand_list(ctx, MIE_VECTOR_REF(dest->op_args))) {
return false;
}
@@ -616,6 +1052,30 @@ static bool parse_generic_op(
return false;
}
if (mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_BRACKET)) {
mie_parser_parse_linefeed(ctx);
if (!mie_parser_parse_successor_list(
ctx, MIE_VECTOR_REF(dest->op_successors))) {
return false;
}
if (!mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_BRACKET)) {
return false;
}
}
if (mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_PAREN)) {
mie_parser_parse_linefeed(ctx);
if (!mie_parser_parse_region_list(
ctx, MIE_VECTOR_REF(dest->op_regions))) {
return false;
}
if (!mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_PAREN)) {
return false;
}
}
if (mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_BRACKET)) {
if (!mie_parser_parse_successor_list(
ctx, MIE_VECTOR_REF(dest->op_successors))) {
@@ -720,3 +1180,101 @@ bool mie_parser_parse_op(
return false;
}
}
static bool parse_string(struct mie_parser *ctx, struct mie_value **dest)
{
b_string *str = get_temp_string(ctx);
struct mie_file_span span;
if (!mie_parser_parse_string(ctx, str, &span)) {
return false;
}
struct mie_value *v = mie_ctx_get_string(ctx->p_ctx, b_string_ptr(str));
if (!v) {
return false;
}
*dest = v;
return true;
}
static bool parse_int(struct mie_parser *ctx, struct mie_value **dest)
{
long long value = 0;
struct mie_file_span span;
if (!mie_parser_parse_int(ctx, &value, &span)) {
return false;
}
if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)) {
return false;
}
const struct mie_type *type = NULL;
if (!mie_parser_parse_type(ctx, &type)) {
return false;
}
size_t width = mie_arith_int_type_get_width(type);
if (width == (size_t)-1) {
return false;
}
struct mie_value *v = mie_ctx_get_int(ctx->p_ctx, value, width);
if (!v) {
return false;
}
*dest = v;
return true;
}
static bool parse_float(struct mie_parser *ctx, struct mie_value **dest)
{
double value = 0;
struct mie_file_span span;
if (!mie_parser_parse_float(ctx, &value, &span)) {
return false;
}
if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)) {
return false;
}
const struct mie_type *type = NULL;
if (!mie_parser_parse_type(ctx, &type)) {
return false;
}
size_t width = mie_arith_float_type_get_width(type);
if (width == (size_t)-1) {
return false;
}
struct mie_value *v = mie_ctx_get_float(ctx->p_ctx, value, width);
if (!v) {
return false;
}
*dest = v;
return true;
}
bool mie_parser_parse_value(struct mie_parser *ctx, struct mie_value **dest)
{
enum mie_token_type type = mie_parser_peek_type(ctx);
switch (type) {
case MIE_TOK_STRING:
return parse_string(ctx, dest);
case MIE_TOK_INT:
return parse_int(ctx, dest);
case MIE_TOK_FLOAT:
return parse_float(ctx, dest);
default:
return false;
}
}

View File

@@ -23,7 +23,7 @@ const char *mie_token_type_to_string(enum mie_token_type type)
ENUM_STR(MIE_TOK_NONE);
ENUM_STR(MIE_TOK_LINEFEED);
ENUM_STR(MIE_TOK_INT);
ENUM_STR(MIE_TOK_DOUBLE);
ENUM_STR(MIE_TOK_FLOAT);
ENUM_STR(MIE_TOK_SYMBOL);
ENUM_STR(MIE_TOK_WORD);
ENUM_STR(MIE_TOK_NAME);

View File

@@ -0,0 +1,25 @@
#include <blue/ds/string.h>
#include <mie/dialect/dialect.h>
#include <mie/trait/trait-definition.h>
struct mie_trait_definition *mie_trait_definition_create(
struct mie_dialect *parent, const char *name)
{
struct mie_trait_definition *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
out->tr_name = b_strdup(name);
if (!out->tr_name) {
free(out);
return NULL;
}
out->tr_parent = parent;
b_rope name_rope = B_ROPE_CSTR(name);
mie_id_map_put(&parent->d_traits, &out->tr_id, &name_rope);
return out;
}

View File

@@ -1,3 +1,5 @@
#include <mie/dialect/dialect.h>
#include <mie/trait/trait-definition.h>
#include <mie/trait/trait-table.h>
#include <mie/trait/trait.h>
@@ -29,7 +31,6 @@ static struct unique_trait *unique_trait_create(const struct mie_trait *trait)
}
memset(out, 0x0, sizeof *out);
out->u_id = trait->tr_id;
out->u_trait = trait;
return out;
@@ -48,7 +49,6 @@ static struct generic_trait *generic_trait_create(const struct mie_trait *trait)
}
memset(out, 0x0, sizeof *out);
out->g_id = trait->tr_def->tr_id;
struct unique_trait *entry = unique_trait_create(trait);
if (!entry) {
@@ -113,12 +113,55 @@ const struct mie_trait *mie_trait_table_get_unique(
static enum mie_status put_unique_trait(
struct mie_trait_table *table, const struct mie_trait *trait)
{
struct unique_trait *unique = unique_trait_create(trait);
if (!unique) {
return MIE_ERR_NO_MEMORY;
}
struct mie_id_builder id_ctx;
mie_id_builder_begin(&id_ctx, mie_id_map_get_ns(&table->tr_unique));
mie_id_builder_add_cstr(&id_ctx, trait->tr_def->tr_parent->d_name);
mie_id_builder_add_char(&id_ctx, '.');
mie_id_builder_add_cstr(&id_ctx, trait->tr_def->tr_name);
mie_id_builder_end(&id_ctx, &unique->u_id);
mie_id_map_put_id(&table->tr_unique, &unique->u_id);
return MIE_SUCCESS;
}
static enum mie_status put_generic_trait(
struct mie_trait_table *table, const struct mie_trait *trait)
{
mie_id id;
struct mie_id_builder id_ctx;
mie_id_builder_begin(&id_ctx, mie_id_map_get_ns(&table->tr_generic));
mie_id_builder_add_cstr(&id_ctx, trait->tr_def->tr_parent->d_name);
mie_id_builder_add_char(&id_ctx, '.');
mie_id_builder_add_cstr(&id_ctx, trait->tr_def->tr_name);
mie_id_builder_end(&id_ctx, &id);
mie_id *target = mie_id_map_get(&table->tr_generic, &id);
struct generic_trait *generic
= b_unbox(struct generic_trait, target, g_id);
if (!generic) {
generic = generic_trait_create(trait);
if (!generic) {
return MIE_ERR_NO_MEMORY;
}
generic->g_id = id;
mie_id_map_put_id(&table->tr_generic, &generic->g_id);
}
struct unique_trait *unique = unique_trait_create(trait);
if (!unique) {
return MIE_ERR_NO_MEMORY;
}
b_queue_push_back(&generic->g_traits, &unique->u_id.e_entry);
return MIE_SUCCESS;
}
@@ -163,6 +206,51 @@ enum mie_status mie_trait_table_get_generic(
return MIE_SUCCESS;
}
enum mie_status mie_trait_table_iterate(
const struct mie_trait_table *table,
int (*func)(const struct mie_trait *, void *), void *arg)
{
struct mie_id_map_iterator it = {0};
mie_id_map_iterator_begin(&it, &table->tr_unique);
int ret = 0;
while (it.it_id) {
const struct unique_trait *trait
= b_unbox(struct unique_trait, it.it_id, u_id);
ret = func(trait->u_trait, arg);
if (ret != 0) {
return MIE_SUCCESS;
}
mie_id_map_iterator_move_next(&it);
}
mie_id_map_iterator_begin(&it, &table->tr_generic);
while (it.it_id) {
const struct generic_trait *trait_group
= b_unbox(struct generic_trait, it.it_id, g_id);
const b_queue_entry *cur = b_queue_first(&trait_group->g_traits);
while (cur) {
const struct unique_trait *trait
= b_unbox(struct unique_trait, cur, u_id.e_entry);
ret = func(trait->u_trait, arg);
if (ret != 0) {
return MIE_SUCCESS;
}
cur = b_queue_next(cur);
}
mie_id_map_iterator_move_next(&it);
}
return MIE_SUCCESS;
}
enum mie_status mie_trait_table_iterator_move_next(
struct mie_trait_table_iterator *it)
{

15
mie/trait/trait.c Normal file
View File

@@ -0,0 +1,15 @@
#include <mie/trait/trait-definition.h>
#include <mie/trait/trait.h>
void mie_trait_print(const struct mie_trait *trait, b_stream *out)
{
if (trait->tr_name) {
b_stream_write_string(out, trait->tr_name, NULL);
} else if (trait->tr_def && trait->tr_def->tr_print) {
trait->tr_def->tr_print(trait->tr_def, trait, out);
} else if (trait->tr_def->tr_name) {
b_stream_write_string(out, trait->tr_def->tr_name, NULL);
} else {
b_stream_write_string(out, "<UNNAMED-TRAIT>", NULL);
}
}

View File

@@ -1,5 +1,5 @@
#include <mie/dialect/type.h>
#include <mie/type/function.h>
#include <mie/type/type-definition.h>
#include <stdlib.h>
#include <string.h>
@@ -12,9 +12,19 @@ static void build_id(const struct mie_type *type, struct mie_id_builder *ctx)
function->func_out.items, function->func_out.count);
}
static struct mie_dialect_type function_type = {
static enum mie_status type_print(
const struct mie_type_definition *type_info,
const struct mie_type *type, b_stream *out)
{
mie_function_type_print((const struct mie_function_type *)type, out);
return MIE_SUCCESS;
}
static struct mie_type_definition function_type = {
.ty_name = "*function",
.ty_data_size = sizeof(struct mie_type),
.ty_build_id = build_id,
.ty_print = type_print,
};
struct mie_function_type *mie_function_type_create(void)
@@ -27,7 +37,6 @@ struct mie_function_type *mie_function_type_create(void)
memset(out, 0x0, sizeof *out);
out->func_base.ty_def = &function_type;
out->func_base.ty_category = MIE_TYPE_FUNCTION;
return out;
}

View File

@@ -1,5 +1,5 @@
#include <mie/dialect/type.h>
#include <mie/type/storage.h>
#include <mie/type/type-definition.h>
#include <stdlib.h>
#include <string.h>
@@ -11,9 +11,19 @@ static void build_id(const struct mie_type *type, struct mie_id_builder *ctx)
ctx, storage->st_parts.items, storage->st_parts.count);
}
static struct mie_dialect_type storage_type = {
static enum mie_status type_print(
const struct mie_type_definition *type_info,
const struct mie_type *type, b_stream *out)
{
mie_storage_type_print((const struct mie_storage_type *)type, out);
return MIE_SUCCESS;
}
static struct mie_type_definition storage_type = {
.ty_name = "*storage",
.ty_data_size = sizeof(struct mie_type),
.ty_build_id = build_id,
.ty_print = type_print,
};
struct mie_storage_type *mie_storage_type_create(void)
@@ -26,7 +36,6 @@ struct mie_storage_type *mie_storage_type_create(void)
memset(out, 0x0, sizeof *out);
out->st_base.ty_def = &storage_type;
out->st_base.ty_category = MIE_TYPE_STORAGE;
return out;
}

View File

@@ -1,11 +1,11 @@
#include <blue/ds/string.h>
#include <mie/dialect/dialect.h>
#include <mie/dialect/type.h>
#include <mie/type/type-definition.h>
struct mie_dialect_type *mie_dialect_type_create(
struct mie_type_definition *mie_type_definition_create(
struct mie_dialect *parent, const char *name)
{
struct mie_dialect_type *out = malloc(sizeof *out);
struct mie_type_definition *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
@@ -17,9 +17,16 @@ struct mie_dialect_type *mie_dialect_type_create(
}
out->ty_parent = parent;
mie_trait_table_init(&out->ty_traits);
b_rope name_rope = B_ROPE_CSTR(name);
mie_id_map_put(&parent->d_types, &out->ty_id, &name_rope);
return out;
}
enum mie_status mie_type_definition_add_trait(
struct mie_type_definition *type, const struct mie_trait *trait)
{
return mie_trait_table_put(&type->ty_traits, trait);
}

View File

@@ -1,9 +1,9 @@
#include <mie/dialect/type.h>
#include <mie/type/function.h>
#include <mie/type/storage.h>
#include <mie/type/type-definition.h>
#include <mie/type/type.h>
struct mie_type *mie_type_create(struct mie_dialect_type *type)
struct mie_type *mie_type_create(struct mie_type_definition *type)
{
if (type->ty_data_size < sizeof(struct mie_type)) {
return NULL;
@@ -22,17 +22,6 @@ struct mie_type *mie_type_create(struct mie_dialect_type *type)
void mie_type_print(const struct mie_type *type, b_stream *out)
{
switch (type->ty_category) {
case MIE_TYPE_STORAGE:
mie_storage_type_print((const struct mie_storage_type *)type, out);
return;
case MIE_TYPE_FUNCTION:
mie_function_type_print((const struct mie_function_type *)type, out);
return;
default:
break;
}
if (type->ty_name) {
b_stream_write_string(out, type->ty_name, NULL);
} else if (type->ty_def && type->ty_def->ty_print) {

View File

@@ -1,4 +1,4 @@
#include <mie/dialect/type.h>
#include <mie/type/type-definition.h>
#include <mie/type/type.h>
#include <mie/value.h>

View File

@@ -1,29 +1,400 @@
#include "cmd.h"
#include <assert.h>
#include <blue/cmd.h>
#include <blue/io/file.h>
#include <blue/io/path.h>
#include <blue/term.h>
#include <mie/ctx.h>
#include <mie/ir/convert.h>
#include <mie/ir/value.h>
#include <mie/dialect/arith.h>
#include <mie/dialect/builtin.h>
#include <mie/dialect/cf.h>
#include <mie/dialect/dialect.h>
#include <mie/dialect/func.h>
#include <mie/dialect/index.h>
#include <mie/dialect/meta.h>
#include <mie/dialect/ptr.h>
#include <mie/dialect/scf.h>
#include <mie/dialect/select.h>
#include <mie/ir/block.h>
#include <mie/ir/op-definition.h>
#include <mie/ir/op.h>
#include <mie/ir/region.h>
#include <mie/ir/register.h>
#include <mie/name.h>
#include <mie/parse/lex.h>
#include <mie/parse/parse.h>
#include <mie/parse/token.h>
#include <mie/trait/trait-definition.h>
#include <mie/trait/trait.h>
#include <mie/type/type-definition.h>
#include <mie/type/type.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
enum {
OPT_TEMP,
ARG_FILEPATH,
};
int validate(const b_command* cmd, const b_arglist* args, const b_array* _)
static int trait_ref_print(const struct mie_trait *trait, void *arg)
{
return 0;
fputc(' ', stdout);
mie_trait_print(trait, b_stdout);
return 0;
}
static void mie_op_arg_print(const struct mie_op_arg *arg)
{
enum mie_register_flags arg_flags = 0;
const char *arg_name = NULL;
const struct mie_type *arg_type = NULL;
if (MIE_TEST_FLAGS(arg->arg_flags, MIE_OP_F_ARG_RESOLVED)) {
arg_flags = arg->arg_value->reg_flags;
arg_name = arg->arg_value->reg_name.n_str;
arg_type = arg->arg_value->reg_type;
} else {
arg_flags = arg->arg_unresolved.reg_flags;
arg_name = arg->arg_unresolved.reg_name;
arg_type = arg->arg_unresolved.reg_type;
}
if (arg_flags & MIE_REGISTER_F_MACHINE) {
b_printf(" [bold,red]MR");
} else {
b_printf(" [bold,magenta]VR");
}
printf(":(");
mie_type_print(arg_type, b_stdout);
b_printf(")%s[reset]", arg_name);
}
static void mie_op_print(const struct mie_op *op)
{
b_stringstream *tmp = b_stringstream_create();
printf("FLAGS:");
(op->op_flags & MIE_OP_F_OP_RESOLVED) && printf(" OP_RESOLVED");
(op->op_flags & MIE_OP_F_ARG_RESOLVED) && printf(" ARG_RESOLVED");
printf("\n");
printf("DIALECT: %s\n",
op->op_dialect ? op->op_dialect->d_name : "<unknown>");
printf("OP: %s\n", op->op_info ? op->op_info->op_name : "<unknown>");
printf("NAME: %s\n", op->op_name ? op->op_name : "<unknown>");
printf("TRAITS:");
mie_trait_table_iterate(&op->op_info->op_traits, trait_ref_print, NULL);
printf("\n");
printf("ATTRIBUTES:");
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_attrib); i++) {
printf(" (%s = ", op->op_attrib.items[i].attrib_name);
mie_value_print(op->op_attrib.items[i].attrib_value, b_stdout);
printf(")");
}
printf("\n");
printf("REGIONS: %zu\n", MIE_VECTOR_COUNT(op->op_regions));
printf("SUCCESSORS:");
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_successors); i++) {
const struct mie_op_successor *s = &op->op_successors.items[i];
if (MIE_TEST_FLAGS(s->s_flags, MIE_OP_F_SUCCESSOR_RESOLVED)) {
printf(" ^%s", s->s_block->b_name.n_str);
} else {
printf(" ^%s?", s->s_block_name);
}
printf(":(");
for (size_t i = 0; i < MIE_VECTOR_COUNT(s->s_args); i++) {
const struct mie_op_arg *arg = &s->s_args.items[i];
mie_op_arg_print(arg);
}
printf(" )");
}
printf("\n");
printf("ARGS:");
for (size_t i = 0; i < op->op_args.count; i++) {
const struct mie_op_arg *arg = &op->op_args.items[i];
mie_op_arg_print(arg);
}
printf("\n");
printf("RESULT:");
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_result); i++) {
const struct mie_register *reg = &op->op_result.items[i];
printf(" %s:(",
(reg->reg_flags & MIE_REGISTER_F_MACHINE) ? "MR" : "VR");
mie_type_print(reg->reg_type, b_stdout);
printf(")%s", reg->reg_name.n_str);
}
printf("\n");
}
static void mie_op_definition_print(const struct mie_op_definition *op)
{
char id_str[MIE_ID_STRING_MAX];
mie_id_to_string(&op->op_id, id_str, sizeof id_str);
b_printf(
" [bold,red]Op:[reset]%-20s [dark_grey]{%s}[reset]\n",
op->op_name, id_str);
}
static void mie_type_definition_print(const struct mie_type_definition *type)
{
char id_str[MIE_ID_STRING_MAX];
mie_id_to_string(&type->ty_id, id_str, sizeof id_str);
b_printf(
" [bold,blue]Ty:[reset]%-20s [dark_grey]{%s}[reset]\n",
type->ty_name, id_str);
}
static void mie_trait_definition_print(const struct mie_trait_definition *trait)
{
char id_str[MIE_ID_STRING_MAX];
mie_id_to_string(&trait->tr_id, id_str, sizeof id_str);
b_printf(
" [bold,yellow]Tr:[reset]%-20s [dark_grey]{%s}[reset]\n",
trait->tr_name, id_str);
}
static void mie_dialect_print(const struct mie_dialect *dialect)
{
char id_str[MIE_ID_STRING_MAX];
mie_id_to_string(&dialect->d_id, id_str, sizeof id_str);
b_printf(
"[bold,green]D:[reset]%-20s [dark_grey]{%s}[reset]\n",
dialect->d_name, id_str);
b_btree_node *node = b_btree_first(&dialect->d_ops.map_entries);
while (node) {
mie_id *id = b_unbox(mie_id, node, e_node);
struct mie_op_definition *op
= b_unbox(struct mie_op_definition, id, op_id);
mie_op_definition_print(op);
node = b_btree_next(node);
}
node = b_btree_first(&dialect->d_types.map_entries);
while (node) {
mie_id *id = b_unbox(mie_id, node, e_node);
struct mie_type_definition *type
= b_unbox(struct mie_type_definition, id, ty_id);
mie_type_definition_print(type);
node = b_btree_next(node);
}
node = b_btree_first(&dialect->d_traits.map_entries);
while (node) {
mie_id *id = b_unbox(mie_id, node, e_node);
struct mie_trait_definition *trait
= b_unbox(struct mie_trait_definition, id, tr_id);
mie_trait_definition_print(trait);
node = b_btree_next(node);
}
}
static void mie_ctx_print(const struct mie_ctx *ctx)
{
b_btree_node *node = b_btree_first(&ctx->ctx_dialects.map_entries);
while (node) {
mie_id *id = b_unbox(mie_id, node, e_node);
struct mie_dialect *dialect
= b_unbox(struct mie_dialect, id, d_id);
mie_dialect_print(dialect);
node = b_btree_next(node);
}
}
static int validate_file(const char *path, const b_arglist *args)
{
b_file *file = NULL;
b_result result
= b_file_open(NULL, B_RV_PATH(path), B_FILE_READ_ONLY, &file);
if (b_result_is_error(result)) {
b_throw(result);
return -1;
}
printf("File OK\n");
struct mie_ctx *ctx = mie_ctx_create();
mie_builtin_dialect_create(ctx);
mie_meta_dialect_create(ctx);
mie_select_dialect_create(ctx);
mie_ptr_dialect_create(ctx);
mie_arith_dialect_create(ctx);
mie_func_dialect_create(ctx);
mie_cf_dialect_create(ctx);
mie_scf_dialect_create(ctx);
mie_index_dialect_create(ctx);
mie_ctx_print(ctx);
struct mie_type *i32 = mie_arith_int_get_type(ctx, 32);
struct mie_type *str = mie_ctx_get_type(ctx, "builtin", "string");
struct mie_type *index = mie_ctx_get_type(ctx, "index", "index");
struct mie_value *i32_value = mie_ctx_get_int(ctx, 1024, 32);
struct mie_value *index_value = mie_ctx_get_index(ctx, 25000);
struct mie_value *str_value = mie_ctx_get_string(ctx, "Hello, world!");
const struct mie_type *storage_type_parts[] = {i32, str, index};
struct mie_type *storage_type = mie_ctx_get_storage_type(
ctx, storage_type_parts,
sizeof storage_type_parts / sizeof *storage_type_parts);
const struct mie_type *func_in_parts[] = {i32, str};
const struct mie_type *func_out_parts[] = {index};
struct mie_type *func_type = mie_ctx_get_function_type(
ctx, func_in_parts, sizeof func_in_parts / sizeof *func_in_parts,
func_out_parts, sizeof func_out_parts / sizeof *func_out_parts);
/* make sure storage/function type caching is working */
assert(storage_type
== mie_ctx_get_storage_type(
ctx, storage_type_parts,
sizeof storage_type_parts / sizeof *storage_type_parts));
assert(func_type
== mie_ctx_get_function_type(
ctx, func_in_parts,
sizeof func_in_parts / sizeof *func_in_parts, func_out_parts,
sizeof func_out_parts / sizeof *func_out_parts));
char id_str[MIE_ID_STRING_MAX];
mie_id_to_string(&i32->ty_id, id_str, sizeof id_str);
printf("i32 type: {%s} %s (instance of %s.%s)\n", id_str, i32->ty_name,
i32->ty_def->ty_parent->d_name, i32->ty_def->ty_name);
mie_id_to_string(&str->ty_id, id_str, sizeof id_str);
printf("str type: {%s} %s (instance of %s.%s)\n", id_str, str->ty_name,
str->ty_def->ty_parent->d_name, str->ty_def->ty_name);
mie_id_to_string(&index->ty_id, id_str, sizeof id_str);
printf("index type: {%s} %s (instance of %s.%s)\n", id_str, index->ty_name,
index->ty_def->ty_parent->d_name, index->ty_def->ty_name);
mie_id_to_string(&storage_type->ty_id, id_str, sizeof id_str);
printf("storage type: {%s} ", id_str);
mie_type_print(storage_type, b_stdout);
printf("\n");
mie_id_to_string(&func_type->ty_id, id_str, sizeof id_str);
printf("function type: {%s} ", id_str);
mie_type_print(func_type, b_stdout);
printf("\n");
printf("i32 value: ");
mie_value_print(i32_value, b_stdout);
printf("\n");
printf("index value: ");
mie_value_print(index_value, b_stdout);
printf("\n");
printf("str value: ");
mie_value_print(str_value, b_stdout);
printf("\n");
struct mie_lex *lex = mie_lex_create(file);
struct mie_parser *parse = mie_parser_create(ctx, lex);
struct mie_name_map *names = mie_name_map_create(NULL);
struct mie_op op = {};
if (!mie_parser_parse_op(parse, names, &op)) {
printf("parse failed\n");
return -1;
}
if (!mie_ctx_resolve_op(ctx, &op)) {
printf("op resolve failed\n");
return -1;
}
mie_op_print(&op);
#if 0
while (1) {
struct mie_token *tok = mie_lex_peek(lex);
if (!tok) {
break;
}
printf("%s[%d:%d -> %d:%d]",
mie_token_type_to_string(tok->tok_type),
tok->tok_start.c_row, tok->tok_start.c_col,
tok->tok_end.c_row, tok->tok_end.c_col);
switch (tok->tok_value_type) {
case MIE_TOK_V_STRING:
printf(" S:%s", tok->tok_str);
break;
case MIE_TOK_V_INT:
printf(" I:%lld", tok->tok_int);
break;
case MIE_TOK_V_DOUBLE:
printf(" D:%lf", tok->tok_double);
break;
case MIE_TOK_V_SYMBOL:
printf(" SYM:%s", mie_token_symbol_to_string(tok->tok_sym));
break;
default:
break;
}
printf("\n");
mie_lex_advance(lex);
}
#endif
mie_lex_destroy(lex);
b_file_unref(file);
return 0;
}
int validate(const b_command *cmd, const b_arglist *args, const b_array *_)
{
b_arglist_iterator it;
b_arglist_foreach_filtered(&it, args, B_COMMAND_INVALID_ID, ARG_FILEPATH)
{
b_arglist_value *path = it.value;
if (path->val_type != B_COMMAND_ARG_STRING) {
continue;
}
int r = validate_file(path->val_str, args);
if (r != 0) {
return r;
}
}
return 0;
}
B_COMMAND(CMD_VALIDATE, CMD_ROOT)
{
B_COMMAND_NAME("validate");
B_COMMAND_SHORT_NAME('V');
B_COMMAND_DESC("validate a mie ir file.");
B_COMMAND_HELP_OPTION();
B_COMMAND_FLAGS(B_COMMAND_SHOW_HELP_BY_DEFAULT);
B_COMMAND_FUNCTION(validate);
B_COMMAND_NAME("validate");
B_COMMAND_SHORT_NAME('V');
B_COMMAND_DESC("validate a mie ir file.");
B_COMMAND_HELP_OPTION();
B_COMMAND_FLAGS(B_COMMAND_SHOW_HELP_BY_DEFAULT);
B_COMMAND_FUNCTION(validate);
B_COMMAND_ARG(ARG_FILEPATH)
{
B_ARG_NAME("filepath");
B_ARG_DESC("the mie file to validate");
B_ARG_NR_VALUES(1);
}
B_COMMAND_HELP_OPTION();
}

View File

@@ -1,6 +1,8 @@
#include "cmd/cmd.h"
#include <blue/cmd.h>
#include <mie/id.h>
#include <stdio.h>
int main(int argc, const char **argv)
{