Compare commits
42 Commits
archive/le
...
9df79f90a6
| Author | SHA1 | Date | |
|---|---|---|---|
| 9df79f90a6 | |||
| c9c9cdf544 | |||
| 3253c4cac9 | |||
| fc61b188e3 | |||
| 6b5fd95ac4 | |||
| 700f7fe96e | |||
| fdf46b8867 | |||
| 417b5dc354 | |||
| d42e02f04d | |||
| 6e55642a19 | |||
| 0c84578f95 | |||
| 4a0fcef862 | |||
| 79c83ef73c | |||
| c6be143925 | |||
| e76e7c17db | |||
| 27e42340de | |||
| c686c31ca0 | |||
| 8ad3f36288 | |||
| 0a45e3b571 | |||
| e98ccd0c80 | |||
| 14a1ef30ee | |||
| 344626f207 | |||
| f4d374288f | |||
| 789bd1309f | |||
| 5b06934e85 | |||
| 9d80d94244 | |||
| 3c2ca0f70e | |||
| aad2cad0a8 | |||
| 8b3093411a | |||
| 7c7e5e7af0 | |||
| 9126edfd57 | |||
| 3c9506256d | |||
| add09d4958 | |||
| 7b6ce3bf6e | |||
| 79ab1c175b | |||
| 0dce84cb7f | |||
| 2e22898fc8 | |||
| 86005451cb | |||
| 21bcbb7edc | |||
| 915cf836f2 | |||
| f9a2cf3b8e | |||
| 6573360656 |
174
.clang-format
Normal file
174
.clang-format
Normal 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"
|
||||
@@ -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
|
||||
|
||||
@@ -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
38
doc/sample/graph/1.mie
Normal 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
33
doc/sample/graph/2.mie
Normal 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
530
doc/sample/ir/Person.2.mie
Normal file
@@ -0,0 +1,530 @@
|
||||
meta.source-filename "Person.im"
|
||||
|
||||
ivy.package-scope "net.doorstuck.test"
|
||||
|
||||
ivy.package-ref "std.io"
|
||||
|
||||
ivy.module {
|
||||
%cout = ivy.global-ref @cout -> ptr
|
||||
%StringBuilder = ivy.global-ref @StringBuilder : ptr
|
||||
|
||||
ivy.class @Person {
|
||||
%self.name = ivy.object-var @name : #ivy.id -> ptr
|
||||
%self.age = ivy.object-var @age : #ivy.id -> ptr
|
||||
%self.val = ivy.object-var @val : #ivy.id -> ptr
|
||||
%self.__example-property-4 = ivy.object-var @val : #ivy.id -> ptr
|
||||
%self.__example-property-5 = ivy.object-var @val : #ivy.id -> ptr
|
||||
|
||||
%lambda.0 = ivy.lambda.body <%env> (%i: #ivy.id) -> void {
|
||||
%StringBuilder = ivy.global-ref @StringBuilder -> ptr
|
||||
%0 = ivy.msg.send to %StringBuilder, new -> #ivy.id
|
||||
|
||||
%1 = ivy.str.constant "Count is "
|
||||
ivy.msg.send to %0, append:%1 -> void
|
||||
|
||||
ivy.msg.send to %0, append:%i -> void
|
||||
|
||||
%2 = ivy.msg.send to %0, to-string -> #ivy.id
|
||||
|
||||
%cout = ivy.global-ref @cout -> ptr
|
||||
%3 = ptr.load %cout : ptr -> #ivy.id
|
||||
ivy.msg.send to %3, put:%2 -> void
|
||||
|
||||
func.return : ()
|
||||
}
|
||||
|
||||
%lambda.1 = ivy.lambda.body <%env> () -> void {
|
||||
%env.q = ivy.pkg.get %env[@q] : #ivy.id -> #ivy.id
|
||||
|
||||
%StringBuilder = ivy.global-ref @StringBuilder -> ptr
|
||||
%0 = ivy.msg.send to %StringBuilder, new -> #ivy.id
|
||||
|
||||
%1 = ivy.str.constant "Value of q is "
|
||||
ivy.msg.send to %0, append:%1 -> void
|
||||
|
||||
ivy.msg.send to %0, append:%env.q -> void
|
||||
|
||||
%2 = ivy.msg.send to %0, to-string -> #ivy.id
|
||||
|
||||
%cout = ivy.global-ref @cout -> ptr
|
||||
%3 = ptr.load %cout : ptr -> #ivy.id
|
||||
ivy.msg.send to %3, put:%2 -> void
|
||||
}
|
||||
|
||||
ivy.method init(name:%name, age:%age) -> void {
|
||||
ptr.store %name, %self.name : #ivy.id, ptr
|
||||
ptr.store %age, %self.age : #ivy.id, ptr
|
||||
func.return : ()
|
||||
}
|
||||
|
||||
ivy.method test(param:%data, _:%extra) -> void {
|
||||
%0 = ptr.load %StringBuilder : ptr -> #ivy.id
|
||||
%1 = ivy.msg.send to %0, new -> #ivy.id
|
||||
|
||||
%2 = ivy.str.constant "Received "
|
||||
ivy.msg.send to %1, append:%2 -> void
|
||||
|
||||
ivy.msg.send to %1, append:%data -> void
|
||||
|
||||
%3 = ivy.str.constant ", "
|
||||
ivy.msg.send to %1, append:%3 -> void
|
||||
|
||||
ivy.msg.send to %1, append:%extra -> void
|
||||
|
||||
%4 = ivy.msg.send to %1, to-string -> #ivy.id
|
||||
|
||||
%5 = ptr.load %cout : ptr -> #ivy.id
|
||||
ivy.msg.send to %5, put:%4 -> void
|
||||
func.return : ()
|
||||
}
|
||||
|
||||
ivy.method name -> #ivy.id {
|
||||
%0 = ptr.load %self.name : ptr -> #ivy.id
|
||||
func.return %0 : #ivy.id
|
||||
}
|
||||
|
||||
ivy.method age -> #ivy.id {
|
||||
%0 = ptr.load %self.age : ptr -> #ivy.id
|
||||
func.return %0 : #ivy.id
|
||||
}
|
||||
|
||||
ivy.method age-in-months -> #ivy.id {
|
||||
%0 = ptr.load %self.age : ptr -> #ivy.id
|
||||
%1 = i32.constant 12
|
||||
%multmp = ivy.mul %0, %1 : (#ivy.id, i32) -> #ivy.id
|
||||
func.return %multmp : #ivy.id
|
||||
}
|
||||
|
||||
ivy.method set-name:%name -> void {
|
||||
ptr.store %name, %self.name : #ivy.id, ptr
|
||||
func.return : ()
|
||||
}
|
||||
|
||||
ivy.method set-age:%age -> void {
|
||||
ptr.store %age, %self.age : #ivy.id, ptr
|
||||
func.return : ()
|
||||
}
|
||||
|
||||
ivy.method set-age:%age in-units:%units -> void {
|
||||
^switch.cond.0:
|
||||
%0 = ivy.atom "years"
|
||||
%cmptmp.0 = ivy.cmp eq %age, %0 : (#ivy.id, #ivy.atom) -> i1
|
||||
cf.br-cond %cmptmp.0, ^switch.body.0, ^switch.cond.1
|
||||
|
||||
^switch.body.0:
|
||||
ptr.store %age, %self.age : #ivy.id, ptr
|
||||
cf.br ^switch.end.0
|
||||
|
||||
^switch.cond.1:
|
||||
%1 = ivy.atom "months"
|
||||
%cmptmp.1 = ivy.cmp eq %age, %1 : (#ivy.id, #ivy.atom) -> i1
|
||||
cf.br-cond %cmptmp.1, ^switch.body.1, ^switch.cond.2
|
||||
|
||||
^switch.body.1:
|
||||
%d0 = i32.constant 12
|
||||
%divtmp.0 = ivy.div %age, %d0 : (#ivy.id, i32) -> #ivy.id
|
||||
ptr.store %divtmp.0, %self.age : #ivy.id, ptr
|
||||
cf.br ^switch.end.0
|
||||
|
||||
^switch.cond.2:
|
||||
%2 = ivy.atom "days"
|
||||
%cmptmp.2 = ivy.cmp eq %age, %2 : (#ivy.id, #ivy.atom) -> i1
|
||||
cf.br-cond %cmptmp.2, ^switch.body.2, ^switch.default
|
||||
|
||||
^switch.body.2:
|
||||
%d1 = i32.constant 365
|
||||
%divtmp.1 = ivy.div %age, %d1 : (#ivy.id, i32) -> #ivy.id
|
||||
ptr.store %divtmp.1, %self.age : #ivy.id, ptr
|
||||
cf.br ^switch.end.0
|
||||
|
||||
^switch.default:
|
||||
%d2 = i32.constant 0
|
||||
cf.br ^switch.end.0
|
||||
|
||||
^switch.end:
|
||||
func.return : ()
|
||||
}
|
||||
|
||||
ivy.method get-age-in-units:%units -> #ivy.id {
|
||||
^switch.cond.0:
|
||||
%0 = ivy.atom "years"
|
||||
%cmptmp.0 = ivy.cmp eq %age, %0 : (#ivy.id, #ivy.atom) -> i1
|
||||
cf.br-cond %cmptmp.0, ^switch.body.0, ^switch.cond.1
|
||||
|
||||
^switch.body.0:
|
||||
%v0 = ptr.load %self.age : ptr -> #ivy.id
|
||||
cf.br ^switch.end(%v0: #ivy.id)
|
||||
|
||||
^switch.cond.0:
|
||||
%1 = ivy.atom "months"
|
||||
%cmptmp.1 = ivy.cmp eq %age, %1 : (#ivy.id, #ivy.atom) -> i1
|
||||
cf.br-cond %cmptmp.1, ^switch.body.1, ^switch.cond.2
|
||||
|
||||
^switch.body.0:
|
||||
%v0 = ptr.load %self.age : ptr -> #ivy.id
|
||||
%d0 = i32.constant 12
|
||||
%divtmp.0 = ivy.div %v0, %d0 : (#ivy.id, i32) -> #ivy.id
|
||||
cf.br ^switch.end(%divtmp.0: #ivy.id)
|
||||
|
||||
^switch.cond.0:
|
||||
%2 = ivy.atom "days"
|
||||
%cmptmp.2 = ivy.cmp eq %age, %2 : (#ivy.id, #ivy.atom) -> i1
|
||||
cf.br-cond %cmptmp.2, ^switch.body.2, ^switch.default
|
||||
|
||||
^switch.body.0:
|
||||
%v1 = ptr.load %self.age : ptr -> #ivy.id
|
||||
%d1 = i32.constant 365
|
||||
%divtmp.1 = ivy.div %v1, %d1 : (#ivy.id, i32) -> #ivy.id
|
||||
cf.br ^switch.end(%divtmp.1: #ivy.id)
|
||||
|
||||
^switch.default:
|
||||
%d2 = i32.constant 0
|
||||
cf.br ^switch.end(%d2.1: i32)
|
||||
|
||||
^switch.end(%result: #ivy.id):
|
||||
func.return %result : #ivy.id
|
||||
}
|
||||
|
||||
ivy.object-prop example-property
|
||||
get {
|
||||
%0 = ptr.load %self.val : ptr -> #ivy.id
|
||||
func.return %0 : #ivy.id
|
||||
}
|
||||
set (%value: #ivy.id) {
|
||||
ptr.store %value, %self.val : #ivy.id, ptr
|
||||
func.return : ()
|
||||
}
|
||||
|
||||
ivy.object-prop example-property-2 get {
|
||||
%0 = ptr.load %self.val : ptr -> #ivy.id
|
||||
func.return %0 : #ivy.id
|
||||
} set (%x: #ivy.id) {
|
||||
ptr.store %x, %self.val : #ivy.id, ptr
|
||||
func.return : ()
|
||||
}
|
||||
|
||||
ivy.object-prop example-property-3 get {
|
||||
%0 = i32.constant 42
|
||||
func.return %0 : i32
|
||||
}
|
||||
|
||||
ivy.object-prop example-property-4 get {
|
||||
%0 = ptr.load %self.p-example-property-4 : ptr -> #ivy.id
|
||||
func.return %0 : #ivy.id
|
||||
} set (%0: #ivy.id) {
|
||||
ptr.store %0, %self.p-example-property-4 : #ivy.id, ptr
|
||||
func.return : ()
|
||||
}
|
||||
|
||||
ivy.object-prop example-property-5 get {
|
||||
%0 = ptr.load %self.p-example-property-5 : ptr -> #ivy.id
|
||||
func.return %0 : #ivy.id
|
||||
}
|
||||
}
|
||||
|
||||
ivy.init-text {
|
||||
; p1 = Person new(name:'John Doe', age:34).
|
||||
%Person = ivy.global-ref @Person : ptr
|
||||
%0 = ivy.str.constant "John Doe"
|
||||
%1 = i32.constant 34
|
||||
|
||||
%2 = ivy.msg.send to %Person, new(name:%0, age:%1) -> #ivy.id
|
||||
|
||||
%p1 = ptr.alloca #ivy.id -> ptr
|
||||
ptr.store %2, %p1 : #ivy.id, ptr
|
||||
|
||||
; p1 set-age:100 in-unit:$months.
|
||||
%3 = ptr.load %p1 : ptr -> #ivy.id
|
||||
%4 = i32.constant 100
|
||||
%5 = ivy.atom "months"
|
||||
ivy.msg.send to %3, set-age:%4 in-units:%5 -> void
|
||||
|
||||
; p1 test(param:'Hello', 'World').
|
||||
%6 = ptr.load %p1 : ptr -> #ivy.id
|
||||
%7 = ivy.str.constant "Hello"
|
||||
%8 = ivy.str.constant "World"
|
||||
ivy.msg.send to %6, test(param:%7, _:%8) -> void
|
||||
|
||||
; i = 0.
|
||||
%i = ptr.alloca i32 -> ptr
|
||||
%9 = i32.constant 0
|
||||
ptr.store %9, %i : i32, ptr
|
||||
|
||||
; while i < 100 do
|
||||
^while.cond:
|
||||
; i < 100
|
||||
%10 = ptr.load %i : ptr -> i32
|
||||
%11 = i32.constant 100
|
||||
%cmptmp = ivy.cmp lt %10, %11 : (i32, i32) -> i1
|
||||
scf.condition(%cmptmp)
|
||||
cf.br-cond %cmptmp, ^while.body, ^while.end
|
||||
|
||||
^while.body:
|
||||
; cout put:'Count is {i}'.
|
||||
%12 = ivy.msg.send to %StringBuilder, new -> #ivy.id
|
||||
|
||||
%13 = ivy.str.constant "Count is "
|
||||
ivy.msg.send to %12, append:%13 -> void
|
||||
|
||||
%14 = ptr.load %i : ptr -> i32
|
||||
ivy.msg.send to %12, append:14 -> void
|
||||
|
||||
%15 = ivy.msg.send to %12, to-string -> #ivy.id
|
||||
|
||||
%16 = ptr.load %cout : ptr -> #ivy.id
|
||||
ivy.msg.send to %16, put:%15 -> void
|
||||
|
||||
; i += 2
|
||||
%17 = ptr.load %i : ptr -> i32
|
||||
%18 = i32.constant 2
|
||||
%addtmp = ivy.add %17, %18 : (i32, i32) -> i32
|
||||
ptr.store %addtmp, %i : i32, ptr
|
||||
cf.br ^while.cond
|
||||
|
||||
^while.end:
|
||||
; 0 to:100 step:2
|
||||
%19 = i32.constant 0
|
||||
%20 = i32.constant 100
|
||||
%21 = i32.constant 2
|
||||
%22 = ivy.msg.send to %19, to:%20 step:%21 -> #ivy.id
|
||||
|
||||
%for.iv.0 = ivy.msg.send to %22, value -> #ivy.id
|
||||
cf.br ^for.cond(%for.iv.0: #ivy.id)
|
||||
|
||||
^for.step:
|
||||
ivy.msg.send to %22, move-next -> void
|
||||
%for.iv.next = ivy.msg.send to %22, value -> #ivy.id
|
||||
cf.br ^for.cond(%for.iv.next: #ivy.id)
|
||||
|
||||
^for.cond(%iv: #ivy.id):
|
||||
%for.valid = ivy.is-null-ref %iv : #ivy.id -> i1
|
||||
cf.br-cond %for.valid, ^for.body(%iv: #ivy.id), ^for.end
|
||||
|
||||
^for.body(%x: #ivy.id):
|
||||
; for x in 0 to:100 step:2 do
|
||||
%23 = ivy.msg.send to %StringBuilder, new -> #ivy.id
|
||||
|
||||
; 'Count is {x}'
|
||||
%24 = ivy.str.constant "Count is "
|
||||
ivy.msg.send to %23, append:%24 -> void
|
||||
|
||||
ivy.msg.send to %23, append:%x -> void
|
||||
|
||||
%25 = ivy.msg.send to %23, to-string -> #ivy.id
|
||||
|
||||
; cout put:"Count is {x}"
|
||||
%26 = ptr.load %cout : ptr -> #ivy.id
|
||||
ivy.msg.send to %26, put:%25 -> void
|
||||
|
||||
cf.br ^for.step
|
||||
|
||||
^for.end:
|
||||
; 0 to:100 step:2 do:...
|
||||
%27 = i32.constant 0
|
||||
%28 = i32.constant 100
|
||||
%29 = i32.constant 2
|
||||
; [ :i | cout put:'Count: {i}' ]
|
||||
%30 = ivy.lambda.create %lambda.0 -> #ivy.id
|
||||
|
||||
; 0 to:100 step:2 do:[ :i | cout put:'Count: {i}' ].
|
||||
ivy.msg.send to %27, to:%28 step:%29 do:%30
|
||||
|
||||
; q = 32.
|
||||
%q = ptr.alloca i32 -> ptr
|
||||
%31 = i32.constant 32
|
||||
ptr.store %31, %q : i32, ptr
|
||||
|
||||
; l = [ cout put:'Value of q is {q}' ].
|
||||
%l = ptr.alloca #ivy.id
|
||||
%32 = ptr.load %q : ptr -> i32
|
||||
%lambda.env = ivy.pkg.create -> #ivy.id
|
||||
ivy.pkg.put %lambda.env[@q] = %32 : (#ivy.id, #ivy.id)
|
||||
|
||||
%33 = ivy.lambda.create <%lambda.env> %lambda.1 -> #ivy.id
|
||||
|
||||
ptr.store %33, %l : #ivy.id, ptr
|
||||
|
||||
; q = 64.
|
||||
%34 = i32.constant 64
|
||||
ptr.store %34, %q : i32, ptr
|
||||
|
||||
; l call.
|
||||
%35 = ptr.load %l : ptr -> #ivy.id
|
||||
ivy.msg.send to %35, call -> void
|
||||
|
||||
%j = ptr.alloca i32 -> ptr
|
||||
|
||||
%36 = i32.constant 32
|
||||
ptr.store %36, %j : i32, ptr
|
||||
|
||||
%37 = ptr.load %i : ptr -> i32
|
||||
%38 = ptr.load %j : ptr -> i32
|
||||
|
||||
%cmptmp = arith.cmp lt %37, %38 : (i32, i32) -> i1
|
||||
|
||||
%39 = ivy.lambda : () -> void {
|
||||
%cout = ivy.global-ref @cout -> ptr
|
||||
%0 = ivy.str.constant "True!"
|
||||
%1 = ptr.load %cout : ptr -> #ivy.id
|
||||
ivy.msg.send to %1, put:%0 -> void
|
||||
}
|
||||
|
||||
%40 = ivy.lambda : () -> void {
|
||||
%cout = ivy.global-ref @cout -> ptr
|
||||
%0 = ivy.str.constant "False!"
|
||||
%1 = ptr.load %cout : ptr -> #ivy.id
|
||||
ivy.msg.send to %1, put:%0 -> void
|
||||
}
|
||||
|
||||
ivy.msg.send to %cmptmp, if:%39 else:%40 -> void
|
||||
|
||||
%41 = ptr.load %i : ptr -> i32
|
||||
%42 = ptr.load %j : ptr -> i32
|
||||
|
||||
%cmptmp.0 = arith.cmp lt %41, %42 : (i32, i32) -> i1
|
||||
|
||||
scf.if %cmptmp.0 -> void {
|
||||
%43 = ivy.str.constant "True!"
|
||||
%44 = ptr.load %cout : ptr -> #ivy.id
|
||||
ivy.msg.send to %44, put:%43 -> void
|
||||
}
|
||||
|
||||
; pkg = {}.
|
||||
%pkg = ptr.alloca #ivy.id -> ptr
|
||||
|
||||
|
||||
%45 = ivy.pkg.create -> #ivy.id
|
||||
ptr.store %45, %pkg : #ivy.id, ptr
|
||||
|
||||
; pkg[0] = 16.
|
||||
%46 = ptr.load %pkg : ptr -> #ivy.id
|
||||
%47 = i32.constant 0
|
||||
%48 = i32.constant 16
|
||||
|
||||
ivy.msg.send to %46, at:%47 put:%48 -> void
|
||||
|
||||
; tuple = (32, 'a string')
|
||||
%tuple = ptr.alloca #ivy.id -> ptr
|
||||
|
||||
%49 = i32.constant 32
|
||||
%50 = ivy.str.constant "a string"
|
||||
|
||||
%51 = ivy.tuple.create %49, %50 : (i32, #ivy.id) -> #ivy.id
|
||||
|
||||
ptr.store %51, %tuple : #ivy.id, ptr
|
||||
|
||||
%52 = ptr.load %tuple : ptr -> #ivy.id
|
||||
%53 = ivy.msg.send to %52, get-iterator -> #ivy.id
|
||||
|
||||
ivy.for %54 in %53 -> void {
|
||||
%key = ivy.tuple.get-item %54[0] : #ivy.id -> #ivy.id
|
||||
%val = ivy.tuple.get-item %54[1] : #ivy.id -> #ivy.id
|
||||
|
||||
; '{key} -> {val}'
|
||||
%55 = ivy.msg.send to %StringBuilder, new -> #ivy.id
|
||||
|
||||
ivy.msg.send to %55, append:%key -> void
|
||||
|
||||
%56 = ivy.str.constant " -> "
|
||||
ivy.msg.send to %55, append:%56 -> void
|
||||
|
||||
ivy.msg.send to %55, append:%val -> void
|
||||
|
||||
%57 = ivy.msg.send to %23, to-string -> #ivy.id
|
||||
|
||||
; cout put:'{key} -> {val}'
|
||||
%58 = ptr.load %cout : ptr -> #ivy.id
|
||||
ivy.msg.send to %58, put:%57 -> void
|
||||
}
|
||||
|
||||
; _ = 3 * 2.
|
||||
%59 = i32.constant 3
|
||||
%60 = i32.constant 2
|
||||
%multmp = arith.mul %59, %60 : (i32, i32) -> i32
|
||||
|
||||
; a = (32, 64).
|
||||
%a = ptr.alloca #ivy.id -> ptr
|
||||
|
||||
%61 = i32.constant 32
|
||||
%62 = i32.constant 64
|
||||
%63 = ivy.tuple.create %61, %62 : (i32, i32) -> #ivy.id
|
||||
|
||||
ptr.store %63, %a : #ivy.id, ptr
|
||||
|
||||
%v = ptr.alloca #ivy.id -> ptr
|
||||
|
||||
%64 = ptr.load %a : ptr -> #ivy.id
|
||||
%65 = ivy.tuple.get-item %64[1] : #ivy.id -> #ivy.id
|
||||
|
||||
ptr.store %65, %v : #ivy.id, ptr
|
||||
|
||||
%66 = ivy.atom "err:number-format"
|
||||
|
||||
ivy.try -> void {
|
||||
|
||||
} catch (%ex = %66), %data {
|
||||
|
||||
} catch-all %ex, %data {
|
||||
|
||||
}
|
||||
|
||||
%67 = ivy.lambda : () -> void {
|
||||
%v = ptr.alloca #ivy.id -> ptr
|
||||
%Int = ivy.global-ref @Int -> ptr
|
||||
%0 = ivy.str.constant "342"
|
||||
|
||||
%1 = ivy.msg.send to %Int, parse:%0
|
||||
|
||||
ptr.store %1, %v : #ivy.id, ptr
|
||||
}
|
||||
|
||||
%68 = ivy.lambda %err, %data : (#ivy.id, #ivy.id) -> void {
|
||||
%0 = ivy.msg.send to %StringBuilder, new -> #ivy.id
|
||||
|
||||
ivy.msg.send to %0, append:%key -> void
|
||||
|
||||
%1 = ivy.str.constant "Cannot parse integer string ("
|
||||
ivy.msg.send to %0, append:%1 -> void
|
||||
|
||||
ivy.msg.send to %0, append:%err -> void
|
||||
|
||||
%2 = ivy.str.constant ")"
|
||||
ivy.msg.send to %0, append:%2 -> void
|
||||
|
||||
%3 = ivy.msg.send to %0, to-string -> #ivy.id
|
||||
|
||||
; cout put:'{key} -> {val}'
|
||||
%4 = ptr.load %cout : ptr -> #ivy.id
|
||||
ivy.msg.send to %4, put:%3 -> void
|
||||
}
|
||||
|
||||
%69 = ivy.lambda %err, %data : (#ivy.id, #ivy.id) -> void {
|
||||
%0 = ivy.msg.send to %StringBuilder, new -> #ivy.id
|
||||
|
||||
ivy.msg.send to %0, append:%key -> void
|
||||
|
||||
%1 = ivy.str.constant "Error "
|
||||
ivy.msg.send to %0, append:%1 -> void
|
||||
|
||||
ivy.msg.send to %0, append:%err -> void
|
||||
|
||||
%2 = ivy.str.constant " occurred ("
|
||||
ivy.msg.send to %0, append:%2 -> void
|
||||
|
||||
ivy.msg.send to %0, append:%data -> void
|
||||
|
||||
%3 = ivy.str.constant ")"
|
||||
|
||||
%4 = ivy.msg.send to %0, to-string -> #ivy.id
|
||||
|
||||
; cout put:'{key} -> {val}'
|
||||
%5 = ptr.load %cout : ptr -> #ivy.id
|
||||
ivy.msg.send to %5, put:%4 -> void
|
||||
}
|
||||
|
||||
%70 = ivy.atom "err:number-format"
|
||||
ivy.msg.send to %67, on:%70 do:%68 -> #ivy.id
|
||||
ivy.msg.send to %67, on-error:%69 -> void
|
||||
ivy.msg.send to %67, call -> void
|
||||
}
|
||||
}
|
||||
535
doc/sample/ir/Person.3.mie
Normal file
535
doc/sample/ir/Person.3.mie
Normal file
@@ -0,0 +1,535 @@
|
||||
meta.source-filename "Person.im"
|
||||
|
||||
ivy.package-scope "net.doorstuck.test"
|
||||
|
||||
ivy.package-ref "std.io"
|
||||
|
||||
ivy.module {
|
||||
%cout = ivy.global-ref @cout -> ptr
|
||||
%StringBuilder = ivy.global-ref @StringBuilder : ptr
|
||||
|
||||
ivy.class @Person {
|
||||
%self.name = ivy.object-var @name : #ivy.id -> ptr
|
||||
%self.age = ivy.object-var @age : #ivy.id -> ptr
|
||||
%self.val = ivy.object-var @val : #ivy.id -> ptr
|
||||
%self.__example-property-4 = ivy.object-var @val : #ivy.id -> ptr
|
||||
%self.__example-property-5 = ivy.object-var @val : #ivy.id -> ptr
|
||||
|
||||
%lambda.0 = ivy.lambda.body <%env> (%i: #ivy.id) -> void {
|
||||
%StringBuilder = ivy.global-ref @StringBuilder -> ptr
|
||||
%0 = ivy.msg.send to %StringBuilder, new -> #ivy.id
|
||||
|
||||
%1 = ivy.str.constant "Count is "
|
||||
ivy.msg.send to %0, append:%1 -> void
|
||||
|
||||
ivy.msg.send to %0, append:%i -> void
|
||||
|
||||
%2 = ivy.msg.send to %0, to-string -> #ivy.id
|
||||
|
||||
%cout = ivy.global-ref @cout -> ptr
|
||||
%3 = ptr.load %cout : ptr -> #ivy.id
|
||||
ivy.msg.send to %3, put:%2 -> void
|
||||
|
||||
func.return : ()
|
||||
}
|
||||
|
||||
%lambda.1 = ivy.lambda.body <%env> () -> void {
|
||||
%env.q = ivy.pkg.get %env[@q] : #ivy.id -> #ivy.id
|
||||
|
||||
%StringBuilder = ivy.global-ref @StringBuilder -> ptr
|
||||
%0 = ivy.msg.send to %StringBuilder, new -> #ivy.id
|
||||
|
||||
%1 = ivy.str.constant "Value of q is "
|
||||
ivy.msg.send to %0, append:%1 -> void
|
||||
|
||||
ivy.msg.send to %0, append:%env.q -> void
|
||||
|
||||
%2 = ivy.msg.send to %0, to-string -> #ivy.id
|
||||
|
||||
%cout = ivy.global-ref @cout -> ptr
|
||||
%3 = ptr.load %cout : ptr -> #ivy.id
|
||||
ivy.msg.send to %3, put:%2 -> void
|
||||
}
|
||||
|
||||
ivy.object.func init(name:%name, age:%age) -> void {
|
||||
ptr.store %name, %self.name : #ivy.id, ptr
|
||||
ptr.store %age, %self.age : #ivy.id, ptr
|
||||
func.return : ()
|
||||
}
|
||||
|
||||
ivy.object.func test(param:%data, _:%extra) -> void {
|
||||
%0 = ptr.load %StringBuilder : ptr -> #ivy.id
|
||||
%1 = ivy.msg.send to %0, new -> #ivy.id
|
||||
|
||||
%2 = ivy.str.constant "Received "
|
||||
ivy.msg.send to %1, append:%2 -> void
|
||||
|
||||
ivy.msg.send to %1, append:%data -> void
|
||||
|
||||
%3 = ivy.str.constant ", "
|
||||
ivy.msg.send to %1, append:%3 -> void
|
||||
|
||||
ivy.msg.send to %1, append:%extra -> void
|
||||
|
||||
%4 = ivy.msg.send to %1, to-string -> #ivy.id
|
||||
|
||||
%5 = ptr.load %cout : ptr -> #ivy.id
|
||||
ivy.msg.send to %5, put:%4 -> void
|
||||
func.return : ()
|
||||
}
|
||||
|
||||
ivy.object.func name -> #ivy.id {
|
||||
%0 = ptr.load %self.name : ptr -> #ivy.id
|
||||
func.return %0 : #ivy.id
|
||||
}
|
||||
|
||||
ivy.object.func age -> #ivy.id {
|
||||
%0 = ptr.load %self.age : ptr -> #ivy.id
|
||||
func.return %0 : #ivy.id
|
||||
}
|
||||
|
||||
ivy.object.func age-in-months -> #ivy.id {
|
||||
%0 = ptr.load %self.age : ptr -> #ivy.id
|
||||
%1 = i32.constant 12
|
||||
%multmp = ivy.mul %0, %1 : (#ivy.id, i32) -> #ivy.id
|
||||
func.return %multmp : #ivy.id
|
||||
}
|
||||
|
||||
ivy.object.func set-name:%name -> void {
|
||||
ptr.store %name, %self.name : #ivy.id, ptr
|
||||
func.return : ()
|
||||
}
|
||||
|
||||
ivy.object.func set-age:%age -> void {
|
||||
ptr.store %age, %self.age : #ivy.id, ptr
|
||||
func.return : ()
|
||||
}
|
||||
|
||||
ivy.object.func set-age:%age in-units:%units -> void {
|
||||
^switch.cond.0:
|
||||
%0 = ivy.atom "years"
|
||||
%cmptmp.0 = ivy.cmp eq %age, %0 : (#ivy.id, #ivy.atom) -> i1
|
||||
cf.br-cond %cmptmp.0, ^switch.body.0, ^switch.cond.1
|
||||
|
||||
^switch.body.0:
|
||||
ptr.store %age, %self.age : #ivy.id, ptr
|
||||
cf.br ^switch.end.0
|
||||
|
||||
^switch.cond.1:
|
||||
%1 = ivy.atom "months"
|
||||
%cmptmp.1 = ivy.cmp eq %age, %1 : (#ivy.id, #ivy.atom) -> i1
|
||||
cf.br-cond %cmptmp.1, ^switch.body.1, ^switch.cond.2
|
||||
|
||||
^switch.body.1:
|
||||
%d0 = i32.constant 12
|
||||
%divtmp.0 = ivy.div %age, %d0 : (#ivy.id, i32) -> #ivy.id
|
||||
ptr.store %divtmp.0, %self.age : #ivy.id, ptr
|
||||
cf.br ^switch.end.0
|
||||
|
||||
^switch.cond.2:
|
||||
%2 = ivy.atom "days"
|
||||
%cmptmp.2 = ivy.cmp eq %age, %2 : (#ivy.id, #ivy.atom) -> i1
|
||||
cf.br-cond %cmptmp.2, ^switch.body.2, ^switch.default
|
||||
|
||||
^switch.body.2:
|
||||
%d1 = i32.constant 365
|
||||
%divtmp.1 = ivy.div %age, %d1 : (#ivy.id, i32) -> #ivy.id
|
||||
ptr.store %divtmp.1, %self.age : #ivy.id, ptr
|
||||
cf.br ^switch.end.0
|
||||
|
||||
^switch.default:
|
||||
%d2 = i32.constant 0
|
||||
ptr.store %d2, %self.age : #ivy.id, ptr
|
||||
cf.br ^switch.end.0
|
||||
|
||||
^switch.end:
|
||||
func.return : ()
|
||||
}
|
||||
|
||||
ivy.object.func get-age-in-units:%units -> #ivy.id {
|
||||
^switch.cond.0:
|
||||
%0 = ivy.atom "years"
|
||||
%cmptmp.0 = ivy.cmp eq %age, %0 : (#ivy.id, #ivy.atom) -> i1
|
||||
cf.br-cond %cmptmp.0, ^switch.body.0, ^switch.cond.1
|
||||
|
||||
^switch.body.0:
|
||||
%v0 = ptr.load %self.age : ptr -> #ivy.id
|
||||
cf.br ^switch.end(%v0: #ivy.id)
|
||||
|
||||
^switch.cond.1:
|
||||
%1 = ivy.atom "months"
|
||||
%cmptmp.1 = ivy.cmp eq %age, %1 : (#ivy.id, #ivy.atom) -> i1
|
||||
cf.br-cond %cmptmp.1, ^switch.body.1, ^switch.cond.2
|
||||
|
||||
^switch.body.1:
|
||||
%v0 = ptr.load %self.age : ptr -> #ivy.id
|
||||
%d0 = i32.constant 12
|
||||
%divtmp.0 = ivy.div %v0, %d0 : (#ivy.id, i32) -> #ivy.id
|
||||
cf.br ^switch.end(%divtmp.0: #ivy.id)
|
||||
|
||||
^switch.cond.2:
|
||||
%2 = ivy.atom "days"
|
||||
%cmptmp.2 = ivy.cmp eq %age, %2 : (#ivy.id, #ivy.atom) -> i1
|
||||
cf.br-cond %cmptmp.2, ^switch.body.2, ^switch.default
|
||||
|
||||
^switch.body.2:
|
||||
%v1 = ptr.load %self.age : ptr -> #ivy.id
|
||||
%d1 = i32.constant 365
|
||||
%divtmp.1 = ivy.div %v1, %d1 : (#ivy.id, i32) -> #ivy.id
|
||||
cf.br ^switch.end(%divtmp.1: #ivy.id)
|
||||
|
||||
^switch.default:
|
||||
%d2 = i32.constant 0
|
||||
cf.br ^switch.end(%d2.1: i32)
|
||||
|
||||
^switch.end(%result: #ivy.id):
|
||||
func.return %result : #ivy.id
|
||||
}
|
||||
|
||||
ivy.object.prop example-property
|
||||
get {
|
||||
%0 = ptr.load %self.val : ptr -> #ivy.id
|
||||
func.return %0 : #ivy.id
|
||||
}
|
||||
set (%value: #ivy.id) {
|
||||
ptr.store %value, %self.val : #ivy.id, ptr
|
||||
func.return : ()
|
||||
}
|
||||
|
||||
ivy.object.prop example-property-2 get {
|
||||
%0 = ptr.load %self.val : ptr -> #ivy.id
|
||||
func.return %0 : #ivy.id
|
||||
} set (%x: #ivy.id) {
|
||||
ptr.store %x, %self.val : #ivy.id, ptr
|
||||
func.return : ()
|
||||
}
|
||||
|
||||
ivy.object.prop example-property-3 get {
|
||||
%0 = i32.constant 42
|
||||
func.return %0 : i32
|
||||
}
|
||||
|
||||
ivy.object.prop example-property-4 get {
|
||||
%0 = ptr.load %self.p-example-property-4 : ptr -> #ivy.id
|
||||
func.return %0 : #ivy.id
|
||||
} set (%0: #ivy.id) {
|
||||
ptr.store %0, %self.p-example-property-4 : #ivy.id, ptr
|
||||
func.return : ()
|
||||
}
|
||||
|
||||
ivy.object.prop example-property-5 get {
|
||||
%0 = ptr.load %self.p-example-property-5 : ptr -> #ivy.id
|
||||
func.return %0 : #ivy.id
|
||||
}
|
||||
}
|
||||
|
||||
ivy.init-text {
|
||||
; p1 = Person new(name:'John Doe', age:34).
|
||||
%Person = ivy.global-ref @Person : ptr
|
||||
%0 = ivy.str.constant "John Doe"
|
||||
%1 = i32.constant 34
|
||||
|
||||
%2 = ivy.msg.send to %Person, new(name:%0, age:%1) -> #ivy.id
|
||||
|
||||
%p1 = ptr.alloca #ivy.id -> ptr
|
||||
ptr.store %2, %p1 : #ivy.id, ptr
|
||||
|
||||
; p1 set-age:100 in-unit:$months.
|
||||
%3 = ptr.load %p1 : ptr -> #ivy.id
|
||||
%4 = i32.constant 100
|
||||
%5 = ivy.atom "months"
|
||||
ivy.msg.send to %3, set-age:%4 in-units:%5 -> void
|
||||
|
||||
; p1 test(param:'Hello', 'World').
|
||||
%6 = ptr.load %p1 : ptr -> #ivy.id
|
||||
%7 = ivy.str.constant "Hello"
|
||||
%8 = ivy.str.constant "World"
|
||||
ivy.msg.send to %6, test(param:%7, _:%8) -> void
|
||||
|
||||
; i = 0.
|
||||
%i = ptr.alloca i32 -> ptr
|
||||
%9 = i32.constant 0
|
||||
ptr.store %9, %i : i32, ptr
|
||||
cf.br ^while.cond
|
||||
|
||||
; while i < 100 do
|
||||
^while.cond:
|
||||
; i < 100
|
||||
%10 = ptr.load %i : ptr -> i32
|
||||
%11 = i32.constant 100
|
||||
%cmptmp = ivy.cmp lt %10, %11 : (i32, i32) -> i1
|
||||
scf.condition(%cmptmp)
|
||||
cf.br-cond %cmptmp, ^while.body, ^while.end
|
||||
|
||||
^while.body:
|
||||
; cout put:'Count is {i}'.
|
||||
%12 = ivy.msg.send to %StringBuilder, new -> #ivy.id
|
||||
|
||||
%13 = ivy.str.constant "Count is "
|
||||
ivy.msg.send to %12, append:%13 -> void
|
||||
|
||||
%14 = ptr.load %i : ptr -> i32
|
||||
ivy.msg.send to %12, append:14 -> void
|
||||
|
||||
%15 = ivy.msg.send to %12, to-string -> #ivy.id
|
||||
|
||||
%16 = ptr.load %cout : ptr -> #ivy.id
|
||||
ivy.msg.send to %16, put:%15 -> void
|
||||
|
||||
; i += 2
|
||||
%17 = ptr.load %i : ptr -> i32
|
||||
%18 = i32.constant 2
|
||||
%addtmp = ivy.add %17, %18 : (i32, i32) -> i32
|
||||
ptr.store %addtmp, %i : i32, ptr
|
||||
cf.br ^while.cond
|
||||
|
||||
^while.end:
|
||||
; 0 to:100 step:2
|
||||
%19 = i32.constant 0
|
||||
%20 = i32.constant 100
|
||||
%21 = i32.constant 2
|
||||
%22 = ivy.msg.send to %19, to:%20 step:%21 -> #ivy.id
|
||||
|
||||
cf.br ^for.init(%22: #ivy.id)
|
||||
|
||||
^for.init(%it: #ivy.id):
|
||||
%for.iv.0 = ivy.msg.send to %it, value -> #ivy.id
|
||||
cf.br ^for.cond(%it: #ivy.id, %for.iv.0: #ivy.id)
|
||||
|
||||
^for.step(%it: #ivy.id):
|
||||
ivy.msg.send to %22, move-next -> void
|
||||
%for.iv.next = ivy.msg.send to %22, value -> #ivy.id
|
||||
cf.br ^for.cond(%it: #ivy.id, %for.iv.next: #ivy.id)
|
||||
|
||||
^for.cond(%it: #ivy.id, %iv: #ivy.id):
|
||||
%for.valid = ivy.is-null-ref %iv : #ivy.id -> i1
|
||||
cf.br-cond %for.valid, ^for.body(%it: #ivy.id, %iv: #ivy.id), ^for.end
|
||||
|
||||
^for.body(%it: #ivy.id, %x: #ivy.id):
|
||||
; for x in 0 to:100 step:2 do
|
||||
%23 = ivy.msg.send to %StringBuilder, new -> #ivy.id
|
||||
|
||||
; 'Count is {x}'
|
||||
%24 = ivy.str.constant "Count is "
|
||||
ivy.msg.send to %23, append:%24 -> void
|
||||
|
||||
ivy.msg.send to %23, append:%x -> void
|
||||
|
||||
%25 = ivy.msg.send to %23, to-string -> #ivy.id
|
||||
|
||||
; cout put:"Count is {x}"
|
||||
%26 = ptr.load %cout : ptr -> #ivy.id
|
||||
ivy.msg.send to %26, put:%25 -> void
|
||||
|
||||
cf.br ^for.step(%it: #ivy.id)
|
||||
|
||||
^for.end:
|
||||
; 0 to:100 step:2 do:...
|
||||
%27 = i32.constant 0
|
||||
%28 = i32.constant 100
|
||||
%29 = i32.constant 2
|
||||
; [ :i | cout put:'Count: {i}' ]
|
||||
%30 = ivy.lambda.create %lambda.0 -> #ivy.id
|
||||
|
||||
; 0 to:100 step:2 do:[ :i | cout put:'Count: {i}' ].
|
||||
ivy.msg.send to %27, to:%28 step:%29 do:%30
|
||||
|
||||
; q = 32.
|
||||
%q = ptr.alloca i32 -> ptr
|
||||
%31 = i32.constant 32
|
||||
ptr.store %31, %q : i32, ptr
|
||||
|
||||
; l = [ cout put:'Value of q is {q}' ].
|
||||
%l = ptr.alloca #ivy.id
|
||||
%32 = ptr.load %q : ptr -> i32
|
||||
%lambda.env = ivy.pkg.create -> #ivy.id
|
||||
ivy.pkg.put %lambda.env[@q] = %32 : (#ivy.id, #ivy.id)
|
||||
|
||||
%33 = ivy.lambda.create <%lambda.env> %lambda.1 -> #ivy.id
|
||||
|
||||
ptr.store %33, %l : #ivy.id, ptr
|
||||
|
||||
; q = 64.
|
||||
%34 = i32.constant 64
|
||||
ptr.store %34, %q : i32, ptr
|
||||
|
||||
; l call.
|
||||
%35 = ptr.load %l : ptr -> #ivy.id
|
||||
ivy.msg.send to %35, call -> void
|
||||
|
||||
%j = ptr.alloca i32 -> ptr
|
||||
|
||||
%36 = i32.constant 32
|
||||
ptr.store %36, %j : i32, ptr
|
||||
|
||||
%37 = ptr.load %i : ptr -> i32
|
||||
%38 = ptr.load %j : ptr -> i32
|
||||
|
||||
%cmptmp = arith.cmp lt %37, %38 : (i32, i32) -> i1
|
||||
|
||||
%39 = ivy.lambda : () -> void {
|
||||
%cout = ivy.global-ref @cout -> ptr
|
||||
%0 = ivy.str.constant "True!"
|
||||
%1 = ptr.load %cout : ptr -> #ivy.id
|
||||
ivy.msg.send to %1, put:%0 -> void
|
||||
}
|
||||
|
||||
%40 = ivy.lambda : () -> void {
|
||||
%cout = ivy.global-ref @cout -> ptr
|
||||
%0 = ivy.str.constant "False!"
|
||||
%1 = ptr.load %cout : ptr -> #ivy.id
|
||||
ivy.msg.send to %1, put:%0 -> void
|
||||
}
|
||||
|
||||
ivy.msg.send to %cmptmp, if:%39 else:%40 -> void
|
||||
|
||||
%41 = ptr.load %i : ptr -> i32
|
||||
%42 = ptr.load %j : ptr -> i32
|
||||
|
||||
%cmptmp.0 = arith.cmp lt %41, %42 : (i32, i32) -> i1
|
||||
|
||||
scf.if %cmptmp.0 -> void {
|
||||
%43 = ivy.str.constant "True!"
|
||||
%44 = ptr.load %cout : ptr -> #ivy.id
|
||||
ivy.msg.send to %44, put:%43 -> void
|
||||
}
|
||||
|
||||
; pkg = {}.
|
||||
%pkg = ptr.alloca #ivy.id -> ptr
|
||||
|
||||
|
||||
%45 = ivy.pkg.create -> #ivy.id
|
||||
ptr.store %45, %pkg : #ivy.id, ptr
|
||||
|
||||
; pkg[0] = 16.
|
||||
%46 = ptr.load %pkg : ptr -> #ivy.id
|
||||
%47 = i32.constant 0
|
||||
%48 = i32.constant 16
|
||||
|
||||
ivy.msg.send to %46, at:%47 put:%48 -> void
|
||||
|
||||
; tuple = (32, 'a string')
|
||||
%tuple = ptr.alloca #ivy.id -> ptr
|
||||
|
||||
%49 = i32.constant 32
|
||||
%50 = ivy.str.constant "a string"
|
||||
|
||||
%51 = ivy.tuple.create %49, %50 : (i32, #ivy.id) -> #ivy.id
|
||||
|
||||
ptr.store %51, %tuple : #ivy.id, ptr
|
||||
|
||||
%52 = ptr.load %tuple : ptr -> #ivy.id
|
||||
%53 = ivy.msg.send to %52, get-iterator -> #ivy.id
|
||||
|
||||
ivy.for %54 in %53 -> void {
|
||||
%key = ivy.tuple.get-item %54[0] : #ivy.id -> #ivy.id
|
||||
%val = ivy.tuple.get-item %54[1] : #ivy.id -> #ivy.id
|
||||
|
||||
; '{key} -> {val}'
|
||||
%55 = ivy.msg.send to %StringBuilder, new -> #ivy.id
|
||||
|
||||
ivy.msg.send to %55, append:%key -> void
|
||||
|
||||
%56 = ivy.str.constant " -> "
|
||||
ivy.msg.send to %55, append:%56 -> void
|
||||
|
||||
ivy.msg.send to %55, append:%val -> void
|
||||
|
||||
%57 = ivy.msg.send to %23, to-string -> #ivy.id
|
||||
|
||||
; cout put:'{key} -> {val}'
|
||||
%58 = ptr.load %cout : ptr -> #ivy.id
|
||||
ivy.msg.send to %58, put:%57 -> void
|
||||
}
|
||||
|
||||
; _ = 3 * 2.
|
||||
%59 = i32.constant 3
|
||||
%60 = i32.constant 2
|
||||
%multmp = arith.mul %59, %60 : (i32, i32) -> i32
|
||||
|
||||
; a = (32, 64).
|
||||
%a = ptr.alloca #ivy.id -> ptr
|
||||
|
||||
%61 = i32.constant 32
|
||||
%62 = i32.constant 64
|
||||
%63 = ivy.tuple.create %61, %62 : (i32, i32) -> #ivy.id
|
||||
|
||||
ptr.store %63, %a : #ivy.id, ptr
|
||||
|
||||
%v = ptr.alloca #ivy.id -> ptr
|
||||
|
||||
%64 = ptr.load %a : ptr -> #ivy.id
|
||||
%65 = ivy.tuple.get-item %64[1] : #ivy.id -> #ivy.id
|
||||
|
||||
ptr.store %65, %v : #ivy.id, ptr
|
||||
|
||||
%66 = ivy.atom "err:number-format"
|
||||
|
||||
ivy.try -> void {
|
||||
|
||||
} catch (%ex = %66), %data {
|
||||
|
||||
} catch-all %ex, %data {
|
||||
|
||||
}
|
||||
|
||||
%67 = ivy.lambda : () -> void {
|
||||
%v = ptr.alloca #ivy.id -> ptr
|
||||
%Int = ivy.global-ref @Int -> ptr
|
||||
%0 = ivy.str.constant "342"
|
||||
|
||||
%1 = ivy.msg.send to %Int, parse:%0
|
||||
|
||||
ptr.store %1, %v : #ivy.id, ptr
|
||||
}
|
||||
|
||||
%68 = ivy.lambda %err, %data : (#ivy.id, #ivy.id) -> void {
|
||||
%0 = ivy.msg.send to %StringBuilder, new -> #ivy.id
|
||||
|
||||
ivy.msg.send to %0, append:%key -> void
|
||||
|
||||
%1 = ivy.str.constant "Cannot parse integer string ("
|
||||
ivy.msg.send to %0, append:%1 -> void
|
||||
|
||||
ivy.msg.send to %0, append:%err -> void
|
||||
|
||||
%2 = ivy.str.constant ")"
|
||||
ivy.msg.send to %0, append:%2 -> void
|
||||
|
||||
%3 = ivy.msg.send to %0, to-string -> #ivy.id
|
||||
|
||||
; cout put:'{key} -> {val}'
|
||||
%4 = ptr.load %cout : ptr -> #ivy.id
|
||||
ivy.msg.send to %4, put:%3 -> void
|
||||
}
|
||||
|
||||
%69 = ivy.lambda %err, %data : (#ivy.id, #ivy.id) -> void {
|
||||
%0 = ivy.msg.send to %StringBuilder, new -> #ivy.id
|
||||
|
||||
ivy.msg.send to %0, append:%key -> void
|
||||
|
||||
%1 = ivy.str.constant "Error "
|
||||
ivy.msg.send to %0, append:%1 -> void
|
||||
|
||||
ivy.msg.send to %0, append:%err -> void
|
||||
|
||||
%2 = ivy.str.constant " occurred ("
|
||||
ivy.msg.send to %0, append:%2 -> void
|
||||
|
||||
ivy.msg.send to %0, append:%data -> void
|
||||
|
||||
%3 = ivy.str.constant ")"
|
||||
|
||||
%4 = ivy.msg.send to %0, to-string -> #ivy.id
|
||||
|
||||
; cout put:'{key} -> {val}'
|
||||
%5 = ptr.load %cout : ptr -> #ivy.id
|
||||
ivy.msg.send to %5, put:%4 -> void
|
||||
}
|
||||
|
||||
%70 = ivy.atom "err:number-format"
|
||||
ivy.msg.send to %67, on:%70 do:%68 -> #ivy.id
|
||||
ivy.msg.send to %67, on-error:%69 -> void
|
||||
ivy.msg.send to %67, call -> void
|
||||
}
|
||||
}
|
||||
460
doc/sample/ir/Person.mie
Normal file
460
doc/sample/ir/Person.mie
Normal 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
|
||||
}
|
||||
}
|
||||
46
doc/sample/ir/Simple.1.mie
Normal file
46
doc/sample/ir/Simple.1.mie
Normal file
@@ -0,0 +1,46 @@
|
||||
meta.source-filename "Simple.im"
|
||||
|
||||
ivy.package-scope "net.doorstuck.test"
|
||||
|
||||
ivy.package-ref "std.io"
|
||||
|
||||
ivy.module {
|
||||
ivy.init-text {
|
||||
%0 = i32.constant 32
|
||||
%1 = i32.constant 64
|
||||
%multmp = arith.mul %0, %1 : (i32, i32) -> i32
|
||||
|
||||
%y = ptr.alloca i32
|
||||
ptr.store %multmp, %y : i32, ptr
|
||||
|
||||
%2 = i32.constant 64
|
||||
%3 = i32.constant 4
|
||||
%divtmp = arith.div %2, %3 : (i32, i32) -> i32
|
||||
|
||||
%z = ptr.alloca i32
|
||||
ptr.store %divtmp, %z : i32, ptr
|
||||
|
||||
%4 = ptr.load %y : ptr -> i32
|
||||
%5 = ptr.load %z : ptr -> i32
|
||||
%addtmp = arith.add %4, %5 : (i32, i32) -> i32
|
||||
|
||||
%x = ptr.alloca i32
|
||||
ptr.store %addtmp, %x : i32, ptr
|
||||
|
||||
%cout = ivy.global-ref @cout -> ptr
|
||||
|
||||
%6 = ivy.string-builder.begin
|
||||
ivy.string-builder.add %6 << "Answer: "
|
||||
|
||||
%7 = ptr.load %x : ptr -> i32
|
||||
ivy.string-builder.add %6 << %7 : i32
|
||||
|
||||
%8 = ivy.string-builder.end %6 -> #ivy.id
|
||||
|
||||
%9 = ptr.load %cout : ptr -> #ivy.id
|
||||
|
||||
ivy.msg.send to %9, put:%8 -> void
|
||||
|
||||
func.return : ()
|
||||
}
|
||||
}
|
||||
50
doc/sample/ir/Simple.2.mie
Normal file
50
doc/sample/ir/Simple.2.mie
Normal file
@@ -0,0 +1,50 @@
|
||||
meta.source-filename "Simple.im"
|
||||
|
||||
ivy.package-scope "net.doorstuck.test"
|
||||
|
||||
ivy.package-ref "std.io"
|
||||
|
||||
ivy.module {
|
||||
%cout = ivy.global-ref @cout -> ptr
|
||||
%StringBuilder = ivy.global-ref @std.lang.StringBuilder -> ptr
|
||||
|
||||
%.str.0 = ivy.str.constant "Answer: "
|
||||
|
||||
ivy.init-text {
|
||||
%0 = i32.constant 32
|
||||
%1 = i32.constant 64
|
||||
%multmp = arith.mul %0, %1 : (i32, i32) -> i32
|
||||
|
||||
%y = ptr.alloca i32
|
||||
ptr.store %multmp, %y : i32, ptr
|
||||
|
||||
%2 = i32.constant 64
|
||||
%3 = i32.constant 4
|
||||
%divtmp = arith.div %2, %3 : (i32, i32) -> i32
|
||||
|
||||
%z = ptr.alloca i32
|
||||
ptr.store %divtmp, %z : i32, ptr
|
||||
|
||||
%4 = ptr.load %y : ptr -> i32
|
||||
%5 = ptr.load %z : ptr -> i32
|
||||
%addtmp = arith.add %4, %5 : (i32, i32) -> i32
|
||||
|
||||
%x = ptr.alloca i32
|
||||
ptr.store %addtmp, %x : i32, ptr
|
||||
|
||||
%10 = ptr.load %StringBuilder : ptr -> #ivy.id
|
||||
|
||||
ivy.msg.send to %10, append:%.str.0 -> void
|
||||
|
||||
%7 = ptr.load %x : ptr -> i32
|
||||
ivy.msg.send to %10, append:%7 -> void
|
||||
|
||||
%8 = ivy.msg.send to %10, to-string -> #ivy.id
|
||||
|
||||
%9 = ptr.load %cout : ptr -> #ivy.id
|
||||
|
||||
ivy.msg.send to %9, put:%8 -> void
|
||||
|
||||
func.return : ()
|
||||
}
|
||||
}
|
||||
63
doc/sample/ir/Simple.3.mie
Normal file
63
doc/sample/ir/Simple.3.mie
Normal file
@@ -0,0 +1,63 @@
|
||||
meta.source-filename "Simple.im"
|
||||
|
||||
ivy.package-scope "net.doorstuck.test"
|
||||
|
||||
ivy.package-ref "std.io"
|
||||
|
||||
ivy.module {
|
||||
%cout = ivy.pool.ident @cout -> #ivy.pool-slot
|
||||
%StringBuilder = ivy.pool.ident @std.lang.StringBuilder -> #ivy.pool-slot
|
||||
|
||||
%.str.0 = ivy.pool.string "Answer: " -> #ivy.pool-slot
|
||||
|
||||
%.sel.o-append = ivy.pool.selector append -> #ivy.pool-slot
|
||||
%.sel.o-to-string = ivy.pool.selector to-string -> #ivy.pool-slot
|
||||
%.sel.o-put = ivy.pool.selector put -> #ivy.pool-slot
|
||||
|
||||
ivy.init-text {
|
||||
%0 = i32.constant 32
|
||||
%1 = i32.constant 64
|
||||
%multmp = *ivy.MUL %0, %1 : (i32, i32) -> i32
|
||||
|
||||
*ivy.PUSH %multmp : i32
|
||||
%y = ivy.bp-slot 0 -> #ivy.bp-slot
|
||||
|
||||
%2 = i32.constant 64
|
||||
%3 = i32.constant 4
|
||||
%divtmp = *ivy.DIV %2, %3 : (i32, i32) -> i32
|
||||
|
||||
*ivy.PUSH %divtmp : i32
|
||||
%z = ivy.bp-slot 1 -> #ivy.bp-slot
|
||||
|
||||
%4 = *ivy.LDR-BP %y : #ivy.bp-slot -> i32
|
||||
%5 = *ivy.LDR-BP %z : #ivy.bp-slot -> i32
|
||||
%addtmp = *ivy.ADD %4, %5 : (i32, i32) -> i32
|
||||
|
||||
*ivy.PUSH %addtmp : i32
|
||||
%x = ivy.bp-slot 2 -> #ivy.bp-slot
|
||||
|
||||
%10 = *ivy.LDR-POOL %StringBuilder : #ivy.pool-slot -> #ivy.id
|
||||
|
||||
%20 = *ivy.LDR-POOL %.sel.o-append : #ivy.pool-slot -> #ivy.id
|
||||
%21 = *ivy.LDR-POOL %.str.0 : #ivy.pool-slot -> #ivy.id
|
||||
*ivy.PUSH %21 : #ivy.id
|
||||
*ivy.MSG-I %10, %20, 1 : (#ivy.id, #ivy.id, i32) -> void
|
||||
|
||||
%7 = *ivy.LDR-BP %x : ptr -> i32
|
||||
*ivy.PUSH %7 : i32
|
||||
%22 = *ivy.LDR-POOL %.sel.o-append : #ivy.pool-slot -> #ivy.id
|
||||
*ivy.MSG-I %10, %22, 1 : (#ivy.id, #ivy.id, i32) -> void
|
||||
|
||||
%23 = *ivy.LDR-POOL %.sel.o-to-string : #ivy.pool-slot -> #ivy.id
|
||||
%8 = *ivy.MSG-I %10, %23, 0 : (#ivy.id, #ivy.id, i32) -> #ivy.id
|
||||
|
||||
%9 = *ivy.LDR-POOL %cout : #ivy.pool-slot -> #ivy.id
|
||||
%24 = *ivy.LDR-POOL %.sel.o-put : #ivy.pool-slot -> #ivy.id
|
||||
|
||||
*ivy.PUSH %8 : #ivy.id
|
||||
|
||||
*ivy.MSG-I %9, %24, 1 : (#ivy.id, #ivy.id, i32) -> void
|
||||
|
||||
*ivy.RET-N : ()
|
||||
}
|
||||
}
|
||||
62
doc/sample/ir/Simple.4.mie
Normal file
62
doc/sample/ir/Simple.4.mie
Normal file
@@ -0,0 +1,62 @@
|
||||
meta.source-filename "Simple.im"
|
||||
|
||||
ivy.package-scope "net.doorstuck.test"
|
||||
|
||||
ivy.package-ref "std.io"
|
||||
|
||||
ivy.module {
|
||||
%cout = ivy.pool.ident @cout -> #ivy.pool-slot
|
||||
%StringBuilder = ivy.pool.ident @std.lang.StringBuilder -> #ivy.pool-slot
|
||||
|
||||
%.str.0 = ivy.pool.string "Answer: " -> #ivy.pool-slot
|
||||
|
||||
%.sel.o-append = ivy.pool.selector append -> #ivy.pool-slot
|
||||
%.sel.o-to-string = ivy.pool.selector to-string -> #ivy.pool-slot
|
||||
%.sel.o-put = ivy.pool.selector put -> #ivy.pool-slot
|
||||
|
||||
ivy.init-text {
|
||||
%0 = i32.constant 32
|
||||
%1 = i32.constant 64
|
||||
%multmp = *ivy.MUL %0, %1 : (i32, i32) -> i32
|
||||
|
||||
*ivy.PUSH %multmp : i32
|
||||
%y = ivy.bp-slot 0 -> #ivy.bp-slot
|
||||
|
||||
%2 = i32.constant 64
|
||||
%3 = i32.constant 4
|
||||
%divtmp = *ivy.DIV %2, %3 : (i32, i32) -> i32
|
||||
|
||||
*ivy.PUSH %divtmp : i32
|
||||
%z = ivy.bp-slot 1 -> #ivy.bp-slot
|
||||
|
||||
%4 = *ivy.LDR %y : #ivy.bp-slot -> i32
|
||||
%5 = *ivy.LDR %z : #ivy.bp-slot -> i32
|
||||
%addtmp = *ivy.ADD %4, %5 : (i32, i32) -> i32
|
||||
|
||||
*ivy.PUSH %addtmp : i32
|
||||
%x = ivy.bp-slot 2 -> #ivy.bp-slot
|
||||
|
||||
%10 = *ivy.LDR %StringBuilder : #ivy.pool-slot -> #ivy.id
|
||||
|
||||
%20 = *ivy.LDR %.sel.o-append : #ivy.pool-slot -> #ivy.id
|
||||
%21 = *ivy.LDR %.str.0 : #ivy.pool-slot -> #ivy.id
|
||||
*ivy.PUSH %21 : #ivy.id
|
||||
*ivy.MSG %10, %20, 1 : (#ivy.id, #ivy.id, i32) -> void
|
||||
|
||||
%7 = *ivy.LDR %x : ptr -> i32
|
||||
*ivy.PUSH %7 : i32
|
||||
*ivy.MSG %10, %20, 1 : (#ivy.id, #ivy.id, i32) -> void
|
||||
|
||||
%23 = *ivy.LDR %.sel.o-to-string : #ivy.pool-slot -> #ivy.id
|
||||
%8 = *ivy.MSG %10, %23, 0 : (#ivy.id, #ivy.id, i32) -> #ivy.id
|
||||
|
||||
%9 = *ivy.LDR %cout : #ivy.pool-slot -> #ivy.id
|
||||
%24 = *ivy.LDR %.sel.o-put : #ivy.pool-slot -> #ivy.id
|
||||
|
||||
*ivy.PUSH %8 : #ivy.id
|
||||
|
||||
*ivy.MSG %9, %24, 1 : (#ivy.id, #ivy.id, i32) -> void
|
||||
|
||||
*ivy.RET-N : ()
|
||||
}
|
||||
}
|
||||
68
doc/sample/ir/Simple.5.mie
Normal file
68
doc/sample/ir/Simple.5.mie
Normal file
@@ -0,0 +1,68 @@
|
||||
meta.source-filename "Simple.im"
|
||||
|
||||
ivy.package-scope "net.doorstuck.test"
|
||||
|
||||
ivy.package-ref "std.io"
|
||||
|
||||
ivy.module {
|
||||
%cout = ivy.pool.ident @cout -> #ivy.pool-slot
|
||||
%StringBuilder = ivy.pool.ident @std.lang.StringBuilder -> #ivy.pool-slot
|
||||
|
||||
%.str.0 = ivy.pool.string "Answer: " -> #ivy.pool-slot
|
||||
|
||||
%.sel.o-append = ivy.pool.selector append -> #ivy.pool-slot
|
||||
%.sel.o-to-string = ivy.pool.selector to-string -> #ivy.pool-slot
|
||||
%.sel.o-put = ivy.pool.selector put -> #ivy.pool-slot
|
||||
|
||||
%.i.0 = i32.constant 0
|
||||
%.i.1 = i32.constant 1
|
||||
%.i.4 = i32.constant 4
|
||||
%.i.32 = i32.constant 32
|
||||
%.i.64 = i32.constant 64
|
||||
|
||||
ivy.init-text {
|
||||
$X0 = *ivy.LDR %.i.32 -> i32
|
||||
$X1 = *ivy.LDR %.i.64 -> i32
|
||||
$X2 = *ivy.MUL $X0, $X1 : (i32, i32) -> i32
|
||||
|
||||
*ivy.PUSH $X2 : i32
|
||||
%.bp.0 = ivy.bp-slot 0 -> #ivy.bp-slot
|
||||
|
||||
$X4 = *ivy.LDR %.i.64 -> i32
|
||||
$X5 = *ivy.LDR %.i.4 -> i32
|
||||
$X6 = *ivy.DIV $X4, $X5 : (i32, i32) -> i32
|
||||
|
||||
*ivy.PUSH $X6 : i32
|
||||
%.bp.1 = ivy.bp-slot 1 -> #ivy.bp-slot
|
||||
|
||||
$X8 = *ivy.LDR %.bp.0 : #ivy.bp-slot -> i32
|
||||
$X9 = *ivy.LDR %.bp.1 : #ivy.bp-slot -> i32
|
||||
$X10 = *ivy.ADD $X8, $X9 : (i32, i32) -> i32
|
||||
|
||||
*ivy.PUSH $X10 : i32
|
||||
%.bp.2 = ivy.bp-slot 2 -> #ivy.bp-slot
|
||||
|
||||
%10 = *ivy.LDR %StringBuilder : #ivy.pool-slot -> #ivy.id
|
||||
|
||||
%20 = *ivy.LDR %.sel.o-append : #ivy.pool-slot -> #ivy.id
|
||||
%21 = *ivy.LDR %.str.0 : #ivy.pool-slot -> #ivy.id
|
||||
*ivy.PUSH %21 : #ivy.id
|
||||
*ivy.MSG %10, %20, %.i.1 : (#ivy.id, #ivy.id, i32) -> void
|
||||
|
||||
%7 = *ivy.LDR %.bp.2 : ptr -> i32
|
||||
*ivy.PUSH %7 : i32
|
||||
*ivy.MSG %10, %20, %.i.1 : (#ivy.id, #ivy.id, i32) -> void
|
||||
|
||||
%23 = *ivy.LDR %.sel.o-to-string : #ivy.pool-slot -> #ivy.id
|
||||
%8 = *ivy.MSG %10, %23, %.i.0 : (#ivy.id, #ivy.id, i32) -> #ivy.id
|
||||
|
||||
%9 = *ivy.LDR %cout : #ivy.pool-slot -> #ivy.id
|
||||
%24 = *ivy.LDR %.sel.o-put : #ivy.pool-slot -> #ivy.id
|
||||
|
||||
*ivy.PUSH %8 : #ivy.id
|
||||
|
||||
*ivy.MSG %9, %24, %.i.1 : (#ivy.id, #ivy.id, i32) -> void
|
||||
|
||||
*ivy.RET-N : ()
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
; Comment
|
||||
func.func @reduce(%buffer: memref<1024*f32>, %lb: index, %ub: index, %step: index) -> f32 {
|
||||
; Initial sum set to 0.
|
||||
%sum.0 = arith.constant 0.0 : f32
|
||||
%sum.0 = f32.constant 0.0
|
||||
; iter_args binds initial values to the loop's region arguments.
|
||||
%sum = scf.for %iv = %lb to %ub step %step iter-args(%sum.iter = %sum.0) -> (f32) {
|
||||
%t = memref.load %buffer[%iv] : memref<1024*f32>
|
||||
@@ -1,6 +1,6 @@
|
||||
func.func @reduce(%buffer: memref<1024*f32>, %lb: index, %ub: index, %step: index) -> f32 {
|
||||
; Initial sum set to 0.
|
||||
%sum.0 = *arith.constant() {value = 0.0 : f32} : () -> f32
|
||||
%sum.0 = *f32.constant() {value = 0.0 : f32} : () -> f32
|
||||
|
||||
; iter_args binds initial values to the loop's region arguments.
|
||||
%sum = scf.for %iv = %lb to %ub step %step iter_args(%sum.iter = %sum.0) -> (f32) {
|
||||
20
doc/sample/ir/for-loop-3.mie
Normal file
20
doc/sample/ir/for-loop-3.mie
Normal 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
|
||||
|
||||
25
doc/sample/ir/for-loop-4.mie
Normal file
25
doc/sample/ir/for-loop-4.mie
Normal 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
|
||||
|
||||
14
doc/sample/ir/lex-test.mie
Normal file
14
doc/sample/ir/lex-test.mie
Normal 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
|
||||
6
doc/sample/ir/parse-test.mie
Normal file
6
doc/sample/ir/parse-test.mie
Normal 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)
|
||||
@@ -5,41 +5,51 @@ endif
|
||||
let s:save_cpo = &cpoptions
|
||||
set cpoptions&vim
|
||||
setlocal iskeyword+=-
|
||||
setlocal shiftwidth=4
|
||||
setlocal tabstop=4
|
||||
|
||||
syn keyword mieUnspecifiedKeyword to step iter-args
|
||||
syn keyword mieUnspecifiedKeyword
|
||||
\ to step iter-args get set
|
||||
\ case then default
|
||||
syn keyword mieInstructionFlag
|
||||
\ eq gt ge lt le
|
||||
syn match mieRegister "%[0-9]\>"
|
||||
syn match mieRegister "%[1-9][0-9]\+\>"
|
||||
syn match mieRegister "%[A-Za-z_\-\.][A-Za-z0-9_\-\.]*\>"
|
||||
syn match mieMachineRegister "$[0-9]\>"
|
||||
syn match mieMachineRegister "$[1-9][0-9]\+\>"
|
||||
syn match mieMachineRegister "$[A-Za-z_\-\.][A-Za-z0-9_\-\.]*\>"
|
||||
syn match mieIdentifier /@\(\w\+\)\(\.\(\w\+\)\)*\>/
|
||||
syn match mieIdentifier /@\.\(\w\+\)\(\.\(\w\+\)\)*\>/
|
||||
syn match mieBlockIdentifier /\^\(\w\+\)\(\.\(\w\+\)\)*/
|
||||
syn match mieBlockLabel /\^\(\w\+\)\(\.\(\w\+\)\)*\:/
|
||||
syn keyword mieBuiltinType void index
|
||||
syn keyword mieBuiltinType f16 f32 f64 f80 f128
|
||||
syn keyword mieBuiltinType void
|
||||
" Use syn match for type names that are ALSO dialect names, to ensure that
|
||||
" dialect operations are still matched as such.
|
||||
syn match mieBuiltinType /\<memref\>/
|
||||
syn match mieBuiltinType "i[0-9]\>"
|
||||
syn match mieBuiltinType "i[1-9][0-9]\+\>"
|
||||
syn match mieBuiltinType /\<ptr\>/
|
||||
syn match mieBuiltinType /\<index\>/
|
||||
syn match mieBuiltinType "\<[if][0-9]\>"
|
||||
syn match mieBuiltinType "\<[if][1-9][0-9]\+\>"
|
||||
syn match mieDialectType /#[A-Za-z][A-Za-z0-9\-]*\(\.[A-Za-z][A-Za-z0-9\-]*\)\+/
|
||||
|
||||
syn match mieInstruction /\*[A-Za-z][A-Za-z0-9\-]*\(\.[A-Za-z][A-Za-z0-9\-]*\)\+\([>\*]\)\@!\>/
|
||||
syn match mieGenericOperation /\~[A-Za-z][A-Za-z0-9\-]*\(\.[A-Za-z][A-Za-z0-9\-]*\)\+\([>\*]\)\@!\>/
|
||||
syn match mieGraphOperation /+[A-Za-z][A-Za-z0-9\-]*\(\.[A-Za-z][A-Za-z0-9\-]*\)\+\([>\*]\)\@!\>/
|
||||
syn match mieCustomOperation /\<[A-Za-z][A-Za-z0-9\-]*\(\.[A-Za-z][A-Za-z0-9\-]*\)\+\>/
|
||||
syn match mieGenericOperation /\*[A-Za-z][A-Za-z0-9\-]*\(\.[A-Za-z][A-Za-z0-9\-]*\)\+\([>\*]\)\@!\>/
|
||||
|
||||
syn match mieAttributeName /\<[A-Za-z][A-Za-z0-9\-_\.]*\(\s*=\)\@=\>/
|
||||
|
||||
syn region mieString start=+"+ end=+"\%(u8\)\=+ end=+$+ extend
|
||||
|
||||
syn match mieFloat /[0-9]\+\.[0-9]\+/
|
||||
syn match mieFloat /-[0-9]\+\.[0-9]\+/
|
||||
syn match mieFloat /+[0-9]\+\.[0-9]\+/
|
||||
syn match mieFloat /\<[0-9]\+\.[0-9]\+/
|
||||
syn match mieFloat /\<-[0-9]\+\.[0-9]\+/
|
||||
syn match mieFloat /\<+[0-9]\+\.[0-9]\+/
|
||||
|
||||
syn match mieInteger /[0-9]\+\(\.\)\@!\>/
|
||||
syn match mieInteger /-[0-9]\+\(\.\)\@!\>/
|
||||
syn match mieInteger /0x[:xdigit:]\+\>/
|
||||
syn match mieInteger /-0x[:xdigit:]\+\>/
|
||||
syn match mieInteger /\<[0-9]\+\(\.\)\@!\>/
|
||||
syn match mieInteger /\<-[0-9]\+\(\.\)\@!\>/
|
||||
syn match mieInteger /\<0x[:xdigit:]\+\>/
|
||||
syn match mieInteger /\<-0x[:xdigit:]\+\>/
|
||||
|
||||
syn match mieIntegerDimension /[0-9]\+x/
|
||||
syn match mieIntegerDimension /0x[:xdigit:]\+x/
|
||||
@@ -55,12 +65,9 @@ syn match mieBraces "[{}]" display
|
||||
syn match mieAngleBrackets "[<>]" display
|
||||
syn match mieOperator "[=:]" display
|
||||
syn match mieOperator "->" display
|
||||
syn match ivyPropertySymbol "\$" display
|
||||
|
||||
" The default highlighting.
|
||||
hi def link mieUnspecifiedKeyword Keyword
|
||||
hi def link ivyPropertySymbol Statement
|
||||
|
||||
hi def link mieInteger Number
|
||||
hi def link mieFloat Number
|
||||
|
||||
@@ -72,12 +79,15 @@ hi def link mieAngleBrackets StorageClass
|
||||
hi def link mieDialectType Type
|
||||
|
||||
hi def link mieGenericOperation @function.builtin
|
||||
hi def link mieGraphOperation Statement
|
||||
hi def link mieCustomOperation Function
|
||||
hi def link mieInstruction @attribute
|
||||
hi def link mieInstructionFlag StorageClass
|
||||
hi def link mieIdentifier Identifier
|
||||
hi def link mieBlockIdentifier Label
|
||||
hi def link mieBlockLabel Label
|
||||
hi def link mieRegister @variable
|
||||
hi def link mieRegister @variable.parameter
|
||||
hi def link mieMachineRegister @variable.builtin
|
||||
|
||||
hi def link mieString String
|
||||
hi def link mieBuiltinType @type.builtin
|
||||
|
||||
@@ -11,5 +11,5 @@ else ()
|
||||
endif ()
|
||||
|
||||
target_include_directories(mie PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include/)
|
||||
target_link_libraries(mie Bluelib::Core Bluelib::Ds)
|
||||
target_link_libraries(mie Bluelib::Core Bluelib::Ds Bluelib::Io)
|
||||
target_compile_definitions(mie PRIVATE MIE_EXPORT=1 MIE_STATIC=${MIE_STATIC})
|
||||
|
||||
454
mie/ctx.c
454
mie/ctx.c
@@ -1,34 +1,29 @@
|
||||
#include <blue/core/bstr.h>
|
||||
#include <blue/ds/hashmap.h>
|
||||
#include <blue/ds/list.h>
|
||||
#include <blue/ds/string.h>
|
||||
#include <mie/ctx.h>
|
||||
#include <mie/ir/const.h>
|
||||
#include <mie/dialect/arith.h>
|
||||
#include <mie/dialect/builtin.h>
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/dialect/index.h>
|
||||
#include <mie/ir/op.h>
|
||||
#include <mie/trait/trait-definition.h>
|
||||
#include <mie/trait/trait.h>
|
||||
#include <mie/type/function.h>
|
||||
#include <mie/type/storage.h>
|
||||
#include <mie/type/type-definition.h>
|
||||
#include <mie/type/type.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
struct ctx_int_cache_entry {
|
||||
b_btree_node i_node;
|
||||
struct mie_type i_type;
|
||||
b_btree i_values;
|
||||
};
|
||||
#define DIALECT_NS_ID \
|
||||
MIE_ID(0xa1, 0x35, 0x01, 0x1b, 0xe4, 0x71, 0x46, 0x08, 0x92, 0xd4, \
|
||||
0xe6, 0x5a, 0x40, 0xba, 0x7f, 0xee)
|
||||
|
||||
struct ctx_int_value_cache_entry {
|
||||
b_btree_node i_node;
|
||||
struct mie_int i_value;
|
||||
};
|
||||
|
||||
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)
|
||||
#define TYPE_NS_ID \
|
||||
MIE_ID(0xf5, 0x4e, 0xc5, 0x8c, 0xc0, 0x1e, 0x48, 0x47, 0xb5, 0xf4, \
|
||||
0x7b, 0xb9, 0x6b, 0x47, 0xca, 0x48)
|
||||
|
||||
struct mie_ctx *mie_ctx_create(void)
|
||||
{
|
||||
@@ -40,244 +35,289 @@ struct mie_ctx *mie_ctx_create(void)
|
||||
|
||||
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));
|
||||
mie_id dialects_ns = DIALECT_NS_ID;
|
||||
mie_id_map_init(&out->ctx_dialects, &dialects_ns);
|
||||
|
||||
out->ctx_null = malloc(sizeof *out->ctx_null);
|
||||
if (!out->ctx_null) {
|
||||
mie_ctx_destroy(out);
|
||||
return NULL;
|
||||
}
|
||||
mie_id types_ns = TYPE_NS_ID;
|
||||
mie_id_map_init(&out->ctx_types, &types_ns);
|
||||
|
||||
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);
|
||||
out->ctx_ints = mie_int_cache_create();
|
||||
out->ctx_floats = mie_float_cache_create();
|
||||
out->ctx_indices = mie_index_cache_create();
|
||||
out->ctx_strings = mie_string_cache_create();
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void mie_ctx_destroy(struct mie_ctx *ctx)
|
||||
bool mie_ctx_resolve_op(const struct mie_ctx *ctx, struct mie_op *op)
|
||||
{
|
||||
ctx->ctx_true = NULL;
|
||||
ctx->ctx_false = NULL;
|
||||
bool fully_resolved = MIE_TEST_FLAGS(
|
||||
op->op_flags, MIE_OP_F_OP_RESOLVED | MIE_OP_F_ARG_RESOLVED);
|
||||
|
||||
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;
|
||||
if (fully_resolved) {
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
const char *dialect_name = NULL, *op_name = NULL;
|
||||
|
||||
char *dot = strchr(op->op_name, '.');
|
||||
if (dot) {
|
||||
*dot = 0;
|
||||
dialect_name = op->op_name;
|
||||
op_name = dot + 1;
|
||||
} else {
|
||||
dialect_name = NULL;
|
||||
op_name = op->op_name;
|
||||
}
|
||||
|
||||
if (ctx->ctx_null) {
|
||||
mie_value_destroy(ctx->ctx_null);
|
||||
const struct mie_dialect *dialect = mie_ctx_get_dialect(ctx, dialect_name);
|
||||
if (dot) {
|
||||
*dot = '.';
|
||||
}
|
||||
|
||||
b_hashmap_unref(ctx->ctx_sel_cache);
|
||||
/* dialect_name is no longer valid after this point */
|
||||
dialect_name = NULL;
|
||||
|
||||
free(ctx);
|
||||
if (!dialect) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const struct mie_op_definition *op_info
|
||||
= mie_dialect_get_op(dialect, op_name);
|
||||
if (!op) {
|
||||
return false;
|
||||
}
|
||||
|
||||
op->op_dialect = dialect;
|
||||
op->op_info = op_info;
|
||||
|
||||
free(op->op_name);
|
||||
op->op_name = NULL;
|
||||
|
||||
op->op_flags |= MIE_OP_F_OP_RESOLVED;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct mie_type *mie_ctx_get_type(struct mie_ctx *ctx, enum mie_type_id type_id)
|
||||
struct mie_dialect *mie_ctx_get_dialect(const struct mie_ctx *ctx, const char *name)
|
||||
{
|
||||
if (type_id == MIE_TYPE_INT) {
|
||||
b_rope name_rope = B_ROPE_CSTR(name);
|
||||
mie_id id;
|
||||
mie_id_init_ns(&id, mie_id_map_get_ns(&ctx->ctx_dialects), &name_rope);
|
||||
|
||||
mie_id *target = mie_id_map_get(&ctx->ctx_dialects, &id);
|
||||
return b_unbox(struct mie_dialect, target, d_id);
|
||||
}
|
||||
|
||||
struct mie_type_definition *mie_ctx_get_type_definition(
|
||||
const struct mie_ctx *ctx, const char *dialect_name, const char *type_name)
|
||||
{
|
||||
b_rope dialect_name_rope = B_ROPE_CSTR(dialect_name);
|
||||
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;
|
||||
}
|
||||
|
||||
if (ctx->ctx_types[type_id]) {
|
||||
return ctx->ctx_types[type_id];
|
||||
b_rope type_name_rope = B_ROPE_CSTR(type_name);
|
||||
mie_id_init_ns(&id, mie_id_map_get_ns(&dialect->d_types), &type_name_rope);
|
||||
target = mie_id_map_get(&dialect->d_types, &id);
|
||||
|
||||
return b_unbox(struct mie_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;
|
||||
}
|
||||
|
||||
struct mie_type *type = mie_type_create();
|
||||
b_rope trait_name_rope = B_ROPE_CSTR(trait_name);
|
||||
mie_id_init_ns(&id, mie_id_map_get_ns(&dialect->d_traits), &trait_name_rope);
|
||||
target = mie_id_map_get(&dialect->d_traits, &id);
|
||||
|
||||
return b_unbox(struct mie_trait_definition, target, tr_id);
|
||||
}
|
||||
|
||||
struct mie_type *mie_ctx_get_type(
|
||||
struct mie_ctx *ctx, const char *dialect_name, const char *type_name)
|
||||
{
|
||||
char full_name[256];
|
||||
snprintf(full_name, sizeof full_name, "%s.%s", dialect_name, type_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_types), &full_name_rope);
|
||||
|
||||
mie_id *target = mie_id_map_get(&ctx->ctx_types, &id);
|
||||
struct mie_type *type = b_unbox(struct mie_type, target, ty_id);
|
||||
if (type) {
|
||||
return type;
|
||||
}
|
||||
|
||||
struct mie_type_definition *type_info
|
||||
= mie_ctx_get_type_definition(ctx, dialect_name, type_name);
|
||||
if (!type_info /* || (type_info->ty_flags & MIE_DIALECT_TYPE_PARAMETISED) */) {
|
||||
/* cannot initialise unknown or parametised types */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (type_info->ty_data_size < sizeof(struct mie_type)) {
|
||||
/* invalid type info */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
type = malloc(type_info->ty_data_size);
|
||||
if (!type) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
type->t_id = type_id;
|
||||
memset(type, 0x0, sizeof *type);
|
||||
|
||||
type->ty_def = type_info;
|
||||
type->ty_name = b_bstr_fmt("%s.%s", dialect_name, type_name);
|
||||
|
||||
if (type_info->ty_init) {
|
||||
type_info->ty_init(type_info, type);
|
||||
}
|
||||
|
||||
mie_id_map_put(&ctx->ctx_types, &type->ty_id, &full_name_rope);
|
||||
|
||||
ctx->ctx_types[type_id] = type;
|
||||
return type;
|
||||
}
|
||||
|
||||
struct mie_value *mie_ctx_get_null(struct mie_ctx *ctx)
|
||||
const struct mie_trait *mie_ctx_get_trait(
|
||||
struct mie_ctx *ctx, const char *dialect_name, const char *trait_name)
|
||||
{
|
||||
return ctx->ctx_null;
|
||||
}
|
||||
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);
|
||||
|
||||
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);
|
||||
mie_id id;
|
||||
mie_id_init_ns(&id, mie_id_map_get_ns(&ctx->ctx_traits), &full_name_rope);
|
||||
|
||||
if (entry) {
|
||||
return &entry->i_type;
|
||||
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;
|
||||
}
|
||||
|
||||
entry = malloc(sizeof *entry);
|
||||
if (!entry) {
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
if (trait_info->tr_data_size < sizeof(struct mie_trait)) {
|
||||
/* invalid trait info */
|
||||
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) {
|
||||
trait = malloc(trait_info->tr_data_size);
|
||||
if (!trait) {
|
||||
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);
|
||||
memset(trait, 0x0, sizeof *trait);
|
||||
|
||||
key.key_data = sel_value->sel_value;
|
||||
trait->tr_def = trait_info;
|
||||
trait->tr_name = b_bstr_fmt("%s.%s", dialect_name, trait_name);
|
||||
|
||||
b_hashmap_value hashmap_value = {
|
||||
.value_data = sel_value,
|
||||
.value_size = sizeof *sel_value,
|
||||
};
|
||||
if (trait_info->tr_init) {
|
||||
trait_info->tr_init(trait_info, trait);
|
||||
}
|
||||
|
||||
b_hashmap_put(ctx->ctx_sel_cache, &key, &hashmap_value);
|
||||
mie_id_map_put(&ctx->ctx_traits, &trait->tr_id, &full_name_rope);
|
||||
|
||||
return MIE_VALUE(sel_value);
|
||||
return trait;
|
||||
}
|
||||
|
||||
struct mie_type *mie_ctx_get_storage_type(
|
||||
struct mie_ctx *ctx, const struct mie_type **parts, size_t nr_parts)
|
||||
{
|
||||
struct mie_id_builder id_builder;
|
||||
mie_id_builder_begin(&id_builder, &ctx->ctx_types.map_ns_id);
|
||||
mie_storage_type_build_id(&id_builder, parts, nr_parts);
|
||||
mie_id id;
|
||||
mie_id_builder_end(&id_builder, &id);
|
||||
|
||||
mie_id *target = mie_id_map_get(&ctx->ctx_types, &id);
|
||||
struct mie_type *type = b_unbox(struct mie_type, target, ty_id);
|
||||
if (type) {
|
||||
return type;
|
||||
}
|
||||
|
||||
struct mie_storage_type *new_type = mie_storage_type_create();
|
||||
for (size_t i = 0; i < nr_parts; i++) {
|
||||
mie_storage_type_add_part(new_type, parts[i]);
|
||||
}
|
||||
|
||||
new_type->st_base.ty_id = id;
|
||||
mie_id_map_put_id(&ctx->ctx_types, &new_type->st_base.ty_id);
|
||||
return (struct mie_type *)new_type;
|
||||
}
|
||||
|
||||
struct mie_type *mie_ctx_get_function_type(
|
||||
struct mie_ctx *ctx, const struct mie_type **in, size_t nr_in,
|
||||
const struct mie_type **out, size_t nr_out)
|
||||
{
|
||||
struct mie_id_builder id_builder;
|
||||
mie_id_builder_begin(&id_builder, &ctx->ctx_types.map_ns_id);
|
||||
mie_function_type_build_id(&id_builder, in, nr_in, out, nr_out);
|
||||
mie_id id;
|
||||
mie_id_builder_end(&id_builder, &id);
|
||||
|
||||
mie_id *target = mie_id_map_get(&ctx->ctx_types, &id);
|
||||
struct mie_type *type = b_unbox(struct mie_type, target, ty_id);
|
||||
if (type) {
|
||||
return type;
|
||||
}
|
||||
|
||||
struct mie_function_type *new_type = mie_function_type_create();
|
||||
for (size_t i = 0; i < nr_in; i++) {
|
||||
mie_function_type_add_in_part(new_type, in[i]);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < nr_out; i++) {
|
||||
mie_function_type_add_out_part(new_type, out[i]);
|
||||
}
|
||||
|
||||
new_type->func_base.ty_id = id;
|
||||
mie_id_map_put_id(&ctx->ctx_types, &new_type->func_base.ty_id);
|
||||
return (struct mie_type *)new_type;
|
||||
}
|
||||
|
||||
struct mie_value *mie_ctx_get_int(struct mie_ctx *ctx, long long val, size_t nr_bits)
|
||||
{
|
||||
return (struct mie_value *)mie_int_cache_get(
|
||||
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)
|
||||
{
|
||||
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);
|
||||
return (struct mie_value *)mie_string_cache_get(ctx->ctx_strings, ctx, s);
|
||||
}
|
||||
|
||||
struct mie_value *mie_ctx_create_array(struct mie_ctx *ctx)
|
||||
struct mie_value *mie_ctx_get_index(struct mie_ctx *ctx, size_t val)
|
||||
{
|
||||
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);
|
||||
return (struct mie_value *)mie_index_cache_get(ctx->ctx_indices, ctx, val);
|
||||
}
|
||||
|
||||
18
mie/dialect/arith/addf.c
Normal file
18
mie/dialect/arith/addf.c
Normal file
@@ -0,0 +1,18 @@
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/ir/op-definition.h>
|
||||
#include <mie/macros.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_arith_addf, "addf")
|
||||
MIE_OP_DEFINITION_PRINT(print);
|
||||
MIE_OP_DEFINITION_PARSE(parse);
|
||||
MIE_OP_DEFINITION_END()
|
||||
18
mie/dialect/arith/addi.c
Normal file
18
mie/dialect/arith/addi.c
Normal file
@@ -0,0 +1,18 @@
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/ir/op-definition.h>
|
||||
#include <mie/macros.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_arith_addi, "addi")
|
||||
MIE_OP_DEFINITION_PRINT(print);
|
||||
MIE_OP_DEFINITION_PARSE(parse);
|
||||
MIE_OP_DEFINITION_END()
|
||||
9
mie/dialect/arith/arith.c
Normal file
9
mie/dialect/arith/arith.c
Normal file
@@ -0,0 +1,9 @@
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/macros.h>
|
||||
|
||||
MIE_DIALECT_BEGIN(mie_arith, "arith")
|
||||
MIE_DIALECT_ADD_TYPE(mie_arith_int);
|
||||
MIE_DIALECT_ADD_TYPE(mie_arith_float);
|
||||
MIE_DIALECT_ADD_OP(mie_arith_addi);
|
||||
MIE_DIALECT_ADD_OP(mie_arith_addf);
|
||||
MIE_DIALECT_END()
|
||||
215
mie/dialect/arith/float-cache.c
Normal file
215
mie/dialect/arith/float-cache.c
Normal 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;
|
||||
}
|
||||
106
mie/dialect/arith/float.c
Normal file
106
mie/dialect/arith/float.c
Normal file
@@ -0,0 +1,106 @@
|
||||
#include <blue/core/bstr.h>
|
||||
#include <mie/ctx.h>
|
||||
#include <mie/dialect/arith.h>
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/macros.h>
|
||||
#include <mie/type/type-definition.h>
|
||||
#include <mie/type/type.h>
|
||||
#include <mie/value.h>
|
||||
|
||||
struct float_type {
|
||||
struct mie_type f_base;
|
||||
size_t f_width;
|
||||
};
|
||||
|
||||
static enum mie_status value_print(
|
||||
const struct mie_type *ty, const struct mie_value *value, b_stream *out)
|
||||
{
|
||||
struct float_type *float_ty = (struct float_type *)ty;
|
||||
struct mie_float *float_val = (struct mie_float *)value;
|
||||
switch (float_ty->f_width) {
|
||||
case MIE_FLOAT_32:
|
||||
b_stream_write_fmt(
|
||||
out, NULL, "%f : f%zu", float_val->f_val.v_32,
|
||||
float_ty->f_width);
|
||||
break;
|
||||
case MIE_FLOAT_64:
|
||||
b_stream_write_fmt(
|
||||
out, NULL, "%lf : f%zu", float_val->f_val.v_64,
|
||||
float_ty->f_width);
|
||||
break;
|
||||
default:
|
||||
b_stream_write_fmt(out, NULL, "NaN : f%zu", float_ty->f_width);
|
||||
break;
|
||||
}
|
||||
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
struct mie_type *mie_arith_float_get_type(struct mie_ctx *ctx, size_t bit_width)
|
||||
{
|
||||
struct mie_type_definition *type_info
|
||||
= mie_ctx_get_type_definition(ctx, "arith", "float");
|
||||
if (!type_info) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
b_rope rope_i = B_ROPE_CHAR('f'), rope_width = B_ROPE_UINT(bit_width);
|
||||
b_rope type_name;
|
||||
b_rope_concat(&type_name, &rope_i, &rope_width);
|
||||
|
||||
mie_id id;
|
||||
mie_id_init_ns(&id, mie_id_map_get_ns(&ctx->ctx_types), &type_name);
|
||||
|
||||
mie_id *target = mie_id_map_get(&ctx->ctx_types, &id);
|
||||
if (target) {
|
||||
return b_unbox(struct mie_type, target, ty_id);
|
||||
}
|
||||
|
||||
struct float_type *type = (struct float_type *)mie_type_create(type_info);
|
||||
if (!type) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
type->f_base.ty_name = b_bstr_fmt("arith.float<%zu>", bit_width);
|
||||
type->f_base.ty_instance_size = sizeof(struct mie_float);
|
||||
type->f_width = bit_width;
|
||||
|
||||
mie_id_map_put(&ctx->ctx_types, &type->f_base.ty_id, &type_name);
|
||||
return (struct mie_type *)type;
|
||||
}
|
||||
|
||||
size_t mie_arith_float_type_get_width(const struct mie_type *type)
|
||||
{
|
||||
if (strcmp(type->ty_def->ty_parent->d_name, "arith") != 0) {
|
||||
return (size_t)-1;
|
||||
}
|
||||
|
||||
if (strcmp(type->ty_def->ty_name, "float") != 0) {
|
||||
return (size_t)-1;
|
||||
}
|
||||
|
||||
const struct float_type *float_type = (const struct float_type *)type;
|
||||
return float_type->f_width;
|
||||
}
|
||||
|
||||
static enum mie_status print(
|
||||
const struct mie_type_definition *def, const struct mie_type *ty,
|
||||
b_stream *out)
|
||||
{
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
static enum mie_status parse(
|
||||
const struct mie_type_definition *def, struct mie_parser *parser,
|
||||
struct mie_type **out)
|
||||
{
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
MIE_TYPE_DEFINITION_BEGIN(mie_arith_float, "float")
|
||||
// MIE_TYPE_DEFINITION_FLAGS(MIE_TYPE_DEFINITION_PARAMETISED);
|
||||
MIE_TYPE_DEFINITION_STRUCT(struct float_type);
|
||||
MIE_TYPE_DEFINITION_PRINT(print);
|
||||
MIE_TYPE_DEFINITION_PARSE(parse);
|
||||
MIE_TYPE_DEFINITION_VALUE_PRINT(value_print);
|
||||
MIE_TYPE_DEFINITION_END()
|
||||
139
mie/dialect/arith/int-cache.c
Normal file
139
mie/dialect/arith/int-cache.c
Normal file
@@ -0,0 +1,139 @@
|
||||
#include <blue/core/btree.h>
|
||||
#include <mie/dialect/arith.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
struct int_width_cache_entry {
|
||||
b_btree_node e_node;
|
||||
struct mie_int e_value;
|
||||
};
|
||||
|
||||
struct int_width_cache {
|
||||
b_btree_node c_node;
|
||||
size_t c_width;
|
||||
b_btree c_ints;
|
||||
};
|
||||
|
||||
struct mie_int_cache {
|
||||
b_btree c_widths;
|
||||
};
|
||||
|
||||
static B_BTREE_DEFINE_SIMPLE_INSERT(
|
||||
struct int_width_cache, c_node, c_width, put_width_cache);
|
||||
static B_BTREE_DEFINE_SIMPLE_GET(
|
||||
struct int_width_cache, size_t, c_node, c_width, get_width_cache);
|
||||
|
||||
static B_BTREE_DEFINE_SIMPLE_INSERT(
|
||||
struct int_width_cache_entry, e_node, e_value.i_val.v_small, put_int);
|
||||
static B_BTREE_DEFINE_SIMPLE_GET(
|
||||
struct int_width_cache_entry, uint64_t, e_node, e_value.i_val.v_small,
|
||||
get_int);
|
||||
|
||||
static struct int_width_cache *int_width_cache_create(size_t width)
|
||||
{
|
||||
struct int_width_cache *out = malloc(sizeof *out);
|
||||
if (!out) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(out, 0x0, sizeof *out);
|
||||
|
||||
out->c_width = width;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
static void int_width_cache_destroy(struct int_width_cache *cache)
|
||||
{
|
||||
b_btree_node *cur = b_btree_first(&cache->c_ints);
|
||||
while (cur) {
|
||||
b_btree_node *next = b_btree_next(cur);
|
||||
b_btree_delete(&cache->c_ints, cur);
|
||||
|
||||
struct int_width_cache_entry *entry
|
||||
= b_unbox(struct int_width_cache_entry, cur, e_node);
|
||||
free(entry);
|
||||
|
||||
cur = next;
|
||||
}
|
||||
|
||||
free(cache);
|
||||
}
|
||||
|
||||
static struct int_width_cache_entry *int_width_cache_entry_create(
|
||||
struct mie_ctx *ctx, size_t width, size_t value)
|
||||
{
|
||||
struct int_width_cache_entry *out = malloc(sizeof *out);
|
||||
if (!out) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(out, 0x0, sizeof *out);
|
||||
|
||||
out->e_value.i_val.v_small = value;
|
||||
out->e_value.i_base.v_type = mie_arith_int_get_type(ctx, width);
|
||||
if (!out->e_value.i_base.v_type) {
|
||||
free(out);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
struct mie_int_cache *mie_int_cache_create(void)
|
||||
{
|
||||
struct mie_int_cache *out = malloc(sizeof *out);
|
||||
if (!out) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(out, 0x0, sizeof *out);
|
||||
return out;
|
||||
}
|
||||
|
||||
void mie_int_cache_destroy(struct mie_int_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 int_width_cache *width_cache
|
||||
= b_unbox(struct int_width_cache, cur, c_node);
|
||||
int_width_cache_destroy(width_cache);
|
||||
|
||||
cur = next;
|
||||
}
|
||||
|
||||
free(cache);
|
||||
}
|
||||
|
||||
struct mie_int *mie_int_cache_get(
|
||||
struct mie_int_cache *cache, struct mie_ctx *ctx, size_t value,
|
||||
size_t bit_width)
|
||||
{
|
||||
struct int_width_cache *width_cache
|
||||
= get_width_cache(&cache->c_widths, bit_width);
|
||||
if (!width_cache) {
|
||||
width_cache = int_width_cache_create(bit_width);
|
||||
|
||||
if (!width_cache) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
put_width_cache(&cache->c_widths, width_cache);
|
||||
}
|
||||
|
||||
struct int_width_cache_entry *entry = get_int(&width_cache->c_ints, value);
|
||||
if (!entry) {
|
||||
entry = int_width_cache_entry_create(ctx, bit_width, value);
|
||||
|
||||
if (!entry) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
put_int(&width_cache->c_ints, entry);
|
||||
}
|
||||
|
||||
return &entry->e_value;
|
||||
}
|
||||
98
mie/dialect/arith/int.c
Normal file
98
mie/dialect/arith/int.c
Normal file
@@ -0,0 +1,98 @@
|
||||
#include <blue/core/bstr.h>
|
||||
#include <mie/ctx.h>
|
||||
#include <mie/dialect/arith.h>
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/macros.h>
|
||||
#include <mie/type/type-definition.h>
|
||||
#include <mie/type/type.h>
|
||||
#include <mie/value.h>
|
||||
|
||||
struct int_type {
|
||||
struct mie_type i_base;
|
||||
size_t i_width;
|
||||
};
|
||||
|
||||
static enum mie_status value_print(
|
||||
const struct mie_type *ty, const struct mie_value *value, b_stream *out)
|
||||
{
|
||||
struct int_type *int_ty = (struct int_type *)ty;
|
||||
struct mie_int *int_val = (struct mie_int *)value;
|
||||
if (int_ty->i_width <= 64) {
|
||||
b_stream_write_fmt(
|
||||
out, NULL, "%zu : i%zu", int_val->i_val.v_small,
|
||||
int_ty->i_width);
|
||||
} else {
|
||||
b_stream_write_fmt(out, NULL, "INF : i%zu", int_ty->i_width);
|
||||
}
|
||||
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
struct mie_type *mie_arith_int_get_type(struct mie_ctx *ctx, size_t bit_width)
|
||||
{
|
||||
struct mie_type_definition *type_info
|
||||
= mie_ctx_get_type_definition(ctx, "arith", "int");
|
||||
if (!type_info) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
b_rope rope_i = B_ROPE_CHAR('i'), rope_width = B_ROPE_UINT(bit_width);
|
||||
b_rope type_name;
|
||||
b_rope_concat(&type_name, &rope_i, &rope_width);
|
||||
|
||||
mie_id id;
|
||||
mie_id_init_ns(&id, mie_id_map_get_ns(&ctx->ctx_types), &type_name);
|
||||
|
||||
mie_id *target = mie_id_map_get(&ctx->ctx_types, &id);
|
||||
if (target) {
|
||||
return b_unbox(struct mie_type, target, ty_id);
|
||||
}
|
||||
|
||||
struct int_type *type = (struct int_type *)mie_type_create(type_info);
|
||||
if (!type) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
type->i_base.ty_name = b_bstr_fmt("arith.int<%zu>", bit_width);
|
||||
type->i_base.ty_instance_size = sizeof(struct mie_int);
|
||||
type->i_width = bit_width;
|
||||
|
||||
mie_id_map_put(&ctx->ctx_types, &type->i_base.ty_id, &type_name);
|
||||
return (struct mie_type *)type;
|
||||
}
|
||||
|
||||
size_t mie_arith_int_type_get_width(const struct mie_type *type)
|
||||
{
|
||||
if (strcmp(type->ty_def->ty_parent->d_name, "arith") != 0) {
|
||||
return (size_t)-1;
|
||||
}
|
||||
|
||||
if (strcmp(type->ty_def->ty_name, "int") != 0) {
|
||||
return (size_t)-1;
|
||||
}
|
||||
|
||||
const struct int_type *int_type = (const struct int_type *)type;
|
||||
return int_type->i_width;
|
||||
}
|
||||
|
||||
static enum mie_status print(
|
||||
const struct mie_type_definition *def, const struct mie_type *ty,
|
||||
b_stream *out)
|
||||
{
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
static enum mie_status parse(
|
||||
const struct mie_type_definition *def, struct mie_parser *parser,
|
||||
struct mie_type **out)
|
||||
{
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
MIE_TYPE_DEFINITION_BEGIN(mie_arith_int, "int")
|
||||
// MIE_TYPE_DEFINITION_FLAGS(MIE_TYPE_DEFINITION_PARAMETISED);
|
||||
MIE_TYPE_DEFINITION_STRUCT(struct int_type);
|
||||
MIE_TYPE_DEFINITION_PRINT(print);
|
||||
MIE_TYPE_DEFINITION_PARSE(parse);
|
||||
MIE_TYPE_DEFINITION_VALUE_PRINT(value_print);
|
||||
MIE_TYPE_DEFINITION_END()
|
||||
7
mie/dialect/builtin/builtin.c
Normal file
7
mie/dialect/builtin/builtin.c
Normal file
@@ -0,0 +1,7 @@
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/macros.h>
|
||||
|
||||
MIE_DIALECT_BEGIN(mie_builtin, "builtin")
|
||||
MIE_DIALECT_ADD_TYPE(mie_builtin_string);
|
||||
MIE_DIALECT_ADD_TRAIT(mie_builtin_isolated_from_above);
|
||||
MIE_DIALECT_END()
|
||||
21
mie/dialect/builtin/isolated-from-above.c
Normal file
21
mie/dialect/builtin/isolated-from-above.c
Normal 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()
|
||||
84
mie/dialect/builtin/string-cache.c
Normal file
84
mie/dialect/builtin/string-cache.c
Normal file
@@ -0,0 +1,84 @@
|
||||
#include <blue/core/btree.h>
|
||||
#include <blue/ds/hashmap.h>
|
||||
#include <mie/ctx.h>
|
||||
#include <mie/dialect/builtin.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
struct mie_string_cache {
|
||||
b_hashmap *c_entries;
|
||||
};
|
||||
|
||||
static struct mie_string *mie_string_create(
|
||||
struct mie_ctx *ctx, const char *s, size_t len)
|
||||
{
|
||||
struct mie_string *out = malloc(sizeof *out);
|
||||
if (!out) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
out->str_base.v_type = mie_ctx_get_type(ctx, "builtin", "string");
|
||||
if (!out->str_base.v_type) {
|
||||
free(out);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
out->str_val = b_strdup(s);
|
||||
if (!out->str_val) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
out->str_len = len;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
static void mie_string_destroy(struct mie_string *str)
|
||||
{
|
||||
}
|
||||
|
||||
struct mie_string_cache *mie_string_cache_create(void)
|
||||
{
|
||||
struct mie_string_cache *out = malloc(sizeof *out);
|
||||
if (!out) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(out, 0x0, sizeof *out);
|
||||
|
||||
out->c_entries = b_hashmap_create(
|
||||
NULL, (b_hashmap_value_destructor)mie_string_destroy);
|
||||
if (!out->c_entries) {
|
||||
free(out);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void mie_string_cache_destroy(struct mie_string_cache *cache)
|
||||
{
|
||||
b_hashmap_unref(cache->c_entries);
|
||||
free(cache);
|
||||
}
|
||||
|
||||
struct mie_string *mie_string_cache_get(
|
||||
struct mie_string_cache *cache, struct mie_ctx *ctx, const char *s)
|
||||
{
|
||||
size_t s_len = strlen(s);
|
||||
b_hashmap_key key = {.key_data = s, .key_size = s_len};
|
||||
const b_hashmap_value *value = b_hashmap_get(cache->c_entries, &key);
|
||||
if (value) {
|
||||
return value->value_data;
|
||||
}
|
||||
|
||||
struct mie_string *str = mie_string_create(ctx, s, s_len);
|
||||
if (!str) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
b_hashmap_value new_val = {.value_data = str, .value_size = sizeof *str};
|
||||
b_hashmap_put(cache->c_entries, &key, &new_val);
|
||||
|
||||
return str;
|
||||
}
|
||||
44
mie/dialect/builtin/string.c
Normal file
44
mie/dialect/builtin/string.c
Normal file
@@ -0,0 +1,44 @@
|
||||
#include <blue/core/bstr.h>
|
||||
#include <mie/ctx.h>
|
||||
#include <mie/dialect/builtin.h>
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/macros.h>
|
||||
#include <mie/type/type-definition.h>
|
||||
#include <mie/type/type.h>
|
||||
#include <mie/value.h>
|
||||
|
||||
static enum mie_status value_print(
|
||||
const struct mie_type *ty, const struct mie_value *value, b_stream *out)
|
||||
{
|
||||
const struct mie_string *str = (const struct mie_string *)value;
|
||||
b_stream_write_fmt(out, NULL, "\"%s\"", str->str_val);
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
static void type_init(
|
||||
const struct mie_type_definition *type_info, struct mie_type *type)
|
||||
{
|
||||
type->ty_instance_size = sizeof(struct mie_string);
|
||||
}
|
||||
|
||||
static enum mie_status print(
|
||||
const struct mie_type_definition *def, const struct mie_type *ty,
|
||||
b_stream *out)
|
||||
{
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
static enum mie_status parse(
|
||||
const struct mie_type_definition *def, struct mie_parser *parser,
|
||||
struct mie_type **out)
|
||||
{
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
MIE_TYPE_DEFINITION_BEGIN(mie_builtin_string, "string")
|
||||
MIE_TYPE_DEFINITION_STRUCT(struct mie_type);
|
||||
MIE_TYPE_DEFINITION_INIT(type_init);
|
||||
MIE_TYPE_DEFINITION_PRINT(print);
|
||||
MIE_TYPE_DEFINITION_PARSE(parse);
|
||||
MIE_TYPE_DEFINITION_VALUE_PRINT(value_print);
|
||||
MIE_TYPE_DEFINITION_END()
|
||||
18
mie/dialect/cf/br-cond.c
Normal file
18
mie/dialect/cf/br-cond.c
Normal file
@@ -0,0 +1,18 @@
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/ir/op-definition.h>
|
||||
#include <mie/macros.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_cf_br_cond, "br-cond")
|
||||
MIE_OP_DEFINITION_PRINT(print);
|
||||
MIE_OP_DEFINITION_PARSE(parse);
|
||||
MIE_OP_DEFINITION_END()
|
||||
18
mie/dialect/cf/br.c
Normal file
18
mie/dialect/cf/br.c
Normal file
@@ -0,0 +1,18 @@
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/ir/op-definition.h>
|
||||
#include <mie/macros.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_cf_br, "br")
|
||||
MIE_OP_DEFINITION_PRINT(print);
|
||||
MIE_OP_DEFINITION_PARSE(parse);
|
||||
MIE_OP_DEFINITION_END()
|
||||
7
mie/dialect/cf/cf.c
Normal file
7
mie/dialect/cf/cf.c
Normal file
@@ -0,0 +1,7 @@
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/macros.h>
|
||||
|
||||
MIE_DIALECT_BEGIN(mie_cf, "cf")
|
||||
MIE_DIALECT_ADD_OP(mie_cf_br);
|
||||
MIE_DIALECT_ADD_OP(mie_cf_br_cond);
|
||||
MIE_DIALECT_END()
|
||||
61
mie/dialect/dialect.c
Normal file
61
mie/dialect/dialect.c
Normal file
@@ -0,0 +1,61 @@
|
||||
#include <blue/ds/string.h>
|
||||
#include <mie/ctx.h>
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/ir/op-definition.h>
|
||||
#include <mie/type/type-definition.h>
|
||||
|
||||
#define TYPE_NS_ID \
|
||||
MIE_ID(0xe4, 0x99, 0x42, 0x58, 0x2b, 0xdb, 0x45, 0xa3, 0xbd, 0x4b, \
|
||||
0x17, 0xe3, 0xc4, 0xa9, 0xbc, 0x30)
|
||||
#define OP_NS_ID \
|
||||
MIE_ID(0xb9, 0x97, 0xcf, 0xd3, 0x81, 0xd4, 0x45, 0x06, 0x9b, 0x44, \
|
||||
0x05, 0x9f, 0xb4, 0x76, 0xf1, 0x2d)
|
||||
|
||||
struct mie_dialect *mie_dialect_create(struct mie_ctx *ctx, const char *name)
|
||||
{
|
||||
struct mie_dialect *out = malloc(sizeof *out);
|
||||
if (!out) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(out, 0x0, sizeof *out);
|
||||
|
||||
out->d_name = b_strdup(name);
|
||||
if (!out->d_name) {
|
||||
free(out);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mie_id op_ns = OP_NS_ID;
|
||||
mie_id_map_init(&out->d_ops, &op_ns);
|
||||
|
||||
mie_id type_ns = TYPE_NS_ID;
|
||||
mie_id_map_init(&out->d_types, &type_ns);
|
||||
|
||||
b_rope name_rope = B_ROPE_CSTR(name);
|
||||
mie_id_map_put(&ctx->ctx_dialects, &out->d_id, &name_rope);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
const struct mie_op_definition *mie_dialect_get_op(
|
||||
const struct mie_dialect *dialect, const char *name)
|
||||
{
|
||||
b_rope name_rope = B_ROPE_CSTR(name);
|
||||
mie_id id;
|
||||
mie_id_init_ns(&id, mie_id_map_get_ns(&dialect->d_ops), &name_rope);
|
||||
|
||||
mie_id *target = mie_id_map_get(&dialect->d_ops, &id);
|
||||
return b_unbox(struct mie_op_definition, target, op_id);
|
||||
}
|
||||
|
||||
const struct mie_type_definition *mie_dialect_get_type(
|
||||
const struct mie_dialect *dialect, const char *name)
|
||||
{
|
||||
b_rope name_rope = B_ROPE_CSTR(name);
|
||||
mie_id id;
|
||||
mie_id_init_ns(&id, mie_id_map_get_ns(&dialect->d_types), &name_rope);
|
||||
|
||||
mie_id *target = mie_id_map_get(&dialect->d_types, &id);
|
||||
return b_unbox(struct mie_type_definition, target, ty_id);
|
||||
}
|
||||
22
mie/dialect/func/func.c
Normal file
22
mie/dialect/func/func.c
Normal file
@@ -0,0 +1,22 @@
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/ir/op-definition.h>
|
||||
#include <mie/macros.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_func_func, "func")
|
||||
MIE_OP_DEFINITION_PRINT(print);
|
||||
MIE_OP_DEFINITION_PARSE(parse);
|
||||
MIE_OP_DEFINITION_END()
|
||||
|
||||
MIE_DIALECT_BEGIN(mie_func, "func")
|
||||
MIE_DIALECT_ADD_OP(mie_func_func);
|
||||
MIE_DIALECT_END()
|
||||
82
mie/dialect/index/index-cache.c
Normal file
82
mie/dialect/index/index-cache.c
Normal file
@@ -0,0 +1,82 @@
|
||||
#include <blue/core/btree.h>
|
||||
#include <mie/ctx.h>
|
||||
#include <mie/dialect/index.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
struct index_cache_entry {
|
||||
b_btree_node e_node;
|
||||
struct mie_index e_value;
|
||||
};
|
||||
|
||||
struct mie_index_cache {
|
||||
b_btree c_entries;
|
||||
};
|
||||
|
||||
static B_BTREE_DEFINE_SIMPLE_INSERT(
|
||||
struct index_cache_entry, e_node, e_value.i_value, put_index);
|
||||
static B_BTREE_DEFINE_SIMPLE_GET(
|
||||
struct index_cache_entry, size_t, e_node, e_value.i_value, get_index);
|
||||
|
||||
static struct index_cache_entry *index_cache_entry_create(
|
||||
struct mie_ctx *ctx, size_t val)
|
||||
{
|
||||
struct index_cache_entry *out = malloc(sizeof *out);
|
||||
if (!out) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
out->e_value.i_value = val;
|
||||
out->e_value.i_base.v_type = mie_ctx_get_type(ctx, "index", "index");
|
||||
if (!out->e_value.i_base.v_type) {
|
||||
free(out);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
struct mie_index_cache *mie_index_cache_create(void)
|
||||
{
|
||||
struct mie_index_cache *out = malloc(sizeof *out);
|
||||
if (!out) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(out, 0x0, sizeof *out);
|
||||
return out;
|
||||
}
|
||||
|
||||
void mie_index_cache_destroy(struct mie_index_cache *cache)
|
||||
{
|
||||
b_btree_node *cur = b_btree_first(&cache->c_entries);
|
||||
while (cur) {
|
||||
b_btree_node *next = b_btree_next(cur);
|
||||
b_btree_delete(&cache->c_entries, cur);
|
||||
|
||||
struct index_cache_entry *entry
|
||||
= b_unbox(struct index_cache_entry, cur, e_node);
|
||||
free(entry);
|
||||
|
||||
cur = next;
|
||||
}
|
||||
|
||||
free(cache);
|
||||
}
|
||||
|
||||
struct mie_index *mie_index_cache_get(
|
||||
struct mie_index_cache *cache, struct mie_ctx *ctx, size_t value)
|
||||
{
|
||||
struct index_cache_entry *entry = get_index(&cache->c_entries, value);
|
||||
if (!entry) {
|
||||
entry = index_cache_entry_create(ctx, value);
|
||||
|
||||
if (!entry) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
put_index(&cache->c_entries, entry);
|
||||
}
|
||||
|
||||
return &entry->e_value;
|
||||
}
|
||||
53
mie/dialect/index/index.c
Normal file
53
mie/dialect/index/index.c
Normal file
@@ -0,0 +1,53 @@
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/dialect/index.h>
|
||||
#include <mie/macros.h>
|
||||
#include <mie/type/type-definition.h>
|
||||
#include <mie/type/type.h>
|
||||
#include <mie/value.h>
|
||||
|
||||
struct index_type {
|
||||
struct mie_type i_base;
|
||||
};
|
||||
|
||||
static enum mie_status value_print(
|
||||
const struct mie_type *ty, const struct mie_value *value, b_stream *out)
|
||||
{
|
||||
struct index_type *index_ty = (struct index_type *)ty;
|
||||
struct mie_index *index_val = (struct mie_index *)value;
|
||||
b_stream_write_fmt(
|
||||
out, NULL, "%zu : %s", index_val->i_value,
|
||||
index_ty->i_base.ty_def->ty_name);
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
static void type_init(
|
||||
const struct mie_type_definition *type_info, struct mie_type *type)
|
||||
{
|
||||
type->ty_instance_size = sizeof(struct mie_index);
|
||||
}
|
||||
|
||||
static enum mie_status print(
|
||||
const struct mie_type_definition *def, const struct mie_type *ty,
|
||||
b_stream *out)
|
||||
{
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
static enum mie_status parse(
|
||||
const struct mie_type_definition *def, struct mie_parser *parser,
|
||||
struct mie_type **out)
|
||||
{
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
MIE_TYPE_DEFINITION_BEGIN(mie_index_index, "index")
|
||||
MIE_TYPE_DEFINITION_STRUCT(struct index_type);
|
||||
MIE_TYPE_DEFINITION_INIT(type_init);
|
||||
MIE_TYPE_DEFINITION_PRINT(print);
|
||||
MIE_TYPE_DEFINITION_PARSE(parse);
|
||||
MIE_TYPE_DEFINITION_VALUE_PRINT(value_print);
|
||||
MIE_TYPE_DEFINITION_END()
|
||||
|
||||
MIE_DIALECT_BEGIN(mie_index, "index")
|
||||
MIE_DIALECT_ADD_TYPE(mie_index_index);
|
||||
MIE_DIALECT_END()
|
||||
6
mie/dialect/meta/meta.c
Normal file
6
mie/dialect/meta/meta.c
Normal file
@@ -0,0 +1,6 @@
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/macros.h>
|
||||
|
||||
MIE_DIALECT_BEGIN(mie_meta, "meta")
|
||||
MIE_DIALECT_ADD_OP(mie_meta_source_filename);
|
||||
MIE_DIALECT_END()
|
||||
18
mie/dialect/meta/source-filename.c
Normal file
18
mie/dialect/meta/source-filename.c
Normal file
@@ -0,0 +1,18 @@
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/ir/op-definition.h>
|
||||
#include <mie/macros.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_meta_source_filename, "source-filename")
|
||||
MIE_OP_DEFINITION_PRINT(print);
|
||||
MIE_OP_DEFINITION_PARSE(parse);
|
||||
MIE_OP_DEFINITION_END()
|
||||
18
mie/dialect/ptr/load.c
Normal file
18
mie/dialect/ptr/load.c
Normal file
@@ -0,0 +1,18 @@
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/ir/op-definition.h>
|
||||
#include <mie/macros.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_ptr_load, "load")
|
||||
MIE_OP_DEFINITION_PRINT(print);
|
||||
MIE_OP_DEFINITION_PARSE(parse);
|
||||
MIE_OP_DEFINITION_END()
|
||||
33
mie/dialect/ptr/ptr.c
Normal file
33
mie/dialect/ptr/ptr.c
Normal file
@@ -0,0 +1,33 @@
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/macros.h>
|
||||
#include <mie/type/type-definition.h>
|
||||
|
||||
struct ptr_type {
|
||||
struct mie_type_definition ptr_base;
|
||||
};
|
||||
|
||||
static enum mie_status print(
|
||||
const struct mie_type_definition *def, const struct mie_type *ty,
|
||||
b_stream *out)
|
||||
{
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
static enum mie_status parse(
|
||||
const struct mie_type_definition *def, struct mie_parser *parser,
|
||||
struct mie_type **out)
|
||||
{
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
MIE_TYPE_DEFINITION_BEGIN(mie_ptr_ptr, "ptr")
|
||||
MIE_TYPE_DEFINITION_STRUCT(struct ptr_type);
|
||||
MIE_TYPE_DEFINITION_PRINT(print);
|
||||
MIE_TYPE_DEFINITION_PARSE(parse);
|
||||
MIE_TYPE_DEFINITION_END()
|
||||
|
||||
MIE_DIALECT_BEGIN(mie_ptr, "ptr")
|
||||
MIE_DIALECT_ADD_OP(mie_ptr_load);
|
||||
MIE_DIALECT_ADD_OP(mie_ptr_store);
|
||||
MIE_DIALECT_ADD_TYPE(mie_ptr_ptr);
|
||||
MIE_DIALECT_END()
|
||||
18
mie/dialect/ptr/store.c
Normal file
18
mie/dialect/ptr/store.c
Normal file
@@ -0,0 +1,18 @@
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/ir/op-definition.h>
|
||||
#include <mie/macros.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_ptr_store, "store")
|
||||
MIE_OP_DEFINITION_PRINT(print);
|
||||
MIE_OP_DEFINITION_PARSE(parse);
|
||||
MIE_OP_DEFINITION_END()
|
||||
18
mie/dialect/scf/for.c
Normal file
18
mie/dialect/scf/for.c
Normal file
@@ -0,0 +1,18 @@
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/ir/op-definition.h>
|
||||
#include <mie/macros.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_scf_for, "for")
|
||||
MIE_OP_DEFINITION_PRINT(print);
|
||||
MIE_OP_DEFINITION_PARSE(parse);
|
||||
MIE_OP_DEFINITION_END()
|
||||
18
mie/dialect/scf/if.c
Normal file
18
mie/dialect/scf/if.c
Normal file
@@ -0,0 +1,18 @@
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/ir/op-definition.h>
|
||||
#include <mie/macros.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_scf_if, "if")
|
||||
MIE_OP_DEFINITION_PRINT(print);
|
||||
MIE_OP_DEFINITION_PARSE(parse);
|
||||
MIE_OP_DEFINITION_END()
|
||||
8
mie/dialect/scf/scf.c
Normal file
8
mie/dialect/scf/scf.c
Normal file
@@ -0,0 +1,8 @@
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/macros.h>
|
||||
|
||||
MIE_DIALECT_BEGIN(mie_scf, "scf")
|
||||
MIE_DIALECT_ADD_OP(mie_scf_if);
|
||||
MIE_DIALECT_ADD_OP(mie_scf_for);
|
||||
MIE_DIALECT_ADD_OP(mie_scf_yield);
|
||||
MIE_DIALECT_END()
|
||||
18
mie/dialect/scf/yield.c
Normal file
18
mie/dialect/scf/yield.c
Normal file
@@ -0,0 +1,18 @@
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/ir/op-definition.h>
|
||||
#include <mie/macros.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_scf_yield, "yield")
|
||||
MIE_OP_DEFINITION_PRINT(print);
|
||||
MIE_OP_DEFINITION_PARSE(parse);
|
||||
MIE_OP_DEFINITION_END()
|
||||
21
mie/dialect/select/graph-only.c
Normal file
21
mie/dialect/select/graph-only.c
Normal 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()
|
||||
21
mie/dialect/select/graph-op.c
Normal file
21
mie/dialect/select/graph-op.c
Normal 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()
|
||||
21
mie/dialect/select/graph-scope.c
Normal file
21
mie/dialect/select/graph-scope.c
Normal 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()
|
||||
21
mie/dialect/select/graph.c
Normal file
21
mie/dialect/select/graph.c
Normal 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()
|
||||
9
mie/dialect/select/select.c
Normal file
9
mie/dialect/select/select.c
Normal 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()
|
||||
217
mie/id.c
Normal file
217
mie/id.c
Normal file
@@ -0,0 +1,217 @@
|
||||
#include <blue/core/bstr.h>
|
||||
#include <blue/core/endian.h>
|
||||
#include <blue/core/hash.h>
|
||||
#include <blue/core/random.h>
|
||||
#include <mie/id.h>
|
||||
#include <string.h>
|
||||
|
||||
static inline int id_memcmp(const uint8_t *a, const uint8_t *b)
|
||||
{
|
||||
return memcmp(a, b, MIE_ID_NR_BYTES);
|
||||
}
|
||||
|
||||
static mie_id *get_id(const b_btree *tree, mie_id *key)
|
||||
{
|
||||
b_btree_node *cur = tree->b_root;
|
||||
while (cur) {
|
||||
mie_id *cur_node = b_unbox(mie_id, cur, e_node);
|
||||
int cmp = memcmp(
|
||||
key->id_bytes, cur_node->id_bytes, sizeof key->id_bytes);
|
||||
|
||||
if (cmp > 0) {
|
||||
cur = b_btree_right(cur);
|
||||
} else if (cmp < 0) {
|
||||
cur = b_btree_left(cur);
|
||||
} else {
|
||||
return cur_node;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void put_id(b_btree *tree, mie_id *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) {
|
||||
mie_id *cur_node = b_unbox(mie_id, cur, e_node);
|
||||
b_btree_node *next = NULL;
|
||||
int cmp = memcmp(
|
||||
node->id_bytes, cur_node->id_bytes, sizeof node->id_bytes);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void mie_id_init(
|
||||
mie_id *out, uint32_t a, uint16_t b, uint16_t c, uint16_t d, uint64_t e)
|
||||
{
|
||||
b_i32 x_a = b_i32_htob(a);
|
||||
b_i16 x_b = b_i16_htob(b);
|
||||
b_i16 x_c = b_i16_htob(c);
|
||||
b_i16 x_d = b_i16_htob(d);
|
||||
b_i64 x_e = b_i64_htob(e);
|
||||
|
||||
memcpy(&out->id_bytes[0], x_a.i_bytes, sizeof x_a.i_bytes);
|
||||
memcpy(&out->id_bytes[4], x_b.i_bytes, sizeof x_b.i_bytes);
|
||||
memcpy(&out->id_bytes[6], x_c.i_bytes, sizeof x_c.i_bytes);
|
||||
memcpy(&out->id_bytes[8], x_d.i_bytes, sizeof x_d.i_bytes);
|
||||
memcpy(&out->id_bytes[10], &x_e.i_bytes[2], sizeof x_e.i_bytes - 2);
|
||||
}
|
||||
|
||||
void mie_id_init_zero(mie_id *out)
|
||||
{
|
||||
memset(out, 0x0, sizeof *out);
|
||||
}
|
||||
|
||||
void mie_id_init_random(mie_id *out)
|
||||
{
|
||||
b_random_ctx *random = b_random_global_ctx();
|
||||
b_random_next_bytes(
|
||||
random, (unsigned char *)out->id_bytes, sizeof out->id_bytes);
|
||||
}
|
||||
|
||||
void mie_id_init_ns(mie_id *out, const mie_id *ns, const b_rope *name)
|
||||
{
|
||||
struct mie_id_builder ctx;
|
||||
mie_id_builder_begin(&ctx, ns);
|
||||
mie_id_builder_add_rope(&ctx, name);
|
||||
mie_id_builder_end(&ctx, out);
|
||||
}
|
||||
|
||||
void mie_id_to_string(const mie_id *id, char *out, size_t max)
|
||||
{
|
||||
b_bstr str;
|
||||
b_bstr_begin(&str, out, max);
|
||||
for (size_t i = 0; i < sizeof id->id_bytes; i++) {
|
||||
if (i == 4 || i == 6 || i == 8 || i == 10) {
|
||||
b_bstr_write_char(&str, '-');
|
||||
}
|
||||
|
||||
b_bstr_write_fmt(&str, "%02x", id->id_bytes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void mie_id_builder_begin(struct mie_id_builder *builder, const mie_id *ns)
|
||||
{
|
||||
memset(builder, 0x0, sizeof *builder);
|
||||
b_hash_ctx_init(&builder->b_hash, B_HASH_SHA1);
|
||||
b_hash_ctx_update(&builder->b_hash, ns->id_bytes, sizeof ns->id_bytes);
|
||||
}
|
||||
|
||||
void mie_id_builder_add(struct mie_id_builder *builder, const void *p, size_t len)
|
||||
{
|
||||
b_hash_ctx_update(&builder->b_hash, p, len);
|
||||
}
|
||||
|
||||
void mie_id_builder_add_rope(struct mie_id_builder *builder, const b_rope *rope)
|
||||
{
|
||||
b_hash_ctx_update_rope(&builder->b_hash, rope);
|
||||
}
|
||||
|
||||
void mie_id_builder_add_marker(
|
||||
struct mie_id_builder *builder, enum mie_id_builder_marker marker)
|
||||
{
|
||||
unsigned char c = marker;
|
||||
b_hash_ctx_update(&builder->b_hash, &c, sizeof c);
|
||||
}
|
||||
|
||||
void mie_id_builder_end(struct mie_id_builder *builder, mie_id *out)
|
||||
{
|
||||
memset(out, 0x0, sizeof *out);
|
||||
b_hash_ctx_finish(&builder->b_hash, out->id_bytes, sizeof out->id_bytes);
|
||||
|
||||
out->id_bytes[6] &= 0x0F;
|
||||
out->id_bytes[6] |= 0x50;
|
||||
|
||||
out->id_bytes[8] &= 0x3F;
|
||||
out->id_bytes[8] |= 0x80;
|
||||
}
|
||||
|
||||
void mie_id_map_init(struct mie_id_map *map, const mie_id *ns)
|
||||
{
|
||||
memset(map, 0x0, sizeof *map);
|
||||
|
||||
map->map_ns_id = *ns;
|
||||
}
|
||||
|
||||
const mie_id *mie_id_map_get_ns(const struct mie_id_map *map)
|
||||
{
|
||||
return &map->map_ns_id;
|
||||
}
|
||||
|
||||
void mie_id_map_put(struct mie_id_map *map, mie_id *id, const b_rope *name)
|
||||
{
|
||||
mie_id_init_ns(id, &map->map_ns_id, name);
|
||||
put_id(&map->map_entries, id);
|
||||
}
|
||||
|
||||
void mie_id_map_put_id(struct mie_id_map *map, mie_id *node)
|
||||
{
|
||||
put_id(&map->map_entries, node);
|
||||
}
|
||||
|
||||
mie_id *mie_id_map_get(const struct mie_id_map *map, mie_id *id)
|
||||
{
|
||||
return get_id(&map->map_entries, id);
|
||||
}
|
||||
|
||||
enum mie_status mie_id_map_iterator_begin(
|
||||
struct mie_id_map_iterator *it, const struct mie_id_map *map)
|
||||
{
|
||||
memset(it, 0x0, sizeof *it);
|
||||
|
||||
it->_n = b_btree_first(&map->map_entries);
|
||||
|
||||
if (!it->_n) {
|
||||
return MIE_ERR_NO_DATA;
|
||||
}
|
||||
|
||||
it->it_id = b_unbox(mie_id, it->_n, e_node);
|
||||
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
enum mie_status mie_id_map_iterator_move_next(struct mie_id_map_iterator *it)
|
||||
{
|
||||
if (!it->_n) {
|
||||
it->it_id = NULL;
|
||||
return MIE_ERR_NO_DATA;
|
||||
}
|
||||
|
||||
it->_n = b_btree_next(it->_n);
|
||||
if (!it->_n) {
|
||||
it->it_id = NULL;
|
||||
return MIE_ERR_NO_DATA;
|
||||
}
|
||||
|
||||
it->it_id = b_unbox(mie_id, it->_n, e_node);
|
||||
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
@@ -3,30 +3,63 @@
|
||||
|
||||
#include <blue/core/btree.h>
|
||||
#include <blue/ds/hashmap.h>
|
||||
#include <mie/type.h>
|
||||
#include <mie/id.h>
|
||||
|
||||
struct mie_op;
|
||||
struct mie_int_cache;
|
||||
struct mie_index_cache;
|
||||
struct mie_string_cache;
|
||||
;
|
||||
|
||||
struct mie_ctx {
|
||||
#if 0
|
||||
struct mie_const *ctx_true, *ctx_false;
|
||||
struct mie_value *ctx_null;
|
||||
struct mie_type *ctx_types[__MIE_TYPE_COUNT];
|
||||
b_btree ctx_int_cache;
|
||||
b_hashmap *ctx_sel_cache;
|
||||
b_hashmap *ctx_string_cache;
|
||||
#endif
|
||||
/* map of struct mie_dialect */
|
||||
struct mie_id_map ctx_dialects;
|
||||
/* map of struct mie_type */
|
||||
struct mie_id_map ctx_types;
|
||||
/* map of struct mie_trait */
|
||||
struct mie_id_map ctx_traits;
|
||||
|
||||
struct mie_int_cache *ctx_ints;
|
||||
struct mie_float_cache *ctx_floats;
|
||||
struct mie_index_cache *ctx_indices;
|
||||
struct mie_string_cache *ctx_strings;
|
||||
};
|
||||
|
||||
extern struct mie_ctx *mie_ctx_create(void);
|
||||
extern void mie_ctx_destroy(struct mie_ctx *ctx);
|
||||
MIE_API struct mie_ctx *mie_ctx_create(void);
|
||||
MIE_API void mie_ctx_destroy(struct mie_ctx *ctx);
|
||||
|
||||
extern struct mie_type *mie_ctx_get_type(
|
||||
struct mie_ctx *ctx, enum mie_type_id type_id);
|
||||
extern struct mie_type *mie_ctx_get_int_type(
|
||||
struct mie_ctx *ctx, unsigned int nr_bits);
|
||||
extern struct mie_value *mie_ctx_get_null(struct mie_ctx *ctx);
|
||||
extern struct mie_value *mie_ctx_get_bool(struct mie_ctx *ctx, bool val);
|
||||
extern struct mie_value *mie_ctx_get_int(
|
||||
struct mie_ctx *ctx, long long val, unsigned int nr_bits);
|
||||
extern struct mie_value *mie_ctx_get_string(struct mie_ctx *ctx, const char *s);
|
||||
extern struct mie_value *mie_ctx_get_selector(struct mie_ctx *ctx, const char *sel);
|
||||
extern struct mie_value *mie_ctx_create_array(struct mie_ctx *ctx);
|
||||
MIE_API bool mie_ctx_resolve_op(const struct mie_ctx *ctx, struct mie_op *op);
|
||||
|
||||
MIE_API struct mie_dialect *mie_ctx_get_dialect(
|
||||
const struct mie_ctx *ctx, const char *name);
|
||||
MIE_API struct mie_type_definition *mie_ctx_get_type_definition(
|
||||
const struct mie_ctx *ctx, const char *dialect_name, const char *type_name);
|
||||
MIE_API const struct mie_trait_definition *mie_ctx_get_trait_definition(
|
||||
const struct mie_ctx *ctx, const char *dialect_name,
|
||||
const char *trait_name);
|
||||
MIE_API struct mie_type *mie_ctx_get_type(
|
||||
struct mie_ctx *ctx, const char *dialect_name, const char *type_name);
|
||||
MIE_API const struct mie_trait *mie_ctx_get_trait(
|
||||
struct mie_ctx *ctx, const char *dialect_name, const char *trait_name);
|
||||
MIE_API struct mie_type *mie_ctx_get_storage_type(
|
||||
struct mie_ctx *ctx, const struct mie_type **parts, size_t nr_parts);
|
||||
MIE_API struct mie_type *mie_ctx_get_function_type(
|
||||
struct mie_ctx *ctx, const struct mie_type **in, size_t nr_in,
|
||||
const struct mie_type **out, size_t nr_out);
|
||||
|
||||
MIE_API struct mie_value *mie_ctx_get_null(struct mie_ctx *ctx);
|
||||
MIE_API struct mie_value *mie_ctx_get_int(
|
||||
struct mie_ctx *ctx, long long val, size_t nr_bits);
|
||||
MIE_API struct mie_value *mie_ctx_get_float(
|
||||
struct mie_ctx *ctx, double val, size_t nr_bits);
|
||||
MIE_API struct mie_value *mie_ctx_get_string(struct mie_ctx *ctx, const char *s);
|
||||
MIE_API struct mie_value *mie_ctx_get_index(struct mie_ctx *ctx, size_t val);
|
||||
|
||||
#endif
|
||||
|
||||
62
mie/include/mie/dialect/arith.h
Normal file
62
mie/include/mie/dialect/arith.h
Normal file
@@ -0,0 +1,62 @@
|
||||
#ifndef MIE_DIALECT_ARITH_H_
|
||||
#define MIE_DIALECT_ARITH_H_
|
||||
|
||||
#include <mie/misc.h>
|
||||
#include <mie/value.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct mie_ctx;
|
||||
struct mie_dialect;
|
||||
|
||||
enum mie_float_width {
|
||||
MIE_FLOAT_32 = 32,
|
||||
MIE_FLOAT_64 = 64,
|
||||
};
|
||||
|
||||
struct mie_int {
|
||||
struct mie_value i_base;
|
||||
union {
|
||||
int64_t v_small;
|
||||
|
||||
struct {
|
||||
long *a_parts;
|
||||
size_t a_nr_parts;
|
||||
} v_arbitrary;
|
||||
} i_val;
|
||||
};
|
||||
|
||||
struct mie_float {
|
||||
struct mie_value f_base;
|
||||
|
||||
union {
|
||||
float v_32;
|
||||
double v_64;
|
||||
} f_val;
|
||||
};
|
||||
|
||||
struct mie_int_cache;
|
||||
|
||||
MIE_API struct mie_dialect *mie_arith_dialect_create(struct mie_ctx *ctx);
|
||||
|
||||
MIE_API struct mie_type *mie_arith_int_get_type(
|
||||
struct mie_ctx *ctx, size_t bit_width);
|
||||
MIE_API struct mie_type *mie_arith_float_get_type(
|
||||
struct mie_ctx *ctx, size_t bit_width);
|
||||
|
||||
MIE_API size_t mie_arith_int_type_get_width(const struct mie_type *type);
|
||||
MIE_API size_t mie_arith_float_type_get_width(const struct mie_type *type);
|
||||
|
||||
MIE_API struct mie_int_cache *mie_int_cache_create(void);
|
||||
MIE_API void mie_int_cache_destroy(struct mie_int_cache *cache);
|
||||
MIE_API struct mie_int *mie_int_cache_get(
|
||||
struct mie_int_cache *cache, struct mie_ctx *ctx, size_t value,
|
||||
size_t bit_width);
|
||||
|
||||
MIE_API struct mie_float_cache *mie_float_cache_create(void);
|
||||
MIE_API void mie_float_cache_destroy(struct mie_float_cache *cache);
|
||||
MIE_API struct mie_float *mie_float_cache_get(
|
||||
struct mie_float_cache *cache, struct mie_ctx *ctx, double value,
|
||||
size_t bit_width);
|
||||
|
||||
#endif
|
||||
29
mie/include/mie/dialect/builtin.h
Normal file
29
mie/include/mie/dialect/builtin.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef MIE_DIALECT_BUILTIN_H_
|
||||
#define MIE_DIALECT_BUILTIN_H_
|
||||
|
||||
#include <blue/ds/string.h>
|
||||
#include <mie/misc.h>
|
||||
#include <mie/value.h>
|
||||
|
||||
struct mie_dialect;
|
||||
|
||||
struct mie_ctx;
|
||||
struct mie_int_type;
|
||||
struct mie_float_type;
|
||||
|
||||
struct mie_string {
|
||||
struct mie_value str_base;
|
||||
char *str_val;
|
||||
size_t str_len;
|
||||
};
|
||||
|
||||
struct mie_string_cache;
|
||||
|
||||
MIE_API struct mie_dialect *mie_builtin_dialect_create(struct mie_ctx *ctx);
|
||||
|
||||
MIE_API struct mie_string_cache *mie_string_cache_create(void);
|
||||
MIE_API void mie_string_cache_destroy(struct mie_string_cache *cache);
|
||||
MIE_API struct mie_string *mie_string_cache_get(
|
||||
struct mie_string_cache *cache, struct mie_ctx *ctx, const char *val);
|
||||
|
||||
#endif
|
||||
11
mie/include/mie/dialect/cf.h
Normal file
11
mie/include/mie/dialect/cf.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef MIE_DIALECT_CF_H_
|
||||
#define MIE_DIALECT_CF_H_
|
||||
|
||||
#include <mie/misc.h>
|
||||
|
||||
struct mie_ctx;
|
||||
struct mie_dialect;
|
||||
|
||||
MIE_API struct mie_dialect *mie_cf_dialect_create(struct mie_ctx *ctx);
|
||||
|
||||
#endif
|
||||
38
mie/include/mie/dialect/dialect.h
Normal file
38
mie/include/mie/dialect/dialect.h
Normal file
@@ -0,0 +1,38 @@
|
||||
#ifndef MIE_DIALECT_DIALECT_H_
|
||||
#define MIE_DIALECT_DIALECT_H_
|
||||
|
||||
#include <blue/core/btree.h>
|
||||
#include <blue/core/queue.h>
|
||||
#include <mie/id.h>
|
||||
#include <mie/misc.h>
|
||||
#include <mie/vector.h>
|
||||
|
||||
struct mie_ctx;
|
||||
|
||||
struct mie_op_definition;
|
||||
struct mie_type_definition;
|
||||
struct mie_trait_definition;
|
||||
|
||||
struct mie_dialect {
|
||||
mie_id d_id;
|
||||
char *d_name;
|
||||
|
||||
/* map of struct mie_op_definition */
|
||||
struct mie_id_map d_ops;
|
||||
/* map of struct mie_type_definition */
|
||||
struct mie_id_map d_types;
|
||||
/* map of struct mie_trait_definition */
|
||||
struct mie_id_map d_traits;
|
||||
};
|
||||
|
||||
MIE_API struct mie_dialect *mie_dialect_create(
|
||||
struct mie_ctx *ctx, const char *name);
|
||||
|
||||
MIE_API const struct mie_op_definition *mie_dialect_get_op(
|
||||
const struct mie_dialect *dialect, const char *name);
|
||||
MIE_API const struct mie_type_definition *mie_dialect_get_type(
|
||||
const struct mie_dialect *dialect, const char *name);
|
||||
MIE_API const struct mie_trait_definition *mie_dialect_get_trait(
|
||||
const struct mie_dialect *dialect, const char *name);
|
||||
|
||||
#endif
|
||||
11
mie/include/mie/dialect/func.h
Normal file
11
mie/include/mie/dialect/func.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef MIE_DIALECT_FUNC_H_
|
||||
#define MIE_DIALECT_FUNC_H_
|
||||
|
||||
#include <mie/misc.h>
|
||||
|
||||
struct mie_ctx;
|
||||
struct mie_dialect;
|
||||
|
||||
MIE_API struct mie_dialect *mie_func_dialect_create(struct mie_ctx *ctx);
|
||||
|
||||
#endif
|
||||
26
mie/include/mie/dialect/index.h
Normal file
26
mie/include/mie/dialect/index.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef MIE_DIALECT_INDEX_H_
|
||||
#define MIE_DIALECT_INDEX_H_
|
||||
|
||||
#include <mie/misc.h>
|
||||
#include <mie/value.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct mie_ctx;
|
||||
struct mie_dialect;
|
||||
|
||||
struct mie_index {
|
||||
struct mie_value i_base;
|
||||
size_t i_value;
|
||||
};
|
||||
|
||||
struct mie_index_cache;
|
||||
|
||||
MIE_API struct mie_dialect *mie_index_dialect_create(struct mie_ctx *ctx);
|
||||
|
||||
MIE_API struct mie_index_cache *mie_index_cache_create(void);
|
||||
MIE_API void mie_index_cache_destroy(struct mie_index_cache *cache);
|
||||
MIE_API struct mie_index *mie_index_cache_get(
|
||||
struct mie_index_cache *cache, struct mie_ctx *ctx, size_t value);
|
||||
|
||||
#endif
|
||||
11
mie/include/mie/dialect/meta.h
Normal file
11
mie/include/mie/dialect/meta.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef MIE_DIALECT_META_H_
|
||||
#define MIE_DIALECT_META_H_
|
||||
|
||||
#include <mie/misc.h>
|
||||
|
||||
struct mie_ctx;
|
||||
struct mie_dialect;
|
||||
|
||||
MIE_API struct mie_dialect *mie_meta_dialect_create(struct mie_ctx *ctx);
|
||||
|
||||
#endif
|
||||
11
mie/include/mie/dialect/ptr.h
Normal file
11
mie/include/mie/dialect/ptr.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef MIE_DIALECT_PTR_H_
|
||||
#define MIE_DIALECT_PTR_H_
|
||||
|
||||
#include <mie/misc.h>
|
||||
|
||||
struct mie_ctx;
|
||||
struct mie_dialect;
|
||||
|
||||
MIE_API struct mie_dialect *mie_ptr_dialect_create(struct mie_ctx *ctx);
|
||||
|
||||
#endif
|
||||
11
mie/include/mie/dialect/scf.h
Normal file
11
mie/include/mie/dialect/scf.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef MIE_DIALECT_SCF_H_
|
||||
#define MIE_DIALECT_SCF_H_
|
||||
|
||||
#include <mie/misc.h>
|
||||
|
||||
struct mie_ctx;
|
||||
struct mie_dialect;
|
||||
|
||||
MIE_API struct mie_dialect *mie_scf_dialect_create(struct mie_ctx *ctx);
|
||||
|
||||
#endif
|
||||
11
mie/include/mie/dialect/select.h
Normal file
11
mie/include/mie/dialect/select.h
Normal 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
|
||||
112
mie/include/mie/id.h
Normal file
112
mie/include/mie/id.h
Normal file
@@ -0,0 +1,112 @@
|
||||
#ifndef MIE_ID_H_
|
||||
#define MIE_ID_H_
|
||||
|
||||
#include <blue/core/btree.h>
|
||||
#include <blue/core/queue.h>
|
||||
#include <blue/core/rope.h>
|
||||
#include <mie/misc.h>
|
||||
#include <mie/status.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define MIE_ID(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) \
|
||||
{ \
|
||||
.id_bytes = {a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p}, \
|
||||
}
|
||||
#define MIE_ID_ZERO ((mie_id) {0})
|
||||
|
||||
#define MIE_ID_STRING_MAX 37
|
||||
|
||||
#define MIE_ID_NR_BYTES 16
|
||||
#define MIE_ID_NR_WORDS (MIE_ID_NR_BYTES / sizeof(uintptr_t))
|
||||
#define MIE_ID_NR_WORDS_16 (MIE_ID_NR_BYTES / sizeof(uint16_t))
|
||||
#define MIE_ID_NR_WORDS_32 (MIE_ID_NR_BYTES / sizeof(uint32_t))
|
||||
#define MIE_ID_NR_WORDS_64 (MIE_ID_NR_BYTES / sizeof(uint64_t))
|
||||
|
||||
enum mie_id_builder_marker {
|
||||
MIE_ID_BUILDER_STORAGE_START = 0x32,
|
||||
MIE_ID_BUILDER_STORAGE_END = 0x8a,
|
||||
MIE_ID_BUILDER_FUNCTION_IN_START = 0x78,
|
||||
MIE_ID_BUILDER_FUNCTION_IN_END = 0x55,
|
||||
MIE_ID_BUILDER_FUNCTION_OUT_START = 0xa2,
|
||||
MIE_ID_BUILDER_FUNCTION_OUT_END = 0xbc,
|
||||
};
|
||||
|
||||
typedef struct mie_id {
|
||||
union {
|
||||
uint8_t id_bytes[MIE_ID_NR_BYTES];
|
||||
uintptr_t id_words[MIE_ID_NR_WORDS];
|
||||
uint16_t id_words_16[MIE_ID_NR_WORDS_16];
|
||||
uint32_t id_words_32[MIE_ID_NR_WORDS_32];
|
||||
uint64_t id_words_64[MIE_ID_NR_WORDS_64];
|
||||
};
|
||||
|
||||
union {
|
||||
b_btree_node e_node;
|
||||
b_queue_entry e_entry;
|
||||
};
|
||||
} mie_id;
|
||||
|
||||
struct mie_id_builder {
|
||||
b_hash_ctx b_hash;
|
||||
};
|
||||
|
||||
struct mie_id_map {
|
||||
mie_id map_ns_id;
|
||||
b_btree map_entries;
|
||||
};
|
||||
|
||||
struct mie_id_map_iterator {
|
||||
mie_id *it_id;
|
||||
b_btree_node *_n;
|
||||
};
|
||||
|
||||
MIE_API void mie_id_init(
|
||||
mie_id *out, uint32_t a, uint16_t b, uint16_t c, uint16_t d, uint64_t e);
|
||||
MIE_API void mie_id_init_zero(mie_id *out);
|
||||
MIE_API void mie_id_init_random(mie_id *out);
|
||||
MIE_API void mie_id_init_ns(mie_id *out, const mie_id *ns, const b_rope *name);
|
||||
|
||||
static inline int mie_id_compare(const mie_id *a, const mie_id *b)
|
||||
{
|
||||
return memcmp(a->id_bytes, b->id_bytes, sizeof a->id_bytes);
|
||||
}
|
||||
|
||||
MIE_API void mie_id_to_string(const mie_id *id, char *out, size_t max);
|
||||
|
||||
MIE_API void mie_id_builder_begin(struct mie_id_builder *builder, const mie_id *ns);
|
||||
MIE_API void mie_id_builder_add(
|
||||
struct mie_id_builder *builder, const void *p, size_t len);
|
||||
static inline void mie_id_builder_add_char(struct mie_id_builder *builder, char c)
|
||||
{
|
||||
mie_id_builder_add(builder, &c, 1);
|
||||
}
|
||||
static inline void mie_id_builder_add_cstr(
|
||||
struct mie_id_builder *builder, const char *s)
|
||||
{
|
||||
mie_id_builder_add(builder, s, strlen(s));
|
||||
}
|
||||
MIE_API void mie_id_builder_add_rope(
|
||||
struct mie_id_builder *builder, const b_rope *rope);
|
||||
MIE_API void mie_id_builder_add_marker(
|
||||
struct mie_id_builder *builder, enum mie_id_builder_marker marker);
|
||||
MIE_API void mie_id_builder_end(struct mie_id_builder *builder, mie_id *out);
|
||||
|
||||
MIE_API void mie_id_map_init(struct mie_id_map *map, const mie_id *ns);
|
||||
static inline bool mie_id_map_empty(const struct mie_id_map *map)
|
||||
{
|
||||
return b_btree_empty(&map->map_entries);
|
||||
}
|
||||
|
||||
MIE_API const mie_id *mie_id_map_get_ns(const struct mie_id_map *map);
|
||||
MIE_API void mie_id_map_put(
|
||||
struct mie_id_map *map, mie_id *node, const b_rope *name);
|
||||
MIE_API void mie_id_map_put_id(struct mie_id_map *map, mie_id *node);
|
||||
MIE_API mie_id *mie_id_map_get(const struct mie_id_map *map, mie_id *id);
|
||||
|
||||
MIE_API enum mie_status mie_id_map_iterator_begin(
|
||||
struct mie_id_map_iterator *it, const struct mie_id_map *map);
|
||||
MIE_API enum mie_status mie_id_map_iterator_move_next(
|
||||
struct mie_id_map_iterator *it);
|
||||
|
||||
#endif
|
||||
@@ -1,12 +0,0 @@
|
||||
#ifndef MIE_ALLOCA_H_
|
||||
#define MIE_ALLOCA_H_
|
||||
|
||||
#include <mie/ir/instr.h>
|
||||
#include <mie/type.h>
|
||||
|
||||
struct mie_alloca {
|
||||
struct mie_instr a_base;
|
||||
struct mie_type *a_type;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,15 +0,0 @@
|
||||
#ifndef MIE_ARG_H_
|
||||
#define MIE_ARG_H_
|
||||
|
||||
#include <mie/ir/value.h>
|
||||
|
||||
#define MIE_ARG(p) ((struct mie_arg *)(p))
|
||||
|
||||
struct mie_arg {
|
||||
struct mie_value arg_base;
|
||||
struct mie_type *arg_type;
|
||||
};
|
||||
|
||||
extern struct mie_arg *mie_arg_create(struct mie_type *type);
|
||||
|
||||
#endif
|
||||
@@ -1,30 +1,21 @@
|
||||
#ifndef MIE_BLOCK_H_
|
||||
#define MIE_BLOCK_H_
|
||||
#ifndef MIE_IR_BLOCK_H_
|
||||
#define MIE_IR_BLOCK_H_
|
||||
|
||||
#define MIE_BLOCK(p) ((struct mie_block *)(p))
|
||||
#include <blue/core/queue.h>
|
||||
#include <mie/misc.h>
|
||||
#include <mie/name.h>
|
||||
#include <mie/vector.h>
|
||||
|
||||
#include <mie/ir/value.h>
|
||||
struct mie_op;
|
||||
struct mie_register;
|
||||
|
||||
struct mie_block {
|
||||
struct mie_value b_base;
|
||||
struct mie_func *b_parent;
|
||||
/* the phi instruction(s). these must appear at the start of the block
|
||||
* and are separated to make traversing the CFG easier */
|
||||
b_queue b_phi;
|
||||
/* the rest of the instructions in the block */
|
||||
b_queue b_instr;
|
||||
/* the instruction that transfers control to the next block,
|
||||
* could be a switch, branch, or ret */
|
||||
struct mie_instr *b_terminator;
|
||||
struct mie_name b_name;
|
||||
|
||||
MIE_VECTOR_DECLARE(struct mie_register, b_params);
|
||||
MIE_VECTOR_DECLARE(struct mie_op, b_ops);
|
||||
};
|
||||
|
||||
MIE_API struct mie_block *mie_block_create(
|
||||
struct mie_func *parent, const char *name);
|
||||
MIE_API bool mie_block_add_instr(struct mie_block *block, struct mie_instr *instr);
|
||||
|
||||
static inline bool mie_block_is_terminated(const struct mie_block *block)
|
||||
{
|
||||
return block->b_terminator != NULL;
|
||||
}
|
||||
MIE_API struct mie_op *mie_block_add_op(struct mie_block *block);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
#ifndef MIE_BRANCH_H_
|
||||
#define MIE_BRANCH_H_
|
||||
|
||||
#include <mie/ir/const.h>
|
||||
#include <mie/ir/instr.h>
|
||||
|
||||
struct mie_branch {
|
||||
struct mie_instr b_base;
|
||||
struct mie_block *b_dest;
|
||||
};
|
||||
|
||||
struct mie_branch_if {
|
||||
struct mie_instr b_base;
|
||||
struct mie_value *b_cond;
|
||||
struct mie_block *b_true_block;
|
||||
struct mie_block *b_false_block;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,119 +0,0 @@
|
||||
#ifndef MIE_BUILDER_H_
|
||||
#define MIE_BUILDER_H_
|
||||
|
||||
#include <blue/core/btree.h>
|
||||
#include <mie/ir/switch.h>
|
||||
#include <mie/ir/value.h>
|
||||
#include <mie/misc.h>
|
||||
#include <mie/type.h>
|
||||
|
||||
struct b_hashmap;
|
||||
|
||||
struct mie_block;
|
||||
struct mie_module;
|
||||
struct mie_data;
|
||||
struct mie_type;
|
||||
struct mie_phi;
|
||||
struct mie_phi_edge;
|
||||
struct mie_ctx;
|
||||
|
||||
struct mie_builder {
|
||||
struct mie_ctx *b_ctx;
|
||||
struct mie_module *b_module;
|
||||
struct mie_block *b_current_block;
|
||||
struct mie_instr *b_prev_instr;
|
||||
};
|
||||
|
||||
enum mie_builder_flags {
|
||||
MIE_BUILDER_IGNORE_RESULT = 0x01u,
|
||||
};
|
||||
|
||||
extern struct mie_builder *mie_builder_create(
|
||||
struct mie_ctx *ctx, struct mie_module *mod);
|
||||
extern void mie_builder_destroy(struct mie_builder *builder);
|
||||
|
||||
extern struct mie_func *mie_builder_get_current_func(struct mie_builder *builder);
|
||||
static inline struct mie_block *mie_builder_get_current_block(
|
||||
struct mie_builder *builder)
|
||||
{
|
||||
return builder->b_current_block;
|
||||
}
|
||||
|
||||
extern struct mie_record *mie_builder_put_record(
|
||||
struct mie_builder *builder, struct mie_const *val, const char *name);
|
||||
extern struct mie_record *mie_builder_get_record(
|
||||
struct mie_builder *builder, const char *name);
|
||||
extern void mie_builder_put_data(struct mie_builder *builder, struct mie_data *data);
|
||||
extern void mie_builder_put_type(struct mie_builder *builder, struct mie_type *type);
|
||||
extern void mie_builder_set_insert_point(
|
||||
struct mie_builder *builder, struct mie_block *block);
|
||||
|
||||
extern struct mie_value *mie_builder_get_data_ptr(
|
||||
struct mie_builder *builder, const char *data_ident);
|
||||
extern struct mie_value *mie_builder_get_string_ptr(
|
||||
struct mie_builder *builder, const char *s);
|
||||
|
||||
extern struct mie_value *mie_builder_ret(
|
||||
struct mie_builder *builder, struct mie_value *val);
|
||||
extern struct mie_value *mie_builder_add(
|
||||
struct mie_builder *builder, struct mie_value *left,
|
||||
struct mie_value *right, const char *name);
|
||||
extern struct mie_value *mie_builder_sub(
|
||||
struct mie_builder *builder, struct mie_value *left,
|
||||
struct mie_value *right, const char *name);
|
||||
extern struct mie_value *mie_builder_mul(
|
||||
struct mie_builder *builder, struct mie_value *left,
|
||||
struct mie_value *right, const char *name);
|
||||
extern struct mie_value *mie_builder_div(
|
||||
struct mie_builder *builder, struct mie_value *left,
|
||||
struct mie_value *right, const char *name);
|
||||
extern struct mie_value *mie_builder_load(
|
||||
struct mie_builder *builder, struct mie_type *type,
|
||||
struct mie_value *src, const char *name);
|
||||
extern struct mie_value *mie_builder_store(
|
||||
struct mie_builder *builder, struct mie_value *val, struct mie_value *dest);
|
||||
extern struct mie_value *mie_builder_alloca(
|
||||
struct mie_builder *builder, struct mie_type *type, const char *name);
|
||||
extern struct mie_value *mie_builder_switch(
|
||||
struct mie_builder *builder, struct mie_value *cond,
|
||||
struct mie_switch_branch *branches, size_t nr_branches,
|
||||
struct mie_block *default_block);
|
||||
extern struct mie_value *mie_builder_br(
|
||||
struct mie_builder *builder, struct mie_block *dest);
|
||||
extern struct mie_value *mie_builder_br_if(
|
||||
struct mie_builder *builder, struct mie_value *cond,
|
||||
struct mie_block *if_true, struct mie_block *if_false);
|
||||
extern struct mie_value *mie_builder_msg(
|
||||
struct mie_builder *builder, struct mie_type *ret_type,
|
||||
struct mie_value *recipient, struct mie_value *selector,
|
||||
struct mie_value **args, size_t nr_args, enum mie_builder_flags flags,
|
||||
const char *name);
|
||||
extern struct mie_value *mie_builder_cmp_eq(
|
||||
struct mie_builder *builder, struct mie_value *left,
|
||||
struct mie_value *right, const char *name);
|
||||
extern struct mie_value *mie_builder_cmp_neq(
|
||||
struct mie_builder *builder, struct mie_value *left,
|
||||
struct mie_value *right, const char *name);
|
||||
extern struct mie_value *mie_builder_cmp_lt(
|
||||
struct mie_builder *builder, struct mie_value *left,
|
||||
struct mie_value *right, const char *name);
|
||||
extern struct mie_value *mie_builder_cmp_gt(
|
||||
struct mie_builder *builder, struct mie_value *left,
|
||||
struct mie_value *right, const char *name);
|
||||
extern struct mie_value *mie_builder_cmp_leq(
|
||||
struct mie_builder *builder, struct mie_value *left,
|
||||
struct mie_value *right, const char *name);
|
||||
extern struct mie_value *mie_builder_cmp_geq(
|
||||
struct mie_builder *builder, struct mie_value *left,
|
||||
struct mie_value *right, const char *name);
|
||||
extern struct mie_value *mie_builder_getelementptr(
|
||||
struct mie_builder *builder, struct mie_type *container_type,
|
||||
struct mie_value *container, struct mie_value *index, const char *name);
|
||||
extern struct mie_value *mie_builder_setelementptr(
|
||||
struct mie_builder *builder, struct mie_type *container_type,
|
||||
struct mie_value *container, struct mie_value *index);
|
||||
extern struct mie_value *mie_builder_phi(
|
||||
struct mie_builder *builder, struct mie_type *type,
|
||||
struct mie_phi_edge *edges, unsigned int nr_edges, const char *name);
|
||||
|
||||
#endif
|
||||
@@ -1,65 +0,0 @@
|
||||
#ifndef MIE_CONST_H_
|
||||
#define MIE_CONST_H_
|
||||
|
||||
#include <blue/ds/list.h>
|
||||
#include <mie/ir/value.h>
|
||||
#include <mie/type.h>
|
||||
|
||||
#define MIE_CONST(p) ((struct mie_const *)(p))
|
||||
|
||||
#define MIE_INT(p) ((struct mie_int *)(p))
|
||||
#define MIE_DOUBLE(p) ((struct mie_double *)(p))
|
||||
#define MIE_STRING(p) ((struct mie_string *)(p))
|
||||
#define MIE_ATOM(p) ((struct mie_atom *)(p))
|
||||
#define MIE_SELECTOR(p) ((struct mie_selector *)(p))
|
||||
#define MIE_ARRAY(p) ((struct mie_array *)(p))
|
||||
|
||||
struct mie_const {
|
||||
struct mie_value c_base;
|
||||
struct mie_type *c_type;
|
||||
};
|
||||
|
||||
struct mie_int {
|
||||
struct mie_const i_base;
|
||||
int64_t i_value;
|
||||
};
|
||||
|
||||
struct mie_double {
|
||||
struct mie_const d_base;
|
||||
double d_value;
|
||||
};
|
||||
|
||||
struct mie_string {
|
||||
struct mie_const s_base;
|
||||
char *s_value;
|
||||
};
|
||||
|
||||
struct mie_atom {
|
||||
struct mie_const a_base;
|
||||
char *a_value;
|
||||
};
|
||||
|
||||
struct mie_selector {
|
||||
struct mie_const sel_base;
|
||||
char *sel_value;
|
||||
};
|
||||
|
||||
struct mie_array {
|
||||
struct mie_const a_base;
|
||||
b_list *a_values;
|
||||
};
|
||||
|
||||
extern void mie_const_init(struct mie_const *c, struct mie_type *type);
|
||||
|
||||
static inline bool mie_value_is_selector(const struct mie_value *v)
|
||||
{
|
||||
if (v->v_type->t_id != MIE_VALUE_CONST) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const struct mie_const *c = MIE_CONST(v);
|
||||
|
||||
return c->c_type->t_id == MIE_TYPE_SELECTOR;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,82 +0,0 @@
|
||||
#ifndef MIE_CONVERT_H_
|
||||
#define MIE_CONVERT_H_
|
||||
|
||||
#include <blue/core/stringstream.h>
|
||||
#include <blue/ds/bitbuffer.h>
|
||||
#include <blue/ds/string.h>
|
||||
#include <mie/misc.h>
|
||||
#include <stdio.h>
|
||||
|
||||
struct mie_value;
|
||||
struct mie_ctx;
|
||||
|
||||
enum mie_ir_format {
|
||||
MIE_IR_NONE = 0,
|
||||
MIE_IR_MEM,
|
||||
MIE_IR_BITCODE,
|
||||
MIE_IR_TEXT,
|
||||
};
|
||||
|
||||
enum mie_ir_converter_medium {
|
||||
MIE_IR_CONVERTER_NONE = 0,
|
||||
MIE_IR_CONVERTER_MIE_VALUE,
|
||||
MIE_IR_CONVERTER_BITSTREAM,
|
||||
MIE_IR_CONVERTER_BITBUFFER,
|
||||
MIE_IR_CONVERTER_STRINGSTREAM,
|
||||
MIE_IR_CONVERTER_STRING,
|
||||
MIE_IR_CONVERTER_FILE,
|
||||
};
|
||||
|
||||
struct mie_ir_converter {
|
||||
struct mie_ctx *c_ctx;
|
||||
enum mie_ir_format c_src_format, c_dest_format;
|
||||
enum mie_ir_converter_medium c_src_medium, c_dest_medium;
|
||||
|
||||
union {
|
||||
/* TODO bitstream */
|
||||
struct mie_value *value;
|
||||
b_bitbuffer *bitbuffer;
|
||||
b_stringstream *stringstream;
|
||||
b_string *string;
|
||||
FILE *file;
|
||||
} c_src;
|
||||
|
||||
union {
|
||||
/* TODO bitstream */
|
||||
struct mie_value **value;
|
||||
b_bitbuffer *bitbuffer;
|
||||
b_stringstream *stringstream;
|
||||
b_string *string;
|
||||
FILE *file;
|
||||
} c_dest;
|
||||
};
|
||||
|
||||
MIE_API struct mie_ir_converter *mie_ir_converter_create(
|
||||
struct mie_ctx *ctx, enum mie_ir_format src, enum mie_ir_format dest);
|
||||
MIE_API void mie_ir_converter_destroy(struct mie_ir_converter *converter);
|
||||
|
||||
MIE_API b_status mie_ir_converter_set_src_value(
|
||||
struct mie_ir_converter *converter, struct mie_value *value);
|
||||
MIE_API b_status mie_ir_converter_set_src_bitbuffer(
|
||||
struct mie_ir_converter *converter, b_bitbuffer *bitbuffer);
|
||||
MIE_API b_status mie_ir_converter_set_src_stringstream(
|
||||
struct mie_ir_converter *converter, b_stringstream *stringstream);
|
||||
MIE_API b_status mie_ir_converter_set_src_string(
|
||||
struct mie_ir_converter *converter, b_string *string);
|
||||
MIE_API b_status mie_ir_converter_set_src_file(
|
||||
struct mie_ir_converter *converter, FILE *file);
|
||||
|
||||
MIE_API b_status mie_ir_converter_set_dest_value(
|
||||
struct mie_ir_converter *converter, struct mie_value **value);
|
||||
MIE_API b_status mie_ir_converter_set_dest_bitbuffer(
|
||||
struct mie_ir_converter *converter, b_bitbuffer *bitbuffer);
|
||||
MIE_API b_status mie_ir_converter_set_dest_stringstream(
|
||||
struct mie_ir_converter *converter, b_stringstream *stringstream);
|
||||
MIE_API b_status mie_ir_converter_set_dest_string(
|
||||
struct mie_ir_converter *converter, b_string *string);
|
||||
MIE_API b_status mie_ir_converter_set_dest_file(
|
||||
struct mie_ir_converter *converter, FILE *file);
|
||||
|
||||
MIE_API b_status mie_ir_converter_process(struct mie_ir_converter *converter);
|
||||
|
||||
#endif
|
||||
@@ -1,32 +0,0 @@
|
||||
#ifndef MIE_DATA_H_
|
||||
#define MIE_DATA_H_
|
||||
|
||||
#include <mie/ir/value.h>
|
||||
|
||||
#define MIE_DATA(p) ((struct mie_data *)(p))
|
||||
|
||||
enum mie_data_type {
|
||||
MIE_DATA_NONE = 0,
|
||||
MIE_DATA_EXTERN_GLOBAL,
|
||||
MIE_DATA_CONST,
|
||||
};
|
||||
|
||||
struct mie_data {
|
||||
struct mie_value d_base;
|
||||
enum mie_data_type d_type;
|
||||
union {
|
||||
struct {
|
||||
struct mie_const *c_value;
|
||||
} d_const;
|
||||
|
||||
struct {
|
||||
struct mie_type *g_type;
|
||||
} d_extern_global;
|
||||
};
|
||||
};
|
||||
|
||||
extern struct mie_data *mie_data_create_extern_global(
|
||||
struct mie_type *type, const char *ident);
|
||||
extern struct mie_data *mie_data_create_const(struct mie_const *value);
|
||||
|
||||
#endif
|
||||
@@ -1,47 +0,0 @@
|
||||
#ifndef MIE_FUNC_H_
|
||||
#define MIE_FUNC_H_
|
||||
|
||||
#define MIE_FUNC(p) ((struct mie_func *)(p))
|
||||
|
||||
#include <mie/ir/value.h>
|
||||
|
||||
struct mie_name_map;
|
||||
struct mie_type;
|
||||
struct mie_arg;
|
||||
struct mie_block;
|
||||
struct b_dict;
|
||||
|
||||
enum mie_func_type {
|
||||
MIE_FUNC_NONE = 0x00u,
|
||||
MIE_FUNC_STATIC = 0x01u,
|
||||
MIE_FUNC_INSTANCE = 0x02u,
|
||||
MIE_FUNC_LAMBDA = 0x03u,
|
||||
};
|
||||
|
||||
struct mie_func {
|
||||
struct mie_value f_base;
|
||||
|
||||
enum mie_func_type f_type;
|
||||
struct mie_type *f_ret;
|
||||
|
||||
struct mie_name_map *f_names;
|
||||
|
||||
b_queue f_args;
|
||||
b_queue f_blocks;
|
||||
};
|
||||
|
||||
extern struct mie_func *mie_func_create(
|
||||
enum mie_func_type type, struct mie_type *ret_type);
|
||||
extern struct mie_value *mie_func_add_arg(
|
||||
struct mie_func *func, struct mie_type *type, const char *name);
|
||||
extern struct mie_block *mie_func_create_block(
|
||||
struct mie_func *func, const char *name);
|
||||
extern void mie_func_insert_block(
|
||||
struct mie_func *func, struct mie_block *block, struct mie_block *after);
|
||||
extern struct mie_value *mie_func_generate_value_name(
|
||||
struct mie_func *func, struct mie_value *val, const char *hint);
|
||||
|
||||
extern struct mie_block *mie_func_get_first_block(struct mie_func *func);
|
||||
extern struct mie_block *mie_func_get_last_block(struct mie_func *func);
|
||||
|
||||
#endif
|
||||
@@ -1,45 +0,0 @@
|
||||
#ifndef MIE_INSTR_H_
|
||||
#define MIE_INSTR_H_
|
||||
|
||||
#include <mie/ir/value.h>
|
||||
|
||||
#define MIE_INSTR(p) ((struct mie_instr *)(p))
|
||||
|
||||
enum mie_instr_type {
|
||||
MIE_INSTR_NONE = 0,
|
||||
MIE_INSTR_RET,
|
||||
MIE_INSTR_ADD,
|
||||
MIE_INSTR_SUB,
|
||||
MIE_INSTR_MUL,
|
||||
MIE_INSTR_DIV,
|
||||
MIE_INSTR_LOAD,
|
||||
MIE_INSTR_STORE,
|
||||
MIE_INSTR_ALLOCA,
|
||||
MIE_INSTR_SWITCH,
|
||||
MIE_INSTR_BR,
|
||||
MIE_INSTR_BR_IF,
|
||||
MIE_INSTR_MSG,
|
||||
MIE_INSTR_CMP_EQ,
|
||||
MIE_INSTR_CMP_NEQ,
|
||||
MIE_INSTR_CMP_LT,
|
||||
MIE_INSTR_CMP_GT,
|
||||
MIE_INSTR_CMP_LEQ,
|
||||
MIE_INSTR_CMP_GEQ,
|
||||
MIE_INSTR_GETELEMENTPTR,
|
||||
MIE_INSTR_SETELEMENTPTR,
|
||||
MIE_INSTR_PHI,
|
||||
};
|
||||
|
||||
struct mie_instr {
|
||||
struct mie_value i_base;
|
||||
enum mie_instr_type i_type;
|
||||
};
|
||||
|
||||
struct mie_ret {
|
||||
struct mie_instr r_base;
|
||||
struct mie_value *r_val;
|
||||
};
|
||||
|
||||
extern void mie_instr_init(struct mie_instr *instr, enum mie_instr_type type);
|
||||
|
||||
#endif
|
||||
@@ -1,37 +1,21 @@
|
||||
#ifndef MIE_MODULE_H_
|
||||
#define MIE_MODULE_H_
|
||||
#ifndef MIE_IR_MODULE_H_
|
||||
#define MIE_IR_MODULE_H_
|
||||
|
||||
#define MIE_MODULE(p) ((struct mie_module *)(p))
|
||||
|
||||
#include <blue/core/queue.h>
|
||||
#include <blue/ds/hashmap.h>
|
||||
#include <mie/ir/value.h>
|
||||
#include <mie/misc.h>
|
||||
#include <mie/name.h>
|
||||
#include <mie/vector.h>
|
||||
#include <stddef.h>
|
||||
|
||||
struct mie_func;
|
||||
struct mie_op;
|
||||
|
||||
struct mie_module {
|
||||
struct mie_value m_base;
|
||||
struct mie_name_map *m_names;
|
||||
b_queue m_records;
|
||||
b_queue m_types;
|
||||
b_queue m_func;
|
||||
|
||||
b_hashmap *m_data;
|
||||
b_hashmap *m_data_strings;
|
||||
MIE_VECTOR_DECLARE(struct mie_op, m_ops);
|
||||
};
|
||||
|
||||
extern struct mie_module *mie_module_create(void);
|
||||
extern void mie_module_add_function(
|
||||
struct mie_module *mod, struct mie_func *func, const char *name);
|
||||
extern struct mie_data *mie_module_get_string_ptr(
|
||||
struct mie_module *mod, const char *s);
|
||||
extern struct mie_data *mie_module_get_data(
|
||||
struct mie_module *mod, const char *name);
|
||||
extern enum b_status mie_module_put_data(
|
||||
struct mie_module *mod, struct mie_data *data, const char *name);
|
||||
MIE_API struct mie_module *mie_module_create(void);
|
||||
MIE_API void mie_module_destroy(struct mie_module *mod);
|
||||
|
||||
extern struct mie_value *mie_module_generate_value_name(
|
||||
struct mie_module *mod, struct mie_value *val, const char *hint);
|
||||
MIE_API struct mie_op *mie_module_add_op(struct mie_module *mod);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
#ifndef MIE_MSG_H_
|
||||
#define MIE_MSG_H_
|
||||
|
||||
#include <mie/ir/instr.h>
|
||||
#include <mie/type.h>
|
||||
|
||||
#define MIE_MSG(p) ((struct mie_msg *)(p))
|
||||
|
||||
struct mie_msg {
|
||||
struct mie_instr msg_base;
|
||||
struct mie_type *msg_ret_type;
|
||||
struct mie_value *msg_recipient;
|
||||
struct mie_value *msg_selector;
|
||||
size_t msg_nr_args;
|
||||
struct mie_value **msg_args;
|
||||
};
|
||||
|
||||
#endif
|
||||
112
mie/include/mie/ir/op-definition.h
Normal file
112
mie/include/mie/ir/op-definition.h
Normal file
@@ -0,0 +1,112 @@
|
||||
#ifndef MIE_IR_OP_DEFINITION_H_
|
||||
#define MIE_IR_OP_DEFINITION_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>
|
||||
|
||||
#define MIE_OP_MAX_PARAMS 8
|
||||
#define MIE_OP_MAX_RESULTS 8
|
||||
|
||||
struct mie_op;
|
||||
struct mie_parser;
|
||||
struct mie_dialect;
|
||||
|
||||
#if 0
|
||||
enum mie_op_trait {
|
||||
MIE_OP_TRAIT_NONE = 0x00u,
|
||||
|
||||
/* this is a graph 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_OP_TRAIT_GRAPH_ONLY = 0x01u,
|
||||
|
||||
/* this is a non-graph op. this op cannot be used within graph regions */
|
||||
MIE_OP_TRAIT_NO_GRAPH = 0x02u,
|
||||
|
||||
/* 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_OP_TRAIT_GRAPH_SCOPE = 0x04u,
|
||||
|
||||
/* regions of an op that has this trait cannot capture or reference
|
||||
* values defined in the enclosing scope. */
|
||||
MIE_OP_TRAIT_ISOLATED_FROM_ABOVE = 0x08u,
|
||||
};
|
||||
#endif
|
||||
|
||||
enum mie_op_param_type {
|
||||
/* op has no parameter */
|
||||
MIE_OP_PARTYPE_NONE = 0,
|
||||
/* op has a parameter of any type. */
|
||||
MIE_OP_PARTYPE_ANY,
|
||||
/* op has a parameter of a fixed, named type. */
|
||||
MIE_OP_PARTYPE_TYPE_NAME,
|
||||
/* op has a parameter whose type matches the type of an attribute value */
|
||||
MIE_OP_PARTYPE_ATTRIB_VAL,
|
||||
};
|
||||
|
||||
enum mie_op_result_type {
|
||||
/* op has no result */
|
||||
MIE_OP_RESTYPE_NONE = 0,
|
||||
/* op has a result of any type. */
|
||||
MIE_OP_RESTYPE_ANY,
|
||||
/* op has a result of a fixed, named type. */
|
||||
MIE_OP_RESTYPE_TYPE_NAME,
|
||||
/* op has a result whose type matches the type of an input parameter */
|
||||
MIE_OP_RESTYPE_IN_VAL,
|
||||
/* op has a result whose type matches the type of an attribute value */
|
||||
MIE_OP_RESTYPE_ATTRIB_VAL,
|
||||
};
|
||||
|
||||
struct mie_op_param {
|
||||
enum mie_op_param_type param_type;
|
||||
|
||||
union {
|
||||
struct {
|
||||
const char *t_dialect;
|
||||
/* this can be NULL, in which case any type from the
|
||||
* dialect named in t_dialect will be accepted. */
|
||||
const char *t_name;
|
||||
} param_type_name;
|
||||
|
||||
const char *param_attrib;
|
||||
};
|
||||
};
|
||||
|
||||
struct mie_op_result {
|
||||
enum mie_op_result_type r_type;
|
||||
|
||||
union {
|
||||
struct {
|
||||
const char *t_dialect;
|
||||
const char *t_name;
|
||||
} r_type_name;
|
||||
|
||||
unsigned int r_in_index;
|
||||
const char *r_attrib;
|
||||
};
|
||||
};
|
||||
|
||||
struct mie_op_definition {
|
||||
mie_id op_id;
|
||||
struct mie_dialect *op_parent;
|
||||
char *op_name;
|
||||
|
||||
struct mie_trait_table op_traits;
|
||||
const struct mie_op_param op_params[MIE_OP_MAX_PARAMS];
|
||||
const struct mie_op_result op_results[MIE_OP_MAX_RESULTS];
|
||||
|
||||
enum mie_status (*op_print)(const struct mie_op *, b_stream *);
|
||||
enum mie_status (*op_parse)(struct mie_parser *, struct mie_op *);
|
||||
};
|
||||
|
||||
MIE_API struct mie_op_definition *mie_op_definition_create(
|
||||
struct mie_dialect *parent, const char *name);
|
||||
|
||||
MIE_API enum mie_status mie_op_definition_add_trait(
|
||||
struct mie_op_definition *op, const struct mie_trait *trait);
|
||||
|
||||
#endif
|
||||
@@ -1,13 +1,78 @@
|
||||
#ifndef MIE_ARITH_H_
|
||||
#define MIE_ARITH_H_
|
||||
#ifndef MIE_IR_OP_H_
|
||||
#define MIE_IR_OP_H_
|
||||
|
||||
#include <mie/ir/instr.h>
|
||||
#include "mie/vector.h"
|
||||
|
||||
struct mie_binary_op {
|
||||
struct mie_instr op_base;
|
||||
struct mie_type *op_type;
|
||||
struct mie_value *op_left;
|
||||
struct mie_value *op_right;
|
||||
#include <mie/ir/register.h>
|
||||
#include <mie/misc.h>
|
||||
#include <mie/name.h>
|
||||
#include <mie/parse/file-span.h>
|
||||
|
||||
struct mie_type;
|
||||
|
||||
struct mie_value;
|
||||
struct mie_block;
|
||||
struct mie_region;
|
||||
|
||||
struct mie_dialect;
|
||||
struct mie_op_definition;
|
||||
|
||||
enum mie_op_flags {
|
||||
MIE_OP_F_OP_RESOLVED = 0x01u,
|
||||
MIE_OP_F_ARG_RESOLVED = 0x02u,
|
||||
MIE_OP_F_SUCCESSOR_RESOLVED = 0x04u,
|
||||
};
|
||||
|
||||
struct mie_op_attribute {
|
||||
char *attrib_name;
|
||||
struct mie_value *attrib_value;
|
||||
};
|
||||
|
||||
struct mie_op_arg {
|
||||
enum mie_op_flags arg_flags;
|
||||
struct mie_file_span arg_span;
|
||||
union {
|
||||
/* only valid if F_ARG_RESOLVED is set in arg_flags */
|
||||
struct mie_register *arg_value;
|
||||
/* only valid if F_ARG_RESOLVED is NOT set in arg_flags */
|
||||
struct mie_register_ref arg_unresolved;
|
||||
};
|
||||
};
|
||||
|
||||
struct mie_op_successor {
|
||||
enum mie_op_flags s_flags;
|
||||
|
||||
union {
|
||||
/* only valid if F_SUCCESSOR_RESOLVED is set in s_flags; */
|
||||
struct mie_block *s_block;
|
||||
/* only valid if F_SUCCESSOR_RESOLVED is NOT set in s_flags; */
|
||||
char *s_block_name;
|
||||
};
|
||||
|
||||
MIE_VECTOR_DECLARE(struct mie_op_arg, s_args);
|
||||
};
|
||||
|
||||
struct mie_op {
|
||||
enum mie_op_flags op_flags;
|
||||
|
||||
/* these pointers are only valid if the F_OP_RESOLVED flag is set */
|
||||
const struct mie_dialect *op_dialect;
|
||||
const struct mie_op_definition *op_info;
|
||||
|
||||
struct mie_file_span op_name_span;
|
||||
/* only valid if the F_RESOLVED flag is NOT set */
|
||||
char *op_name;
|
||||
|
||||
MIE_VECTOR_DECLARE(struct mie_region, op_regions);
|
||||
MIE_VECTOR_DECLARE(struct mie_op_successor, op_successors);
|
||||
MIE_VECTOR_DECLARE(struct mie_op_attribute, op_attrib);
|
||||
MIE_VECTOR_DECLARE(struct mie_op_arg, op_args);
|
||||
MIE_VECTOR_DECLARE(struct mie_register, op_result);
|
||||
};
|
||||
|
||||
MIE_API void mie_op_destroy(struct mie_op *op);
|
||||
|
||||
MIE_API struct mie_region *mie_op_add_region(struct mie_op *op);
|
||||
MIE_API struct mie_op_successor *mie_op_add_successor(struct mie_op *op);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
#ifndef MIE_PHI_H_
|
||||
#define MIE_PHI_H_
|
||||
|
||||
#include <blue/core/queue.h>
|
||||
#include <mie/ir/instr.h>
|
||||
#include <mie/misc.h>
|
||||
|
||||
struct mie_phi_edge {
|
||||
b_queue_entry e_entry;
|
||||
struct mie_block *e_incoming_block;
|
||||
struct mie_value *e_value;
|
||||
};
|
||||
|
||||
struct mie_phi {
|
||||
struct mie_instr p_base;
|
||||
struct mie_type *p_type;
|
||||
|
||||
unsigned int p_nr_edges;
|
||||
struct mie_phi_edge *p_edges;
|
||||
};
|
||||
|
||||
MIE_API struct mie_phi_edge *mie_phi_edge_create(
|
||||
struct mie_block *incoming_block, struct mie_value *value);
|
||||
|
||||
#endif
|
||||
@@ -1,33 +0,0 @@
|
||||
#ifndef MIE_PTR_H_
|
||||
#define MIE_PTR_H_
|
||||
|
||||
#include <mie/ir/instr.h>
|
||||
#include <mie/type.h>
|
||||
|
||||
struct mie_getelementptr {
|
||||
struct mie_instr gep_base;
|
||||
struct mie_type *gep_container_type;
|
||||
struct mie_value *gep_container;
|
||||
struct mie_value *gep_index;
|
||||
};
|
||||
|
||||
struct mie_setelementptr {
|
||||
struct mie_instr sep_base;
|
||||
struct mie_type *sep_container_type;
|
||||
struct mie_value *sep_container;
|
||||
struct mie_value *sep_index;
|
||||
};
|
||||
|
||||
struct mie_load {
|
||||
struct mie_instr l_base;
|
||||
struct mie_type *l_type;
|
||||
struct mie_value *l_src;
|
||||
};
|
||||
|
||||
struct mie_store {
|
||||
struct mie_instr s_base;
|
||||
struct mie_value *s_val;
|
||||
struct mie_value *s_dest;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,16 +0,0 @@
|
||||
#ifndef MIE_RECORD_H_
|
||||
#define MIE_RECORD_H_
|
||||
|
||||
#define MIE_RECORD(p) ((struct mie_record *)(p))
|
||||
|
||||
#include <mie/ir/const.h>
|
||||
#include <mie/ir/value.h>
|
||||
|
||||
struct mie_record {
|
||||
struct mie_value r_base;
|
||||
const struct mie_const *r_value;
|
||||
};
|
||||
|
||||
extern struct mie_record *mie_record_create(const struct mie_const *val);
|
||||
|
||||
#endif
|
||||
17
mie/include/mie/ir/region.h
Normal file
17
mie/include/mie/ir/region.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef MIE_IR_REGION_H_
|
||||
#define MIE_IR_REGION_H_
|
||||
|
||||
#include <mie/misc.h>
|
||||
#include <mie/vector.h>
|
||||
#include <stddef.h>
|
||||
|
||||
struct mie_block;
|
||||
|
||||
struct mie_region {
|
||||
struct mie_name_map *r_names;
|
||||
MIE_VECTOR_DECLARE(struct mie_block, r_blocks);
|
||||
};
|
||||
|
||||
MIE_API struct mie_block *mie_region_add_block(struct mie_region *region);
|
||||
|
||||
#endif
|
||||
51
mie/include/mie/ir/register.h
Normal file
51
mie/include/mie/ir/register.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#ifndef MIE_IR_REGISTER_H_
|
||||
#define MIE_IR_REGISTER_H_
|
||||
|
||||
#include <mie/name.h>
|
||||
|
||||
struct mie_target_register;
|
||||
|
||||
enum mie_register_flags {
|
||||
MIE_REGISTER_F_NONE = 0,
|
||||
MIE_REGISTER_F_OP_RESULT = 0x01u,
|
||||
MIE_REGISTER_F_OP_PARAM = 0x02u,
|
||||
MIE_REGISTER_F_BLOCK_PARAM = 0x04u,
|
||||
|
||||
/* only ONE of these two flags can be set at a time */
|
||||
MIE_REGISTER_F_VIRTUAL = 0x10u,
|
||||
MIE_REGISTER_F_MACHINE = 0x20u,
|
||||
};
|
||||
|
||||
/* represents a yet-to-be-resolved reference to a mie_register */
|
||||
struct mie_register_ref {
|
||||
enum mie_register_flags reg_flags;
|
||||
char *reg_name;
|
||||
/* what we THINK the type of the register is.
|
||||
* if this is set, it gets checked during the register resolution process. */
|
||||
const struct mie_type *reg_type;
|
||||
};
|
||||
|
||||
struct mie_register {
|
||||
enum mie_register_flags reg_flags;
|
||||
union {
|
||||
/* only valid if F_VIRTUAL is set. */
|
||||
struct mie_name reg_name;
|
||||
/* only valid if F_MACHINE is set. */
|
||||
struct mie_target_register *reg_mach;
|
||||
};
|
||||
const struct mie_type *reg_type;
|
||||
/* if this is an OP_RESULT register, this points to the block within
|
||||
* which this register is defined.
|
||||
* if this is an OP_PARAM register, this pointer is NULL.
|
||||
* if this is a BLOCK_PARAM register, this points to the block for
|
||||
* which this register is a parameter. */
|
||||
struct mie_block *reg_block;
|
||||
/* if this is an OP_RESULT register, this points to the operation
|
||||
* that defines the register.
|
||||
* if this is an OP_PARAM register, this points to the operation
|
||||
* for which this register is a parameter
|
||||
* if this is a BLOCK_PARAM register, this pointer is NULL */
|
||||
struct mie_op *reg_op;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,21 +0,0 @@
|
||||
#ifndef MIE_SWITCH_H_
|
||||
#define MIE_SWITCH_H_
|
||||
|
||||
#include <mie/ir/const.h>
|
||||
#include <mie/ir/instr.h>
|
||||
|
||||
struct mie_switch_branch {
|
||||
struct mie_value *b_value;
|
||||
struct mie_block *b_jump_to;
|
||||
};
|
||||
|
||||
struct mie_switch {
|
||||
struct mie_instr s_base;
|
||||
struct mie_value *s_src;
|
||||
struct mie_block *s_default;
|
||||
|
||||
size_t s_nr_branches;
|
||||
struct mie_switch_branch *s_branches;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,60 +0,0 @@
|
||||
#ifndef MIE_VALUE_H_
|
||||
#define MIE_VALUE_H_
|
||||
|
||||
#include <blue/core/queue.h>
|
||||
#include <mie/misc.h>
|
||||
#include <mie/name.h>
|
||||
|
||||
#define MIE_VALUE(p) ((struct mie_value *)(p))
|
||||
|
||||
struct mie_ctx;
|
||||
struct mie_value;
|
||||
|
||||
enum mie_value_type_id {
|
||||
MIE_VALUE_NONE = 0,
|
||||
MIE_VALUE_MODULE,
|
||||
MIE_VALUE_TYPE,
|
||||
MIE_VALUE_RECORD,
|
||||
MIE_VALUE_FUNC,
|
||||
MIE_VALUE_ARG,
|
||||
MIE_VALUE_BLOCK,
|
||||
MIE_VALUE_INSTR,
|
||||
MIE_VALUE_CONST,
|
||||
MIE_VALUE_DATA,
|
||||
};
|
||||
|
||||
enum mie_value_flags {
|
||||
MIE_VALUE_F_NONE = 0x00u,
|
||||
MIE_VALUE_F_STATIC = 0x01u,
|
||||
};
|
||||
|
||||
struct mie_value_type {
|
||||
enum mie_value_type_id t_id;
|
||||
struct mie_type *(*t_get_type)(struct mie_value *, struct mie_ctx *);
|
||||
void (*t_cleanup)(struct mie_value *);
|
||||
};
|
||||
|
||||
struct mie_value {
|
||||
struct mie_name v_name;
|
||||
const struct mie_value_type *v_type;
|
||||
enum mie_value_flags v_flags;
|
||||
b_queue_entry v_entry;
|
||||
};
|
||||
|
||||
MIE_API void mie_value_init(struct mie_value *val, enum mie_value_type_id type);
|
||||
MIE_API void mie_value_destroy(struct mie_value *val);
|
||||
|
||||
MIE_API struct mie_type *mie_value_get_type(
|
||||
struct mie_value *val, struct mie_ctx *ctx);
|
||||
|
||||
static inline bool mie_value_is(
|
||||
const struct mie_value *val, enum mie_value_type_id type_id)
|
||||
{
|
||||
if (!val->v_type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return val->v_type->t_id == type_id;
|
||||
}
|
||||
|
||||
#endif
|
||||
116
mie/include/mie/macros.h
Normal file
116
mie/include/mie/macros.h
Normal file
@@ -0,0 +1,116 @@
|
||||
#ifndef MIE_MACROS_H_
|
||||
#define MIE_MACROS_H_
|
||||
|
||||
#define __MIE_DIALECT_BEGIN(func_prefix, dialect_name) \
|
||||
struct mie_dialect *func_prefix##_dialect_create(struct mie_ctx *ctx) \
|
||||
{ \
|
||||
struct mie_dialect *self = mie_dialect_create(ctx, dialect_name); \
|
||||
if (!self) { \
|
||||
return NULL; \
|
||||
} \
|
||||
struct mie_op_definition *op = NULL; \
|
||||
struct mie_type_definition *type = NULL; \
|
||||
struct mie_trait_definition *trait = NULL;
|
||||
|
||||
#define __MIE_DIALECT_END() \
|
||||
return self; \
|
||||
}
|
||||
|
||||
#define __MIE_OP_DEFINITION_BEGIN(func_prefix, op_name) \
|
||||
struct mie_op_definition *func_prefix##_op_create( \
|
||||
struct mie_dialect *d, struct mie_ctx *ctx) \
|
||||
{ \
|
||||
struct mie_op_definition *op \
|
||||
= mie_op_definition_create(d, op_name); \
|
||||
if (!op) { \
|
||||
return NULL; \
|
||||
} \
|
||||
const struct mie_trait *trait = NULL;
|
||||
|
||||
#define __MIE_OP_DEFINITION_END() \
|
||||
return op; \
|
||||
}
|
||||
|
||||
#define __MIE_TYPE_DEFINITION_BEGIN(func_prefix, type_name) \
|
||||
struct mie_type_definition *func_prefix##_type_create( \
|
||||
struct mie_dialect *d, struct mie_ctx *ctx) \
|
||||
{ \
|
||||
struct mie_type_definition *type \
|
||||
= mie_type_definition_create(d, type_name); \
|
||||
if (!type) { \
|
||||
return NULL; \
|
||||
} \
|
||||
const struct mie_trait *trait = NULL;
|
||||
|
||||
#define __MIE_TYPE_DEFINITION_END() \
|
||||
return type; \
|
||||
}
|
||||
|
||||
#define __MIE_TRAIT_DEFINITION_BEGIN(func_prefix, trait_name) \
|
||||
struct mie_trait_definition *func_prefix##_trait_create( \
|
||||
struct mie_dialect *d, struct mie_ctx *ctx) \
|
||||
{ \
|
||||
struct mie_trait_definition *trait \
|
||||
= mie_trait_definition_create(d, trait_name); \
|
||||
if (!trait) { \
|
||||
return NULL; \
|
||||
}
|
||||
|
||||
#define __MIE_TRAIT_DEFINITION_END() \
|
||||
return trait; \
|
||||
}
|
||||
|
||||
#define __MIE_DIALECT_ADD_OP(op_id) \
|
||||
extern struct mie_op_definition *op_id##_op_create( \
|
||||
struct mie_dialect *, struct mie_ctx *); \
|
||||
op = op_id##_op_create(self, ctx)
|
||||
#define __MIE_DIALECT_ADD_TYPE(type_id) \
|
||||
extern struct mie_type_definition *type_id##_type_create( \
|
||||
struct mie_dialect *, struct mie_ctx *); \
|
||||
type = type_id##_type_create(self, ctx)
|
||||
#define __MIE_DIALECT_ADD_TRAIT(trait_id) \
|
||||
extern struct mie_trait_definition *trait_id##_trait_create( \
|
||||
struct mie_dialect *, struct mie_ctx *); \
|
||||
trait = trait_id##_trait_create(self, ctx)
|
||||
|
||||
#define MIE_DIALECT_BEGIN(c_sym, name) __MIE_DIALECT_BEGIN(c_sym, name)
|
||||
#define MIE_DIALECT_END() __MIE_DIALECT_END()
|
||||
#define MIE_DIALECT_ADD_OP(c_sym) __MIE_DIALECT_ADD_OP(c_sym)
|
||||
#define MIE_DIALECT_ADD_TYPE(c_sym) __MIE_DIALECT_ADD_TYPE(c_sym)
|
||||
#define MIE_DIALECT_ADD_TRAIT(c_sym) __MIE_DIALECT_ADD_TRAIT(c_sym)
|
||||
|
||||
#define MIE_OP_DEFINITION_BEGIN(c_sym, op) __MIE_OP_DEFINITION_BEGIN(c_sym, op)
|
||||
#define MIE_OP_DEFINITION_END() __MIE_OP_DEFINITION_END()
|
||||
#define MIE_OP_DEFINITION_PRINT(func) op->op_print = (func)
|
||||
#define MIE_OP_DEFINITION_PARSE(func) op->op_parse = (func)
|
||||
#define MIE_OP_DEFINITION_TRAIT(trait_dialect, trait_name) \
|
||||
trait = mie_ctx_get_trait(ctx, trait_dialect, trait_name); \
|
||||
mie_op_definition_add_trait(op, trait);
|
||||
|
||||
#define MIE_TYPE_DEFINITION_BEGIN(c_sym, type) \
|
||||
__MIE_TYPE_DEFINITION_BEGIN(c_sym, type)
|
||||
#define MIE_TYPE_DEFINITION_END() __MIE_TYPE_DEFINITION_END()
|
||||
#define MIE_TYPE_DEFINITION_FLAGS(flags) type->ty_flags = flags
|
||||
#define MIE_TYPE_DEFINITION_STRUCT(name) type->ty_data_size = sizeof(name)
|
||||
#define MIE_TYPE_DEFINITION_INIT(func) type->ty_init = (func)
|
||||
#define MIE_TYPE_DEFINITION_PRINT(func) type->ty_print = (func)
|
||||
#define MIE_TYPE_DEFINITION_VALUE_PRINT(func) type->ty_value_print = (func)
|
||||
#define MIE_TYPE_DEFINITION_PARSE(func) type->ty_parse = (func)
|
||||
#define MIE_TYPE_DEFINITION_BUILD_ID(func) type->ty_build_id = (func)
|
||||
#define MIE_TYPE_DEFINITION_INIT(func) type->ty_init = (func)
|
||||
#define MIE_TYPE_DEFINITION_CLEANUP(func) type->ty_cleanup = (func)
|
||||
#define MIE_TYPE_DEFINITION_TRAIT(trait_dialect, trait_name) \
|
||||
trait = mie_ctx_get_trait(ctx, trait_dialect, trait_name); \
|
||||
mie_type_definition_add_trait(type, trait);
|
||||
|
||||
#define MIE_TRAIT_DEFINITION_BEGIN(c_sym, trait) \
|
||||
__MIE_TRAIT_DEFINITION_BEGIN(c_sym, trait)
|
||||
#define MIE_TRAIT_DEFINITION_END() __MIE_TRAIT_DEFINITION_END()
|
||||
#define MIE_TRAIT_DEFINITION_TARGETS(targets) trait->tr_target = (targets)
|
||||
#define MIE_TRAIT_DEFINITION_STRUCT(name) trait->tr_data_size = sizeof(name)
|
||||
#define MIE_TRAIT_DEFINITION_PRINT(func) trait->tr_print = (func)
|
||||
#define MIE_TRAIT_DEFINITION_BUILD_ID(func) trait->tr_build_id = (func)
|
||||
#define MIE_TRAIT_DEFINITION_CLEANUP(func) trait->tr_cleanup = (func)
|
||||
#define MIE_TRAIT_DEFINITION_VALIDATE(func) trait->tr_validate = (func)
|
||||
|
||||
#endif
|
||||
@@ -11,7 +11,9 @@
|
||||
#define MIE_API extern
|
||||
#endif
|
||||
|
||||
#define MIN(x, y) ((x) < (y) ? (x) : (y))
|
||||
#define MAX(x, y) ((x) > (y) ? (x) : (y))
|
||||
#define MIN(x, y) ((x) < (y) ? (x) : (y))
|
||||
#define MAX(x, y) ((x) > (y) ? (x) : (y))
|
||||
|
||||
#define MIE_TEST_FLAGS(value, flags) (((value) & (flags)) == (flags))
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,13 +3,21 @@
|
||||
|
||||
#include <blue/core/btree.h>
|
||||
#include <blue/core/queue.h>
|
||||
#include <mie/misc.h>
|
||||
#include <mie/parse/file-span.h>
|
||||
|
||||
#define MIE_NAME_VALID(p) (((p)->n_str) != NULL)
|
||||
|
||||
struct mie_name_map;
|
||||
|
||||
enum mie_name_map_flags {
|
||||
MIE_NAME_MAP_STRICT = 0x01u,
|
||||
/* put(): take the name hint as the required name, and don't amend it
|
||||
* to ensure uniqueness. if the given name already exists, the operation
|
||||
* fails. */
|
||||
MIE_NAME_MAP_F_STRICT = 0x01u,
|
||||
/* get(): if the given name does not exist in the name map, recursively
|
||||
* search the parent map(s) until a result is found. */
|
||||
MIE_NAME_MAP_F_RECURSIVE = 0x02u,
|
||||
};
|
||||
|
||||
enum mie_name_map_entry_type {
|
||||
@@ -31,6 +39,10 @@ struct mie_name {
|
||||
struct mie_name_map_entry n_base;
|
||||
struct mie_name_map *n_parent;
|
||||
char *n_str;
|
||||
|
||||
/* if this name was read from a file, these structs can be used to
|
||||
* record the location within the file where the name is found. */
|
||||
struct mie_file_span n_start, n_end;
|
||||
};
|
||||
|
||||
struct mie_name_bucket {
|
||||
@@ -39,13 +51,17 @@ struct mie_name_bucket {
|
||||
};
|
||||
|
||||
struct mie_name_map {
|
||||
const struct mie_name_map *m_parent;
|
||||
b_btree m_entries;
|
||||
size_t m_next_id;
|
||||
};
|
||||
|
||||
extern struct mie_name_map *mie_name_map_create(void);
|
||||
extern struct mie_name_map *mie_name_map_create(const struct mie_name_map *parent);
|
||||
extern void mie_name_map_destroy(struct mie_name_map *map);
|
||||
|
||||
extern const struct mie_name *mie_name_map_get(
|
||||
const struct mie_name_map *map, const char *name,
|
||||
enum mie_name_map_flags flags);
|
||||
extern struct mie_name *mie_name_map_put(
|
||||
struct mie_name_map *map, struct mie_name *entry, const char *hint,
|
||||
enum mie_name_map_flags flags);
|
||||
|
||||
23
mie/include/mie/parse/file-span.h
Normal file
23
mie/include/mie/parse/file-span.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef MIE_PARSE_FILE_SPAN_H_
|
||||
#define MIE_PARSE_FILE_SPAN_H_
|
||||
|
||||
#include <mie/misc.h>
|
||||
|
||||
struct mie_token;
|
||||
|
||||
/* a single row/column pair, representing a location within a file.
|
||||
* both values are 1-based (i.e. the first character in a file is at c_row=1,
|
||||
* c_col=1*/
|
||||
struct mie_file_cell {
|
||||
unsigned int c_row, c_col;
|
||||
};
|
||||
|
||||
/* represents a span of characters within a file.
|
||||
* used for diagnostic reporting */
|
||||
struct mie_file_span {
|
||||
struct mie_file_cell s_start, s_end;
|
||||
};
|
||||
|
||||
MIE_API void mie_file_span_init(struct mie_file_span *span, struct mie_token *tok);
|
||||
|
||||
#endif
|
||||
18
mie/include/mie/parse/lex.h
Normal file
18
mie/include/mie/parse/lex.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef MIE_PARSE_LEX_H_
|
||||
#define MIE_PARSE_LEX_H_
|
||||
|
||||
#include <blue/core/stream.h>
|
||||
#include <mie/misc.h>
|
||||
#include <mie/status.h>
|
||||
|
||||
struct mie_lex;
|
||||
struct mie_token;
|
||||
|
||||
MIE_API struct mie_lex *mie_lex_create(b_stream *src);
|
||||
MIE_API void mie_lex_destroy(struct mie_lex *lex);
|
||||
|
||||
MIE_API enum mie_status mie_lex_get_status(const struct mie_lex *lex);
|
||||
MIE_API struct mie_token *mie_lex_peek(struct mie_lex *lex);
|
||||
MIE_API void mie_lex_advance(struct mie_lex *lex);
|
||||
|
||||
#endif
|
||||
125
mie/include/mie/parse/parse.h
Normal file
125
mie/include/mie/parse/parse.h
Normal file
@@ -0,0 +1,125 @@
|
||||
#ifndef MIE_PARSE_PARSE_H_
|
||||
#define MIE_PARSE_PARSE_H_
|
||||
|
||||
#include <blue/ds/string.h>
|
||||
#include <mie/ir/register.h>
|
||||
#include <mie/misc.h>
|
||||
#include <mie/parse/token.h>
|
||||
#include <mie/status.h>
|
||||
#include <mie/vector.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
struct mie_parser;
|
||||
struct mie_name_map;
|
||||
struct mie_lex;
|
||||
struct mie_ctx;
|
||||
|
||||
struct mie_type;
|
||||
struct mie_module;
|
||||
struct mie_region;
|
||||
struct mie_op;
|
||||
struct mie_op_arg;
|
||||
struct mie_op_attribute;
|
||||
struct mie_op_successor;
|
||||
struct mie_register;
|
||||
struct mie_value;
|
||||
|
||||
MIE_API struct mie_parser *mie_parser_create(
|
||||
struct mie_ctx *ctx, struct mie_lex *lex);
|
||||
MIE_API void mie_parser_destroy(struct mie_parser *ctx);
|
||||
MIE_API enum mie_status mie_parser_get_status(const struct mie_parser *ctx);
|
||||
|
||||
MIE_API struct mie_token *mie_parser_peek(struct mie_parser *ctx);
|
||||
MIE_API enum mie_token_type mie_parser_peek_type(struct mie_parser *ctx);
|
||||
MIE_API enum mie_token_symbol mie_parser_peek_symbol(struct mie_parser *ctx);
|
||||
MIE_API bool mie_parser_advance(struct mie_parser *ctx);
|
||||
|
||||
MIE_API bool mie_parser_check_eof(struct mie_parser *ctx);
|
||||
MIE_API bool mie_parser_check_type(struct mie_parser *ctx, enum mie_token_type type);
|
||||
MIE_API bool mie_parser_check_symbol(
|
||||
struct mie_parser *ctx, enum mie_token_symbol sym);
|
||||
|
||||
MIE_API bool mie_parser_parse_int(
|
||||
struct mie_parser *ctx, long long *out, struct mie_file_span *loc);
|
||||
MIE_API bool mie_parser_parse_float(
|
||||
struct mie_parser *ctx, double *out, struct mie_file_span *loc);
|
||||
MIE_API bool mie_parser_parse_word(
|
||||
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
|
||||
MIE_API bool mie_parser_parse_instname(
|
||||
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
|
||||
MIE_API bool mie_parser_parse_graphname(
|
||||
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
|
||||
MIE_API bool mie_parser_parse_opname(
|
||||
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
|
||||
MIE_API bool mie_parser_parse_vregname(
|
||||
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
|
||||
MIE_API bool mie_parser_parse_mregname(
|
||||
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
|
||||
MIE_API bool mie_parser_parse_blockname(
|
||||
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
|
||||
MIE_API bool mie_parser_parse_typename(
|
||||
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
|
||||
MIE_API bool mie_parser_parse_symname(
|
||||
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
|
||||
MIE_API bool mie_parser_parse_string(
|
||||
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
|
||||
MIE_API bool mie_parser_parse_keyword(struct mie_parser *ctx, const char *kw);
|
||||
MIE_API bool mie_parser_parse_symbol(
|
||||
struct mie_parser *ctx, enum mie_token_symbol sym);
|
||||
MIE_API bool mie_parser_parse_linefeed(struct mie_parser *ctx);
|
||||
|
||||
MIE_API bool mie_parser_parse_type(
|
||||
struct mie_parser *ctx, const struct mie_type **out);
|
||||
MIE_API bool mie_parser_parse_type_list(
|
||||
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(const struct mie_type *, out));
|
||||
MIE_API bool mie_parser_parse_function_type(
|
||||
struct mie_parser *ctx, struct mie_type **out);
|
||||
|
||||
MIE_API bool mie_parser_parse_operand(
|
||||
struct mie_parser *ctx, struct mie_op_arg *out);
|
||||
MIE_API bool mie_parser_parse_operand_list(
|
||||
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_arg, out));
|
||||
|
||||
MIE_API bool mie_parser_parse_parameter(
|
||||
struct mie_parser *ctx, struct mie_op_arg *out);
|
||||
MIE_API bool mie_parser_parse_parameter_list(
|
||||
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_arg, out));
|
||||
|
||||
MIE_API bool mie_parser_parse_unknown_keyword(struct mie_parser *ctx, b_string *out);
|
||||
MIE_API bool mie_parser_parse_unknown_symbol(
|
||||
struct mie_parser *ctx, enum mie_token_symbol sym);
|
||||
|
||||
MIE_API bool mie_parser_parse_register(
|
||||
struct mie_parser *ctx, struct mie_name_map *names,
|
||||
struct mie_register *out);
|
||||
MIE_API bool mie_parser_parse_register_list(
|
||||
struct mie_parser *ctx, struct mie_name_map *names,
|
||||
MIE_VECTOR_REF_PARAM(struct mie_register, out));
|
||||
|
||||
MIE_API bool mie_parser_parse_region(
|
||||
struct mie_parser *ctx, struct mie_region *region);
|
||||
MIE_API bool mie_parser_parse_region_list(
|
||||
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_region, out));
|
||||
MIE_API bool mie_parser_parse_anonymous_block(
|
||||
struct mie_parser *ctx, struct mie_name_map *names,
|
||||
struct mie_block *block);
|
||||
MIE_API bool mie_parser_parse_block(
|
||||
struct mie_parser *ctx, struct mie_name_map *names,
|
||||
struct mie_block *block);
|
||||
|
||||
MIE_API bool mie_parser_parse_attribute(
|
||||
struct mie_parser *ctx, struct mie_op_attribute *attrib);
|
||||
MIE_API bool mie_parser_parse_attribute_list(
|
||||
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_attribute, out));
|
||||
|
||||
MIE_API bool mie_parser_parse_successor(
|
||||
struct mie_parser *ctx, struct mie_op_successor *successor);
|
||||
MIE_API bool mie_parser_parse_successor_list(
|
||||
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_successor, out));
|
||||
|
||||
MIE_API bool mie_parser_parse_module(struct mie_parser *ctx, struct mie_module *mod);
|
||||
MIE_API bool mie_parser_parse_op(
|
||||
struct mie_parser *ctx, struct mie_name_map *names, struct mie_op *dest);
|
||||
MIE_API bool mie_parser_parse_value(struct mie_parser *ctx, struct mie_value **dest);
|
||||
|
||||
#endif
|
||||
94
mie/include/mie/parse/token.h
Normal file
94
mie/include/mie/parse/token.h
Normal file
@@ -0,0 +1,94 @@
|
||||
#ifndef MIE_PARSE_TOKEN_H_
|
||||
#define MIE_PARSE_TOKEN_H_
|
||||
|
||||
#include <blue/core/queue.h>
|
||||
#include <mie/misc.h>
|
||||
#include <mie/parse/file-span.h>
|
||||
|
||||
#define MIE_TOKEN_TYPE(tok) ((tok) ? (tok)->tok_type : MIE_TOK_NONE)
|
||||
#define MIE_TOKEN_IS(tok, type) ((tok) && ((tok)->tok_type & (type)) != 0)
|
||||
#define MIE_TOKEN_IS_SYMBOL(tok, sym) \
|
||||
((tok) && (tok)->tok_type == MIE_TOK_SYMBOL && (tok)->tok_sym == (sym))
|
||||
|
||||
enum mie_token_type {
|
||||
MIE_TOK_NONE = 0,
|
||||
MIE_TOK_LINEFEED = 0x0001u,
|
||||
MIE_TOK_INT = 0x0002u,
|
||||
MIE_TOK_FLOAT = 0x0004u,
|
||||
MIE_TOK_SYMBOL = 0x0008u,
|
||||
MIE_TOK_STRING = 0x0010u,
|
||||
/* single words, not dot-delimited */
|
||||
MIE_TOK_WORD = 0x0020u,
|
||||
/* set of words with at least one dot */
|
||||
MIE_TOK_NAME = 0x0040u,
|
||||
/* word or name, prefixed with an * asterisk */
|
||||
MIE_TOK_INSTNAME = 0x0080u,
|
||||
/* word or name, prefixed with an @ at */
|
||||
MIE_TOK_SYMNAME = 0x0100u,
|
||||
/* word or name, prefixed with a ~ tilde */
|
||||
MIE_TOK_OPNAME = 0x0200u,
|
||||
/* word or name, prefixed with a + plus */
|
||||
MIE_TOK_GRAPHNAME = 0x0400u,
|
||||
/* word or name, prefixed with a % percent */
|
||||
MIE_TOK_VREGNAME = 0x0800u,
|
||||
/* word or name, prefixed with a $ dollar */
|
||||
MIE_TOK_MREGNAME = 0x1000u,
|
||||
/* word or name, prefixed with a ^ caret */
|
||||
MIE_TOK_BLOCKNAME = 0x2000u,
|
||||
/* word or name, prefixed with a # hash */
|
||||
MIE_TOK_TYPENAME = 0x4000u,
|
||||
};
|
||||
|
||||
enum mie_token_value_type {
|
||||
MIE_TOK_V_NONE = 0,
|
||||
MIE_TOK_V_INT,
|
||||
MIE_TOK_V_FLOAT,
|
||||
MIE_TOK_V_STRING,
|
||||
MIE_TOK_V_SYMBOL,
|
||||
};
|
||||
|
||||
enum mie_token_symbol {
|
||||
MIE_SYM_NONE = 0,
|
||||
MIE_SYM_COLON,
|
||||
MIE_SYM_EQUAL,
|
||||
MIE_SYM_COMMA,
|
||||
MIE_SYM_HYPHEN,
|
||||
MIE_SYM_ASTERISK,
|
||||
MIE_SYM_PLUS,
|
||||
MIE_SYM_PERCENT,
|
||||
MIE_SYM_DOLLAR,
|
||||
MIE_SYM_CARET,
|
||||
MIE_SYM_HASH,
|
||||
MIE_SYM_TILDE,
|
||||
MIE_SYM_ATSIGN,
|
||||
MIE_SYM_LEFT_BRACE,
|
||||
MIE_SYM_RIGHT_BRACE,
|
||||
MIE_SYM_LEFT_BRACKET,
|
||||
MIE_SYM_RIGHT_BRACKET,
|
||||
MIE_SYM_LEFT_PAREN,
|
||||
MIE_SYM_RIGHT_PAREN,
|
||||
MIE_SYM_LEFT_ANGLE,
|
||||
MIE_SYM_RIGHT_ANGLE,
|
||||
MIE_SYM_HYPHEN_RIGHT_ANGLE,
|
||||
MIE_SYM_OTHER,
|
||||
};
|
||||
|
||||
struct mie_token {
|
||||
struct mie_file_span tok_location;
|
||||
enum mie_token_type tok_type;
|
||||
enum mie_token_value_type tok_value_type;
|
||||
b_queue_entry tok_entry;
|
||||
|
||||
union {
|
||||
char *tok_str;
|
||||
enum mie_token_symbol tok_sym;
|
||||
long long tok_int;
|
||||
double tok_float;
|
||||
};
|
||||
};
|
||||
|
||||
MIE_API void mie_token_destroy(struct mie_token *tok);
|
||||
MIE_API const char *mie_token_type_to_string(enum mie_token_type type);
|
||||
MIE_API const char *mie_token_symbol_to_string(enum mie_token_symbol sym);
|
||||
|
||||
#endif
|
||||
@@ -1,55 +0,0 @@
|
||||
#ifndef MIE_SELECT_BUILDER_H_
|
||||
#define MIE_SELECT_BUILDER_H_
|
||||
|
||||
#include <mie/misc.h>
|
||||
#include <mie/status.h>
|
||||
|
||||
struct mie_ctx;
|
||||
struct mie_instr;
|
||||
struct mie_value;
|
||||
struct mie_select_builder;
|
||||
struct mie_select_node;
|
||||
struct mie_select_graph;
|
||||
struct mie_select_value;
|
||||
struct mie_target;
|
||||
|
||||
MIE_API struct mie_select_builder *mie_select_builder_create(
|
||||
struct mie_ctx *ctx, const struct mie_target *target);
|
||||
MIE_API void mie_select_builder_destroy(struct mie_select_builder *builder);
|
||||
|
||||
MIE_API struct mie_select_graph *mie_select_builder_get_graph(
|
||||
struct mie_select_builder *builder);
|
||||
MIE_API struct mie_ctx *mie_select_builder_get_ctx(
|
||||
struct mie_select_builder *builder);
|
||||
MIE_API const struct mie_target *mie_select_builder_get_target(
|
||||
struct mie_select_builder *builder);
|
||||
MIE_API struct mie_select_graph *mie_select_builder_finish(
|
||||
struct mie_select_builder *builder);
|
||||
|
||||
MIE_API enum mie_status mie_select_builder_get_const(
|
||||
struct mie_select_builder *builder, long long value,
|
||||
struct mie_select_value *out);
|
||||
|
||||
MIE_API enum mie_status mie_select_builder_push_instr(
|
||||
struct mie_select_builder *builder, struct mie_instr *instr);
|
||||
|
||||
MIE_API struct mie_select_node *mie_select_builder_find_node_with_ivalue(
|
||||
struct mie_select_builder *builder, const struct mie_target *target,
|
||||
unsigned int opcode, long long val);
|
||||
|
||||
MIE_API struct mie_select_value *mie_select_builder_get_value(
|
||||
struct mie_select_builder *builder, struct mie_value *ir_val);
|
||||
MIE_API enum mie_status mie_select_builder_set_value(
|
||||
struct mie_select_builder *builder, struct mie_value *ir_val,
|
||||
struct mie_select_value *graph_val);
|
||||
|
||||
MIE_API struct mie_select_value *mie_select_builder_get_mem_access(
|
||||
struct mie_select_builder *builder, struct mie_value *ir_val);
|
||||
MIE_API enum mie_status mie_select_builder_set_mem_access(
|
||||
struct mie_select_builder *builder, struct mie_value *ir_val,
|
||||
struct mie_select_value *graph_val);
|
||||
|
||||
MIE_API enum mie_status mie_select_builder_collapse_chain_ends(
|
||||
struct mie_select_builder *builder, struct mie_select_value *out);
|
||||
|
||||
#endif
|
||||
@@ -1,54 +0,0 @@
|
||||
#ifndef MIE_SELECT_GRAPH_H_
|
||||
#define MIE_SELECT_GRAPH_H_
|
||||
|
||||
#include <blue/core/btree.h>
|
||||
#include <blue/core/queue.h>
|
||||
#include <mie/misc.h>
|
||||
#include <mie/target/target.h>
|
||||
|
||||
struct mie_ctx;
|
||||
struct mie_type;
|
||||
struct mie_instr;
|
||||
|
||||
struct mie_select_value {
|
||||
struct mie_select_node *v_node;
|
||||
unsigned int v_index;
|
||||
};
|
||||
|
||||
struct mie_select_use {
|
||||
struct mie_select_node *u_user;
|
||||
struct mie_select_value u_value;
|
||||
b_queue_entry u_entry;
|
||||
};
|
||||
|
||||
struct mie_select_chain_end {
|
||||
struct mie_select_value c_value;
|
||||
b_queue_entry c_entry;
|
||||
};
|
||||
|
||||
struct mie_select_graph {
|
||||
b_queue g_nodes;
|
||||
struct mie_select_node *g_root;
|
||||
struct mie_select_value g_entry;
|
||||
b_queue g_chain_ends;
|
||||
size_t g_frame_index;
|
||||
size_t g_node_id;
|
||||
};
|
||||
|
||||
struct mie_select_use_iterator {
|
||||
b_queue_entry *it_ptr;
|
||||
};
|
||||
|
||||
MIE_API struct mie_select_graph *mie_select_graph_create(struct mie_ctx *ctx);
|
||||
MIE_API void mie_select_graph_destroy(struct mie_select_graph *graph);
|
||||
|
||||
MIE_API enum mie_status mie_select_graph_get_node(
|
||||
struct mie_select_graph *graph, const struct mie_target *target,
|
||||
unsigned int op, struct mie_select_value **operands, size_t nr_operands,
|
||||
struct mie_type **values, size_t nr_values, struct mie_select_node **out);
|
||||
|
||||
MIE_API void mie_select_graph_dump_text(struct mie_select_graph *graph);
|
||||
MIE_API void mie_select_graph_dump_dot(
|
||||
struct mie_select_graph *graph, const char *filename);
|
||||
|
||||
#endif
|
||||
@@ -1,104 +0,0 @@
|
||||
#ifndef MIE_SELECT_NODE_H_
|
||||
#define MIE_SELECT_NODE_H_
|
||||
|
||||
#include <blue/core/queue.h>
|
||||
#include <mie/status.h>
|
||||
#include <mie/type.h>
|
||||
|
||||
#define MIE_SELECT_NODE_OUTPUT_MAX 4
|
||||
|
||||
struct mie_target;
|
||||
struct mie_value;
|
||||
struct mie_select_value;
|
||||
|
||||
enum mie_select_node_flags {
|
||||
MIE_SELECT_NODE_F_IVALUE = 0x01u,
|
||||
MIE_SELECT_NODE_F_PVALUE = 0x02u,
|
||||
};
|
||||
|
||||
struct mie_select_node {
|
||||
size_t n_id;
|
||||
unsigned long n_opcode;
|
||||
enum mie_select_node_flags n_flags;
|
||||
|
||||
char *n_description;
|
||||
|
||||
/* certain "builtin" parameters that can be used by opcodes */
|
||||
struct {
|
||||
struct mie_value *v;
|
||||
long long i;
|
||||
void *p;
|
||||
} n_value;
|
||||
|
||||
/* queue entry, links to mie_select_graph.g_nodes */
|
||||
b_queue_entry n_entry;
|
||||
|
||||
/* linked lists of struct mie_select_use,
|
||||
* listing all the places where this node is being used as an
|
||||
* operand.
|
||||
* these pointers point to data in another node's n_operands,
|
||||
* and the memory belongs to these other nodes, not us.
|
||||
*/
|
||||
b_queue n_use;
|
||||
|
||||
/* array of struct mie_select_use
|
||||
* listing all the nodes that are being used as operands by
|
||||
* this node. other nodes hold pointers to these mie_select_use array
|
||||
* entries as part of their n_use queue.
|
||||
*/
|
||||
struct mie_select_use *n_operands;
|
||||
size_t n_nr_operands;
|
||||
|
||||
/* array of struct mie_type pointers
|
||||
* listing the types of the values that are produced as outputs by
|
||||
* this node. the type pointers themselves are owned by a mie_ctx.
|
||||
*/
|
||||
struct mie_type **n_results;
|
||||
size_t n_nr_results;
|
||||
|
||||
/* the target system that provides the operation described by n_opcode. */
|
||||
const struct mie_target *n_target;
|
||||
};
|
||||
|
||||
struct mie_select_node_iterator {
|
||||
b_queue_entry *it_ptr;
|
||||
};
|
||||
|
||||
static inline struct mie_select_node *mie_select_node_iterator_unbox(
|
||||
struct mie_select_node_iterator *it)
|
||||
{
|
||||
return b_unbox(struct mie_select_node, it->it_ptr, n_entry);
|
||||
}
|
||||
|
||||
MIE_API void mie_select_node_iterator_next(struct mie_select_node_iterator *it);
|
||||
MIE_API bool mie_select_node_iterator_is_valid(
|
||||
const struct mie_select_node_iterator *it);
|
||||
|
||||
MIE_API struct mie_select_node *mie_select_node_create(
|
||||
const struct mie_target *target, unsigned int op,
|
||||
struct mie_type **results, size_t nr_results);
|
||||
MIE_API void mie_select_node_destroy(struct mie_select_node *node);
|
||||
|
||||
MIE_API enum mie_status mie_select_node_set_operands(
|
||||
struct mie_select_node *node, struct mie_select_value *operands,
|
||||
size_t nr_operands);
|
||||
MIE_API enum mie_status mie_select_node_clear_operands(struct mie_select_node *node);
|
||||
|
||||
MIE_API void mie_select_node_get_users(
|
||||
struct mie_select_node *node, struct mie_select_node_iterator *it);
|
||||
MIE_API void mie_select_node_get_uses(
|
||||
struct mie_select_node *node, struct mie_select_node_iterator *it);
|
||||
|
||||
MIE_API enum mie_status mie_select_node_get_value(
|
||||
struct mie_select_node *node, struct mie_type *type, size_t index,
|
||||
struct mie_select_value *out);
|
||||
|
||||
MIE_API enum mie_status mie_select_node_set_description(
|
||||
struct mie_select_node *node, const char *format, ...);
|
||||
|
||||
MIE_API struct mie_select_node *mie_select_node_get_glued_node(
|
||||
struct mie_select_node *node);
|
||||
MIE_API struct mie_select_node *mie_select_node_get_glued_user(
|
||||
struct mie_select_node *node);
|
||||
|
||||
#endif
|
||||
@@ -1,33 +0,0 @@
|
||||
#ifndef MIE_SELECT_OPCODE_H_
|
||||
#define MIE_SELECT_OPCODE_H_
|
||||
|
||||
enum mie_select_opcode {
|
||||
MIE_SELECT_OP_NONE = 0,
|
||||
MIE_SELECT_OP_ENTRY,
|
||||
MIE_SELECT_OP_ROOT,
|
||||
MIE_SELECT_OP_BLOCK,
|
||||
MIE_SELECT_OP_CONSTANT,
|
||||
MIE_SELECT_OP_FRAME_INDEX,
|
||||
MIE_SELECT_OP_REGISTER,
|
||||
MIE_SELECT_OP_COPY_FROM_REG,
|
||||
MIE_SELECT_OP_COPY_TO_REG,
|
||||
MIE_SELECT_OP_GLOBAL_ADDRESS,
|
||||
MIE_SELECT_OP_CHAIN_GROUP,
|
||||
MIE_SELECT_OP_LOAD,
|
||||
MIE_SELECT_OP_STORE,
|
||||
MIE_SELECT_OP_ADD,
|
||||
MIE_SELECT_OP_SUB,
|
||||
MIE_SELECT_OP_MUL,
|
||||
MIE_SELECT_OP_DIV,
|
||||
MIE_SELECT_OP_XOR,
|
||||
MIE_SELECT_OP_CMP_EQ,
|
||||
MIE_SELECT_OP_CMP_NEQ,
|
||||
MIE_SELECT_OP_CMP_LT,
|
||||
MIE_SELECT_OP_CMP_GT,
|
||||
MIE_SELECT_OP_CMP_LEQ,
|
||||
MIE_SELECT_OP_CMP_GEQ,
|
||||
MIE_SELECT_OP_BR,
|
||||
MIE_SELECT_OP_BR_COND,
|
||||
};
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user