Compare commits
15 Commits
27e42340de
...
9df79f90a6
| Author | SHA1 | Date | |
|---|---|---|---|
| 9df79f90a6 | |||
| c9c9cdf544 | |||
| 3253c4cac9 | |||
| fc61b188e3 | |||
| 6b5fd95ac4 | |||
| 700f7fe96e | |||
| fdf46b8867 | |||
| 417b5dc354 | |||
| d42e02f04d | |||
| 6e55642a19 | |||
| 0c84578f95 | |||
| 4a0fcef862 | |||
| 79c83ef73c | |||
| c6be143925 | |||
| e76e7c17db |
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
|
||||
|
||||
372
mie/ctx.c
372
mie/ctx.c
@@ -7,10 +7,12 @@
|
||||
#include <mie/dialect/builtin.h>
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/dialect/index.h>
|
||||
#include <mie/dialect/type.h>
|
||||
#include <mie/ir/op.h>
|
||||
#include <mie/trait/trait-definition.h>
|
||||
#include <mie/trait/trait.h>
|
||||
#include <mie/type/function.h>
|
||||
#include <mie/type/storage.h>
|
||||
#include <mie/type/type-definition.h>
|
||||
#include <mie/type/type.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -23,285 +25,6 @@
|
||||
MIE_ID(0xf5, 0x4e, 0xc5, 0x8c, 0xc0, 0x1e, 0x48, 0x47, 0xb5, 0xf4, \
|
||||
0x7b, 0xb9, 0x6b, 0x47, 0xca, 0x48)
|
||||
|
||||
struct ctx_int_cache_entry {
|
||||
b_btree_node i_node;
|
||||
// struct mie_type i_type;
|
||||
b_btree i_values;
|
||||
};
|
||||
|
||||
struct ctx_int_value_cache_entry {
|
||||
b_btree_node i_node;
|
||||
// struct mie_int i_value;
|
||||
};
|
||||
|
||||
#if 0
|
||||
|
||||
B_BTREE_DEFINE_SIMPLE_INSERT(
|
||||
struct ctx_int_cache_entry, i_node, i_type.t_width, put_cached_int_type)
|
||||
B_BTREE_DEFINE_SIMPLE_GET(
|
||||
struct ctx_int_cache_entry, unsigned int, i_node, i_type.t_width,
|
||||
get_cached_int_type)
|
||||
|
||||
B_BTREE_DEFINE_SIMPLE_INSERT(
|
||||
struct ctx_int_value_cache_entry, i_node, i_value.i_value,
|
||||
put_cached_int_value)
|
||||
B_BTREE_DEFINE_SIMPLE_GET(
|
||||
struct ctx_int_value_cache_entry, int64_t, i_node, i_value.i_value,
|
||||
get_cached_int_value)
|
||||
|
||||
struct mie_ctx *mie_ctx_create(void)
|
||||
{
|
||||
struct mie_ctx *out = malloc(sizeof *out);
|
||||
|
||||
if (!out) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(out, 0x0, sizeof *out);
|
||||
|
||||
out->ctx_true = MIE_CONST(mie_ctx_get_int(out, 1, 1));
|
||||
out->ctx_false = MIE_CONST(mie_ctx_get_int(out, 0, 1));
|
||||
|
||||
out->ctx_null = malloc(sizeof *out->ctx_null);
|
||||
if (!out->ctx_null) {
|
||||
mie_ctx_destroy(out);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mie_value_init(out->ctx_null, MIE_VALUE_NONE);
|
||||
|
||||
out->ctx_sel_cache = b_hashmap_create(free, free);
|
||||
out->ctx_string_cache = b_hashmap_create(free, free);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void mie_ctx_destroy(struct mie_ctx *ctx)
|
||||
{
|
||||
ctx->ctx_true = NULL;
|
||||
ctx->ctx_false = NULL;
|
||||
|
||||
b_btree_node *node = b_btree_first(&ctx->ctx_int_cache);
|
||||
while (node) {
|
||||
struct ctx_int_cache_entry *entry
|
||||
= b_unbox(struct ctx_int_cache_entry, node, i_node);
|
||||
b_btree_node *next = b_btree_next(node);
|
||||
b_btree_delete(&ctx->ctx_int_cache, node);
|
||||
|
||||
b_btree_node *node2 = b_btree_first(&entry->i_values);
|
||||
while (node2) {
|
||||
struct ctx_int_value_cache_entry *value = b_unbox(
|
||||
struct ctx_int_value_cache_entry, node2, i_node);
|
||||
b_btree_node *next2 = b_btree_next(node2);
|
||||
b_btree_delete(&entry->i_values, node2);
|
||||
free(value);
|
||||
node2 = next2;
|
||||
}
|
||||
|
||||
free(entry);
|
||||
node = next;
|
||||
}
|
||||
|
||||
const size_t nr_types = sizeof ctx->ctx_types / sizeof ctx->ctx_types[0];
|
||||
for (size_t i = 0; i < nr_types; i++) {
|
||||
if (ctx->ctx_types[i]) {
|
||||
mie_value_destroy(MIE_VALUE(ctx->ctx_types[i]));
|
||||
ctx->ctx_types[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->ctx_null) {
|
||||
mie_value_destroy(ctx->ctx_null);
|
||||
}
|
||||
|
||||
b_hashmap_unref(ctx->ctx_sel_cache);
|
||||
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
struct mie_type *mie_ctx_get_type(struct mie_ctx *ctx, enum mie_type_id type_id)
|
||||
{
|
||||
if (type_id == MIE_TYPE_INT) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ctx->ctx_types[type_id]) {
|
||||
return ctx->ctx_types[type_id];
|
||||
}
|
||||
|
||||
struct mie_type *type = mie_type_create();
|
||||
if (!type) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
type->t_id = type_id;
|
||||
|
||||
ctx->ctx_types[type_id] = type;
|
||||
return type;
|
||||
}
|
||||
|
||||
struct mie_value *mie_ctx_get_null(struct mie_ctx *ctx)
|
||||
{
|
||||
return ctx->ctx_null;
|
||||
}
|
||||
|
||||
struct mie_type *mie_ctx_get_int_type(struct mie_ctx *ctx, unsigned int nr_bits)
|
||||
{
|
||||
struct ctx_int_cache_entry *entry
|
||||
= get_cached_int_type(&ctx->ctx_int_cache, nr_bits);
|
||||
|
||||
if (entry) {
|
||||
return &entry->i_type;
|
||||
}
|
||||
|
||||
entry = malloc(sizeof *entry);
|
||||
if (!entry) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(entry, 0x0, sizeof *entry);
|
||||
|
||||
entry->i_type.t_id = MIE_TYPE_INT;
|
||||
entry->i_type.t_width = nr_bits;
|
||||
|
||||
put_cached_int_type(&ctx->ctx_int_cache, entry);
|
||||
return &entry->i_type;
|
||||
}
|
||||
|
||||
struct mie_value *mie_ctx_get_bool(struct mie_ctx *ctx, bool val)
|
||||
{
|
||||
return MIE_VALUE(val ? ctx->ctx_true : ctx->ctx_false);
|
||||
}
|
||||
|
||||
struct mie_value *mie_ctx_get_int(
|
||||
struct mie_ctx *ctx, long long val, unsigned int nr_bits)
|
||||
{
|
||||
struct ctx_int_cache_entry *entry
|
||||
= get_cached_int_type(&ctx->ctx_int_cache, nr_bits);
|
||||
|
||||
if (!entry) {
|
||||
entry = malloc(sizeof *entry);
|
||||
if (!entry) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(entry, 0x0, sizeof *entry);
|
||||
|
||||
entry->i_type.t_id = MIE_TYPE_INT;
|
||||
entry->i_type.t_width = nr_bits;
|
||||
|
||||
put_cached_int_type(&ctx->ctx_int_cache, entry);
|
||||
}
|
||||
|
||||
struct ctx_int_value_cache_entry *value
|
||||
= get_cached_int_value(&entry->i_values, val);
|
||||
if (value) {
|
||||
return MIE_VALUE(&value->i_value);
|
||||
}
|
||||
|
||||
value = malloc(sizeof *value);
|
||||
if (!value) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(value, 0x0, sizeof *value);
|
||||
|
||||
mie_const_init(&value->i_value.i_base, &entry->i_type);
|
||||
value->i_value.i_value = val;
|
||||
|
||||
put_cached_int_value(&entry->i_values, value);
|
||||
|
||||
return MIE_VALUE(&value->i_value);
|
||||
}
|
||||
|
||||
struct mie_value *mie_ctx_get_selector(struct mie_ctx *ctx, const char *sel)
|
||||
{
|
||||
b_hashmap_key key = {
|
||||
.key_data = sel,
|
||||
.key_size = strlen(sel),
|
||||
};
|
||||
|
||||
const b_hashmap_value *cache_entry
|
||||
= b_hashmap_get(ctx->ctx_sel_cache, &key);
|
||||
|
||||
if (cache_entry) {
|
||||
return cache_entry->value_data;
|
||||
}
|
||||
|
||||
struct mie_selector *sel_value = malloc(sizeof *sel_value);
|
||||
if (!sel_value) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct mie_type *sel_type = mie_ctx_get_type(ctx, MIE_TYPE_SELECTOR);
|
||||
mie_const_init(&sel_value->sel_base, sel_type);
|
||||
sel_value->sel_value = b_strdup(sel);
|
||||
|
||||
key.key_data = sel_value->sel_value;
|
||||
|
||||
b_hashmap_value hashmap_value = {
|
||||
.value_data = sel_value,
|
||||
.value_size = sizeof *sel_value,
|
||||
};
|
||||
|
||||
b_hashmap_put(ctx->ctx_sel_cache, &key, &hashmap_value);
|
||||
|
||||
return MIE_VALUE(sel_value);
|
||||
}
|
||||
|
||||
struct mie_value *mie_ctx_get_string(struct mie_ctx *ctx, const char *s)
|
||||
{
|
||||
b_hashmap_key key = {
|
||||
.key_data = s,
|
||||
.key_size = strlen(s),
|
||||
};
|
||||
|
||||
const b_hashmap_value *cache_entry
|
||||
= b_hashmap_get(ctx->ctx_string_cache, &key);
|
||||
|
||||
if (cache_entry) {
|
||||
return cache_entry->value_data;
|
||||
}
|
||||
|
||||
struct mie_string *string_value = malloc(sizeof *string_value);
|
||||
if (!string_value) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct mie_type *string_type = mie_ctx_get_type(ctx, MIE_TYPE_STR);
|
||||
mie_const_init(&string_value->s_base, string_type);
|
||||
string_value->s_value = b_strdup(s);
|
||||
|
||||
key.key_data = string_value->s_value;
|
||||
|
||||
b_hashmap_value hashmap_value = {
|
||||
.value_data = string_value,
|
||||
.value_size = sizeof *string_value,
|
||||
};
|
||||
|
||||
b_hashmap_put(ctx->ctx_string_cache, &key, &hashmap_value);
|
||||
|
||||
return MIE_VALUE(string_value);
|
||||
}
|
||||
|
||||
struct mie_value *mie_ctx_create_array(struct mie_ctx *ctx)
|
||||
{
|
||||
struct mie_type *array_type = mie_ctx_get_type(ctx, MIE_TYPE_ARRAY);
|
||||
struct mie_array *array = malloc(sizeof *array);
|
||||
|
||||
if (!array) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(array, 0x0, sizeof *array);
|
||||
mie_const_init(&array->a_base, array_type);
|
||||
|
||||
array->a_values = b_list_create();
|
||||
|
||||
return MIE_VALUE(array);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct mie_ctx *mie_ctx_create(void)
|
||||
{
|
||||
struct mie_ctx *out = malloc(sizeof *out);
|
||||
@@ -319,6 +42,7 @@ struct mie_ctx *mie_ctx_create(void)
|
||||
mie_id_map_init(&out->ctx_types, &types_ns);
|
||||
|
||||
out->ctx_ints = mie_int_cache_create();
|
||||
out->ctx_floats = mie_float_cache_create();
|
||||
out->ctx_indices = mie_index_cache_create();
|
||||
out->ctx_strings = mie_string_cache_create();
|
||||
|
||||
@@ -328,7 +52,7 @@ struct mie_ctx *mie_ctx_create(void)
|
||||
bool mie_ctx_resolve_op(const struct mie_ctx *ctx, struct mie_op *op)
|
||||
{
|
||||
bool fully_resolved = MIE_TEST_FLAGS(
|
||||
op->op_flags, MIE_OP_F_OP_RESOLVED | MIE_OP_F_ARGS_RESOLVED);
|
||||
op->op_flags, MIE_OP_F_OP_RESOLVED | MIE_OP_F_ARG_RESOLVED);
|
||||
|
||||
if (fully_resolved) {
|
||||
return true;
|
||||
@@ -358,7 +82,7 @@ bool mie_ctx_resolve_op(const struct mie_ctx *ctx, struct mie_op *op)
|
||||
return false;
|
||||
}
|
||||
|
||||
const struct mie_dialect_op *op_info
|
||||
const struct mie_op_definition *op_info
|
||||
= mie_dialect_get_op(dialect, op_name);
|
||||
if (!op) {
|
||||
return false;
|
||||
@@ -385,7 +109,7 @@ struct mie_dialect *mie_ctx_get_dialect(const struct mie_ctx *ctx, const char *n
|
||||
return b_unbox(struct mie_dialect, target, d_id);
|
||||
}
|
||||
|
||||
struct mie_dialect_type *mie_ctx_get_dialect_type(
|
||||
struct mie_type_definition *mie_ctx_get_type_definition(
|
||||
const struct mie_ctx *ctx, const char *dialect_name, const char *type_name)
|
||||
{
|
||||
b_rope dialect_name_rope = B_ROPE_CSTR(dialect_name);
|
||||
@@ -403,14 +127,35 @@ struct mie_dialect_type *mie_ctx_get_dialect_type(
|
||||
mie_id_init_ns(&id, mie_id_map_get_ns(&dialect->d_types), &type_name_rope);
|
||||
target = mie_id_map_get(&dialect->d_types, &id);
|
||||
|
||||
return b_unbox(struct mie_dialect_type, target, ty_id);
|
||||
return b_unbox(struct mie_type_definition, target, ty_id);
|
||||
}
|
||||
|
||||
const struct mie_trait_definition *mie_ctx_get_trait_definition(
|
||||
const struct mie_ctx *ctx, const char *dialect_name, const char *trait_name)
|
||||
{
|
||||
b_rope dialect_name_rope = B_ROPE_CSTR(dialect_name);
|
||||
mie_id id;
|
||||
mie_id_init_ns(
|
||||
&id, mie_id_map_get_ns(&ctx->ctx_dialects), &dialect_name_rope);
|
||||
|
||||
mie_id *target = mie_id_map_get(&ctx->ctx_dialects, &id);
|
||||
struct mie_dialect *dialect = b_unbox(struct mie_dialect, target, d_id);
|
||||
if (!dialect) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
b_rope trait_name_rope = B_ROPE_CSTR(trait_name);
|
||||
mie_id_init_ns(&id, mie_id_map_get_ns(&dialect->d_traits), &trait_name_rope);
|
||||
target = mie_id_map_get(&dialect->d_traits, &id);
|
||||
|
||||
return b_unbox(struct mie_trait_definition, target, tr_id);
|
||||
}
|
||||
|
||||
struct mie_type *mie_ctx_get_type(
|
||||
struct mie_ctx *ctx, const char *dialect_name, const char *type_name)
|
||||
{
|
||||
char full_name[256];
|
||||
snprintf(full_name, sizeof full_name, "%s.%s", dialect_name, dialect_name);
|
||||
snprintf(full_name, sizeof full_name, "%s.%s", dialect_name, type_name);
|
||||
b_rope full_name_rope = B_ROPE_CSTR(full_name);
|
||||
|
||||
mie_id id;
|
||||
@@ -422,8 +167,8 @@ struct mie_type *mie_ctx_get_type(
|
||||
return type;
|
||||
}
|
||||
|
||||
struct mie_dialect_type *type_info
|
||||
= mie_ctx_get_dialect_type(ctx, dialect_name, type_name);
|
||||
struct mie_type_definition *type_info
|
||||
= mie_ctx_get_type_definition(ctx, dialect_name, type_name);
|
||||
if (!type_info /* || (type_info->ty_flags & MIE_DIALECT_TYPE_PARAMETISED) */) {
|
||||
/* cannot initialise unknown or parametised types */
|
||||
return NULL;
|
||||
@@ -453,6 +198,53 @@ struct mie_type *mie_ctx_get_type(
|
||||
return type;
|
||||
}
|
||||
|
||||
const struct mie_trait *mie_ctx_get_trait(
|
||||
struct mie_ctx *ctx, const char *dialect_name, const char *trait_name)
|
||||
{
|
||||
char full_name[256];
|
||||
snprintf(full_name, sizeof full_name, "%s.%s", dialect_name, trait_name);
|
||||
b_rope full_name_rope = B_ROPE_CSTR(full_name);
|
||||
|
||||
mie_id id;
|
||||
mie_id_init_ns(&id, mie_id_map_get_ns(&ctx->ctx_traits), &full_name_rope);
|
||||
|
||||
mie_id *target = mie_id_map_get(&ctx->ctx_traits, &id);
|
||||
struct mie_trait *trait = b_unbox(struct mie_trait, target, tr_id);
|
||||
if (trait) {
|
||||
return trait;
|
||||
}
|
||||
|
||||
const struct mie_trait_definition *trait_info
|
||||
= mie_ctx_get_trait_definition(ctx, dialect_name, trait_name);
|
||||
if (!trait_info /* || (trait_info->ty_flags & MIE_DIALECT_TYPE_PARAMETISED) */) {
|
||||
/* cannot initialise unknown or parametised traits */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (trait_info->tr_data_size < sizeof(struct mie_trait)) {
|
||||
/* invalid trait info */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
trait = malloc(trait_info->tr_data_size);
|
||||
if (!trait) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(trait, 0x0, sizeof *trait);
|
||||
|
||||
trait->tr_def = trait_info;
|
||||
trait->tr_name = b_bstr_fmt("%s.%s", dialect_name, trait_name);
|
||||
|
||||
if (trait_info->tr_init) {
|
||||
trait_info->tr_init(trait_info, trait);
|
||||
}
|
||||
|
||||
mie_id_map_put(&ctx->ctx_traits, &trait->tr_id, &full_name_rope);
|
||||
|
||||
return trait;
|
||||
}
|
||||
|
||||
struct mie_type *mie_ctx_get_storage_type(
|
||||
struct mie_ctx *ctx, const struct mie_type **parts, size_t nr_parts)
|
||||
{
|
||||
@@ -514,6 +306,12 @@ struct mie_value *mie_ctx_get_int(struct mie_ctx *ctx, long long val, size_t nr_
|
||||
ctx->ctx_ints, ctx, val, nr_bits);
|
||||
}
|
||||
|
||||
struct mie_value *mie_ctx_get_float(struct mie_ctx *ctx, double val, size_t nr_bits)
|
||||
{
|
||||
return (struct mie_value *)mie_float_cache_get(
|
||||
ctx->ctx_floats, ctx, val, nr_bits);
|
||||
}
|
||||
|
||||
struct mie_value *mie_ctx_get_string(struct mie_ctx *ctx, const char *s)
|
||||
{
|
||||
return (struct mie_value *)mie_string_cache_get(ctx->ctx_strings, ctx, s);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/dialect/op.h>
|
||||
#include <mie/ir/op-definition.h>
|
||||
#include <mie/macros.h>
|
||||
|
||||
static enum mie_status print(const struct mie_op *op, b_stream *out)
|
||||
@@ -12,7 +12,7 @@ static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
MIE_DIALECT_OP_BEGIN(mie_arith_addf, "addf")
|
||||
MIE_DIALECT_OP_PRINT(print);
|
||||
MIE_DIALECT_OP_PARSE(parse);
|
||||
MIE_DIALECT_OP_END()
|
||||
MIE_OP_DEFINITION_BEGIN(mie_arith_addf, "addf")
|
||||
MIE_OP_DEFINITION_PRINT(print);
|
||||
MIE_OP_DEFINITION_PARSE(parse);
|
||||
MIE_OP_DEFINITION_END()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/dialect/op.h>
|
||||
#include <mie/ir/op-definition.h>
|
||||
#include <mie/macros.h>
|
||||
|
||||
static enum mie_status print(const struct mie_op *op, b_stream *out)
|
||||
@@ -12,7 +12,7 @@ static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
MIE_DIALECT_OP_BEGIN(mie_arith_addi, "addi")
|
||||
MIE_DIALECT_OP_PRINT(print);
|
||||
MIE_DIALECT_OP_PARSE(parse);
|
||||
MIE_DIALECT_OP_END()
|
||||
MIE_OP_DEFINITION_BEGIN(mie_arith_addi, "addi")
|
||||
MIE_OP_DEFINITION_PRINT(print);
|
||||
MIE_OP_DEFINITION_PARSE(parse);
|
||||
MIE_OP_DEFINITION_END()
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -2,8 +2,8 @@
|
||||
#include <mie/ctx.h>
|
||||
#include <mie/dialect/arith.h>
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/dialect/type.h>
|
||||
#include <mie/macros.h>
|
||||
#include <mie/type/type-definition.h>
|
||||
#include <mie/type/type.h>
|
||||
#include <mie/value.h>
|
||||
|
||||
@@ -12,7 +12,7 @@ struct float_type {
|
||||
size_t f_width;
|
||||
};
|
||||
|
||||
static void value_print(
|
||||
static enum mie_status value_print(
|
||||
const struct mie_type *ty, const struct mie_value *value, b_stream *out)
|
||||
{
|
||||
struct float_type *float_ty = (struct float_type *)ty;
|
||||
@@ -32,12 +32,14 @@ static void value_print(
|
||||
b_stream_write_fmt(out, NULL, "NaN : f%zu", float_ty->f_width);
|
||||
break;
|
||||
}
|
||||
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
struct mie_type *mie_arith_float_get_type(struct mie_ctx *ctx, size_t bit_width)
|
||||
{
|
||||
struct mie_dialect_type *type_info
|
||||
= mie_ctx_get_dialect_type(ctx, "arith", "float");
|
||||
struct mie_type_definition *type_info
|
||||
= mie_ctx_get_type_definition(ctx, "arith", "float");
|
||||
if (!type_info) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -67,23 +69,38 @@ struct mie_type *mie_arith_float_get_type(struct mie_ctx *ctx, size_t bit_width)
|
||||
return (struct mie_type *)type;
|
||||
}
|
||||
|
||||
size_t mie_arith_float_type_get_width(const struct mie_type *type)
|
||||
{
|
||||
if (strcmp(type->ty_def->ty_parent->d_name, "arith") != 0) {
|
||||
return (size_t)-1;
|
||||
}
|
||||
|
||||
if (strcmp(type->ty_def->ty_name, "float") != 0) {
|
||||
return (size_t)-1;
|
||||
}
|
||||
|
||||
const struct float_type *float_type = (const struct float_type *)type;
|
||||
return float_type->f_width;
|
||||
}
|
||||
|
||||
static enum mie_status print(
|
||||
const struct mie_dialect_type *def, const struct mie_type *ty, b_stream *out)
|
||||
const struct mie_type_definition *def, const struct mie_type *ty,
|
||||
b_stream *out)
|
||||
{
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
static enum mie_status parse(
|
||||
const struct mie_dialect_type *def, struct mie_parser *parser,
|
||||
const struct mie_type_definition *def, struct mie_parser *parser,
|
||||
struct mie_type **out)
|
||||
{
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
MIE_DIALECT_TYPE_BEGIN(mie_arith_float, "float")
|
||||
// MIE_DIALECT_TYPE_FLAGS(MIE_DIALECT_TYPE_PARAMETISED);
|
||||
MIE_DIALECT_TYPE_STRUCT(struct float_type);
|
||||
MIE_DIALECT_TYPE_PRINT(print);
|
||||
MIE_DIALECT_TYPE_PARSE(parse);
|
||||
MIE_DIALECT_TYPE_VALUE_PRINT(value_print);
|
||||
MIE_DIALECT_TYPE_END()
|
||||
MIE_TYPE_DEFINITION_BEGIN(mie_arith_float, "float")
|
||||
// MIE_TYPE_DEFINITION_FLAGS(MIE_TYPE_DEFINITION_PARAMETISED);
|
||||
MIE_TYPE_DEFINITION_STRUCT(struct float_type);
|
||||
MIE_TYPE_DEFINITION_PRINT(print);
|
||||
MIE_TYPE_DEFINITION_PARSE(parse);
|
||||
MIE_TYPE_DEFINITION_VALUE_PRINT(value_print);
|
||||
MIE_TYPE_DEFINITION_END()
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
#include <mie/ctx.h>
|
||||
#include <mie/dialect/arith.h>
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/dialect/type.h>
|
||||
#include <mie/macros.h>
|
||||
#include <mie/type/type-definition.h>
|
||||
#include <mie/type/type.h>
|
||||
#include <mie/value.h>
|
||||
|
||||
@@ -12,7 +12,7 @@ struct int_type {
|
||||
size_t i_width;
|
||||
};
|
||||
|
||||
static void value_print(
|
||||
static enum mie_status value_print(
|
||||
const struct mie_type *ty, const struct mie_value *value, b_stream *out)
|
||||
{
|
||||
struct int_type *int_ty = (struct int_type *)ty;
|
||||
@@ -24,12 +24,14 @@ static void value_print(
|
||||
} else {
|
||||
b_stream_write_fmt(out, NULL, "INF : i%zu", int_ty->i_width);
|
||||
}
|
||||
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
struct mie_type *mie_arith_int_get_type(struct mie_ctx *ctx, size_t bit_width)
|
||||
{
|
||||
struct mie_dialect_type *type_info
|
||||
= mie_ctx_get_dialect_type(ctx, "arith", "int");
|
||||
struct mie_type_definition *type_info
|
||||
= mie_ctx_get_type_definition(ctx, "arith", "int");
|
||||
if (!type_info) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -59,23 +61,38 @@ struct mie_type *mie_arith_int_get_type(struct mie_ctx *ctx, size_t bit_width)
|
||||
return (struct mie_type *)type;
|
||||
}
|
||||
|
||||
size_t mie_arith_int_type_get_width(const struct mie_type *type)
|
||||
{
|
||||
if (strcmp(type->ty_def->ty_parent->d_name, "arith") != 0) {
|
||||
return (size_t)-1;
|
||||
}
|
||||
|
||||
if (strcmp(type->ty_def->ty_name, "int") != 0) {
|
||||
return (size_t)-1;
|
||||
}
|
||||
|
||||
const struct int_type *int_type = (const struct int_type *)type;
|
||||
return int_type->i_width;
|
||||
}
|
||||
|
||||
static enum mie_status print(
|
||||
const struct mie_dialect_type *def, const struct mie_type *ty, b_stream *out)
|
||||
const struct mie_type_definition *def, const struct mie_type *ty,
|
||||
b_stream *out)
|
||||
{
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
static enum mie_status parse(
|
||||
const struct mie_dialect_type *def, struct mie_parser *parser,
|
||||
const struct mie_type_definition *def, struct mie_parser *parser,
|
||||
struct mie_type **out)
|
||||
{
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
MIE_DIALECT_TYPE_BEGIN(mie_arith_int, "int")
|
||||
// MIE_DIALECT_TYPE_FLAGS(MIE_DIALECT_TYPE_PARAMETISED);
|
||||
MIE_DIALECT_TYPE_STRUCT(struct int_type);
|
||||
MIE_DIALECT_TYPE_PRINT(print);
|
||||
MIE_DIALECT_TYPE_PARSE(parse);
|
||||
MIE_DIALECT_TYPE_VALUE_PRINT(value_print);
|
||||
MIE_DIALECT_TYPE_END()
|
||||
MIE_TYPE_DEFINITION_BEGIN(mie_arith_int, "int")
|
||||
// MIE_TYPE_DEFINITION_FLAGS(MIE_TYPE_DEFINITION_PARAMETISED);
|
||||
MIE_TYPE_DEFINITION_STRUCT(struct int_type);
|
||||
MIE_TYPE_DEFINITION_PRINT(print);
|
||||
MIE_TYPE_DEFINITION_PARSE(parse);
|
||||
MIE_TYPE_DEFINITION_VALUE_PRINT(value_print);
|
||||
MIE_TYPE_DEFINITION_END()
|
||||
|
||||
@@ -3,4 +3,5 @@
|
||||
|
||||
MIE_DIALECT_BEGIN(mie_builtin, "builtin")
|
||||
MIE_DIALECT_ADD_TYPE(mie_builtin_string);
|
||||
MIE_DIALECT_ADD_TRAIT(mie_builtin_isolated_from_above);
|
||||
MIE_DIALECT_END()
|
||||
|
||||
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()
|
||||
@@ -2,40 +2,43 @@
|
||||
#include <mie/ctx.h>
|
||||
#include <mie/dialect/builtin.h>
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/dialect/type.h>
|
||||
#include <mie/macros.h>
|
||||
#include <mie/type/type-definition.h>
|
||||
#include <mie/type/type.h>
|
||||
#include <mie/value.h>
|
||||
|
||||
static void value_print(
|
||||
static enum mie_status value_print(
|
||||
const struct mie_type *ty, const struct mie_value *value, b_stream *out)
|
||||
{
|
||||
const struct mie_string *str = (const struct mie_string *)value;
|
||||
b_stream_write_fmt(out, NULL, "\"%s\"", str->str_val);
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
static void type_init(const struct mie_dialect_type *type_info, struct mie_type *type)
|
||||
static void type_init(
|
||||
const struct mie_type_definition *type_info, struct mie_type *type)
|
||||
{
|
||||
type->ty_instance_size = sizeof(struct mie_string);
|
||||
}
|
||||
|
||||
static enum mie_status print(
|
||||
const struct mie_dialect_type *def, const struct mie_type *ty, b_stream *out)
|
||||
const struct mie_type_definition *def, const struct mie_type *ty,
|
||||
b_stream *out)
|
||||
{
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
static enum mie_status parse(
|
||||
const struct mie_dialect_type *def, struct mie_parser *parser,
|
||||
const struct mie_type_definition *def, struct mie_parser *parser,
|
||||
struct mie_type **out)
|
||||
{
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
MIE_DIALECT_TYPE_BEGIN(mie_builtin_string, "string")
|
||||
MIE_DIALECT_TYPE_STRUCT(struct mie_type);
|
||||
MIE_DIALECT_TYPE_INIT(type_init);
|
||||
MIE_DIALECT_TYPE_PRINT(print);
|
||||
MIE_DIALECT_TYPE_PARSE(parse);
|
||||
MIE_DIALECT_TYPE_VALUE_PRINT(value_print);
|
||||
MIE_DIALECT_TYPE_END()
|
||||
MIE_TYPE_DEFINITION_BEGIN(mie_builtin_string, "string")
|
||||
MIE_TYPE_DEFINITION_STRUCT(struct mie_type);
|
||||
MIE_TYPE_DEFINITION_INIT(type_init);
|
||||
MIE_TYPE_DEFINITION_PRINT(print);
|
||||
MIE_TYPE_DEFINITION_PARSE(parse);
|
||||
MIE_TYPE_DEFINITION_VALUE_PRINT(value_print);
|
||||
MIE_TYPE_DEFINITION_END()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/dialect/op.h>
|
||||
#include <mie/ir/op-definition.h>
|
||||
#include <mie/macros.h>
|
||||
|
||||
static enum mie_status print(const struct mie_op *op, b_stream *out)
|
||||
@@ -12,7 +12,7 @@ static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
MIE_DIALECT_OP_BEGIN(mie_cf_br_cond, "br-cond")
|
||||
MIE_DIALECT_OP_PRINT(print);
|
||||
MIE_DIALECT_OP_PARSE(parse);
|
||||
MIE_DIALECT_OP_END()
|
||||
MIE_OP_DEFINITION_BEGIN(mie_cf_br_cond, "br-cond")
|
||||
MIE_OP_DEFINITION_PRINT(print);
|
||||
MIE_OP_DEFINITION_PARSE(parse);
|
||||
MIE_OP_DEFINITION_END()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/dialect/op.h>
|
||||
#include <mie/ir/op-definition.h>
|
||||
#include <mie/macros.h>
|
||||
|
||||
static enum mie_status print(const struct mie_op *op, b_stream *out)
|
||||
@@ -12,7 +12,7 @@ static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
MIE_DIALECT_OP_BEGIN(mie_cf_br, "br")
|
||||
MIE_DIALECT_OP_PRINT(print);
|
||||
MIE_DIALECT_OP_PARSE(parse);
|
||||
MIE_DIALECT_OP_END()
|
||||
MIE_OP_DEFINITION_BEGIN(mie_cf_br, "br")
|
||||
MIE_OP_DEFINITION_PRINT(print);
|
||||
MIE_OP_DEFINITION_PARSE(parse);
|
||||
MIE_OP_DEFINITION_END()
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include <blue/ds/string.h>
|
||||
#include <mie/ctx.h>
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/dialect/op.h>
|
||||
#include <mie/dialect/type.h>
|
||||
#include <mie/ir/op-definition.h>
|
||||
#include <mie/type/type-definition.h>
|
||||
|
||||
#define TYPE_NS_ID \
|
||||
MIE_ID(0xe4, 0x99, 0x42, 0x58, 0x2b, 0xdb, 0x45, 0xa3, 0xbd, 0x4b, \
|
||||
@@ -38,7 +38,7 @@ struct mie_dialect *mie_dialect_create(struct mie_ctx *ctx, const char *name)
|
||||
return out;
|
||||
}
|
||||
|
||||
const struct mie_dialect_op *mie_dialect_get_op(
|
||||
const struct mie_op_definition *mie_dialect_get_op(
|
||||
const struct mie_dialect *dialect, const char *name)
|
||||
{
|
||||
b_rope name_rope = B_ROPE_CSTR(name);
|
||||
@@ -46,10 +46,10 @@ const struct mie_dialect_op *mie_dialect_get_op(
|
||||
mie_id_init_ns(&id, mie_id_map_get_ns(&dialect->d_ops), &name_rope);
|
||||
|
||||
mie_id *target = mie_id_map_get(&dialect->d_ops, &id);
|
||||
return b_unbox(struct mie_dialect_op, target, op_id);
|
||||
return b_unbox(struct mie_op_definition, target, op_id);
|
||||
}
|
||||
|
||||
const struct mie_dialect_type *mie_dialect_get_type(
|
||||
const struct mie_type_definition *mie_dialect_get_type(
|
||||
const struct mie_dialect *dialect, const char *name)
|
||||
{
|
||||
b_rope name_rope = B_ROPE_CSTR(name);
|
||||
@@ -57,5 +57,5 @@ const struct mie_dialect_type *mie_dialect_get_type(
|
||||
mie_id_init_ns(&id, mie_id_map_get_ns(&dialect->d_types), &name_rope);
|
||||
|
||||
mie_id *target = mie_id_map_get(&dialect->d_types, &id);
|
||||
return b_unbox(struct mie_dialect_type, target, ty_id);
|
||||
return b_unbox(struct mie_type_definition, target, ty_id);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/dialect/op.h>
|
||||
#include <mie/ir/op-definition.h>
|
||||
#include <mie/macros.h>
|
||||
|
||||
static enum mie_status print(const struct mie_op *op, b_stream *out)
|
||||
@@ -12,10 +12,10 @@ static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
MIE_DIALECT_OP_BEGIN(mie_func_func, "func")
|
||||
MIE_DIALECT_OP_PRINT(print);
|
||||
MIE_DIALECT_OP_PARSE(parse);
|
||||
MIE_DIALECT_OP_END()
|
||||
MIE_OP_DEFINITION_BEGIN(mie_func_func, "func")
|
||||
MIE_OP_DEFINITION_PRINT(print);
|
||||
MIE_OP_DEFINITION_PARSE(parse);
|
||||
MIE_OP_DEFINITION_END()
|
||||
|
||||
MIE_DIALECT_BEGIN(mie_func, "func")
|
||||
MIE_DIALECT_ADD_OP(mie_func_func);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/dialect/index.h>
|
||||
#include <mie/dialect/type.h>
|
||||
#include <mie/macros.h>
|
||||
#include <mie/type/type-definition.h>
|
||||
#include <mie/type/type.h>
|
||||
#include <mie/value.h>
|
||||
|
||||
@@ -9,7 +9,7 @@ struct index_type {
|
||||
struct mie_type i_base;
|
||||
};
|
||||
|
||||
static void value_print(
|
||||
static enum mie_status value_print(
|
||||
const struct mie_type *ty, const struct mie_value *value, b_stream *out)
|
||||
{
|
||||
struct index_type *index_ty = (struct index_type *)ty;
|
||||
@@ -17,33 +17,36 @@ static void value_print(
|
||||
b_stream_write_fmt(
|
||||
out, NULL, "%zu : %s", index_val->i_value,
|
||||
index_ty->i_base.ty_def->ty_name);
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
static void type_init(const struct mie_dialect_type *type_info, struct mie_type *type)
|
||||
static void type_init(
|
||||
const struct mie_type_definition *type_info, struct mie_type *type)
|
||||
{
|
||||
type->ty_instance_size = sizeof(struct mie_index);
|
||||
}
|
||||
|
||||
static enum mie_status print(
|
||||
const struct mie_dialect_type *def, const struct mie_type *ty, b_stream *out)
|
||||
const struct mie_type_definition *def, const struct mie_type *ty,
|
||||
b_stream *out)
|
||||
{
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
static enum mie_status parse(
|
||||
const struct mie_dialect_type *def, struct mie_parser *parser,
|
||||
const struct mie_type_definition *def, struct mie_parser *parser,
|
||||
struct mie_type **out)
|
||||
{
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
MIE_DIALECT_TYPE_BEGIN(mie_index_index, "index")
|
||||
MIE_DIALECT_TYPE_STRUCT(struct index_type);
|
||||
MIE_DIALECT_TYPE_INIT(type_init);
|
||||
MIE_DIALECT_TYPE_PRINT(print);
|
||||
MIE_DIALECT_TYPE_PARSE(parse);
|
||||
MIE_DIALECT_TYPE_VALUE_PRINT(value_print);
|
||||
MIE_DIALECT_TYPE_END()
|
||||
MIE_TYPE_DEFINITION_BEGIN(mie_index_index, "index")
|
||||
MIE_TYPE_DEFINITION_STRUCT(struct index_type);
|
||||
MIE_TYPE_DEFINITION_INIT(type_init);
|
||||
MIE_TYPE_DEFINITION_PRINT(print);
|
||||
MIE_TYPE_DEFINITION_PARSE(parse);
|
||||
MIE_TYPE_DEFINITION_VALUE_PRINT(value_print);
|
||||
MIE_TYPE_DEFINITION_END()
|
||||
|
||||
MIE_DIALECT_BEGIN(mie_index, "index")
|
||||
MIE_DIALECT_ADD_TYPE(mie_index_index);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/dialect/op.h>
|
||||
#include <mie/ir/op-definition.h>
|
||||
#include <mie/macros.h>
|
||||
|
||||
static enum mie_status print(const struct mie_op *op, b_stream *out)
|
||||
@@ -12,7 +12,7 @@ static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
MIE_DIALECT_OP_BEGIN(mie_meta_source_filename, "source-filename")
|
||||
MIE_DIALECT_OP_PRINT(print);
|
||||
MIE_DIALECT_OP_PARSE(parse);
|
||||
MIE_DIALECT_OP_END()
|
||||
MIE_OP_DEFINITION_BEGIN(mie_meta_source_filename, "source-filename")
|
||||
MIE_OP_DEFINITION_PRINT(print);
|
||||
MIE_OP_DEFINITION_PARSE(parse);
|
||||
MIE_OP_DEFINITION_END()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/dialect/op.h>
|
||||
#include <mie/ir/op-definition.h>
|
||||
#include <mie/macros.h>
|
||||
|
||||
static enum mie_status print(const struct mie_op *op, b_stream *out)
|
||||
@@ -12,7 +12,7 @@ static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
MIE_DIALECT_OP_BEGIN(mie_ptr_load, "load")
|
||||
MIE_DIALECT_OP_PRINT(print);
|
||||
MIE_DIALECT_OP_PARSE(parse);
|
||||
MIE_DIALECT_OP_END()
|
||||
MIE_OP_DEFINITION_BEGIN(mie_ptr_load, "load")
|
||||
MIE_OP_DEFINITION_PRINT(print);
|
||||
MIE_OP_DEFINITION_PARSE(parse);
|
||||
MIE_OP_DEFINITION_END()
|
||||
|
||||
@@ -1,29 +1,30 @@
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/dialect/type.h>
|
||||
#include <mie/macros.h>
|
||||
#include <mie/type/type-definition.h>
|
||||
|
||||
struct ptr_type {
|
||||
struct mie_dialect_type ptr_base;
|
||||
struct mie_type_definition ptr_base;
|
||||
};
|
||||
|
||||
static enum mie_status print(
|
||||
const struct mie_dialect_type *def, const struct mie_type *ty, b_stream *out)
|
||||
const struct mie_type_definition *def, const struct mie_type *ty,
|
||||
b_stream *out)
|
||||
{
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
static enum mie_status parse(
|
||||
const struct mie_dialect_type *def, struct mie_parser *parser,
|
||||
const struct mie_type_definition *def, struct mie_parser *parser,
|
||||
struct mie_type **out)
|
||||
{
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
MIE_DIALECT_TYPE_BEGIN(mie_ptr_ptr, "ptr")
|
||||
MIE_DIALECT_TYPE_STRUCT(struct ptr_type);
|
||||
MIE_DIALECT_TYPE_PRINT(print);
|
||||
MIE_DIALECT_TYPE_PARSE(parse);
|
||||
MIE_DIALECT_TYPE_END()
|
||||
MIE_TYPE_DEFINITION_BEGIN(mie_ptr_ptr, "ptr")
|
||||
MIE_TYPE_DEFINITION_STRUCT(struct ptr_type);
|
||||
MIE_TYPE_DEFINITION_PRINT(print);
|
||||
MIE_TYPE_DEFINITION_PARSE(parse);
|
||||
MIE_TYPE_DEFINITION_END()
|
||||
|
||||
MIE_DIALECT_BEGIN(mie_ptr, "ptr")
|
||||
MIE_DIALECT_ADD_OP(mie_ptr_load);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/dialect/op.h>
|
||||
#include <mie/ir/op-definition.h>
|
||||
#include <mie/macros.h>
|
||||
|
||||
static enum mie_status print(const struct mie_op *op, b_stream *out)
|
||||
@@ -12,7 +12,7 @@ static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
MIE_DIALECT_OP_BEGIN(mie_ptr_store, "store")
|
||||
MIE_DIALECT_OP_PRINT(print);
|
||||
MIE_DIALECT_OP_PARSE(parse);
|
||||
MIE_DIALECT_OP_END()
|
||||
MIE_OP_DEFINITION_BEGIN(mie_ptr_store, "store")
|
||||
MIE_OP_DEFINITION_PRINT(print);
|
||||
MIE_OP_DEFINITION_PARSE(parse);
|
||||
MIE_OP_DEFINITION_END()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/dialect/op.h>
|
||||
#include <mie/ir/op-definition.h>
|
||||
#include <mie/macros.h>
|
||||
|
||||
static enum mie_status print(const struct mie_op *op, b_stream *out)
|
||||
@@ -12,7 +12,7 @@ static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
MIE_DIALECT_OP_BEGIN(mie_scf_for, "for")
|
||||
MIE_DIALECT_OP_PRINT(print);
|
||||
MIE_DIALECT_OP_PARSE(parse);
|
||||
MIE_DIALECT_OP_END()
|
||||
MIE_OP_DEFINITION_BEGIN(mie_scf_for, "for")
|
||||
MIE_OP_DEFINITION_PRINT(print);
|
||||
MIE_OP_DEFINITION_PARSE(parse);
|
||||
MIE_OP_DEFINITION_END()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/dialect/op.h>
|
||||
#include <mie/ir/op-definition.h>
|
||||
#include <mie/macros.h>
|
||||
|
||||
static enum mie_status print(const struct mie_op *op, b_stream *out)
|
||||
@@ -12,7 +12,7 @@ static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
MIE_DIALECT_OP_BEGIN(mie_scf_if, "if")
|
||||
MIE_DIALECT_OP_PRINT(print);
|
||||
MIE_DIALECT_OP_PARSE(parse);
|
||||
MIE_DIALECT_OP_END()
|
||||
MIE_OP_DEFINITION_BEGIN(mie_scf_if, "if")
|
||||
MIE_OP_DEFINITION_PRINT(print);
|
||||
MIE_OP_DEFINITION_PARSE(parse);
|
||||
MIE_OP_DEFINITION_END()
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#include "scf.h"
|
||||
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/macros.h>
|
||||
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
#ifndef MIE_DIALECT_SCF_H_
|
||||
#define MIE_DIALECT_SCF_H_
|
||||
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/dialect/op.h>
|
||||
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/dialect/op.h>
|
||||
#include <mie/ir/op-definition.h>
|
||||
#include <mie/macros.h>
|
||||
|
||||
static enum mie_status print(const struct mie_op *op, b_stream *out)
|
||||
@@ -12,7 +12,7 @@ static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
MIE_DIALECT_OP_BEGIN(mie_scf_yield, "yield")
|
||||
MIE_DIALECT_OP_PRINT(print);
|
||||
MIE_DIALECT_OP_PARSE(parse);
|
||||
MIE_DIALECT_OP_END()
|
||||
MIE_OP_DEFINITION_BEGIN(mie_scf_yield, "yield")
|
||||
MIE_OP_DEFINITION_PRINT(print);
|
||||
MIE_OP_DEFINITION_PARSE(parse);
|
||||
MIE_OP_DEFINITION_END()
|
||||
|
||||
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()
|
||||
90
mie/id.c
90
mie/id.c
@@ -118,34 +118,6 @@ void mie_id_to_string(const mie_id *id, char *out, size_t max)
|
||||
}
|
||||
}
|
||||
|
||||
void mie_id_map_init(struct mie_id_map *map, const mie_id *ns)
|
||||
{
|
||||
memset(map, 0x0, sizeof *map);
|
||||
|
||||
map->map_ns_id = *ns;
|
||||
}
|
||||
|
||||
const mie_id *mie_id_map_get_ns(const struct mie_id_map *map)
|
||||
{
|
||||
return &map->map_ns_id;
|
||||
}
|
||||
|
||||
void mie_id_map_put(struct mie_id_map *map, mie_id *id, const b_rope *name)
|
||||
{
|
||||
mie_id_init_ns(id, &map->map_ns_id, name);
|
||||
put_id(&map->map_entries, id);
|
||||
}
|
||||
|
||||
void mie_id_map_put_id(struct mie_id_map *map, mie_id *node)
|
||||
{
|
||||
put_id(&map->map_entries, node);
|
||||
}
|
||||
|
||||
mie_id *mie_id_map_get(const struct mie_id_map *map, mie_id *id)
|
||||
{
|
||||
return get_id(&map->map_entries, id);
|
||||
}
|
||||
|
||||
void mie_id_builder_begin(struct mie_id_builder *builder, const mie_id *ns)
|
||||
{
|
||||
memset(builder, 0x0, sizeof *builder);
|
||||
@@ -181,3 +153,65 @@ void mie_id_builder_end(struct mie_id_builder *builder, mie_id *out)
|
||||
out->id_bytes[8] &= 0x3F;
|
||||
out->id_bytes[8] |= 0x80;
|
||||
}
|
||||
|
||||
void mie_id_map_init(struct mie_id_map *map, const mie_id *ns)
|
||||
{
|
||||
memset(map, 0x0, sizeof *map);
|
||||
|
||||
map->map_ns_id = *ns;
|
||||
}
|
||||
|
||||
const mie_id *mie_id_map_get_ns(const struct mie_id_map *map)
|
||||
{
|
||||
return &map->map_ns_id;
|
||||
}
|
||||
|
||||
void mie_id_map_put(struct mie_id_map *map, mie_id *id, const b_rope *name)
|
||||
{
|
||||
mie_id_init_ns(id, &map->map_ns_id, name);
|
||||
put_id(&map->map_entries, id);
|
||||
}
|
||||
|
||||
void mie_id_map_put_id(struct mie_id_map *map, mie_id *node)
|
||||
{
|
||||
put_id(&map->map_entries, node);
|
||||
}
|
||||
|
||||
mie_id *mie_id_map_get(const struct mie_id_map *map, mie_id *id)
|
||||
{
|
||||
return get_id(&map->map_entries, id);
|
||||
}
|
||||
|
||||
enum mie_status mie_id_map_iterator_begin(
|
||||
struct mie_id_map_iterator *it, const struct mie_id_map *map)
|
||||
{
|
||||
memset(it, 0x0, sizeof *it);
|
||||
|
||||
it->_n = b_btree_first(&map->map_entries);
|
||||
|
||||
if (!it->_n) {
|
||||
return MIE_ERR_NO_DATA;
|
||||
}
|
||||
|
||||
it->it_id = b_unbox(mie_id, it->_n, e_node);
|
||||
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
enum mie_status mie_id_map_iterator_move_next(struct mie_id_map_iterator *it)
|
||||
{
|
||||
if (!it->_n) {
|
||||
it->it_id = NULL;
|
||||
return MIE_ERR_NO_DATA;
|
||||
}
|
||||
|
||||
it->_n = b_btree_next(it->_n);
|
||||
if (!it->_n) {
|
||||
it->it_id = NULL;
|
||||
return MIE_ERR_NO_DATA;
|
||||
}
|
||||
|
||||
it->it_id = b_unbox(mie_id, it->_n, e_node);
|
||||
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ struct mie_ctx {
|
||||
struct mie_id_map ctx_traits;
|
||||
|
||||
struct mie_int_cache *ctx_ints;
|
||||
struct mie_float_cache *ctx_floats;
|
||||
struct mie_index_cache *ctx_indices;
|
||||
struct mie_string_cache *ctx_strings;
|
||||
};
|
||||
@@ -38,11 +39,14 @@ MIE_API bool mie_ctx_resolve_op(const struct mie_ctx *ctx, struct mie_op *op);
|
||||
|
||||
MIE_API struct mie_dialect *mie_ctx_get_dialect(
|
||||
const struct mie_ctx *ctx, const char *name);
|
||||
MIE_API struct mie_dialect_type *mie_ctx_get_dialect_type(
|
||||
MIE_API struct mie_type_definition *mie_ctx_get_type_definition(
|
||||
const struct mie_ctx *ctx, const char *dialect_name, const char *type_name);
|
||||
MIE_API const struct mie_trait_definition *mie_ctx_get_trait_definition(
|
||||
const struct mie_ctx *ctx, const char *dialect_name,
|
||||
const char *trait_name);
|
||||
MIE_API struct mie_type *mie_ctx_get_type(
|
||||
struct mie_ctx *ctx, const char *dialect_name, const char *type_name);
|
||||
MIE_API struct mie_type *mie_ctx_get_trait(
|
||||
MIE_API const struct mie_trait *mie_ctx_get_trait(
|
||||
struct mie_ctx *ctx, const char *dialect_name, const char *trait_name);
|
||||
MIE_API struct mie_type *mie_ctx_get_storage_type(
|
||||
struct mie_ctx *ctx, const struct mie_type **parts, size_t nr_parts);
|
||||
|
||||
@@ -44,10 +44,19 @@ MIE_API struct mie_type *mie_arith_int_get_type(
|
||||
MIE_API struct mie_type *mie_arith_float_get_type(
|
||||
struct mie_ctx *ctx, size_t bit_width);
|
||||
|
||||
MIE_API size_t mie_arith_int_type_get_width(const struct mie_type *type);
|
||||
MIE_API size_t mie_arith_float_type_get_width(const struct mie_type *type);
|
||||
|
||||
MIE_API struct mie_int_cache *mie_int_cache_create(void);
|
||||
MIE_API void mie_int_cache_destroy(struct mie_int_cache *cache);
|
||||
MIE_API struct mie_int *mie_int_cache_get(
|
||||
struct mie_int_cache *cache, struct mie_ctx *ctx, size_t value,
|
||||
size_t bit_width);
|
||||
|
||||
MIE_API struct mie_float_cache *mie_float_cache_create(void);
|
||||
MIE_API void mie_float_cache_destroy(struct mie_float_cache *cache);
|
||||
MIE_API struct mie_float *mie_float_cache_get(
|
||||
struct mie_float_cache *cache, struct mie_ctx *ctx, double value,
|
||||
size_t bit_width);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -9,17 +9,17 @@
|
||||
|
||||
struct mie_ctx;
|
||||
|
||||
struct mie_dialect_op;
|
||||
struct mie_dialect_type;
|
||||
struct mie_op_definition;
|
||||
struct mie_type_definition;
|
||||
struct mie_trait_definition;
|
||||
|
||||
struct mie_dialect {
|
||||
mie_id d_id;
|
||||
char *d_name;
|
||||
|
||||
/* map of struct mie_dialect_op */
|
||||
/* map of struct mie_op_definition */
|
||||
struct mie_id_map d_ops;
|
||||
/* map of struct mie_dialect_type */
|
||||
/* map of struct mie_type_definition */
|
||||
struct mie_id_map d_types;
|
||||
/* map of struct mie_trait_definition */
|
||||
struct mie_id_map d_traits;
|
||||
@@ -28,9 +28,9 @@ struct mie_dialect {
|
||||
MIE_API struct mie_dialect *mie_dialect_create(
|
||||
struct mie_ctx *ctx, const char *name);
|
||||
|
||||
MIE_API const struct mie_dialect_op *mie_dialect_get_op(
|
||||
MIE_API const struct mie_op_definition *mie_dialect_get_op(
|
||||
const struct mie_dialect *dialect, const char *name);
|
||||
MIE_API const struct mie_dialect_type *mie_dialect_get_type(
|
||||
MIE_API const struct mie_type_definition *mie_dialect_get_type(
|
||||
const struct mie_dialect *dialect, const char *name);
|
||||
MIE_API const struct mie_trait_definition *mie_dialect_get_trait(
|
||||
const struct mie_dialect *dialect, const char *name);
|
||||
|
||||
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
|
||||
@@ -1,52 +0,0 @@
|
||||
#ifndef MIE_DIALECT_TYPE_H_
|
||||
#define MIE_DIALECT_TYPE_H_
|
||||
|
||||
#include <blue/core/btree.h>
|
||||
#include <blue/core/stream.h>
|
||||
#include <mie/id.h>
|
||||
#include <mie/status.h>
|
||||
#include <mie/trait/trait-table.h>
|
||||
|
||||
struct mie_type;
|
||||
struct mie_value;
|
||||
struct mie_parser;
|
||||
struct mie_dialect;
|
||||
|
||||
enum mie_type_trait {
|
||||
/* this type is parametised. one or more arguments are required to create
|
||||
* a corresponding mie_type instance. in textual IR, references to this
|
||||
* type will be followed by a set of arguments surrounded
|
||||
* by <angle brackets>. */
|
||||
MIE_TYPE_TRAIT_PARAMETISED = 0x01u,
|
||||
|
||||
/* this type can only be used within graph regions. unlike graph ops,
|
||||
* no special prefix is required */
|
||||
MIE_TYPE_TRAIT_GRAPH_TYPE = 0x02u,
|
||||
};
|
||||
|
||||
struct mie_dialect_type {
|
||||
mie_id ty_id;
|
||||
struct mie_trait_table ty_traits;
|
||||
struct mie_dialect *ty_parent;
|
||||
char *ty_name;
|
||||
|
||||
size_t ty_data_size;
|
||||
|
||||
void (*ty_init)(const struct mie_dialect_type *, struct mie_type *);
|
||||
void (*ty_cleanup)(const struct mie_dialect_type *, struct mie_type *);
|
||||
void (*ty_instance_cleanup)(const struct mie_type *, struct mie_value *);
|
||||
enum mie_status (*ty_print)(
|
||||
const struct mie_dialect_type *, const struct mie_type *,
|
||||
b_stream *);
|
||||
void (*ty_value_print)(
|
||||
const struct mie_type *, const struct mie_value *, b_stream *);
|
||||
enum mie_status (*ty_parse)(
|
||||
const struct mie_dialect_type *, struct mie_parser *,
|
||||
struct mie_type **);
|
||||
void (*ty_build_id)(const struct mie_type *, struct mie_id_builder *);
|
||||
};
|
||||
|
||||
MIE_API struct mie_dialect_type *mie_dialect_type_create(
|
||||
struct mie_dialect *parent, const char *name);
|
||||
|
||||
#endif
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <blue/core/queue.h>
|
||||
#include <blue/core/rope.h>
|
||||
#include <mie/misc.h>
|
||||
#include <mie/status.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -55,6 +56,11 @@ struct mie_id_map {
|
||||
b_btree map_entries;
|
||||
};
|
||||
|
||||
struct mie_id_map_iterator {
|
||||
mie_id *it_id;
|
||||
b_btree_node *_n;
|
||||
};
|
||||
|
||||
MIE_API void mie_id_init(
|
||||
mie_id *out, uint32_t a, uint16_t b, uint16_t c, uint16_t d, uint64_t e);
|
||||
MIE_API void mie_id_init_zero(mie_id *out);
|
||||
@@ -68,13 +74,6 @@ static inline int mie_id_compare(const mie_id *a, const mie_id *b)
|
||||
|
||||
MIE_API void mie_id_to_string(const mie_id *id, char *out, size_t max);
|
||||
|
||||
MIE_API void mie_id_map_init(struct mie_id_map *map, const mie_id *ns);
|
||||
MIE_API const mie_id *mie_id_map_get_ns(const struct mie_id_map *map);
|
||||
MIE_API void mie_id_map_put(
|
||||
struct mie_id_map *map, mie_id *node, const b_rope *name);
|
||||
MIE_API void mie_id_map_put_id(struct mie_id_map *map, mie_id *node);
|
||||
MIE_API mie_id *mie_id_map_get(const struct mie_id_map *map, mie_id *id);
|
||||
|
||||
MIE_API void mie_id_builder_begin(struct mie_id_builder *builder, const mie_id *ns);
|
||||
MIE_API void mie_id_builder_add(
|
||||
struct mie_id_builder *builder, const void *p, size_t len);
|
||||
@@ -93,4 +92,21 @@ MIE_API void mie_id_builder_add_marker(
|
||||
struct mie_id_builder *builder, enum mie_id_builder_marker marker);
|
||||
MIE_API void mie_id_builder_end(struct mie_id_builder *builder, mie_id *out);
|
||||
|
||||
MIE_API void mie_id_map_init(struct mie_id_map *map, const mie_id *ns);
|
||||
static inline bool mie_id_map_empty(const struct mie_id_map *map)
|
||||
{
|
||||
return b_btree_empty(&map->map_entries);
|
||||
}
|
||||
|
||||
MIE_API const mie_id *mie_id_map_get_ns(const struct mie_id_map *map);
|
||||
MIE_API void mie_id_map_put(
|
||||
struct mie_id_map *map, mie_id *node, const b_rope *name);
|
||||
MIE_API void mie_id_map_put_id(struct mie_id_map *map, mie_id *node);
|
||||
MIE_API mie_id *mie_id_map_get(const struct mie_id_map *map, mie_id *id);
|
||||
|
||||
MIE_API enum mie_status mie_id_map_iterator_begin(
|
||||
struct mie_id_map_iterator *it, const struct mie_id_map *map);
|
||||
MIE_API enum mie_status mie_id_map_iterator_move_next(
|
||||
struct mie_id_map_iterator *it);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef MIE_DIALECT_OP_H_
|
||||
#define MIE_DIALECT_OP_H_
|
||||
#ifndef MIE_IR_OP_DEFINITION_H_
|
||||
#define MIE_IR_OP_DEFINITION_H_
|
||||
|
||||
#include <blue/core/btree.h>
|
||||
#include <blue/core/stream.h>
|
||||
@@ -14,6 +14,7 @@ struct mie_op;
|
||||
struct mie_parser;
|
||||
struct mie_dialect;
|
||||
|
||||
#if 0
|
||||
enum mie_op_trait {
|
||||
MIE_OP_TRAIT_NONE = 0x00u,
|
||||
|
||||
@@ -34,6 +35,7 @@ enum mie_op_trait {
|
||||
* values defined in the enclosing scope. */
|
||||
MIE_OP_TRAIT_ISOLATED_FROM_ABOVE = 0x08u,
|
||||
};
|
||||
#endif
|
||||
|
||||
enum mie_op_param_type {
|
||||
/* op has no parameter */
|
||||
@@ -88,7 +90,7 @@ struct mie_op_result {
|
||||
};
|
||||
};
|
||||
|
||||
struct mie_dialect_op {
|
||||
struct mie_op_definition {
|
||||
mie_id op_id;
|
||||
struct mie_dialect *op_parent;
|
||||
char *op_name;
|
||||
@@ -101,7 +103,10 @@ struct mie_dialect_op {
|
||||
enum mie_status (*op_parse)(struct mie_parser *, struct mie_op *);
|
||||
};
|
||||
|
||||
MIE_API struct mie_dialect_op *mie_dialect_op_create(
|
||||
MIE_API struct mie_op_definition *mie_op_definition_create(
|
||||
struct mie_dialect *parent, const char *name);
|
||||
|
||||
MIE_API enum mie_status mie_op_definition_add_trait(
|
||||
struct mie_op_definition *op, const struct mie_trait *trait);
|
||||
|
||||
#endif
|
||||
@@ -15,16 +15,12 @@ struct mie_block;
|
||||
struct mie_region;
|
||||
|
||||
struct mie_dialect;
|
||||
struct mie_dialect_op;
|
||||
struct mie_op_definition;
|
||||
|
||||
enum mie_op_flags {
|
||||
MIE_OP_F_OP_RESOLVED = 0x01u,
|
||||
MIE_OP_F_ARGS_RESOLVED = 0x02u,
|
||||
};
|
||||
|
||||
struct mie_op_successor {
|
||||
struct mie_block *s_block;
|
||||
MIE_VECTOR_DECLARE(struct mie_register *, s_params);
|
||||
MIE_OP_F_ARG_RESOLVED = 0x02u,
|
||||
MIE_OP_F_SUCCESSOR_RESOLVED = 0x04u,
|
||||
};
|
||||
|
||||
struct mie_op_attribute {
|
||||
@@ -33,21 +29,35 @@ struct mie_op_attribute {
|
||||
};
|
||||
|
||||
struct mie_op_arg {
|
||||
enum mie_op_flags arg_flags;
|
||||
struct mie_file_span arg_span;
|
||||
union {
|
||||
/* only valid if the parent op's F_ARGS_RESOLVED flag is set */
|
||||
/* only valid if F_ARG_RESOLVED is set in arg_flags */
|
||||
struct mie_register *arg_value;
|
||||
/* only valid if the parent op's F_ARGS_RESOLVED flag is NOT set */
|
||||
/* only valid if F_ARG_RESOLVED is NOT set in arg_flags */
|
||||
struct mie_register_ref arg_unresolved;
|
||||
};
|
||||
};
|
||||
|
||||
struct mie_op_successor {
|
||||
enum mie_op_flags s_flags;
|
||||
|
||||
union {
|
||||
/* only valid if F_SUCCESSOR_RESOLVED is set in s_flags; */
|
||||
struct mie_block *s_block;
|
||||
/* only valid if F_SUCCESSOR_RESOLVED is NOT set in s_flags; */
|
||||
char *s_block_name;
|
||||
};
|
||||
|
||||
MIE_VECTOR_DECLARE(struct mie_op_arg, s_args);
|
||||
};
|
||||
|
||||
struct mie_op {
|
||||
enum mie_op_flags op_flags;
|
||||
|
||||
/* these pointers are only valid if the F_RESOLVED flag is set */
|
||||
/* these pointers are only valid if the F_OP_RESOLVED flag is set */
|
||||
const struct mie_dialect *op_dialect;
|
||||
const struct mie_dialect_op *op_info;
|
||||
const struct mie_op_definition *op_info;
|
||||
|
||||
struct mie_file_span op_name_span;
|
||||
/* only valid if the F_RESOLVED flag is NOT set */
|
||||
|
||||
@@ -8,76 +8,109 @@
|
||||
if (!self) { \
|
||||
return NULL; \
|
||||
} \
|
||||
struct mie_dialect_op *op = NULL; \
|
||||
struct mie_dialect_type *type = NULL;
|
||||
struct mie_op_definition *op = NULL; \
|
||||
struct mie_type_definition *type = NULL; \
|
||||
struct mie_trait_definition *trait = NULL;
|
||||
|
||||
#define __MIE_DIALECT_END() \
|
||||
return self; \
|
||||
}
|
||||
|
||||
#define __MIE_DIALECT_OP_BEGIN(func_prefix, op_name) \
|
||||
struct mie_dialect_op *func_prefix##_op_create( \
|
||||
#define __MIE_OP_DEFINITION_BEGIN(func_prefix, op_name) \
|
||||
struct mie_op_definition *func_prefix##_op_create( \
|
||||
struct mie_dialect *d, struct mie_ctx *ctx) \
|
||||
{ \
|
||||
struct mie_dialect_op *op = mie_dialect_op_create(d, op_name); \
|
||||
struct mie_op_definition *op \
|
||||
= mie_op_definition_create(d, op_name); \
|
||||
if (!op) { \
|
||||
return NULL; \
|
||||
}
|
||||
} \
|
||||
const struct mie_trait *trait = NULL;
|
||||
|
||||
#define __MIE_DIALECT_OP_END() \
|
||||
#define __MIE_OP_DEFINITION_END() \
|
||||
return op; \
|
||||
}
|
||||
|
||||
#define __MIE_DIALECT_TYPE_BEGIN(func_prefix, type_name) \
|
||||
struct mie_dialect_type *func_prefix##_type_create( \
|
||||
#define __MIE_TYPE_DEFINITION_BEGIN(func_prefix, type_name) \
|
||||
struct mie_type_definition *func_prefix##_type_create( \
|
||||
struct mie_dialect *d, struct mie_ctx *ctx) \
|
||||
{ \
|
||||
struct mie_dialect_type *type \
|
||||
= mie_dialect_type_create(d, type_name); \
|
||||
struct mie_type_definition *type \
|
||||
= mie_type_definition_create(d, type_name); \
|
||||
if (!type) { \
|
||||
return NULL; \
|
||||
}
|
||||
} \
|
||||
const struct mie_trait *trait = NULL;
|
||||
|
||||
#define __MIE_DIALECT_TYPE_END() \
|
||||
#define __MIE_TYPE_DEFINITION_END() \
|
||||
return type; \
|
||||
}
|
||||
|
||||
#define __MIE_TRAIT_DEFINITION_BEGIN(func_prefix, trait_name) \
|
||||
struct mie_trait_definition *func_prefix##_trait_create( \
|
||||
struct mie_dialect *d, struct mie_ctx *ctx) \
|
||||
{ \
|
||||
struct mie_trait_definition *trait \
|
||||
= mie_trait_definition_create(d, trait_name); \
|
||||
if (!trait) { \
|
||||
return NULL; \
|
||||
}
|
||||
|
||||
#define __MIE_TRAIT_DEFINITION_END() \
|
||||
return trait; \
|
||||
}
|
||||
|
||||
#define __MIE_DIALECT_ADD_OP(op_id) \
|
||||
extern struct mie_dialect_op *op_id##_op_create( \
|
||||
extern struct mie_op_definition *op_id##_op_create( \
|
||||
struct mie_dialect *, struct mie_ctx *); \
|
||||
op = op_id##_op_create(self, ctx)
|
||||
#define __MIE_DIALECT_ADD_TYPE(type_id) \
|
||||
extern struct mie_dialect_type *type_id##_type_create( \
|
||||
extern struct mie_type_definition *type_id##_type_create( \
|
||||
struct mie_dialect *, struct mie_ctx *); \
|
||||
type = type_id##_type_create(self, ctx)
|
||||
#define __MIE_DIALECT_ADD_TRAIT(trait_id) \
|
||||
extern struct mie_trait_definition *trait_id##_trait_create( \
|
||||
struct mie_dialect *, struct mie_ctx *); \
|
||||
trait = trait_id##_trait_create(self, ctx)
|
||||
|
||||
#define MIE_DIALECT_BEGIN(c_sym, name) __MIE_DIALECT_BEGIN(c_sym, name)
|
||||
#define MIE_DIALECT_END() __MIE_DIALECT_END()
|
||||
#define MIE_DIALECT_ADD_OP(c_sym) __MIE_DIALECT_ADD_OP(c_sym)
|
||||
#define MIE_DIALECT_ADD_TYPE(c_sym) __MIE_DIALECT_ADD_TYPE(c_sym)
|
||||
#define MIE_DIALECT_BEGIN(c_sym, name) __MIE_DIALECT_BEGIN(c_sym, name)
|
||||
#define MIE_DIALECT_END() __MIE_DIALECT_END()
|
||||
#define MIE_DIALECT_ADD_OP(c_sym) __MIE_DIALECT_ADD_OP(c_sym)
|
||||
#define MIE_DIALECT_ADD_TYPE(c_sym) __MIE_DIALECT_ADD_TYPE(c_sym)
|
||||
#define MIE_DIALECT_ADD_TRAIT(c_sym) __MIE_DIALECT_ADD_TRAIT(c_sym)
|
||||
|
||||
#define MIE_DIALECT_OP_BEGIN(c_sym, op) __MIE_DIALECT_OP_BEGIN(c_sym, op)
|
||||
#define MIE_DIALECT_OP_END() __MIE_DIALECT_OP_END()
|
||||
#define MIE_DIALECT_OP_PRINT(func) op->op_print = (func)
|
||||
#define MIE_DIALECT_OP_PARSE(func) op->op_parse = (func)
|
||||
#define MIE_OP_DEFINITION_BEGIN(c_sym, op) __MIE_OP_DEFINITION_BEGIN(c_sym, op)
|
||||
#define MIE_OP_DEFINITION_END() __MIE_OP_DEFINITION_END()
|
||||
#define MIE_OP_DEFINITION_PRINT(func) op->op_print = (func)
|
||||
#define MIE_OP_DEFINITION_PARSE(func) op->op_parse = (func)
|
||||
#define MIE_OP_DEFINITION_TRAIT(trait_dialect, trait_name) \
|
||||
trait = mie_ctx_get_trait(ctx, trait_dialect, trait_name); \
|
||||
mie_op_definition_add_trait(op, trait);
|
||||
|
||||
#define MIE_DIALECT_TYPE_BEGIN(c_sym, type) \
|
||||
__MIE_DIALECT_TYPE_BEGIN(c_sym, type)
|
||||
#define MIE_DIALECT_TYPE_END() __MIE_DIALECT_TYPE_END()
|
||||
#define MIE_DIALECT_TYPE_FLAGS(flags) type->ty_flags = flags
|
||||
#define MIE_DIALECT_TYPE_STRUCT(name) type->ty_data_size = sizeof(name)
|
||||
#define MIE_DIALECT_TYPE_INIT(func) type->ty_init = (func)
|
||||
#define MIE_DIALECT_TYPE_PRINT(func) type->ty_print = (func)
|
||||
#define MIE_DIALECT_TYPE_VALUE_PRINT(func) type->ty_value_print = (func)
|
||||
#define MIE_DIALECT_TYPE_PARSE(func) type->ty_parse = (func)
|
||||
#define MIE_DIALECT_TYPE_BUILD_ID(func) type->ty_build_id = (func)
|
||||
#define MIE_DIALECT_TYPE_INIT(func) type->ty_init = (func)
|
||||
#define MIE_DIALECT_TYPE_CLEANUP(func) type->ty_cleanup = (func)
|
||||
#define MIE_TYPE_DEFINITION_BEGIN(c_sym, type) \
|
||||
__MIE_TYPE_DEFINITION_BEGIN(c_sym, type)
|
||||
#define MIE_TYPE_DEFINITION_END() __MIE_TYPE_DEFINITION_END()
|
||||
#define MIE_TYPE_DEFINITION_FLAGS(flags) type->ty_flags = flags
|
||||
#define MIE_TYPE_DEFINITION_STRUCT(name) type->ty_data_size = sizeof(name)
|
||||
#define MIE_TYPE_DEFINITION_INIT(func) type->ty_init = (func)
|
||||
#define MIE_TYPE_DEFINITION_PRINT(func) type->ty_print = (func)
|
||||
#define MIE_TYPE_DEFINITION_VALUE_PRINT(func) type->ty_value_print = (func)
|
||||
#define MIE_TYPE_DEFINITION_PARSE(func) type->ty_parse = (func)
|
||||
#define MIE_TYPE_DEFINITION_BUILD_ID(func) type->ty_build_id = (func)
|
||||
#define MIE_TYPE_DEFINITION_INIT(func) type->ty_init = (func)
|
||||
#define MIE_TYPE_DEFINITION_CLEANUP(func) type->ty_cleanup = (func)
|
||||
#define MIE_TYPE_DEFINITION_TRAIT(trait_dialect, trait_name) \
|
||||
trait = mie_ctx_get_trait(ctx, trait_dialect, trait_name); \
|
||||
mie_type_definition_add_trait(type, trait);
|
||||
|
||||
#define MIE_DIALECT_TRAIT_BEGIN(c_sym, trait)
|
||||
#define MIE_DIALECT_TRAIT_END()
|
||||
#define MIE_DIALECT_TRAIT_STRUCT(name)
|
||||
#define MIE_DIALECT_TRAIT_PRINT(func)
|
||||
#define MIE_DIALECT_TRAIT_CLEANUP(func)
|
||||
#define MIE_TRAIT_DEFINITION_BEGIN(c_sym, trait) \
|
||||
__MIE_TRAIT_DEFINITION_BEGIN(c_sym, trait)
|
||||
#define MIE_TRAIT_DEFINITION_END() __MIE_TRAIT_DEFINITION_END()
|
||||
#define MIE_TRAIT_DEFINITION_TARGETS(targets) trait->tr_target = (targets)
|
||||
#define MIE_TRAIT_DEFINITION_STRUCT(name) trait->tr_data_size = sizeof(name)
|
||||
#define MIE_TRAIT_DEFINITION_PRINT(func) trait->tr_print = (func)
|
||||
#define MIE_TRAIT_DEFINITION_BUILD_ID(func) trait->tr_build_id = (func)
|
||||
#define MIE_TRAIT_DEFINITION_CLEANUP(func) trait->tr_cleanup = (func)
|
||||
#define MIE_TRAIT_DEFINITION_VALIDATE(func) trait->tr_validate = (func)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -22,6 +22,7 @@ struct mie_op_arg;
|
||||
struct mie_op_attribute;
|
||||
struct mie_op_successor;
|
||||
struct mie_register;
|
||||
struct mie_value;
|
||||
|
||||
MIE_API struct mie_parser *mie_parser_create(
|
||||
struct mie_ctx *ctx, struct mie_lex *lex);
|
||||
@@ -38,6 +39,10 @@ MIE_API bool mie_parser_check_type(struct mie_parser *ctx, enum mie_token_type t
|
||||
MIE_API bool mie_parser_check_symbol(
|
||||
struct mie_parser *ctx, enum mie_token_symbol sym);
|
||||
|
||||
MIE_API bool mie_parser_parse_int(
|
||||
struct mie_parser *ctx, long long *out, struct mie_file_span *loc);
|
||||
MIE_API bool mie_parser_parse_float(
|
||||
struct mie_parser *ctx, double *out, struct mie_file_span *loc);
|
||||
MIE_API bool mie_parser_parse_word(
|
||||
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
|
||||
MIE_API bool mie_parser_parse_instname(
|
||||
@@ -61,6 +66,7 @@ MIE_API bool mie_parser_parse_string(
|
||||
MIE_API bool mie_parser_parse_keyword(struct mie_parser *ctx, const char *kw);
|
||||
MIE_API bool mie_parser_parse_symbol(
|
||||
struct mie_parser *ctx, enum mie_token_symbol sym);
|
||||
MIE_API bool mie_parser_parse_linefeed(struct mie_parser *ctx);
|
||||
|
||||
MIE_API bool mie_parser_parse_type(
|
||||
struct mie_parser *ctx, const struct mie_type **out);
|
||||
@@ -74,6 +80,11 @@ MIE_API bool mie_parser_parse_operand(
|
||||
MIE_API bool mie_parser_parse_operand_list(
|
||||
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_arg, out));
|
||||
|
||||
MIE_API bool mie_parser_parse_parameter(
|
||||
struct mie_parser *ctx, struct mie_op_arg *out);
|
||||
MIE_API bool mie_parser_parse_parameter_list(
|
||||
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_arg, out));
|
||||
|
||||
MIE_API bool mie_parser_parse_unknown_keyword(struct mie_parser *ctx, b_string *out);
|
||||
MIE_API bool mie_parser_parse_unknown_symbol(
|
||||
struct mie_parser *ctx, enum mie_token_symbol sym);
|
||||
@@ -89,6 +100,12 @@ MIE_API bool mie_parser_parse_region(
|
||||
struct mie_parser *ctx, struct mie_region *region);
|
||||
MIE_API bool mie_parser_parse_region_list(
|
||||
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_region, out));
|
||||
MIE_API bool mie_parser_parse_anonymous_block(
|
||||
struct mie_parser *ctx, struct mie_name_map *names,
|
||||
struct mie_block *block);
|
||||
MIE_API bool mie_parser_parse_block(
|
||||
struct mie_parser *ctx, struct mie_name_map *names,
|
||||
struct mie_block *block);
|
||||
|
||||
MIE_API bool mie_parser_parse_attribute(
|
||||
struct mie_parser *ctx, struct mie_op_attribute *attrib);
|
||||
@@ -103,5 +120,6 @@ MIE_API bool mie_parser_parse_successor_list(
|
||||
MIE_API bool mie_parser_parse_module(struct mie_parser *ctx, struct mie_module *mod);
|
||||
MIE_API bool mie_parser_parse_op(
|
||||
struct mie_parser *ctx, struct mie_name_map *names, struct mie_op *dest);
|
||||
MIE_API bool mie_parser_parse_value(struct mie_parser *ctx, struct mie_value **dest);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -14,7 +14,7 @@ enum mie_token_type {
|
||||
MIE_TOK_NONE = 0,
|
||||
MIE_TOK_LINEFEED = 0x0001u,
|
||||
MIE_TOK_INT = 0x0002u,
|
||||
MIE_TOK_DOUBLE = 0x0004u,
|
||||
MIE_TOK_FLOAT = 0x0004u,
|
||||
MIE_TOK_SYMBOL = 0x0008u,
|
||||
MIE_TOK_STRING = 0x0010u,
|
||||
/* single words, not dot-delimited */
|
||||
@@ -42,7 +42,7 @@ enum mie_token_type {
|
||||
enum mie_token_value_type {
|
||||
MIE_TOK_V_NONE = 0,
|
||||
MIE_TOK_V_INT,
|
||||
MIE_TOK_V_DOUBLE,
|
||||
MIE_TOK_V_FLOAT,
|
||||
MIE_TOK_V_STRING,
|
||||
MIE_TOK_V_SYMBOL,
|
||||
};
|
||||
@@ -83,7 +83,7 @@ struct mie_token {
|
||||
char *tok_str;
|
||||
enum mie_token_symbol tok_sym;
|
||||
long long tok_int;
|
||||
double tok_double;
|
||||
double tok_float;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ enum mie_status {
|
||||
MIE_ERR_INTERNAL_FAILURE,
|
||||
MIE_ERR_NO_MEMORY,
|
||||
MIE_ERR_NO_ENTRY,
|
||||
MIE_ERR_NO_DATA,
|
||||
};
|
||||
|
||||
MIE_API const struct b_error_vendor *mie_error_vendor(void);
|
||||
|
||||
64
mie/include/mie/trait/trait-definition.h
Normal file
64
mie/include/mie/trait/trait-definition.h
Normal file
@@ -0,0 +1,64 @@
|
||||
#ifndef MIE_TRAIT_TRAIT_DEFINITION_H_
|
||||
#define MIE_TRAIT_TRAIT_DEFINITION_H_
|
||||
|
||||
#include <blue/core/stream.h>
|
||||
#include <mie/id.h>
|
||||
#include <mie/status.h>
|
||||
|
||||
struct mie_trait;
|
||||
struct mie_dialect;
|
||||
|
||||
enum mie_trait_flags {
|
||||
/* a trait user can only apply the trait once. this is assumed to be the
|
||||
* case unless a trait is parametised, in which case this flag can be
|
||||
* used to prevent more than one specialisation from being used. */
|
||||
MIE_TRAIT_F_UNIQUE = 0x01u,
|
||||
MIE_TRAIT_F_PARAMETISED = 0x02u,
|
||||
};
|
||||
|
||||
/* describe exactly which objects a trait can be applied to */
|
||||
enum mie_trait_target_type {
|
||||
MIE_TRAIT_TARGET_NONE = 0x00u,
|
||||
MIE_TRAIT_TARGET_OP = 0x01u,
|
||||
MIE_TRAIT_TARGET_TYPE = 0x02u,
|
||||
};
|
||||
|
||||
struct mie_trait_target {
|
||||
enum mie_trait_target_type target_type;
|
||||
union {
|
||||
const struct mie_type *ptr_type;
|
||||
const struct mie_op *ptr_op;
|
||||
} target_ptr;
|
||||
};
|
||||
|
||||
/* used to define a trait */
|
||||
struct mie_trait_definition {
|
||||
/* ID for the generic trait */
|
||||
mie_id tr_id;
|
||||
char *tr_name;
|
||||
struct mie_dialect *tr_parent;
|
||||
enum mie_trait_flags tr_flags;
|
||||
/* compatible target bitmask */
|
||||
enum mie_trait_target_type tr_target;
|
||||
|
||||
/* the size of any corresponding struct mie_trait instances */
|
||||
size_t tr_data_size;
|
||||
|
||||
void (*tr_init)(const struct mie_trait_definition *, struct mie_trait *);
|
||||
enum mie_status (*tr_build_id)(
|
||||
const struct mie_trait_definition *, const struct mie_trait *,
|
||||
struct mie_id_builder *);
|
||||
enum mie_status (*tr_print)(
|
||||
const struct mie_trait_definition *, const struct mie_trait *,
|
||||
b_stream *);
|
||||
enum mie_status (*tr_cleanup)(
|
||||
const struct mie_trait_definition *, struct mie_trait *);
|
||||
enum mie_status (*tr_validate)(
|
||||
const struct mie_trait_definition *, const struct mie_trait *,
|
||||
const struct mie_trait_target *);
|
||||
};
|
||||
|
||||
MIE_API struct mie_trait_definition *mie_trait_definition_create(
|
||||
struct mie_dialect *parent, const char *name);
|
||||
|
||||
#endif
|
||||
@@ -15,6 +15,9 @@ struct mie_trait_table {
|
||||
|
||||
struct mie_trait_table_iterator {
|
||||
const struct mie_trait *it_trait;
|
||||
int _f;
|
||||
struct mie_id_map_iterator _n;
|
||||
const struct mie_trait_table *_m;
|
||||
b_queue_entry *_e;
|
||||
};
|
||||
|
||||
@@ -32,6 +35,9 @@ MIE_API enum mie_status mie_trait_table_get_generic(
|
||||
const char *trait_name, struct mie_trait_table_iterator *it);
|
||||
MIE_API enum mie_status mie_trait_table_put(
|
||||
struct mie_trait_table *table, const struct mie_trait *trait);
|
||||
MIE_API enum mie_status mie_trait_table_iterate(
|
||||
const struct mie_trait_table *table,
|
||||
int (*func)(const struct mie_trait *, void *), void *arg);
|
||||
|
||||
MIE_API enum mie_status mie_trait_table_iterator_move_next(
|
||||
struct mie_trait_table_iterator *it);
|
||||
|
||||
@@ -3,40 +3,18 @@
|
||||
|
||||
#include <mie/id.h>
|
||||
|
||||
struct mie_trait;
|
||||
|
||||
enum mie_trait_flags {
|
||||
/* a trait user can only apply the trait once. this is assumed to be the
|
||||
* case unless a trait is parametised, in which case this flag can be
|
||||
* used to prevent more than one specialisation from being used. */
|
||||
MIE_TRAIT_F_UNIQUE = 0x01u,
|
||||
MIE_TRAIT_F_PARAMETISED = 0x02u,
|
||||
};
|
||||
|
||||
/* used to define a trait */
|
||||
struct mie_trait_definition {
|
||||
/* ID for the generic trait */
|
||||
mie_id tr_id;
|
||||
char *tr_name;
|
||||
enum mie_trait_flags tr_flags;
|
||||
|
||||
/* the size of any corresponding struct mie_trait instances */
|
||||
size_t tr_data_size;
|
||||
|
||||
enum mie_status (*tr_build_id)(
|
||||
const struct mie_trait_definition *, const struct mie_trait *,
|
||||
struct mie_id_builder *);
|
||||
enum mie_status (*tr_print)(
|
||||
const struct mie_trait_definition *, const struct mie_trait *,
|
||||
b_stream *);
|
||||
};
|
||||
struct mie_dialect;
|
||||
struct mie_trait_definition;
|
||||
|
||||
/* used to link an op/type/etc to a trait. if the trait is parametised, this
|
||||
* struct includes any parameter values. */
|
||||
struct mie_trait {
|
||||
/* this is NOT the same as tr_def->tr_id */
|
||||
mie_id tr_id;
|
||||
char *tr_name;
|
||||
const struct mie_trait_definition *tr_def;
|
||||
};
|
||||
|
||||
MIE_API void mie_trait_print(const struct mie_trait *type, b_stream *out);
|
||||
|
||||
#endif
|
||||
|
||||
39
mie/include/mie/type/type-definition.h
Normal file
39
mie/include/mie/type/type-definition.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#ifndef MIE_TYPE_TYPE_DEFINITION_H_
|
||||
#define MIE_TYPE_TYPE_DEFINITION_H_
|
||||
|
||||
#include <mie/trait/trait-table.h>
|
||||
|
||||
struct mie_value;
|
||||
struct mie_type;
|
||||
struct mie_parser;
|
||||
|
||||
/* a static struct that defines the properties, traits, and callbacks for a type. */
|
||||
struct mie_type_definition {
|
||||
mie_id ty_id;
|
||||
struct mie_trait_table ty_traits;
|
||||
struct mie_dialect *ty_parent;
|
||||
char *ty_name;
|
||||
|
||||
size_t ty_data_size;
|
||||
|
||||
void (*ty_init)(const struct mie_type_definition *, struct mie_type *);
|
||||
void (*ty_cleanup)(const struct mie_type_definition *, struct mie_type *);
|
||||
void (*ty_instance_cleanup)(const struct mie_type *, struct mie_value *);
|
||||
enum mie_status (*ty_print)(
|
||||
const struct mie_type_definition *, const struct mie_type *,
|
||||
b_stream *);
|
||||
enum mie_status (*ty_value_print)(
|
||||
const struct mie_type *, const struct mie_value *, b_stream *);
|
||||
enum mie_status (*ty_parse)(
|
||||
const struct mie_type_definition *, struct mie_parser *,
|
||||
struct mie_type **);
|
||||
void (*ty_build_id)(const struct mie_type *, struct mie_id_builder *);
|
||||
};
|
||||
|
||||
MIE_API struct mie_type_definition *mie_type_definition_create(
|
||||
struct mie_dialect *parent, const char *name);
|
||||
|
||||
MIE_API enum mie_status mie_type_definition_add_trait(
|
||||
struct mie_type_definition *type, const struct mie_trait *trait);
|
||||
|
||||
#endif
|
||||
@@ -8,37 +8,40 @@
|
||||
#include <stddef.h>
|
||||
|
||||
struct mie_dialect;
|
||||
struct mie_dialect_type;
|
||||
struct mie_type_definition;
|
||||
|
||||
struct mie_value;
|
||||
struct mie_id_builder;
|
||||
|
||||
enum mie_type_category {
|
||||
/* all other types */
|
||||
MIE_TYPE_OTHER = 0,
|
||||
/* storage types (structs, etc) */
|
||||
MIE_TYPE_STORAGE,
|
||||
/* functional types (represents the param/result types of a function) */
|
||||
MIE_TYPE_FUNCTION,
|
||||
};
|
||||
#if 0
|
||||
enum mie_type_trait {
|
||||
/* this type is parametised. one or more arguments are required to create
|
||||
* a corresponding mie_type instance. in textual IR, references to this
|
||||
* type will be followed by a set of arguments surrounded
|
||||
* by <angle brackets>. */
|
||||
MIE_TYPE_TRAIT_PARAMETISED = 0x01u,
|
||||
|
||||
/* a mie_type is an instance of mie_dialect_type.
|
||||
* if the mie_dialect_type is a parametised type, the resulting mie_type
|
||||
/* this type can only be used within graph regions. unlike graph ops,
|
||||
* no special prefix is required */
|
||||
MIE_TYPE_TRAIT_GRAPH_TYPE = 0x02u,
|
||||
};
|
||||
#endif
|
||||
|
||||
/* a mie_type is a type-instance created from a mie_type_definition.
|
||||
* if the mie_type_definition is a parametised type, the resulting mie_type
|
||||
* will have those parameters baked in.
|
||||
* this is a base struct. dialects that defined their own types do so by
|
||||
* inheriting from this struct. */
|
||||
struct mie_type {
|
||||
/* this is NOT the same as ty_def->ty_id */
|
||||
mie_id ty_id;
|
||||
enum mie_type_category ty_category;
|
||||
|
||||
char *ty_name;
|
||||
struct mie_dialect_type *ty_def;
|
||||
struct mie_type_definition *ty_def;
|
||||
|
||||
size_t ty_instance_size;
|
||||
};
|
||||
|
||||
MIE_API struct mie_type *mie_type_create(struct mie_dialect_type *type);
|
||||
MIE_API struct mie_type *mie_type_create(struct mie_type_definition *type);
|
||||
MIE_API void mie_type_print(const struct mie_type *type, b_stream *out);
|
||||
MIE_API void mie_type_build_id(
|
||||
const struct mie_type *type, struct mie_id_builder *ctx);
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#include <blue/ds/string.h>
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/dialect/op.h>
|
||||
#include <mie/ir/op-definition.h>
|
||||
|
||||
struct mie_dialect_op *mie_dialect_op_create(
|
||||
struct mie_op_definition *mie_op_definition_create(
|
||||
struct mie_dialect *parent, const char *name)
|
||||
{
|
||||
struct mie_dialect_op *out = malloc(sizeof *out);
|
||||
struct mie_op_definition *out = malloc(sizeof *out);
|
||||
if (!out) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -17,9 +17,16 @@ struct mie_dialect_op *mie_dialect_op_create(
|
||||
}
|
||||
|
||||
out->op_parent = parent;
|
||||
mie_trait_table_init(&out->op_traits);
|
||||
|
||||
b_rope name_rope = B_ROPE_CSTR(name);
|
||||
mie_id_map_put(&parent->d_ops, &out->op_id, &name_rope);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
enum mie_status mie_op_definition_add_trait(
|
||||
struct mie_op_definition *op, const struct mie_trait *trait)
|
||||
{
|
||||
return mie_trait_table_put(&op->op_traits, trait);
|
||||
}
|
||||
@@ -404,7 +404,7 @@ static enum mie_status push_int(struct mie_lex *lex, unsigned long long v)
|
||||
return push_token(lex, tok);
|
||||
}
|
||||
|
||||
static enum mie_status push_double(struct mie_lex *lex, double v)
|
||||
static enum mie_status push_float(struct mie_lex *lex, double v)
|
||||
{
|
||||
struct mie_token *tok = malloc(sizeof *tok);
|
||||
if (!tok) {
|
||||
@@ -413,9 +413,9 @@ static enum mie_status push_double(struct mie_lex *lex, double v)
|
||||
|
||||
memset(tok, 0x0, sizeof *tok);
|
||||
|
||||
tok->tok_type = MIE_TOK_DOUBLE;
|
||||
tok->tok_value_type = MIE_TOK_V_DOUBLE;
|
||||
tok->tok_double = v;
|
||||
tok->tok_type = MIE_TOK_FLOAT;
|
||||
tok->tok_value_type = MIE_TOK_V_FLOAT;
|
||||
tok->tok_float = v;
|
||||
return push_token(lex, tok);
|
||||
}
|
||||
|
||||
@@ -541,7 +541,7 @@ static enum mie_status read_number(struct mie_lex *lex, bool negate)
|
||||
v *= -1;
|
||||
}
|
||||
|
||||
return push_double(lex, v);
|
||||
return push_float(lex, v);
|
||||
} else {
|
||||
unsigned long long v = strtoull(s, &ep, base);
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <mie/ctx.h>
|
||||
#include <mie/dialect/arith.h>
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/dialect/type.h>
|
||||
#include <mie/ir/block.h>
|
||||
#include <mie/ir/module.h>
|
||||
#include <mie/ir/op.h>
|
||||
#include <mie/ir/region.h>
|
||||
@@ -10,13 +10,22 @@
|
||||
#include <mie/parse/parse.h>
|
||||
#include <mie/parse/token.h>
|
||||
#include <mie/type/function.h>
|
||||
#include <mie/type/type-definition.h>
|
||||
#include <mie/vector.h>
|
||||
|
||||
struct mie_parser {
|
||||
struct mie_ctx *p_ctx;
|
||||
struct mie_lex *p_lex;
|
||||
enum mie_status p_status;
|
||||
b_string *s_tmp;
|
||||
};
|
||||
|
||||
static b_string *get_temp_string(struct mie_parser *parser)
|
||||
{
|
||||
b_string_clear(parser->s_tmp);
|
||||
return parser->s_tmp;
|
||||
}
|
||||
|
||||
struct mie_parser *mie_parser_create(struct mie_ctx *ctx, struct mie_lex *lex)
|
||||
{
|
||||
struct mie_parser *out = malloc(sizeof *out);
|
||||
@@ -26,6 +35,12 @@ struct mie_parser *mie_parser_create(struct mie_ctx *ctx, struct mie_lex *lex)
|
||||
|
||||
memset(out, 0x0, sizeof *out);
|
||||
|
||||
out->s_tmp = b_string_create();
|
||||
if (!out->s_tmp) {
|
||||
free(out);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
out->p_ctx = ctx;
|
||||
out->p_lex = lex;
|
||||
out->p_status = MIE_SUCCESS;
|
||||
@@ -35,6 +50,10 @@ struct mie_parser *mie_parser_create(struct mie_ctx *ctx, struct mie_lex *lex)
|
||||
|
||||
void mie_parser_destroy(struct mie_parser *ctx)
|
||||
{
|
||||
if (ctx->s_tmp) {
|
||||
b_string_unref(ctx->s_tmp);
|
||||
}
|
||||
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
@@ -85,6 +104,48 @@ bool mie_parser_advance(struct mie_parser *ctx)
|
||||
return mie_lex_get_status(ctx->p_lex) == MIE_SUCCESS;
|
||||
}
|
||||
|
||||
bool mie_parser_parse_int(
|
||||
struct mie_parser *ctx, long long *out, struct mie_file_span *loc)
|
||||
{
|
||||
if (!mie_parser_check_type(ctx, MIE_TOK_INT)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct mie_token *tok = mie_lex_peek(ctx->p_lex);
|
||||
if (tok->tok_value_type != MIE_TOK_V_INT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (loc) {
|
||||
mie_file_span_init(loc, tok);
|
||||
}
|
||||
|
||||
*out = tok->tok_int;
|
||||
mie_lex_advance(ctx->p_lex);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mie_parser_parse_float(
|
||||
struct mie_parser *ctx, double *out, struct mie_file_span *loc)
|
||||
{
|
||||
if (!mie_parser_check_type(ctx, MIE_TOK_FLOAT)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct mie_token *tok = mie_lex_peek(ctx->p_lex);
|
||||
if (tok->tok_value_type != MIE_TOK_V_FLOAT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (loc) {
|
||||
mie_file_span_init(loc, tok);
|
||||
}
|
||||
|
||||
*out = tok->tok_float;
|
||||
mie_lex_advance(ctx->p_lex);
|
||||
return true;
|
||||
}
|
||||
|
||||
#define TOKEN_PARSER(name, id) \
|
||||
bool mie_parser_parse_##name( \
|
||||
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc) \
|
||||
@@ -93,7 +154,16 @@ bool mie_parser_advance(struct mie_parser *ctx)
|
||||
return false; \
|
||||
} \
|
||||
struct mie_token *tok = mie_lex_peek(ctx->p_lex); \
|
||||
b_string_append_cstr(out, tok->tok_str); \
|
||||
switch (tok->tok_value_type) { \
|
||||
case MIE_TOK_V_STRING: \
|
||||
b_string_append_cstr(out, tok->tok_str); \
|
||||
break; \
|
||||
case MIE_TOK_V_INT: \
|
||||
b_string_append_cstrf(out, "%lld", tok->tok_int); \
|
||||
break; \
|
||||
default: \
|
||||
return false; \
|
||||
} \
|
||||
if (loc) { \
|
||||
mie_file_span_init(loc, tok); \
|
||||
} \
|
||||
@@ -123,17 +193,27 @@ bool mie_parser_parse_symbol(struct mie_parser *ctx, enum mie_token_symbol sym)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool parse_builtin_type_name(
|
||||
struct mie_parser *ctx, const struct mie_type **out)
|
||||
bool mie_parser_parse_linefeed(struct mie_parser *ctx)
|
||||
{
|
||||
b_string *name = b_string_create();
|
||||
struct mie_file_span loc;
|
||||
if (!mie_parser_parse_word(ctx, name, &loc)) {
|
||||
b_string_unref(name);
|
||||
struct mie_token *tok = mie_lex_peek(ctx->p_lex);
|
||||
if (tok->tok_type != MIE_TOK_LINEFEED) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const struct mie_dialect_type *type_info = NULL;
|
||||
mie_lex_advance(ctx->p_lex);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool parse_builtin_type_name(
|
||||
struct mie_parser *ctx, const struct mie_type **out)
|
||||
{
|
||||
b_string *name = get_temp_string(ctx);
|
||||
struct mie_file_span loc;
|
||||
if (!mie_parser_parse_word(ctx, name, &loc)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const struct mie_type_definition *type_info = NULL;
|
||||
const struct mie_type *type = NULL;
|
||||
size_t width = 0;
|
||||
char tmp = 0;
|
||||
@@ -147,20 +227,21 @@ static bool parse_builtin_type_name(
|
||||
const char *name_cstr = b_string_ptr(name);
|
||||
|
||||
if (!strcmp(name_cstr, "memref")) {
|
||||
type_info = mie_ctx_get_dialect_type(
|
||||
type_info = mie_ctx_get_type_definition(
|
||||
ctx->p_ctx, "memref", "memref");
|
||||
} else if (!strcmp(name_cstr, "index")) {
|
||||
type_info
|
||||
= mie_ctx_get_dialect_type(ctx->p_ctx, "index", "index");
|
||||
type_info = mie_ctx_get_type_definition(
|
||||
ctx->p_ctx, "index", "index");
|
||||
} else if (!strcmp(name_cstr, "str")) {
|
||||
type_info = mie_ctx_get_dialect_type(
|
||||
type_info = mie_ctx_get_type_definition(
|
||||
ctx->p_ctx, "builtin", "string");
|
||||
} else if (sscanf(name_cstr, "i%zu%c", &width, &tmp) == 1) {
|
||||
type_info = mie_ctx_get_dialect_type(ctx->p_ctx, "arith", "int");
|
||||
type_info = mie_ctx_get_type_definition(
|
||||
ctx->p_ctx, "arith", "int");
|
||||
base_type = INT;
|
||||
} else if (sscanf(name_cstr, "f%zu%c", &width, &tmp) == 1) {
|
||||
type_info
|
||||
= mie_ctx_get_dialect_type(ctx->p_ctx, "arith", "float");
|
||||
type_info = mie_ctx_get_type_definition(
|
||||
ctx->p_ctx, "arith", "float");
|
||||
base_type = FLOAT;
|
||||
}
|
||||
|
||||
@@ -188,10 +269,9 @@ static bool parse_builtin_type_name(
|
||||
|
||||
static bool parse_type_name(struct mie_parser *ctx, const struct mie_type **out)
|
||||
{
|
||||
b_string *name = b_string_create();
|
||||
b_string *name = get_temp_string(ctx);
|
||||
struct mie_file_span loc;
|
||||
if (!mie_parser_parse_typename(ctx, name, &loc)) {
|
||||
b_string_unref(name);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -353,7 +433,7 @@ MIE_API bool mie_parser_parse_function_type(
|
||||
bool mie_parser_parse_operand(struct mie_parser *ctx, struct mie_op_arg *out)
|
||||
{
|
||||
memset(out, 0x0, sizeof *out);
|
||||
b_string *str = b_string_create();
|
||||
b_string *str = get_temp_string(ctx);
|
||||
bool result = false;
|
||||
|
||||
struct mie_file_span loc;
|
||||
@@ -367,7 +447,6 @@ bool mie_parser_parse_operand(struct mie_parser *ctx, struct mie_op_arg *out)
|
||||
result = true;
|
||||
}
|
||||
|
||||
b_string_unref(str);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -420,6 +499,82 @@ bool mie_parser_parse_operand_list(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mie_parser_parse_parameter(struct mie_parser *ctx, struct mie_op_arg *out)
|
||||
{
|
||||
memset(out, 0x0, sizeof *out);
|
||||
b_string *str = get_temp_string(ctx);
|
||||
|
||||
struct mie_file_span loc;
|
||||
if (mie_parser_parse_vregname(ctx, str, &loc)) {
|
||||
out->arg_unresolved.reg_name = b_string_steal(str);
|
||||
out->arg_unresolved.reg_flags = MIE_REGISTER_F_VIRTUAL;
|
||||
} else if (mie_parser_parse_mregname(ctx, str, &loc)) {
|
||||
out->arg_unresolved.reg_name = b_string_steal(str);
|
||||
out->arg_unresolved.reg_flags = MIE_REGISTER_F_MACHINE;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mie_parser_parse_type(ctx, &out->arg_unresolved.reg_type)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mie_parser_parse_parameter_list(
|
||||
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_arg, out))
|
||||
{
|
||||
bool ok = false;
|
||||
struct mie_op_arg *operand = NULL;
|
||||
|
||||
struct mie_token *tok = mie_parser_peek(ctx);
|
||||
enum mie_token_type type = MIE_TOKEN_TYPE(tok);
|
||||
if (type != MIE_TOK_VREGNAME && type != MIE_TOK_MREGNAME) {
|
||||
return false;
|
||||
}
|
||||
|
||||
operand = mie_vector_ref_emplace_back(out);
|
||||
if (!operand) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mie_parser_parse_parameter(ctx, operand)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
tok = mie_parser_peek(ctx);
|
||||
|
||||
if (!MIE_TOKEN_IS_SYMBOL(tok, MIE_SYM_COMMA)) {
|
||||
break;
|
||||
}
|
||||
|
||||
mie_parser_advance(ctx);
|
||||
tok = mie_parser_peek(ctx);
|
||||
type = MIE_TOKEN_TYPE(tok);
|
||||
|
||||
if (type != MIE_TOK_VREGNAME && type != MIE_TOK_MREGNAME) {
|
||||
return false;
|
||||
}
|
||||
|
||||
operand = mie_vector_ref_emplace_back(out);
|
||||
if (!operand) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mie_parser_parse_parameter(ctx, operand)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mie_parser_parse_register(
|
||||
struct mie_parser *ctx, struct mie_name_map *names, struct mie_register *out)
|
||||
{
|
||||
@@ -438,14 +593,26 @@ bool mie_parser_parse_register(
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mie_name_map_put(
|
||||
names, &out->reg_name, tok->tok_str, MIE_NAME_MAP_F_STRICT)) {
|
||||
return false;
|
||||
struct mie_name *name = NULL;
|
||||
b_string *tmp = get_temp_string(ctx);
|
||||
switch (tok->tok_value_type) {
|
||||
case MIE_TOK_V_STRING:
|
||||
name = mie_name_map_put(
|
||||
names, &out->reg_name, tok->tok_str, MIE_NAME_MAP_F_STRICT);
|
||||
break;
|
||||
case MIE_TOK_V_INT:
|
||||
b_string_append_cstrf(tmp, "%lld", tok->tok_int);
|
||||
name = mie_name_map_put(
|
||||
names, &out->reg_name, b_string_ptr(tmp),
|
||||
MIE_NAME_MAP_F_STRICT);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
mie_parser_advance(ctx);
|
||||
|
||||
return true;
|
||||
return name != NULL;
|
||||
}
|
||||
|
||||
bool mie_parser_parse_register_list(
|
||||
@@ -526,6 +693,35 @@ bool mie_parser_parse_module(struct mie_parser *ctx, struct mie_module *mod)
|
||||
|
||||
bool mie_parser_parse_region(struct mie_parser *ctx, struct mie_region *region)
|
||||
{
|
||||
region->r_names = mie_name_map_create(NULL);
|
||||
|
||||
if (!mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_BRACE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mie_parser_parse_linefeed(ctx);
|
||||
struct mie_block *block = NULL;
|
||||
|
||||
if (mie_parser_peek_type(ctx) != MIE_TOK_BLOCKNAME) {
|
||||
block = mie_vector_emplace_back(region->r_blocks);
|
||||
|
||||
if (!mie_parser_parse_anonymous_block(ctx, region->r_names, block)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
while (1) {
|
||||
if (mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_BRACE)) {
|
||||
break;
|
||||
}
|
||||
|
||||
block = mie_vector_emplace_back(region->r_blocks);
|
||||
|
||||
if (!mie_parser_parse_block(ctx, region->r_names, block)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -561,28 +757,269 @@ bool mie_parser_parse_region_list(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mie_parser_parse_anonymous_block(
|
||||
struct mie_parser *ctx, struct mie_name_map *names, struct mie_block *block)
|
||||
{
|
||||
mie_parser_parse_linefeed(ctx);
|
||||
|
||||
struct mie_op *op = mie_vector_emplace_back(block->b_ops);
|
||||
if (!mie_parser_parse_op(ctx, names, op)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mie_parser_parse_linefeed(ctx);
|
||||
|
||||
while (1) {
|
||||
if (mie_parser_peek_type(ctx) == MIE_TOK_BLOCKNAME) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (mie_parser_peek_symbol(ctx) == MIE_SYM_RIGHT_BRACE) {
|
||||
break;
|
||||
}
|
||||
|
||||
struct mie_op *op = mie_vector_emplace_back(block->b_ops);
|
||||
if (!mie_parser_parse_op(ctx, names, op)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mie_parser_parse_linefeed(ctx)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool parse_block_parameters(
|
||||
struct mie_parser *ctx, struct mie_name_map *names, struct mie_block *block)
|
||||
{
|
||||
if (!mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_PAREN)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MIE_VECTOR_DEFINE(struct mie_op_arg, block_params);
|
||||
|
||||
if (!mie_parser_parse_parameter_list(ctx, MIE_VECTOR_REF(block_params))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_PAREN)
|
||||
|| !mie_parser_parse_symbol(ctx, MIE_SYM_COLON)
|
||||
|| !mie_parser_parse_linefeed(ctx)) {
|
||||
mie_vector_destroy(block_params, NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < MIE_VECTOR_COUNT(block_params); i++) {
|
||||
struct mie_register *param_reg
|
||||
= mie_vector_emplace_back(block->b_params);
|
||||
param_reg->reg_flags = block_params.items[i].arg_unresolved.reg_flags
|
||||
| MIE_REGISTER_F_BLOCK_PARAM;
|
||||
param_reg->reg_type = block_params.items[i].arg_unresolved.reg_type;
|
||||
param_reg->reg_block = block;
|
||||
if (!mie_name_map_put(
|
||||
names, ¶m_reg->reg_name,
|
||||
block_params.items[i].arg_unresolved.reg_name,
|
||||
MIE_NAME_MAP_F_STRICT)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mie_parser_parse_block(
|
||||
struct mie_parser *ctx, struct mie_name_map *names, struct mie_block *block)
|
||||
{
|
||||
b_string *str = get_temp_string(ctx);
|
||||
struct mie_file_span span;
|
||||
|
||||
if (!mie_parser_parse_blockname(ctx, str, &span)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mie_name_map_put(
|
||||
names, &block->b_name, b_string_ptr(str),
|
||||
MIE_NAME_MAP_F_STRICT)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mie_parser_peek_symbol(ctx) == MIE_SYM_LEFT_PAREN
|
||||
&& !parse_block_parameters(ctx, names, block)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)
|
||||
|| !mie_parser_parse_linefeed(ctx)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
if (mie_parser_peek_type(ctx) == MIE_TOK_BLOCKNAME) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (mie_parser_peek_symbol(ctx) == MIE_SYM_RIGHT_BRACE) {
|
||||
break;
|
||||
}
|
||||
|
||||
struct mie_op *op = mie_vector_emplace_back(block->b_ops);
|
||||
if (!mie_parser_parse_op(ctx, names, op)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mie_parser_parse_linefeed(ctx)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mie_parser_parse_attribute(
|
||||
struct mie_parser *ctx, struct mie_op_attribute *attrib)
|
||||
{
|
||||
return false;
|
||||
b_string *str = get_temp_string(ctx);
|
||||
struct mie_file_span span;
|
||||
if (!mie_parser_parse_word(ctx, str, &span)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
attrib->attrib_name = b_string_steal(str);
|
||||
|
||||
if (!mie_parser_parse_symbol(ctx, MIE_SYM_EQUAL)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct mie_value *value = NULL;
|
||||
if (!mie_parser_parse_value(ctx, &value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
attrib->attrib_value = value;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mie_parser_parse_attribute_list(
|
||||
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_attribute, out))
|
||||
{
|
||||
return false;
|
||||
bool ok = false;
|
||||
struct mie_op_attribute *attrib = NULL;
|
||||
|
||||
attrib = mie_vector_ref_emplace_back(out);
|
||||
if (!attrib) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mie_parser_parse_attribute(ctx, attrib)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
const struct mie_token *tok = mie_parser_peek(ctx);
|
||||
|
||||
if (!MIE_TOKEN_IS_SYMBOL(tok, MIE_SYM_COMMA)) {
|
||||
break;
|
||||
}
|
||||
|
||||
mie_parser_advance(ctx);
|
||||
mie_parser_parse_linefeed(ctx);
|
||||
|
||||
attrib = mie_vector_ref_emplace_back(out);
|
||||
if (!attrib) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mie_parser_parse_attribute(ctx, attrib)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mie_parser_parse_successor(
|
||||
struct mie_parser *ctx, struct mie_op_successor *successor)
|
||||
bool mie_parser_parse_successor(struct mie_parser *ctx, struct mie_op_successor *out)
|
||||
{
|
||||
memset(out, 0x0, sizeof *out);
|
||||
b_string *str = get_temp_string(ctx);
|
||||
bool result = false;
|
||||
struct mie_file_span span;
|
||||
|
||||
if (!mie_parser_parse_blockname(ctx, str, &span)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
out->s_block_name = b_string_steal(str);
|
||||
|
||||
if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_PAREN)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!mie_parser_parse_parameter_list(ctx, MIE_VECTOR_REF(out->s_args))) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_PAREN)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
fail:
|
||||
if (out->s_block_name) {
|
||||
free(out->s_block_name);
|
||||
out->s_block_name = NULL;
|
||||
}
|
||||
|
||||
if (MIE_VECTOR_MAX(out->s_args) > 0) {
|
||||
mie_vector_destroy(out->s_args, NULL);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool mie_parser_parse_successor_list(
|
||||
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_successor, out))
|
||||
{
|
||||
return false;
|
||||
bool ok = false;
|
||||
struct mie_op_successor *successor = NULL;
|
||||
|
||||
successor = mie_vector_ref_emplace_back(out);
|
||||
if (!successor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mie_parser_parse_successor(ctx, successor)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
const struct mie_token *tok = mie_parser_peek(ctx);
|
||||
|
||||
if (!MIE_TOKEN_IS_SYMBOL(tok, MIE_SYM_COMMA)) {
|
||||
break;
|
||||
}
|
||||
|
||||
mie_parser_advance(ctx);
|
||||
mie_parser_parse_linefeed(ctx);
|
||||
|
||||
successor = mie_vector_ref_emplace_back(out);
|
||||
if (!successor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mie_parser_parse_successor(ctx, successor)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool parse_custom_op(
|
||||
@@ -594,21 +1031,20 @@ static bool parse_custom_op(
|
||||
static bool parse_generic_op(
|
||||
struct mie_parser *ctx, struct mie_name_map *names, struct mie_op *dest)
|
||||
{
|
||||
b_string *str = b_string_create();
|
||||
b_string *str = get_temp_string(ctx);
|
||||
struct mie_file_span loc;
|
||||
if (!mie_parser_parse_opname(ctx, str, &loc)) {
|
||||
b_string_unref(str);
|
||||
return false;
|
||||
}
|
||||
|
||||
dest->op_name = b_string_steal(str);
|
||||
b_string_unref(str);
|
||||
|
||||
if (!mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_PAREN)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mie_parser_parse_operand_list(ctx, MIE_VECTOR_REF(dest->op_args))) {
|
||||
if (mie_parser_peek_symbol(ctx) != MIE_SYM_RIGHT_PAREN
|
||||
&& !mie_parser_parse_operand_list(ctx, MIE_VECTOR_REF(dest->op_args))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -616,6 +1052,30 @@ static bool parse_generic_op(
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_BRACKET)) {
|
||||
mie_parser_parse_linefeed(ctx);
|
||||
if (!mie_parser_parse_successor_list(
|
||||
ctx, MIE_VECTOR_REF(dest->op_successors))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_BRACKET)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_PAREN)) {
|
||||
mie_parser_parse_linefeed(ctx);
|
||||
if (!mie_parser_parse_region_list(
|
||||
ctx, MIE_VECTOR_REF(dest->op_regions))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_PAREN)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_BRACKET)) {
|
||||
if (!mie_parser_parse_successor_list(
|
||||
ctx, MIE_VECTOR_REF(dest->op_successors))) {
|
||||
@@ -720,3 +1180,101 @@ bool mie_parser_parse_op(
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool parse_string(struct mie_parser *ctx, struct mie_value **dest)
|
||||
{
|
||||
b_string *str = get_temp_string(ctx);
|
||||
struct mie_file_span span;
|
||||
if (!mie_parser_parse_string(ctx, str, &span)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct mie_value *v = mie_ctx_get_string(ctx->p_ctx, b_string_ptr(str));
|
||||
|
||||
if (!v) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*dest = v;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool parse_int(struct mie_parser *ctx, struct mie_value **dest)
|
||||
{
|
||||
long long value = 0;
|
||||
struct mie_file_span span;
|
||||
|
||||
if (!mie_parser_parse_int(ctx, &value, &span)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const struct mie_type *type = NULL;
|
||||
if (!mie_parser_parse_type(ctx, &type)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t width = mie_arith_int_type_get_width(type);
|
||||
if (width == (size_t)-1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct mie_value *v = mie_ctx_get_int(ctx->p_ctx, value, width);
|
||||
if (!v) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*dest = v;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool parse_float(struct mie_parser *ctx, struct mie_value **dest)
|
||||
{
|
||||
double value = 0;
|
||||
struct mie_file_span span;
|
||||
|
||||
if (!mie_parser_parse_float(ctx, &value, &span)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const struct mie_type *type = NULL;
|
||||
if (!mie_parser_parse_type(ctx, &type)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t width = mie_arith_float_type_get_width(type);
|
||||
if (width == (size_t)-1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct mie_value *v = mie_ctx_get_float(ctx->p_ctx, value, width);
|
||||
if (!v) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*dest = v;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mie_parser_parse_value(struct mie_parser *ctx, struct mie_value **dest)
|
||||
{
|
||||
enum mie_token_type type = mie_parser_peek_type(ctx);
|
||||
|
||||
switch (type) {
|
||||
case MIE_TOK_STRING:
|
||||
return parse_string(ctx, dest);
|
||||
case MIE_TOK_INT:
|
||||
return parse_int(ctx, dest);
|
||||
case MIE_TOK_FLOAT:
|
||||
return parse_float(ctx, dest);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ const char *mie_token_type_to_string(enum mie_token_type type)
|
||||
ENUM_STR(MIE_TOK_NONE);
|
||||
ENUM_STR(MIE_TOK_LINEFEED);
|
||||
ENUM_STR(MIE_TOK_INT);
|
||||
ENUM_STR(MIE_TOK_DOUBLE);
|
||||
ENUM_STR(MIE_TOK_FLOAT);
|
||||
ENUM_STR(MIE_TOK_SYMBOL);
|
||||
ENUM_STR(MIE_TOK_WORD);
|
||||
ENUM_STR(MIE_TOK_NAME);
|
||||
|
||||
25
mie/trait/trait-definition.c
Normal file
25
mie/trait/trait-definition.c
Normal file
@@ -0,0 +1,25 @@
|
||||
#include <blue/ds/string.h>
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/trait/trait-definition.h>
|
||||
|
||||
struct mie_trait_definition *mie_trait_definition_create(
|
||||
struct mie_dialect *parent, const char *name)
|
||||
{
|
||||
struct mie_trait_definition *out = malloc(sizeof *out);
|
||||
if (!out) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
out->tr_name = b_strdup(name);
|
||||
if (!out->tr_name) {
|
||||
free(out);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
out->tr_parent = parent;
|
||||
|
||||
b_rope name_rope = B_ROPE_CSTR(name);
|
||||
mie_id_map_put(&parent->d_traits, &out->tr_id, &name_rope);
|
||||
|
||||
return out;
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/trait/trait-definition.h>
|
||||
#include <mie/trait/trait-table.h>
|
||||
#include <mie/trait/trait.h>
|
||||
|
||||
@@ -29,7 +31,6 @@ static struct unique_trait *unique_trait_create(const struct mie_trait *trait)
|
||||
}
|
||||
|
||||
memset(out, 0x0, sizeof *out);
|
||||
out->u_id = trait->tr_id;
|
||||
out->u_trait = trait;
|
||||
|
||||
return out;
|
||||
@@ -48,7 +49,6 @@ static struct generic_trait *generic_trait_create(const struct mie_trait *trait)
|
||||
}
|
||||
|
||||
memset(out, 0x0, sizeof *out);
|
||||
out->g_id = trait->tr_def->tr_id;
|
||||
|
||||
struct unique_trait *entry = unique_trait_create(trait);
|
||||
if (!entry) {
|
||||
@@ -113,12 +113,55 @@ const struct mie_trait *mie_trait_table_get_unique(
|
||||
static enum mie_status put_unique_trait(
|
||||
struct mie_trait_table *table, const struct mie_trait *trait)
|
||||
{
|
||||
struct unique_trait *unique = unique_trait_create(trait);
|
||||
if (!unique) {
|
||||
return MIE_ERR_NO_MEMORY;
|
||||
}
|
||||
|
||||
struct mie_id_builder id_ctx;
|
||||
mie_id_builder_begin(&id_ctx, mie_id_map_get_ns(&table->tr_unique));
|
||||
mie_id_builder_add_cstr(&id_ctx, trait->tr_def->tr_parent->d_name);
|
||||
mie_id_builder_add_char(&id_ctx, '.');
|
||||
mie_id_builder_add_cstr(&id_ctx, trait->tr_def->tr_name);
|
||||
mie_id_builder_end(&id_ctx, &unique->u_id);
|
||||
|
||||
mie_id_map_put_id(&table->tr_unique, &unique->u_id);
|
||||
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
static enum mie_status put_generic_trait(
|
||||
struct mie_trait_table *table, const struct mie_trait *trait)
|
||||
{
|
||||
mie_id id;
|
||||
struct mie_id_builder id_ctx;
|
||||
mie_id_builder_begin(&id_ctx, mie_id_map_get_ns(&table->tr_generic));
|
||||
mie_id_builder_add_cstr(&id_ctx, trait->tr_def->tr_parent->d_name);
|
||||
mie_id_builder_add_char(&id_ctx, '.');
|
||||
mie_id_builder_add_cstr(&id_ctx, trait->tr_def->tr_name);
|
||||
mie_id_builder_end(&id_ctx, &id);
|
||||
|
||||
mie_id *target = mie_id_map_get(&table->tr_generic, &id);
|
||||
struct generic_trait *generic
|
||||
= b_unbox(struct generic_trait, target, g_id);
|
||||
if (!generic) {
|
||||
generic = generic_trait_create(trait);
|
||||
|
||||
if (!generic) {
|
||||
return MIE_ERR_NO_MEMORY;
|
||||
}
|
||||
|
||||
generic->g_id = id;
|
||||
mie_id_map_put_id(&table->tr_generic, &generic->g_id);
|
||||
}
|
||||
|
||||
struct unique_trait *unique = unique_trait_create(trait);
|
||||
if (!unique) {
|
||||
return MIE_ERR_NO_MEMORY;
|
||||
}
|
||||
|
||||
b_queue_push_back(&generic->g_traits, &unique->u_id.e_entry);
|
||||
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -163,6 +206,51 @@ enum mie_status mie_trait_table_get_generic(
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
enum mie_status mie_trait_table_iterate(
|
||||
const struct mie_trait_table *table,
|
||||
int (*func)(const struct mie_trait *, void *), void *arg)
|
||||
{
|
||||
struct mie_id_map_iterator it = {0};
|
||||
mie_id_map_iterator_begin(&it, &table->tr_unique);
|
||||
int ret = 0;
|
||||
|
||||
while (it.it_id) {
|
||||
const struct unique_trait *trait
|
||||
= b_unbox(struct unique_trait, it.it_id, u_id);
|
||||
ret = func(trait->u_trait, arg);
|
||||
|
||||
if (ret != 0) {
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
mie_id_map_iterator_move_next(&it);
|
||||
}
|
||||
|
||||
mie_id_map_iterator_begin(&it, &table->tr_generic);
|
||||
|
||||
while (it.it_id) {
|
||||
const struct generic_trait *trait_group
|
||||
= b_unbox(struct generic_trait, it.it_id, g_id);
|
||||
|
||||
const b_queue_entry *cur = b_queue_first(&trait_group->g_traits);
|
||||
while (cur) {
|
||||
const struct unique_trait *trait
|
||||
= b_unbox(struct unique_trait, cur, u_id.e_entry);
|
||||
ret = func(trait->u_trait, arg);
|
||||
|
||||
if (ret != 0) {
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
cur = b_queue_next(cur);
|
||||
}
|
||||
|
||||
mie_id_map_iterator_move_next(&it);
|
||||
}
|
||||
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
enum mie_status mie_trait_table_iterator_move_next(
|
||||
struct mie_trait_table_iterator *it)
|
||||
{
|
||||
|
||||
15
mie/trait/trait.c
Normal file
15
mie/trait/trait.c
Normal file
@@ -0,0 +1,15 @@
|
||||
#include <mie/trait/trait-definition.h>
|
||||
#include <mie/trait/trait.h>
|
||||
|
||||
void mie_trait_print(const struct mie_trait *trait, b_stream *out)
|
||||
{
|
||||
if (trait->tr_name) {
|
||||
b_stream_write_string(out, trait->tr_name, NULL);
|
||||
} else if (trait->tr_def && trait->tr_def->tr_print) {
|
||||
trait->tr_def->tr_print(trait->tr_def, trait, out);
|
||||
} else if (trait->tr_def->tr_name) {
|
||||
b_stream_write_string(out, trait->tr_def->tr_name, NULL);
|
||||
} else {
|
||||
b_stream_write_string(out, "<UNNAMED-TRAIT>", NULL);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <mie/dialect/type.h>
|
||||
#include <mie/type/function.h>
|
||||
#include <mie/type/type-definition.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -12,9 +12,19 @@ static void build_id(const struct mie_type *type, struct mie_id_builder *ctx)
|
||||
function->func_out.items, function->func_out.count);
|
||||
}
|
||||
|
||||
static struct mie_dialect_type function_type = {
|
||||
static enum mie_status type_print(
|
||||
const struct mie_type_definition *type_info,
|
||||
const struct mie_type *type, b_stream *out)
|
||||
{
|
||||
mie_function_type_print((const struct mie_function_type *)type, out);
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
static struct mie_type_definition function_type = {
|
||||
.ty_name = "*function",
|
||||
.ty_data_size = sizeof(struct mie_type),
|
||||
.ty_build_id = build_id,
|
||||
.ty_print = type_print,
|
||||
};
|
||||
|
||||
struct mie_function_type *mie_function_type_create(void)
|
||||
@@ -27,7 +37,6 @@ struct mie_function_type *mie_function_type_create(void)
|
||||
memset(out, 0x0, sizeof *out);
|
||||
|
||||
out->func_base.ty_def = &function_type;
|
||||
out->func_base.ty_category = MIE_TYPE_FUNCTION;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <mie/dialect/type.h>
|
||||
#include <mie/type/storage.h>
|
||||
#include <mie/type/type-definition.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -11,9 +11,19 @@ static void build_id(const struct mie_type *type, struct mie_id_builder *ctx)
|
||||
ctx, storage->st_parts.items, storage->st_parts.count);
|
||||
}
|
||||
|
||||
static struct mie_dialect_type storage_type = {
|
||||
static enum mie_status type_print(
|
||||
const struct mie_type_definition *type_info,
|
||||
const struct mie_type *type, b_stream *out)
|
||||
{
|
||||
mie_storage_type_print((const struct mie_storage_type *)type, out);
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
static struct mie_type_definition storage_type = {
|
||||
.ty_name = "*storage",
|
||||
.ty_data_size = sizeof(struct mie_type),
|
||||
.ty_build_id = build_id,
|
||||
.ty_print = type_print,
|
||||
};
|
||||
|
||||
struct mie_storage_type *mie_storage_type_create(void)
|
||||
@@ -26,7 +36,6 @@ struct mie_storage_type *mie_storage_type_create(void)
|
||||
memset(out, 0x0, sizeof *out);
|
||||
|
||||
out->st_base.ty_def = &storage_type;
|
||||
out->st_base.ty_category = MIE_TYPE_STORAGE;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#include <blue/ds/string.h>
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/dialect/type.h>
|
||||
#include <mie/type/type-definition.h>
|
||||
|
||||
struct mie_dialect_type *mie_dialect_type_create(
|
||||
struct mie_type_definition *mie_type_definition_create(
|
||||
struct mie_dialect *parent, const char *name)
|
||||
{
|
||||
struct mie_dialect_type *out = malloc(sizeof *out);
|
||||
struct mie_type_definition *out = malloc(sizeof *out);
|
||||
if (!out) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -17,9 +17,16 @@ struct mie_dialect_type *mie_dialect_type_create(
|
||||
}
|
||||
|
||||
out->ty_parent = parent;
|
||||
mie_trait_table_init(&out->ty_traits);
|
||||
|
||||
b_rope name_rope = B_ROPE_CSTR(name);
|
||||
mie_id_map_put(&parent->d_types, &out->ty_id, &name_rope);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
enum mie_status mie_type_definition_add_trait(
|
||||
struct mie_type_definition *type, const struct mie_trait *trait)
|
||||
{
|
||||
return mie_trait_table_put(&type->ty_traits, trait);
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
#include <mie/dialect/type.h>
|
||||
#include <mie/type/function.h>
|
||||
#include <mie/type/storage.h>
|
||||
#include <mie/type/type-definition.h>
|
||||
#include <mie/type/type.h>
|
||||
|
||||
struct mie_type *mie_type_create(struct mie_dialect_type *type)
|
||||
struct mie_type *mie_type_create(struct mie_type_definition *type)
|
||||
{
|
||||
if (type->ty_data_size < sizeof(struct mie_type)) {
|
||||
return NULL;
|
||||
@@ -22,17 +22,6 @@ struct mie_type *mie_type_create(struct mie_dialect_type *type)
|
||||
|
||||
void mie_type_print(const struct mie_type *type, b_stream *out)
|
||||
{
|
||||
switch (type->ty_category) {
|
||||
case MIE_TYPE_STORAGE:
|
||||
mie_storage_type_print((const struct mie_storage_type *)type, out);
|
||||
return;
|
||||
case MIE_TYPE_FUNCTION:
|
||||
mie_function_type_print((const struct mie_function_type *)type, out);
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (type->ty_name) {
|
||||
b_stream_write_string(out, type->ty_name, NULL);
|
||||
} else if (type->ty_def && type->ty_def->ty_print) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include <mie/dialect/type.h>
|
||||
#include <mie/type/type-definition.h>
|
||||
#include <mie/type/type.h>
|
||||
#include <mie/value.h>
|
||||
|
||||
|
||||
@@ -1,29 +1,400 @@
|
||||
#include "cmd.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <blue/cmd.h>
|
||||
#include <blue/io/file.h>
|
||||
#include <blue/io/path.h>
|
||||
#include <blue/term.h>
|
||||
#include <mie/ctx.h>
|
||||
#include <mie/ir/convert.h>
|
||||
#include <mie/ir/value.h>
|
||||
#include <mie/dialect/arith.h>
|
||||
#include <mie/dialect/builtin.h>
|
||||
#include <mie/dialect/cf.h>
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/dialect/func.h>
|
||||
#include <mie/dialect/index.h>
|
||||
#include <mie/dialect/meta.h>
|
||||
#include <mie/dialect/ptr.h>
|
||||
#include <mie/dialect/scf.h>
|
||||
#include <mie/dialect/select.h>
|
||||
#include <mie/ir/block.h>
|
||||
#include <mie/ir/op-definition.h>
|
||||
#include <mie/ir/op.h>
|
||||
#include <mie/ir/region.h>
|
||||
#include <mie/ir/register.h>
|
||||
#include <mie/name.h>
|
||||
#include <mie/parse/lex.h>
|
||||
#include <mie/parse/parse.h>
|
||||
#include <mie/parse/token.h>
|
||||
#include <mie/trait/trait-definition.h>
|
||||
#include <mie/trait/trait.h>
|
||||
#include <mie/type/type-definition.h>
|
||||
#include <mie/type/type.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
enum {
|
||||
OPT_TEMP,
|
||||
ARG_FILEPATH,
|
||||
};
|
||||
|
||||
int validate(const b_command* cmd, const b_arglist* args, const b_array* _)
|
||||
static int trait_ref_print(const struct mie_trait *trait, void *arg)
|
||||
{
|
||||
return 0;
|
||||
fputc(' ', stdout);
|
||||
mie_trait_print(trait, b_stdout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mie_op_arg_print(const struct mie_op_arg *arg)
|
||||
{
|
||||
enum mie_register_flags arg_flags = 0;
|
||||
const char *arg_name = NULL;
|
||||
const struct mie_type *arg_type = NULL;
|
||||
|
||||
if (MIE_TEST_FLAGS(arg->arg_flags, MIE_OP_F_ARG_RESOLVED)) {
|
||||
arg_flags = arg->arg_value->reg_flags;
|
||||
arg_name = arg->arg_value->reg_name.n_str;
|
||||
arg_type = arg->arg_value->reg_type;
|
||||
} else {
|
||||
arg_flags = arg->arg_unresolved.reg_flags;
|
||||
arg_name = arg->arg_unresolved.reg_name;
|
||||
arg_type = arg->arg_unresolved.reg_type;
|
||||
}
|
||||
|
||||
if (arg_flags & MIE_REGISTER_F_MACHINE) {
|
||||
b_printf(" [bold,red]MR");
|
||||
} else {
|
||||
b_printf(" [bold,magenta]VR");
|
||||
}
|
||||
|
||||
printf(":(");
|
||||
mie_type_print(arg_type, b_stdout);
|
||||
b_printf(")%s[reset]", arg_name);
|
||||
}
|
||||
|
||||
static void mie_op_print(const struct mie_op *op)
|
||||
{
|
||||
b_stringstream *tmp = b_stringstream_create();
|
||||
|
||||
printf("FLAGS:");
|
||||
(op->op_flags & MIE_OP_F_OP_RESOLVED) && printf(" OP_RESOLVED");
|
||||
(op->op_flags & MIE_OP_F_ARG_RESOLVED) && printf(" ARG_RESOLVED");
|
||||
printf("\n");
|
||||
printf("DIALECT: %s\n",
|
||||
op->op_dialect ? op->op_dialect->d_name : "<unknown>");
|
||||
printf("OP: %s\n", op->op_info ? op->op_info->op_name : "<unknown>");
|
||||
printf("NAME: %s\n", op->op_name ? op->op_name : "<unknown>");
|
||||
printf("TRAITS:");
|
||||
mie_trait_table_iterate(&op->op_info->op_traits, trait_ref_print, NULL);
|
||||
printf("\n");
|
||||
printf("ATTRIBUTES:");
|
||||
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_attrib); i++) {
|
||||
printf(" (%s = ", op->op_attrib.items[i].attrib_name);
|
||||
mie_value_print(op->op_attrib.items[i].attrib_value, b_stdout);
|
||||
printf(")");
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf("REGIONS: %zu\n", MIE_VECTOR_COUNT(op->op_regions));
|
||||
printf("SUCCESSORS:");
|
||||
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_successors); i++) {
|
||||
const struct mie_op_successor *s = &op->op_successors.items[i];
|
||||
if (MIE_TEST_FLAGS(s->s_flags, MIE_OP_F_SUCCESSOR_RESOLVED)) {
|
||||
printf(" ^%s", s->s_block->b_name.n_str);
|
||||
} else {
|
||||
printf(" ^%s?", s->s_block_name);
|
||||
}
|
||||
|
||||
printf(":(");
|
||||
|
||||
for (size_t i = 0; i < MIE_VECTOR_COUNT(s->s_args); i++) {
|
||||
const struct mie_op_arg *arg = &s->s_args.items[i];
|
||||
mie_op_arg_print(arg);
|
||||
}
|
||||
|
||||
printf(" )");
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf("ARGS:");
|
||||
for (size_t i = 0; i < op->op_args.count; i++) {
|
||||
const struct mie_op_arg *arg = &op->op_args.items[i];
|
||||
mie_op_arg_print(arg);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf("RESULT:");
|
||||
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_result); i++) {
|
||||
const struct mie_register *reg = &op->op_result.items[i];
|
||||
printf(" %s:(",
|
||||
(reg->reg_flags & MIE_REGISTER_F_MACHINE) ? "MR" : "VR");
|
||||
mie_type_print(reg->reg_type, b_stdout);
|
||||
printf(")%s", reg->reg_name.n_str);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void mie_op_definition_print(const struct mie_op_definition *op)
|
||||
{
|
||||
char id_str[MIE_ID_STRING_MAX];
|
||||
mie_id_to_string(&op->op_id, id_str, sizeof id_str);
|
||||
b_printf(
|
||||
" [bold,red]Op:[reset]%-20s [dark_grey]{%s}[reset]\n",
|
||||
op->op_name, id_str);
|
||||
}
|
||||
|
||||
static void mie_type_definition_print(const struct mie_type_definition *type)
|
||||
{
|
||||
char id_str[MIE_ID_STRING_MAX];
|
||||
mie_id_to_string(&type->ty_id, id_str, sizeof id_str);
|
||||
b_printf(
|
||||
" [bold,blue]Ty:[reset]%-20s [dark_grey]{%s}[reset]\n",
|
||||
type->ty_name, id_str);
|
||||
}
|
||||
|
||||
static void mie_trait_definition_print(const struct mie_trait_definition *trait)
|
||||
{
|
||||
char id_str[MIE_ID_STRING_MAX];
|
||||
mie_id_to_string(&trait->tr_id, id_str, sizeof id_str);
|
||||
b_printf(
|
||||
" [bold,yellow]Tr:[reset]%-20s [dark_grey]{%s}[reset]\n",
|
||||
trait->tr_name, id_str);
|
||||
}
|
||||
|
||||
static void mie_dialect_print(const struct mie_dialect *dialect)
|
||||
{
|
||||
char id_str[MIE_ID_STRING_MAX];
|
||||
mie_id_to_string(&dialect->d_id, id_str, sizeof id_str);
|
||||
b_printf(
|
||||
"[bold,green]D:[reset]%-20s [dark_grey]{%s}[reset]\n",
|
||||
dialect->d_name, id_str);
|
||||
|
||||
b_btree_node *node = b_btree_first(&dialect->d_ops.map_entries);
|
||||
while (node) {
|
||||
mie_id *id = b_unbox(mie_id, node, e_node);
|
||||
struct mie_op_definition *op
|
||||
= b_unbox(struct mie_op_definition, id, op_id);
|
||||
|
||||
mie_op_definition_print(op);
|
||||
node = b_btree_next(node);
|
||||
}
|
||||
|
||||
node = b_btree_first(&dialect->d_types.map_entries);
|
||||
while (node) {
|
||||
mie_id *id = b_unbox(mie_id, node, e_node);
|
||||
struct mie_type_definition *type
|
||||
= b_unbox(struct mie_type_definition, id, ty_id);
|
||||
|
||||
mie_type_definition_print(type);
|
||||
node = b_btree_next(node);
|
||||
}
|
||||
|
||||
node = b_btree_first(&dialect->d_traits.map_entries);
|
||||
while (node) {
|
||||
mie_id *id = b_unbox(mie_id, node, e_node);
|
||||
struct mie_trait_definition *trait
|
||||
= b_unbox(struct mie_trait_definition, id, tr_id);
|
||||
|
||||
mie_trait_definition_print(trait);
|
||||
node = b_btree_next(node);
|
||||
}
|
||||
}
|
||||
|
||||
static void mie_ctx_print(const struct mie_ctx *ctx)
|
||||
{
|
||||
b_btree_node *node = b_btree_first(&ctx->ctx_dialects.map_entries);
|
||||
while (node) {
|
||||
mie_id *id = b_unbox(mie_id, node, e_node);
|
||||
struct mie_dialect *dialect
|
||||
= b_unbox(struct mie_dialect, id, d_id);
|
||||
|
||||
mie_dialect_print(dialect);
|
||||
node = b_btree_next(node);
|
||||
}
|
||||
}
|
||||
|
||||
static int validate_file(const char *path, const b_arglist *args)
|
||||
{
|
||||
b_file *file = NULL;
|
||||
b_result result
|
||||
= b_file_open(NULL, B_RV_PATH(path), B_FILE_READ_ONLY, &file);
|
||||
if (b_result_is_error(result)) {
|
||||
b_throw(result);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("File OK\n");
|
||||
|
||||
struct mie_ctx *ctx = mie_ctx_create();
|
||||
mie_builtin_dialect_create(ctx);
|
||||
mie_meta_dialect_create(ctx);
|
||||
mie_select_dialect_create(ctx);
|
||||
mie_ptr_dialect_create(ctx);
|
||||
mie_arith_dialect_create(ctx);
|
||||
mie_func_dialect_create(ctx);
|
||||
mie_cf_dialect_create(ctx);
|
||||
mie_scf_dialect_create(ctx);
|
||||
mie_index_dialect_create(ctx);
|
||||
|
||||
mie_ctx_print(ctx);
|
||||
|
||||
struct mie_type *i32 = mie_arith_int_get_type(ctx, 32);
|
||||
struct mie_type *str = mie_ctx_get_type(ctx, "builtin", "string");
|
||||
struct mie_type *index = mie_ctx_get_type(ctx, "index", "index");
|
||||
struct mie_value *i32_value = mie_ctx_get_int(ctx, 1024, 32);
|
||||
struct mie_value *index_value = mie_ctx_get_index(ctx, 25000);
|
||||
struct mie_value *str_value = mie_ctx_get_string(ctx, "Hello, world!");
|
||||
|
||||
const struct mie_type *storage_type_parts[] = {i32, str, index};
|
||||
struct mie_type *storage_type = mie_ctx_get_storage_type(
|
||||
ctx, storage_type_parts,
|
||||
sizeof storage_type_parts / sizeof *storage_type_parts);
|
||||
|
||||
const struct mie_type *func_in_parts[] = {i32, str};
|
||||
const struct mie_type *func_out_parts[] = {index};
|
||||
struct mie_type *func_type = mie_ctx_get_function_type(
|
||||
ctx, func_in_parts, sizeof func_in_parts / sizeof *func_in_parts,
|
||||
func_out_parts, sizeof func_out_parts / sizeof *func_out_parts);
|
||||
|
||||
/* make sure storage/function type caching is working */
|
||||
assert(storage_type
|
||||
== mie_ctx_get_storage_type(
|
||||
ctx, storage_type_parts,
|
||||
sizeof storage_type_parts / sizeof *storage_type_parts));
|
||||
assert(func_type
|
||||
== mie_ctx_get_function_type(
|
||||
ctx, func_in_parts,
|
||||
sizeof func_in_parts / sizeof *func_in_parts, func_out_parts,
|
||||
sizeof func_out_parts / sizeof *func_out_parts));
|
||||
|
||||
char id_str[MIE_ID_STRING_MAX];
|
||||
mie_id_to_string(&i32->ty_id, id_str, sizeof id_str);
|
||||
printf("i32 type: {%s} %s (instance of %s.%s)\n", id_str, i32->ty_name,
|
||||
i32->ty_def->ty_parent->d_name, i32->ty_def->ty_name);
|
||||
mie_id_to_string(&str->ty_id, id_str, sizeof id_str);
|
||||
printf("str type: {%s} %s (instance of %s.%s)\n", id_str, str->ty_name,
|
||||
str->ty_def->ty_parent->d_name, str->ty_def->ty_name);
|
||||
mie_id_to_string(&index->ty_id, id_str, sizeof id_str);
|
||||
printf("index type: {%s} %s (instance of %s.%s)\n", id_str, index->ty_name,
|
||||
index->ty_def->ty_parent->d_name, index->ty_def->ty_name);
|
||||
mie_id_to_string(&storage_type->ty_id, id_str, sizeof id_str);
|
||||
printf("storage type: {%s} ", id_str);
|
||||
mie_type_print(storage_type, b_stdout);
|
||||
printf("\n");
|
||||
|
||||
mie_id_to_string(&func_type->ty_id, id_str, sizeof id_str);
|
||||
printf("function type: {%s} ", id_str);
|
||||
mie_type_print(func_type, b_stdout);
|
||||
printf("\n");
|
||||
|
||||
printf("i32 value: ");
|
||||
mie_value_print(i32_value, b_stdout);
|
||||
printf("\n");
|
||||
|
||||
printf("index value: ");
|
||||
mie_value_print(index_value, b_stdout);
|
||||
printf("\n");
|
||||
|
||||
printf("str value: ");
|
||||
mie_value_print(str_value, b_stdout);
|
||||
printf("\n");
|
||||
|
||||
struct mie_lex *lex = mie_lex_create(file);
|
||||
struct mie_parser *parse = mie_parser_create(ctx, lex);
|
||||
|
||||
struct mie_name_map *names = mie_name_map_create(NULL);
|
||||
|
||||
struct mie_op op = {};
|
||||
|
||||
if (!mie_parser_parse_op(parse, names, &op)) {
|
||||
printf("parse failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!mie_ctx_resolve_op(ctx, &op)) {
|
||||
printf("op resolve failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
mie_op_print(&op);
|
||||
|
||||
#if 0
|
||||
|
||||
while (1) {
|
||||
struct mie_token *tok = mie_lex_peek(lex);
|
||||
if (!tok) {
|
||||
break;
|
||||
}
|
||||
|
||||
printf("%s[%d:%d -> %d:%d]",
|
||||
mie_token_type_to_string(tok->tok_type),
|
||||
tok->tok_start.c_row, tok->tok_start.c_col,
|
||||
tok->tok_end.c_row, tok->tok_end.c_col);
|
||||
|
||||
switch (tok->tok_value_type) {
|
||||
case MIE_TOK_V_STRING:
|
||||
printf(" S:%s", tok->tok_str);
|
||||
break;
|
||||
case MIE_TOK_V_INT:
|
||||
printf(" I:%lld", tok->tok_int);
|
||||
break;
|
||||
case MIE_TOK_V_DOUBLE:
|
||||
printf(" D:%lf", tok->tok_double);
|
||||
break;
|
||||
case MIE_TOK_V_SYMBOL:
|
||||
printf(" SYM:%s", mie_token_symbol_to_string(tok->tok_sym));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
mie_lex_advance(lex);
|
||||
}
|
||||
#endif
|
||||
|
||||
mie_lex_destroy(lex);
|
||||
|
||||
b_file_unref(file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int validate(const b_command *cmd, const b_arglist *args, const b_array *_)
|
||||
{
|
||||
b_arglist_iterator it;
|
||||
b_arglist_foreach_filtered(&it, args, B_COMMAND_INVALID_ID, ARG_FILEPATH)
|
||||
{
|
||||
b_arglist_value *path = it.value;
|
||||
if (path->val_type != B_COMMAND_ARG_STRING) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int r = validate_file(path->val_str, args);
|
||||
if (r != 0) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
B_COMMAND(CMD_VALIDATE, CMD_ROOT)
|
||||
{
|
||||
B_COMMAND_NAME("validate");
|
||||
B_COMMAND_SHORT_NAME('V');
|
||||
B_COMMAND_DESC("validate a mie ir file.");
|
||||
B_COMMAND_HELP_OPTION();
|
||||
B_COMMAND_FLAGS(B_COMMAND_SHOW_HELP_BY_DEFAULT);
|
||||
B_COMMAND_FUNCTION(validate);
|
||||
B_COMMAND_NAME("validate");
|
||||
B_COMMAND_SHORT_NAME('V');
|
||||
B_COMMAND_DESC("validate a mie ir file.");
|
||||
B_COMMAND_HELP_OPTION();
|
||||
B_COMMAND_FLAGS(B_COMMAND_SHOW_HELP_BY_DEFAULT);
|
||||
B_COMMAND_FUNCTION(validate);
|
||||
|
||||
B_COMMAND_ARG(ARG_FILEPATH)
|
||||
{
|
||||
B_ARG_NAME("filepath");
|
||||
B_ARG_DESC("the mie file to validate");
|
||||
B_ARG_NR_VALUES(1);
|
||||
}
|
||||
|
||||
B_COMMAND_HELP_OPTION();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "cmd/cmd.h"
|
||||
|
||||
#include <blue/cmd.h>
|
||||
#include <mie/id.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, const char **argv)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user