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 { func.func @reduce(%buffer: memref<1024*f32>, %lb: index, %ub: index, %step: index) -> f32 {
; Initial sum set to 0. ; 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. ; 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) { %sum = scf.for %iv = %lb to %ub step %step iter-args(%sum.iter = %sum.0) -> (f32) {
%t = memref.load %buffer[%iv] : memref<1024*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 { func.func @reduce(%buffer: memref<1024*f32>, %lb: index, %ub: index, %step: index) -> f32 {
; Initial sum set to 0. ; 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. ; 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) { %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 let s:save_cpo = &cpoptions
set cpoptions&vim set cpoptions&vim
setlocal iskeyword+=- 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 syn keyword mieInstructionFlag
\ eq gt ge lt le \ eq gt ge lt le
syn match mieRegister "%[0-9]\>" syn match mieRegister "%[0-9]\>"
syn match mieRegister "%[1-9][0-9]\+\>" syn match mieRegister "%[1-9][0-9]\+\>"
syn match mieRegister "%[A-Za-z_\-\.][A-Za-z0-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 mieIdentifier /@\.\(\w\+\)\(\.\(\w\+\)\)*\>/ syn match mieIdentifier /@\.\(\w\+\)\(\.\(\w\+\)\)*\>/
syn match mieBlockIdentifier /\^\(\w\+\)\(\.\(\w\+\)\)*/ syn match mieBlockIdentifier /\^\(\w\+\)\(\.\(\w\+\)\)*/
syn match mieBlockLabel /\^\(\w\+\)\(\.\(\w\+\)\)*\:/ syn match mieBlockLabel /\^\(\w\+\)\(\.\(\w\+\)\)*\:/
syn keyword mieBuiltinType void index syn keyword mieBuiltinType void
syn keyword mieBuiltinType f16 f32 f64 f80 f128
" Use syn match for type names that are ALSO dialect names, to ensure that " Use syn match for type names that are ALSO dialect names, to ensure that
" dialect operations are still matched as such. " dialect operations are still matched as such.
syn match mieBuiltinType /\<memref\>/ syn match mieBuiltinType /\<memref\>/
syn match mieBuiltinType "i[0-9]\>" syn match mieBuiltinType /\<ptr\>/
syn match mieBuiltinType "i[1-9][0-9]\+\>" 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 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 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 match mieAttributeName /\<[A-Za-z][A-Za-z0-9\-_\.]*\(\s*=\)\@=\>/
syn region mieString start=+"+ end=+"\%(u8\)\=+ end=+$+ extend 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 /-[0-9]\+\(\.\)\@!\>/ syn match mieInteger /\<-[0-9]\+\(\.\)\@!\>/
syn match mieInteger /0x[:xdigit:]\+\>/ syn match mieInteger /\<0x[:xdigit:]\+\>/
syn match mieInteger /-0x[:xdigit:]\+\>/ syn match mieInteger /\<-0x[:xdigit:]\+\>/
syn match mieIntegerDimension /[0-9]\+x/ syn match mieIntegerDimension /[0-9]\+x/
syn match mieIntegerDimension /0x[:xdigit:]\+x/ syn match mieIntegerDimension /0x[:xdigit:]\+x/
@@ -55,12 +65,9 @@ syn match mieBraces "[{}]" display
syn match mieAngleBrackets "[<>]" display syn match mieAngleBrackets "[<>]" display
syn match mieOperator "[=:]" display syn match mieOperator "[=:]" display
syn match mieOperator "->" display syn match mieOperator "->" display
syn match ivyPropertySymbol "\$" display
" The default highlighting. " The default highlighting.
hi def link mieUnspecifiedKeyword Keyword hi def link mieUnspecifiedKeyword Keyword
hi def link ivyPropertySymbol Statement
hi def link mieInteger Number hi def link mieInteger Number
hi def link mieFloat Number hi def link mieFloat Number
@@ -72,12 +79,15 @@ hi def link mieAngleBrackets StorageClass
hi def link mieDialectType Type hi def link mieDialectType Type
hi def link mieGenericOperation @function.builtin hi def link mieGenericOperation @function.builtin
hi def link mieGraphOperation Statement
hi def link mieCustomOperation Function hi def link mieCustomOperation Function
hi def link mieInstruction @attribute
hi def link mieInstructionFlag StorageClass hi def link mieInstructionFlag StorageClass
hi def link mieIdentifier Identifier hi def link mieIdentifier Identifier
hi def link mieBlockIdentifier Label hi def link mieBlockIdentifier Label
hi def link mieBlockLabel 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 mieString String
hi def link mieBuiltinType @type.builtin hi def link mieBuiltinType @type.builtin

372
mie/ctx.c
View File

@@ -7,10 +7,12 @@
#include <mie/dialect/builtin.h> #include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h> #include <mie/dialect/dialect.h>
#include <mie/dialect/index.h> #include <mie/dialect/index.h>
#include <mie/dialect/type.h>
#include <mie/ir/op.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/function.h>
#include <mie/type/storage.h> #include <mie/type/storage.h>
#include <mie/type/type-definition.h>
#include <mie/type/type.h> #include <mie/type/type.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -23,285 +25,6 @@
MIE_ID(0xf5, 0x4e, 0xc5, 0x8c, 0xc0, 0x1e, 0x48, 0x47, 0xb5, 0xf4, \ MIE_ID(0xf5, 0x4e, 0xc5, 0x8c, 0xc0, 0x1e, 0x48, 0x47, 0xb5, 0xf4, \
0x7b, 0xb9, 0x6b, 0x47, 0xca, 0x48) 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 *mie_ctx_create(void)
{ {
struct mie_ctx *out = malloc(sizeof *out); 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); mie_id_map_init(&out->ctx_types, &types_ns);
out->ctx_ints = mie_int_cache_create(); out->ctx_ints = mie_int_cache_create();
out->ctx_floats = mie_float_cache_create();
out->ctx_indices = mie_index_cache_create(); out->ctx_indices = mie_index_cache_create();
out->ctx_strings = mie_string_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 mie_ctx_resolve_op(const struct mie_ctx *ctx, struct mie_op *op)
{ {
bool fully_resolved = MIE_TEST_FLAGS( 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) { if (fully_resolved) {
return true; return true;
@@ -358,7 +82,7 @@ bool mie_ctx_resolve_op(const struct mie_ctx *ctx, struct mie_op *op)
return false; return false;
} }
const struct mie_dialect_op *op_info const struct mie_op_definition *op_info
= mie_dialect_get_op(dialect, op_name); = mie_dialect_get_op(dialect, op_name);
if (!op) { if (!op) {
return false; 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); 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) const struct mie_ctx *ctx, const char *dialect_name, const char *type_name)
{ {
b_rope dialect_name_rope = B_ROPE_CSTR(dialect_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); 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); 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_type *mie_ctx_get_type(
struct mie_ctx *ctx, const char *dialect_name, const char *type_name) struct mie_ctx *ctx, const char *dialect_name, const char *type_name)
{ {
char full_name[256]; 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); b_rope full_name_rope = B_ROPE_CSTR(full_name);
mie_id id; mie_id id;
@@ -422,8 +167,8 @@ struct mie_type *mie_ctx_get_type(
return type; return type;
} }
struct mie_dialect_type *type_info struct mie_type_definition *type_info
= mie_ctx_get_dialect_type(ctx, dialect_name, type_name); = mie_ctx_get_type_definition(ctx, dialect_name, type_name);
if (!type_info /* || (type_info->ty_flags & MIE_DIALECT_TYPE_PARAMETISED) */) { if (!type_info /* || (type_info->ty_flags & MIE_DIALECT_TYPE_PARAMETISED) */) {
/* cannot initialise unknown or parametised types */ /* cannot initialise unknown or parametised types */
return NULL; return NULL;
@@ -453,6 +198,53 @@ struct mie_type *mie_ctx_get_type(
return 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_type *mie_ctx_get_storage_type(
struct mie_ctx *ctx, const struct mie_type **parts, size_t nr_parts) 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); 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) 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); 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/dialect.h>
#include <mie/dialect/op.h> #include <mie/ir/op-definition.h>
#include <mie/macros.h> #include <mie/macros.h>
static enum mie_status print(const struct mie_op *op, b_stream *out) 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; return MIE_SUCCESS;
} }
MIE_DIALECT_OP_BEGIN(mie_arith_addf, "addf") MIE_OP_DEFINITION_BEGIN(mie_arith_addf, "addf")
MIE_DIALECT_OP_PRINT(print); MIE_OP_DEFINITION_PRINT(print);
MIE_DIALECT_OP_PARSE(parse); MIE_OP_DEFINITION_PARSE(parse);
MIE_DIALECT_OP_END() MIE_OP_DEFINITION_END()

View File

@@ -1,5 +1,5 @@
#include <mie/dialect/dialect.h> #include <mie/dialect/dialect.h>
#include <mie/dialect/op.h> #include <mie/ir/op-definition.h>
#include <mie/macros.h> #include <mie/macros.h>
static enum mie_status print(const struct mie_op *op, b_stream *out) 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; return MIE_SUCCESS;
} }
MIE_DIALECT_OP_BEGIN(mie_arith_addi, "addi") MIE_OP_DEFINITION_BEGIN(mie_arith_addi, "addi")
MIE_DIALECT_OP_PRINT(print); MIE_OP_DEFINITION_PRINT(print);
MIE_DIALECT_OP_PARSE(parse); MIE_OP_DEFINITION_PARSE(parse);
MIE_DIALECT_OP_END() 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/ctx.h>
#include <mie/dialect/arith.h> #include <mie/dialect/arith.h>
#include <mie/dialect/dialect.h> #include <mie/dialect/dialect.h>
#include <mie/dialect/type.h>
#include <mie/macros.h> #include <mie/macros.h>
#include <mie/type/type-definition.h>
#include <mie/type/type.h> #include <mie/type/type.h>
#include <mie/value.h> #include <mie/value.h>
@@ -12,7 +12,7 @@ struct float_type {
size_t f_width; 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) const struct mie_type *ty, const struct mie_value *value, b_stream *out)
{ {
struct float_type *float_ty = (struct float_type *)ty; 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); b_stream_write_fmt(out, NULL, "NaN : f%zu", float_ty->f_width);
break; break;
} }
return MIE_SUCCESS;
} }
struct mie_type *mie_arith_float_get_type(struct mie_ctx *ctx, size_t bit_width) struct mie_type *mie_arith_float_get_type(struct mie_ctx *ctx, size_t bit_width)
{ {
struct mie_dialect_type *type_info struct mie_type_definition *type_info
= mie_ctx_get_dialect_type(ctx, "arith", "float"); = mie_ctx_get_type_definition(ctx, "arith", "float");
if (!type_info) { if (!type_info) {
return NULL; 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; 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( 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; return MIE_SUCCESS;
} }
static enum mie_status parse( 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) struct mie_type **out)
{ {
return MIE_SUCCESS; return MIE_SUCCESS;
} }
MIE_DIALECT_TYPE_BEGIN(mie_arith_float, "float") MIE_TYPE_DEFINITION_BEGIN(mie_arith_float, "float")
// MIE_DIALECT_TYPE_FLAGS(MIE_DIALECT_TYPE_PARAMETISED); // MIE_TYPE_DEFINITION_FLAGS(MIE_TYPE_DEFINITION_PARAMETISED);
MIE_DIALECT_TYPE_STRUCT(struct float_type); MIE_TYPE_DEFINITION_STRUCT(struct float_type);
MIE_DIALECT_TYPE_PRINT(print); MIE_TYPE_DEFINITION_PRINT(print);
MIE_DIALECT_TYPE_PARSE(parse); MIE_TYPE_DEFINITION_PARSE(parse);
MIE_DIALECT_TYPE_VALUE_PRINT(value_print); MIE_TYPE_DEFINITION_VALUE_PRINT(value_print);
MIE_DIALECT_TYPE_END() MIE_TYPE_DEFINITION_END()

View File

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

View File

@@ -3,4 +3,5 @@
MIE_DIALECT_BEGIN(mie_builtin, "builtin") MIE_DIALECT_BEGIN(mie_builtin, "builtin")
MIE_DIALECT_ADD_TYPE(mie_builtin_string); MIE_DIALECT_ADD_TYPE(mie_builtin_string);
MIE_DIALECT_ADD_TRAIT(mie_builtin_isolated_from_above);
MIE_DIALECT_END() 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/ctx.h>
#include <mie/dialect/builtin.h> #include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h> #include <mie/dialect/dialect.h>
#include <mie/dialect/type.h>
#include <mie/macros.h> #include <mie/macros.h>
#include <mie/type/type-definition.h>
#include <mie/type/type.h> #include <mie/type/type.h>
#include <mie/value.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_type *ty, const struct mie_value *value, b_stream *out)
{ {
const struct mie_string *str = (const struct mie_string *)value; const struct mie_string *str = (const struct mie_string *)value;
b_stream_write_fmt(out, NULL, "\"%s\"", str->str_val); 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); type->ty_instance_size = sizeof(struct mie_string);
} }
static enum mie_status print( 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; return MIE_SUCCESS;
} }
static enum mie_status parse( 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) struct mie_type **out)
{ {
return MIE_SUCCESS; return MIE_SUCCESS;
} }
MIE_DIALECT_TYPE_BEGIN(mie_builtin_string, "string") MIE_TYPE_DEFINITION_BEGIN(mie_builtin_string, "string")
MIE_DIALECT_TYPE_STRUCT(struct mie_type); MIE_TYPE_DEFINITION_STRUCT(struct mie_type);
MIE_DIALECT_TYPE_INIT(type_init); MIE_TYPE_DEFINITION_INIT(type_init);
MIE_DIALECT_TYPE_PRINT(print); MIE_TYPE_DEFINITION_PRINT(print);
MIE_DIALECT_TYPE_PARSE(parse); MIE_TYPE_DEFINITION_PARSE(parse);
MIE_DIALECT_TYPE_VALUE_PRINT(value_print); MIE_TYPE_DEFINITION_VALUE_PRINT(value_print);
MIE_DIALECT_TYPE_END() MIE_TYPE_DEFINITION_END()

View File

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

View File

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

View File

@@ -1,8 +1,8 @@
#include <blue/ds/string.h> #include <blue/ds/string.h>
#include <mie/ctx.h> #include <mie/ctx.h>
#include <mie/dialect/dialect.h> #include <mie/dialect/dialect.h>
#include <mie/dialect/op.h> #include <mie/ir/op-definition.h>
#include <mie/dialect/type.h> #include <mie/type/type-definition.h>
#define TYPE_NS_ID \ #define TYPE_NS_ID \
MIE_ID(0xe4, 0x99, 0x42, 0x58, 0x2b, 0xdb, 0x45, 0xa3, 0xbd, 0x4b, \ 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; 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) const struct mie_dialect *dialect, const char *name)
{ {
b_rope name_rope = B_ROPE_CSTR(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_init_ns(&id, mie_id_map_get_ns(&dialect->d_ops), &name_rope);
mie_id *target = mie_id_map_get(&dialect->d_ops, &id); 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) const struct mie_dialect *dialect, const char *name)
{ {
b_rope name_rope = B_ROPE_CSTR(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_init_ns(&id, mie_id_map_get_ns(&dialect->d_types), &name_rope);
mie_id *target = mie_id_map_get(&dialect->d_types, &id); 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/dialect.h>
#include <mie/dialect/op.h> #include <mie/ir/op-definition.h>
#include <mie/macros.h> #include <mie/macros.h>
static enum mie_status print(const struct mie_op *op, b_stream *out) 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; return MIE_SUCCESS;
} }
MIE_DIALECT_OP_BEGIN(mie_func_func, "func") MIE_OP_DEFINITION_BEGIN(mie_func_func, "func")
MIE_DIALECT_OP_PRINT(print); MIE_OP_DEFINITION_PRINT(print);
MIE_DIALECT_OP_PARSE(parse); MIE_OP_DEFINITION_PARSE(parse);
MIE_DIALECT_OP_END() MIE_OP_DEFINITION_END()
MIE_DIALECT_BEGIN(mie_func, "func") MIE_DIALECT_BEGIN(mie_func, "func")
MIE_DIALECT_ADD_OP(mie_func_func); MIE_DIALECT_ADD_OP(mie_func_func);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,3 @@
#include "scf.h"
#include <mie/dialect/dialect.h> #include <mie/dialect/dialect.h>
#include <mie/macros.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/dialect.h>
#include <mie/dialect/op.h> #include <mie/ir/op-definition.h>
#include <mie/macros.h> #include <mie/macros.h>
static enum mie_status print(const struct mie_op *op, b_stream *out) 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; return MIE_SUCCESS;
} }
MIE_DIALECT_OP_BEGIN(mie_scf_yield, "yield") MIE_OP_DEFINITION_BEGIN(mie_scf_yield, "yield")
MIE_DIALECT_OP_PRINT(print); MIE_OP_DEFINITION_PRINT(print);
MIE_DIALECT_OP_PARSE(parse); MIE_OP_DEFINITION_PARSE(parse);
MIE_DIALECT_OP_END() 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) void mie_id_builder_begin(struct mie_id_builder *builder, const mie_id *ns)
{ {
memset(builder, 0x0, sizeof *builder); 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] &= 0x3F;
out->id_bytes[8] |= 0x80; 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_id_map ctx_traits;
struct mie_int_cache *ctx_ints; struct mie_int_cache *ctx_ints;
struct mie_float_cache *ctx_floats;
struct mie_index_cache *ctx_indices; struct mie_index_cache *ctx_indices;
struct mie_string_cache *ctx_strings; 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( MIE_API struct mie_dialect *mie_ctx_get_dialect(
const struct mie_ctx *ctx, const char *name); 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); 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( MIE_API struct mie_type *mie_ctx_get_type(
struct mie_ctx *ctx, const char *dialect_name, const char *type_name); 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); struct mie_ctx *ctx, const char *dialect_name, const char *trait_name);
MIE_API struct mie_type *mie_ctx_get_storage_type( MIE_API struct mie_type *mie_ctx_get_storage_type(
struct mie_ctx *ctx, const struct mie_type **parts, size_t nr_parts); 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( MIE_API struct mie_type *mie_arith_float_get_type(
struct mie_ctx *ctx, size_t bit_width); 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 struct mie_int_cache *mie_int_cache_create(void);
MIE_API void mie_int_cache_destroy(struct mie_int_cache *cache); MIE_API void mie_int_cache_destroy(struct mie_int_cache *cache);
MIE_API struct mie_int *mie_int_cache_get( MIE_API struct mie_int *mie_int_cache_get(
struct mie_int_cache *cache, struct mie_ctx *ctx, size_t value, struct mie_int_cache *cache, struct mie_ctx *ctx, size_t value,
size_t bit_width); 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 #endif

View File

@@ -9,17 +9,17 @@
struct mie_ctx; struct mie_ctx;
struct mie_dialect_op; struct mie_op_definition;
struct mie_dialect_type; struct mie_type_definition;
struct mie_trait_definition; struct mie_trait_definition;
struct mie_dialect { struct mie_dialect {
mie_id d_id; mie_id d_id;
char *d_name; char *d_name;
/* map of struct mie_dialect_op */ /* map of struct mie_op_definition */
struct mie_id_map d_ops; struct mie_id_map d_ops;
/* map of struct mie_dialect_type */ /* map of struct mie_type_definition */
struct mie_id_map d_types; struct mie_id_map d_types;
/* map of struct mie_trait_definition */ /* map of struct mie_trait_definition */
struct mie_id_map d_traits; struct mie_id_map d_traits;
@@ -28,9 +28,9 @@ struct mie_dialect {
MIE_API struct mie_dialect *mie_dialect_create( MIE_API struct mie_dialect *mie_dialect_create(
struct mie_ctx *ctx, const char *name); 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); 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); const struct mie_dialect *dialect, const char *name);
MIE_API const struct mie_trait_definition *mie_dialect_get_trait( MIE_API const struct mie_trait_definition *mie_dialect_get_trait(
const struct mie_dialect *dialect, const char *name); 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/queue.h>
#include <blue/core/rope.h> #include <blue/core/rope.h>
#include <mie/misc.h> #include <mie/misc.h>
#include <mie/status.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
@@ -55,6 +56,11 @@ struct mie_id_map {
b_btree map_entries; b_btree map_entries;
}; };
struct mie_id_map_iterator {
mie_id *it_id;
b_btree_node *_n;
};
MIE_API void mie_id_init( 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_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); 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_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_begin(struct mie_id_builder *builder, const mie_id *ns);
MIE_API void mie_id_builder_add( MIE_API void mie_id_builder_add(
struct mie_id_builder *builder, const void *p, size_t len); 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); 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_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 #endif

View File

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

View File

@@ -15,16 +15,12 @@ struct mie_block;
struct mie_region; struct mie_region;
struct mie_dialect; struct mie_dialect;
struct mie_dialect_op; struct mie_op_definition;
enum mie_op_flags { enum mie_op_flags {
MIE_OP_F_OP_RESOLVED = 0x01u, MIE_OP_F_OP_RESOLVED = 0x01u,
MIE_OP_F_ARGS_RESOLVED = 0x02u, MIE_OP_F_ARG_RESOLVED = 0x02u,
}; MIE_OP_F_SUCCESSOR_RESOLVED = 0x04u,
struct mie_op_successor {
struct mie_block *s_block;
MIE_VECTOR_DECLARE(struct mie_register *, s_params);
}; };
struct mie_op_attribute { struct mie_op_attribute {
@@ -33,21 +29,35 @@ struct mie_op_attribute {
}; };
struct mie_op_arg { struct mie_op_arg {
enum mie_op_flags arg_flags;
struct mie_file_span arg_span; struct mie_file_span arg_span;
union { 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; 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_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 { struct mie_op {
enum mie_op_flags op_flags; 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_dialect;
const struct mie_dialect_op *op_info; const struct mie_op_definition *op_info;
struct mie_file_span op_name_span; struct mie_file_span op_name_span;
/* only valid if the F_RESOLVED flag is NOT set */ /* only valid if the F_RESOLVED flag is NOT set */

View File

@@ -8,76 +8,109 @@
if (!self) { \ if (!self) { \
return NULL; \ return NULL; \
} \ } \
struct mie_dialect_op *op = NULL; \ struct mie_op_definition *op = NULL; \
struct mie_dialect_type *type = NULL; struct mie_type_definition *type = NULL; \
struct mie_trait_definition *trait = NULL;
#define __MIE_DIALECT_END() \ #define __MIE_DIALECT_END() \
return self; \ return self; \
} }
#define __MIE_DIALECT_OP_BEGIN(func_prefix, op_name) \ #define __MIE_OP_DEFINITION_BEGIN(func_prefix, op_name) \
struct mie_dialect_op *func_prefix##_op_create( \ struct mie_op_definition *func_prefix##_op_create( \
struct mie_dialect *d, struct mie_ctx *ctx) \ 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) { \ if (!op) { \
return NULL; \ return NULL; \
} } \
const struct mie_trait *trait = NULL;
#define __MIE_DIALECT_OP_END() \ #define __MIE_OP_DEFINITION_END() \
return op; \ return op; \
} }
#define __MIE_DIALECT_TYPE_BEGIN(func_prefix, type_name) \ #define __MIE_TYPE_DEFINITION_BEGIN(func_prefix, type_name) \
struct mie_dialect_type *func_prefix##_type_create( \ struct mie_type_definition *func_prefix##_type_create( \
struct mie_dialect *d, struct mie_ctx *ctx) \ struct mie_dialect *d, struct mie_ctx *ctx) \
{ \ { \
struct mie_dialect_type *type \ struct mie_type_definition *type \
= mie_dialect_type_create(d, type_name); \ = mie_type_definition_create(d, type_name); \
if (!type) { \ if (!type) { \
return NULL; \ return NULL; \
} } \
const struct mie_trait *trait = NULL;
#define __MIE_DIALECT_TYPE_END() \ #define __MIE_TYPE_DEFINITION_END() \
return type; \ 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) \ #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 *); \ struct mie_dialect *, struct mie_ctx *); \
op = op_id##_op_create(self, ctx) op = op_id##_op_create(self, ctx)
#define __MIE_DIALECT_ADD_TYPE(type_id) \ #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 *); \ struct mie_dialect *, struct mie_ctx *); \
type = type_id##_type_create(self, 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_BEGIN(c_sym, name) __MIE_DIALECT_BEGIN(c_sym, name)
#define MIE_DIALECT_END() __MIE_DIALECT_END() #define MIE_DIALECT_END() __MIE_DIALECT_END()
#define MIE_DIALECT_ADD_OP(c_sym) __MIE_DIALECT_ADD_OP(c_sym) #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_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_OP_DEFINITION_BEGIN(c_sym, op) __MIE_OP_DEFINITION_BEGIN(c_sym, op)
#define MIE_DIALECT_OP_END() __MIE_DIALECT_OP_END() #define MIE_OP_DEFINITION_END() __MIE_OP_DEFINITION_END()
#define MIE_DIALECT_OP_PRINT(func) op->op_print = (func) #define MIE_OP_DEFINITION_PRINT(func) op->op_print = (func)
#define MIE_DIALECT_OP_PARSE(func) op->op_parse = (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) \ #define MIE_TYPE_DEFINITION_BEGIN(c_sym, type) \
__MIE_DIALECT_TYPE_BEGIN(c_sym, type) __MIE_TYPE_DEFINITION_BEGIN(c_sym, type)
#define MIE_DIALECT_TYPE_END() __MIE_DIALECT_TYPE_END() #define MIE_TYPE_DEFINITION_END() __MIE_TYPE_DEFINITION_END()
#define MIE_DIALECT_TYPE_FLAGS(flags) type->ty_flags = flags #define MIE_TYPE_DEFINITION_FLAGS(flags) type->ty_flags = flags
#define MIE_DIALECT_TYPE_STRUCT(name) type->ty_data_size = sizeof(name) #define MIE_TYPE_DEFINITION_STRUCT(name) type->ty_data_size = sizeof(name)
#define MIE_DIALECT_TYPE_INIT(func) type->ty_init = (func) #define MIE_TYPE_DEFINITION_INIT(func) type->ty_init = (func)
#define MIE_DIALECT_TYPE_PRINT(func) type->ty_print = (func) #define MIE_TYPE_DEFINITION_PRINT(func) type->ty_print = (func)
#define MIE_DIALECT_TYPE_VALUE_PRINT(func) type->ty_value_print = (func) #define MIE_TYPE_DEFINITION_VALUE_PRINT(func) type->ty_value_print = (func)
#define MIE_DIALECT_TYPE_PARSE(func) type->ty_parse = (func) #define MIE_TYPE_DEFINITION_PARSE(func) type->ty_parse = (func)
#define MIE_DIALECT_TYPE_BUILD_ID(func) type->ty_build_id = (func) #define MIE_TYPE_DEFINITION_BUILD_ID(func) type->ty_build_id = (func)
#define MIE_DIALECT_TYPE_INIT(func) type->ty_init = (func) #define MIE_TYPE_DEFINITION_INIT(func) type->ty_init = (func)
#define MIE_DIALECT_TYPE_CLEANUP(func) type->ty_cleanup = (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_TRAIT_DEFINITION_BEGIN(c_sym, trait) \
#define MIE_DIALECT_TRAIT_END() __MIE_TRAIT_DEFINITION_BEGIN(c_sym, trait)
#define MIE_DIALECT_TRAIT_STRUCT(name) #define MIE_TRAIT_DEFINITION_END() __MIE_TRAIT_DEFINITION_END()
#define MIE_DIALECT_TRAIT_PRINT(func) #define MIE_TRAIT_DEFINITION_TARGETS(targets) trait->tr_target = (targets)
#define MIE_DIALECT_TRAIT_CLEANUP(func) #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 #endif

View File

@@ -22,6 +22,7 @@ struct mie_op_arg;
struct mie_op_attribute; struct mie_op_attribute;
struct mie_op_successor; struct mie_op_successor;
struct mie_register; struct mie_register;
struct mie_value;
MIE_API struct mie_parser *mie_parser_create( MIE_API struct mie_parser *mie_parser_create(
struct mie_ctx *ctx, struct mie_lex *lex); 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( MIE_API bool mie_parser_check_symbol(
struct mie_parser *ctx, enum mie_token_symbol sym); 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( MIE_API bool mie_parser_parse_word(
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc); struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_instname( 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_keyword(struct mie_parser *ctx, const char *kw);
MIE_API bool mie_parser_parse_symbol( MIE_API bool mie_parser_parse_symbol(
struct mie_parser *ctx, enum mie_token_symbol sym); 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( MIE_API bool mie_parser_parse_type(
struct mie_parser *ctx, const struct mie_type **out); 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( MIE_API bool mie_parser_parse_operand_list(
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_arg, out)); 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_keyword(struct mie_parser *ctx, b_string *out);
MIE_API bool mie_parser_parse_unknown_symbol( MIE_API bool mie_parser_parse_unknown_symbol(
struct mie_parser *ctx, enum mie_token_symbol sym); 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); struct mie_parser *ctx, struct mie_region *region);
MIE_API bool mie_parser_parse_region_list( MIE_API bool mie_parser_parse_region_list(
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_region, out)); 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( MIE_API bool mie_parser_parse_attribute(
struct mie_parser *ctx, struct mie_op_attribute *attrib); 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_module(struct mie_parser *ctx, struct mie_module *mod);
MIE_API bool mie_parser_parse_op( MIE_API bool mie_parser_parse_op(
struct mie_parser *ctx, struct mie_name_map *names, struct mie_op *dest); 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 #endif

View File

@@ -14,7 +14,7 @@ enum mie_token_type {
MIE_TOK_NONE = 0, MIE_TOK_NONE = 0,
MIE_TOK_LINEFEED = 0x0001u, MIE_TOK_LINEFEED = 0x0001u,
MIE_TOK_INT = 0x0002u, MIE_TOK_INT = 0x0002u,
MIE_TOK_DOUBLE = 0x0004u, MIE_TOK_FLOAT = 0x0004u,
MIE_TOK_SYMBOL = 0x0008u, MIE_TOK_SYMBOL = 0x0008u,
MIE_TOK_STRING = 0x0010u, MIE_TOK_STRING = 0x0010u,
/* single words, not dot-delimited */ /* single words, not dot-delimited */
@@ -42,7 +42,7 @@ enum mie_token_type {
enum mie_token_value_type { enum mie_token_value_type {
MIE_TOK_V_NONE = 0, MIE_TOK_V_NONE = 0,
MIE_TOK_V_INT, MIE_TOK_V_INT,
MIE_TOK_V_DOUBLE, MIE_TOK_V_FLOAT,
MIE_TOK_V_STRING, MIE_TOK_V_STRING,
MIE_TOK_V_SYMBOL, MIE_TOK_V_SYMBOL,
}; };
@@ -83,7 +83,7 @@ struct mie_token {
char *tok_str; char *tok_str;
enum mie_token_symbol tok_sym; enum mie_token_symbol tok_sym;
long long tok_int; 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_INTERNAL_FAILURE,
MIE_ERR_NO_MEMORY, MIE_ERR_NO_MEMORY,
MIE_ERR_NO_ENTRY, MIE_ERR_NO_ENTRY,
MIE_ERR_NO_DATA,
}; };
MIE_API const struct b_error_vendor *mie_error_vendor(void); 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 { struct mie_trait_table_iterator {
const struct mie_trait *it_trait; const struct mie_trait *it_trait;
int _f;
struct mie_id_map_iterator _n;
const struct mie_trait_table *_m;
b_queue_entry *_e; 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); const char *trait_name, struct mie_trait_table_iterator *it);
MIE_API enum mie_status mie_trait_table_put( MIE_API enum mie_status mie_trait_table_put(
struct mie_trait_table *table, const struct mie_trait *trait); 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( MIE_API enum mie_status mie_trait_table_iterator_move_next(
struct mie_trait_table_iterator *it); struct mie_trait_table_iterator *it);

View File

@@ -3,40 +3,18 @@
#include <mie/id.h> #include <mie/id.h>
struct mie_trait; struct mie_dialect;
struct mie_trait_definition;
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 *);
};
/* used to link an op/type/etc to a trait. if the trait is parametised, this /* used to link an op/type/etc to a trait. if the trait is parametised, this
* struct includes any parameter values. */ * struct includes any parameter values. */
struct mie_trait { struct mie_trait {
/* this is NOT the same as tr_def->tr_id */ /* this is NOT the same as tr_def->tr_id */
mie_id tr_id; mie_id tr_id;
char *tr_name;
const struct mie_trait_definition *tr_def; const struct mie_trait_definition *tr_def;
}; };
MIE_API void mie_trait_print(const struct mie_trait *type, b_stream *out);
#endif #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> #include <stddef.h>
struct mie_dialect; struct mie_dialect;
struct mie_dialect_type; struct mie_type_definition;
struct mie_value;
struct mie_id_builder; struct mie_id_builder;
enum mie_type_category { #if 0
/* all other types */ enum mie_type_trait {
MIE_TYPE_OTHER = 0, /* this type is parametised. one or more arguments are required to create
/* storage types (structs, etc) */ * a corresponding mie_type instance. in textual IR, references to this
MIE_TYPE_STORAGE, * type will be followed by a set of arguments surrounded
/* functional types (represents the param/result types of a function) */ * by <angle brackets>. */
MIE_TYPE_FUNCTION, MIE_TYPE_TRAIT_PARAMETISED = 0x01u,
};
/* a mie_type is an instance of mie_dialect_type. /* this type can only be used within graph regions. unlike graph ops,
* if the mie_dialect_type is a parametised type, the resulting mie_type * 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. * will have those parameters baked in.
* this is a base struct. dialects that defined their own types do so by * this is a base struct. dialects that defined their own types do so by
* inheriting from this struct. */ * inheriting from this struct. */
struct mie_type { struct mie_type {
/* this is NOT the same as ty_def->ty_id */ /* this is NOT the same as ty_def->ty_id */
mie_id ty_id; mie_id ty_id;
enum mie_type_category ty_category;
char *ty_name; char *ty_name;
struct mie_dialect_type *ty_def; struct mie_type_definition *ty_def;
size_t ty_instance_size; 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_print(const struct mie_type *type, b_stream *out);
MIE_API void mie_type_build_id( MIE_API void mie_type_build_id(
const struct mie_type *type, struct mie_id_builder *ctx); const struct mie_type *type, struct mie_id_builder *ctx);

View File

@@ -1,11 +1,11 @@
#include <blue/ds/string.h> #include <blue/ds/string.h>
#include <mie/dialect/dialect.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 *parent, const char *name)
{ {
struct mie_dialect_op *out = malloc(sizeof *out); struct mie_op_definition *out = malloc(sizeof *out);
if (!out) { if (!out) {
return NULL; return NULL;
} }
@@ -17,9 +17,16 @@ struct mie_dialect_op *mie_dialect_op_create(
} }
out->op_parent = parent; out->op_parent = parent;
mie_trait_table_init(&out->op_traits);
b_rope name_rope = B_ROPE_CSTR(name); b_rope name_rope = B_ROPE_CSTR(name);
mie_id_map_put(&parent->d_ops, &out->op_id, &name_rope); mie_id_map_put(&parent->d_ops, &out->op_id, &name_rope);
return out; 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); 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); struct mie_token *tok = malloc(sizeof *tok);
if (!tok) { if (!tok) {
@@ -413,9 +413,9 @@ static enum mie_status push_double(struct mie_lex *lex, double v)
memset(tok, 0x0, sizeof *tok); memset(tok, 0x0, sizeof *tok);
tok->tok_type = MIE_TOK_DOUBLE; tok->tok_type = MIE_TOK_FLOAT;
tok->tok_value_type = MIE_TOK_V_DOUBLE; tok->tok_value_type = MIE_TOK_V_FLOAT;
tok->tok_double = v; tok->tok_float = v;
return push_token(lex, tok); return push_token(lex, tok);
} }
@@ -541,7 +541,7 @@ static enum mie_status read_number(struct mie_lex *lex, bool negate)
v *= -1; v *= -1;
} }
return push_double(lex, v); return push_float(lex, v);
} else { } else {
unsigned long long v = strtoull(s, &ep, base); unsigned long long v = strtoull(s, &ep, base);

View File

@@ -1,7 +1,7 @@
#include <mie/ctx.h> #include <mie/ctx.h>
#include <mie/dialect/arith.h> #include <mie/dialect/arith.h>
#include <mie/dialect/dialect.h> #include <mie/dialect/dialect.h>
#include <mie/dialect/type.h> #include <mie/ir/block.h>
#include <mie/ir/module.h> #include <mie/ir/module.h>
#include <mie/ir/op.h> #include <mie/ir/op.h>
#include <mie/ir/region.h> #include <mie/ir/region.h>
@@ -10,13 +10,22 @@
#include <mie/parse/parse.h> #include <mie/parse/parse.h>
#include <mie/parse/token.h> #include <mie/parse/token.h>
#include <mie/type/function.h> #include <mie/type/function.h>
#include <mie/type/type-definition.h>
#include <mie/vector.h>
struct mie_parser { struct mie_parser {
struct mie_ctx *p_ctx; struct mie_ctx *p_ctx;
struct mie_lex *p_lex; struct mie_lex *p_lex;
enum mie_status p_status; 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 *mie_parser_create(struct mie_ctx *ctx, struct mie_lex *lex)
{ {
struct mie_parser *out = malloc(sizeof *out); 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); 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_ctx = ctx;
out->p_lex = lex; out->p_lex = lex;
out->p_status = MIE_SUCCESS; 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) void mie_parser_destroy(struct mie_parser *ctx)
{ {
if (ctx->s_tmp) {
b_string_unref(ctx->s_tmp);
}
free(ctx); free(ctx);
} }
@@ -85,6 +104,48 @@ bool mie_parser_advance(struct mie_parser *ctx)
return mie_lex_get_status(ctx->p_lex) == MIE_SUCCESS; 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) \ #define TOKEN_PARSER(name, id) \
bool mie_parser_parse_##name( \ bool mie_parser_parse_##name( \
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc) \ 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; \ return false; \
} \ } \
struct mie_token *tok = mie_lex_peek(ctx->p_lex); \ struct mie_token *tok = mie_lex_peek(ctx->p_lex); \
switch (tok->tok_value_type) { \
case MIE_TOK_V_STRING: \
b_string_append_cstr(out, tok->tok_str); \ 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) { \ if (loc) { \
mie_file_span_init(loc, tok); \ 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; return true;
} }
static bool parse_builtin_type_name( bool mie_parser_parse_linefeed(struct mie_parser *ctx)
struct mie_parser *ctx, const struct mie_type **out)
{ {
b_string *name = b_string_create(); struct mie_token *tok = mie_lex_peek(ctx->p_lex);
struct mie_file_span loc; if (tok->tok_type != MIE_TOK_LINEFEED) {
if (!mie_parser_parse_word(ctx, name, &loc)) {
b_string_unref(name);
return false; 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; const struct mie_type *type = NULL;
size_t width = 0; size_t width = 0;
char tmp = 0; char tmp = 0;
@@ -147,20 +227,21 @@ static bool parse_builtin_type_name(
const char *name_cstr = b_string_ptr(name); const char *name_cstr = b_string_ptr(name);
if (!strcmp(name_cstr, "memref")) { if (!strcmp(name_cstr, "memref")) {
type_info = mie_ctx_get_dialect_type( type_info = mie_ctx_get_type_definition(
ctx->p_ctx, "memref", "memref"); ctx->p_ctx, "memref", "memref");
} else if (!strcmp(name_cstr, "index")) { } else if (!strcmp(name_cstr, "index")) {
type_info type_info = mie_ctx_get_type_definition(
= mie_ctx_get_dialect_type(ctx->p_ctx, "index", "index"); ctx->p_ctx, "index", "index");
} else if (!strcmp(name_cstr, "str")) { } 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"); ctx->p_ctx, "builtin", "string");
} else if (sscanf(name_cstr, "i%zu%c", &width, &tmp) == 1) { } 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; base_type = INT;
} else if (sscanf(name_cstr, "f%zu%c", &width, &tmp) == 1) { } else if (sscanf(name_cstr, "f%zu%c", &width, &tmp) == 1) {
type_info type_info = mie_ctx_get_type_definition(
= mie_ctx_get_dialect_type(ctx->p_ctx, "arith", "float"); ctx->p_ctx, "arith", "float");
base_type = 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) 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; struct mie_file_span loc;
if (!mie_parser_parse_typename(ctx, name, &loc)) { if (!mie_parser_parse_typename(ctx, name, &loc)) {
b_string_unref(name);
return false; 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) bool mie_parser_parse_operand(struct mie_parser *ctx, struct mie_op_arg *out)
{ {
memset(out, 0x0, sizeof *out); memset(out, 0x0, sizeof *out);
b_string *str = b_string_create(); b_string *str = get_temp_string(ctx);
bool result = false; bool result = false;
struct mie_file_span loc; 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; result = true;
} }
b_string_unref(str);
return result; return result;
} }
@@ -420,6 +499,82 @@ bool mie_parser_parse_operand_list(
return true; 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( bool mie_parser_parse_register(
struct mie_parser *ctx, struct mie_name_map *names, struct mie_register *out) struct mie_parser *ctx, struct mie_name_map *names, struct mie_register *out)
{ {
@@ -438,14 +593,26 @@ bool mie_parser_parse_register(
return false; return false;
} }
if (!mie_name_map_put( struct mie_name *name = NULL;
names, &out->reg_name, tok->tok_str, MIE_NAME_MAP_F_STRICT)) { b_string *tmp = get_temp_string(ctx);
return false; 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); mie_parser_advance(ctx);
return true; return name != NULL;
} }
bool mie_parser_parse_register_list( 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) 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; return true;
} }
@@ -561,30 +757,271 @@ bool mie_parser_parse_region_list(
return true; 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( bool mie_parser_parse_attribute(
struct mie_parser *ctx, struct mie_op_attribute *attrib) struct mie_parser *ctx, struct mie_op_attribute *attrib)
{ {
b_string *str = get_temp_string(ctx);
struct mie_file_span span;
if (!mie_parser_parse_word(ctx, str, &span)) {
return false; 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( bool mie_parser_parse_attribute_list(
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_attribute, out)) struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_attribute, out))
{ {
bool ok = false;
struct mie_op_attribute *attrib = NULL;
attrib = mie_vector_ref_emplace_back(out);
if (!attrib) {
return false; return false;
} }
bool mie_parser_parse_successor( if (!mie_parser_parse_attribute(ctx, attrib)) {
struct mie_parser *ctx, struct mie_op_successor *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);
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 *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; return false;
} }
bool mie_parser_parse_successor_list( bool mie_parser_parse_successor_list(
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_successor, out)) struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_successor, out))
{ {
bool ok = false;
struct mie_op_successor *successor = NULL;
successor = mie_vector_ref_emplace_back(out);
if (!successor) {
return false; 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( static bool parse_custom_op(
struct mie_parser *ctx, struct mie_name_map *names, struct mie_op *dest) struct mie_parser *ctx, struct mie_name_map *names, struct mie_op *dest)
{ {
@@ -594,21 +1031,20 @@ static bool parse_custom_op(
static bool parse_generic_op( static bool parse_generic_op(
struct mie_parser *ctx, struct mie_name_map *names, struct mie_op *dest) 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; struct mie_file_span loc;
if (!mie_parser_parse_opname(ctx, str, &loc)) { if (!mie_parser_parse_opname(ctx, str, &loc)) {
b_string_unref(str);
return false; return false;
} }
dest->op_name = b_string_steal(str); dest->op_name = b_string_steal(str);
b_string_unref(str);
if (!mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_PAREN)) { if (!mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_PAREN)) {
return false; 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; return false;
} }
@@ -616,6 +1052,30 @@ static bool parse_generic_op(
return false; 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_symbol(ctx, MIE_SYM_LEFT_BRACKET)) {
if (!mie_parser_parse_successor_list( if (!mie_parser_parse_successor_list(
ctx, MIE_VECTOR_REF(dest->op_successors))) { ctx, MIE_VECTOR_REF(dest->op_successors))) {
@@ -720,3 +1180,101 @@ bool mie_parser_parse_op(
return false; 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_NONE);
ENUM_STR(MIE_TOK_LINEFEED); ENUM_STR(MIE_TOK_LINEFEED);
ENUM_STR(MIE_TOK_INT); ENUM_STR(MIE_TOK_INT);
ENUM_STR(MIE_TOK_DOUBLE); ENUM_STR(MIE_TOK_FLOAT);
ENUM_STR(MIE_TOK_SYMBOL); ENUM_STR(MIE_TOK_SYMBOL);
ENUM_STR(MIE_TOK_WORD); ENUM_STR(MIE_TOK_WORD);
ENUM_STR(MIE_TOK_NAME); 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-table.h>
#include <mie/trait/trait.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); memset(out, 0x0, sizeof *out);
out->u_id = trait->tr_id;
out->u_trait = trait; out->u_trait = trait;
return out; return out;
@@ -48,7 +49,6 @@ static struct generic_trait *generic_trait_create(const struct mie_trait *trait)
} }
memset(out, 0x0, sizeof *out); memset(out, 0x0, sizeof *out);
out->g_id = trait->tr_def->tr_id;
struct unique_trait *entry = unique_trait_create(trait); struct unique_trait *entry = unique_trait_create(trait);
if (!entry) { if (!entry) {
@@ -113,12 +113,55 @@ const struct mie_trait *mie_trait_table_get_unique(
static enum mie_status put_unique_trait( static enum mie_status put_unique_trait(
struct mie_trait_table *table, const struct mie_trait *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; return MIE_SUCCESS;
} }
static enum mie_status put_generic_trait( static enum mie_status put_generic_trait(
struct mie_trait_table *table, const struct mie_trait *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; return MIE_SUCCESS;
} }
@@ -163,6 +206,51 @@ enum mie_status mie_trait_table_get_generic(
return MIE_SUCCESS; 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( enum mie_status mie_trait_table_iterator_move_next(
struct mie_trait_table_iterator *it) 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/function.h>
#include <mie/type/type-definition.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.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); 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_data_size = sizeof(struct mie_type),
.ty_build_id = build_id, .ty_build_id = build_id,
.ty_print = type_print,
}; };
struct mie_function_type *mie_function_type_create(void) 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); memset(out, 0x0, sizeof *out);
out->func_base.ty_def = &function_type; out->func_base.ty_def = &function_type;
out->func_base.ty_category = MIE_TYPE_FUNCTION;
return out; return out;
} }

View File

@@ -1,5 +1,5 @@
#include <mie/dialect/type.h>
#include <mie/type/storage.h> #include <mie/type/storage.h>
#include <mie/type/type-definition.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.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); 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_data_size = sizeof(struct mie_type),
.ty_build_id = build_id, .ty_build_id = build_id,
.ty_print = type_print,
}; };
struct mie_storage_type *mie_storage_type_create(void) 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); memset(out, 0x0, sizeof *out);
out->st_base.ty_def = &storage_type; out->st_base.ty_def = &storage_type;
out->st_base.ty_category = MIE_TYPE_STORAGE;
return out; return out;
} }

View File

@@ -1,11 +1,11 @@
#include <blue/ds/string.h> #include <blue/ds/string.h>
#include <mie/dialect/dialect.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 *parent, const char *name)
{ {
struct mie_dialect_type *out = malloc(sizeof *out); struct mie_type_definition *out = malloc(sizeof *out);
if (!out) { if (!out) {
return NULL; return NULL;
} }
@@ -17,9 +17,16 @@ struct mie_dialect_type *mie_dialect_type_create(
} }
out->ty_parent = parent; out->ty_parent = parent;
mie_trait_table_init(&out->ty_traits);
b_rope name_rope = B_ROPE_CSTR(name); b_rope name_rope = B_ROPE_CSTR(name);
mie_id_map_put(&parent->d_types, &out->ty_id, &name_rope); mie_id_map_put(&parent->d_types, &out->ty_id, &name_rope);
return out; 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/function.h>
#include <mie/type/storage.h> #include <mie/type/storage.h>
#include <mie/type/type-definition.h>
#include <mie/type/type.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)) { if (type->ty_data_size < sizeof(struct mie_type)) {
return NULL; 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) 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) { if (type->ty_name) {
b_stream_write_string(out, type->ty_name, NULL); b_stream_write_string(out, type->ty_name, NULL);
} else if (type->ty_def && type->ty_def->ty_print) { } 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/type/type.h>
#include <mie/value.h> #include <mie/value.h>

View File

@@ -1,20 +1,382 @@
#include "cmd.h" #include "cmd.h"
#include <assert.h>
#include <blue/cmd.h> #include <blue/cmd.h>
#include <blue/io/file.h>
#include <blue/io/path.h>
#include <blue/term.h> #include <blue/term.h>
#include <mie/ctx.h> #include <mie/ctx.h>
#include <mie/ir/convert.h> #include <mie/dialect/arith.h>
#include <mie/ir/value.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 <stdbool.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
enum { enum {
OPT_TEMP, ARG_FILEPATH,
}; };
static int trait_ref_print(const struct mie_trait *trait, void *arg)
{
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 *_) 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; return 0;
} }
@@ -26,4 +388,13 @@ B_COMMAND(CMD_VALIDATE, CMD_ROOT)
B_COMMAND_HELP_OPTION(); B_COMMAND_HELP_OPTION();
B_COMMAND_FLAGS(B_COMMAND_SHOW_HELP_BY_DEFAULT); B_COMMAND_FLAGS(B_COMMAND_SHOW_HELP_BY_DEFAULT);
B_COMMAND_FUNCTION(validate); 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 "cmd/cmd.h"
#include <blue/cmd.h> #include <blue/cmd.h>
#include <mie/id.h>
#include <stdio.h>
int main(int argc, const char **argv) int main(int argc, const char **argv)
{ {