Compare commits

42 Commits

Author SHA1 Message Date
9df79f90a6 meta: add clang-format config 2026-01-11 14:51:49 +00:00
c9c9cdf544 tool: add temporary parsing and ctx tests to validate subcommand 2026-01-11 14:51:37 +00:00
3253c4cac9 vim: add support for mach-registers, graph instructions, etc 2026-01-11 14:51:09 +00:00
fc61b188e3 doc: add more sample ir and graph files 2026-01-11 14:50:28 +00:00
6b5fd95ac4 mie: op: add data structure for op successors 2026-01-11 14:49:02 +00:00
700f7fe96e mie: add no-data status code 2026-01-11 14:48:45 +00:00
fdf46b8867 mie: add select dialect 2026-01-11 14:48:30 +00:00
417b5dc354 mie: builtin: add isolated-from-above trait 2026-01-11 14:38:28 +00:00
d42e02f04d mie: parse: implement parsing of regions, block, attributes, and values 2026-01-11 14:26:54 +00:00
6e55642a19 mie: arith: add support for querying the width of int/float types 2026-01-11 14:23:10 +00:00
0c84578f95 mie: add support for caching float values 2026-01-11 14:17:45 +00:00
4a0fcef862 mie: add support for adding traits to types and ops 2026-01-11 14:14:43 +00:00
79c83ef73c mie: id: add iteration support to mie_id_map 2026-01-11 14:03:51 +00:00
c6be143925 mie: trait: add function callback to perform trait-specific validation on an object 2026-01-08 22:26:32 +00:00
e76e7c17db mie: move op and type definition from dialect/ to ir/ and type/ respectively 2026-01-08 22:16:50 +00:00
27e42340de mie: ir: implement deferred resolution of op arguments 2026-01-08 19:21:50 +00:00
c686c31ca0 mie: add data structures for registering and applying extensible traits 2026-01-08 19:21:17 +00:00
8ad3f36288 mie: parse: implement type reference parsing 2026-01-08 19:19:45 +00:00
0a45e3b571 mie: type: implement function and storage types 2026-01-08 19:17:34 +00:00
e98ccd0c80 mie: vector: store vector components in an anonymous struct; improve macro consistency 2026-01-08 19:15:35 +00:00
14a1ef30ee mie: parse: add mie_file_span to record character span locations within files 2026-01-08 19:07:19 +00:00
344626f207 mie: type: move all function pointers from mie_type to mie_dialect_type 2026-01-08 19:00:13 +00:00
f4d374288f mie: id: add an interface for building a mie_id value across multiple steps 2026-01-08 18:56:45 +00:00
789bd1309f mie: name: implement parent-child maps and recursive name searches 2026-01-08 18:53:56 +00:00
5b06934e85 mie: ctx: add int, string, and index value caches 2026-01-04 18:58:04 +00:00
9d80d94244 mie: add index dialect 2026-01-04 18:57:38 +00:00
3c2ca0f70e mie: builtin: add string type 2026-01-04 18:57:13 +00:00
aad2cad0a8 mie: add structure to represent primitive values 2026-01-04 18:56:43 +00:00
8b3093411a mie: arith: add support for int and float values 2026-01-04 18:56:03 +00:00
7c7e5e7af0 mie: add more dialect definition macros 2026-01-04 18:54:06 +00:00
9126edfd57 mie: ctx: implement generic (non-parametised) type initialisation 2026-01-04 18:42:12 +00:00
3c9506256d mie: arith: implement int value cache data structure 2026-01-04 18:36:33 +00:00
add09d4958 mie: add data structures to represent type-instances
unlike values, type-instances represent specialisations of parametised types.
they behave like concrete implementations of C++ template types.

for example: arith.int represents an integer type of unspecified bit-width.
a type-instance of this type would be arith.int<32> (or i32 for short) which
has a defined width of 32 bits.
2026-01-04 14:10:52 +00:00
7b6ce3bf6e mie: add dialect data structures, and some builtin dialects 2026-01-04 14:10:43 +00:00
79ab1c175b mie: add IR data structures 2026-01-04 14:10:13 +00:00
0dce84cb7f mie: add macros for defining dialect and dialect types/ops 2026-01-04 14:09:55 +00:00
2e22898fc8 mie: ctx: implementing registering dialects and type-instances 2026-01-04 14:09:31 +00:00
86005451cb mie: parse: implement more IR-parsing functions 2026-01-04 14:08:57 +00:00
21bcbb7edc mie: add a namespace/uuid-based map data structure
rather than a traditional dictionary or hashmap, this data structure supports a one-to-one
mapping between a UUID and a value. this is an intrusive data structure like mie_name_map
(a value struct must include an instance of mie_id), but this one does not support name collisions.

mie_id_map generates and issues UUIDs based on a name provided by the caller. All UUIDs are v5,
meaning they are generated using a SHA1 hash of a namespace UUID (specified when the mie_id_map
is initialised), and a unique name provided by the caller.

mie_id can also be used standalone to generate, store, and stringify UUIDs.
2026-01-04 14:03:22 +00:00
915cf836f2 mie: add macros for defining and using resizable vectors 2026-01-04 14:02:14 +00:00
f9a2cf3b8e mie: remove all legacy ir and select code 2025-12-21 13:51:26 +00:00
6573360656 mie: start implementing new ir parser 2025-12-21 13:51:07 +00:00
166 changed files with 8865 additions and 5596 deletions

174
.clang-format Normal file
View File

@@ -0,0 +1,174 @@
BasedOnStyle: WebKit
IndentWidth: 8
---
Language: C
DerivePointerAlignment: false
PointerAlignment: Right
ColumnLimit: 80
AlignAfterOpenBracket: AlwaysBreak
AlignConsecutiveAssignments: None
AlignConsecutiveBitFields: None
AlignConsecutiveDeclarations: None
AlignConsecutiveMacros: AcrossEmptyLinesAndComments
AlignEscapedNewlines: Right
AlignOperands: AlignAfterOperator
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: false
AllowAllConstructorInitializersOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Empty
AllowShortCaseLabelsOnASingleLine: false
AllowShortEnumsOnASingleLine: false
AllowShortFunctionsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: false
AllowShortLambdasOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: true
BinPackParameters: true
ExperimentalAutoDetectBinPacking: false
BitFieldColonSpacing: Both
BreakBeforeBraces: Linux
BreakBeforeBinaryOperators: All
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeComma
BreakInheritanceList: BeforeComma
BreakStringLiterals: true
ContinuationIndentWidth: 8
Cpp11BracedListStyle: true
IncludeBlocks: Regroup
SortIncludes: true
IndentRequires: true
NamespaceIndentation: Inner
ReflowComments: true
SpacesBeforeTrailingComments: 3
TabWidth: 8
UseTab: AlignWithSpaces
PenaltyReturnTypeOnItsOwnLine: 1000000
PenaltyExcessCharacter: 5
PenaltyBreakOpenParenthesis: 5
PenaltyBreakBeforeFirstCallParameter: 5
PenaltyIndentedWhitespace: 0
AttributeMacros:
- BLUELIB_API
ForEachMacros:
- b_btree_foreach
- b_queue_foreach
MacroBlockBegin: "MIE_.*_BEGIN"
MacroBlockEnd: "MIE_.*_END"
---
Language: Cpp
DerivePointerAlignment: false
PointerAlignment: Right
ColumnLimit: 80
AlignAfterOpenBracket: AlwaysBreak
AlignConsecutiveAssignments: None
AlignConsecutiveBitFields: None
AlignConsecutiveDeclarations: None
AlignConsecutiveMacros: AcrossEmptyLinesAndComments
AlignEscapedNewlines: Right
AlignOperands: AlignAfterOperator
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: false
AllowAllConstructorInitializersOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Empty
AllowShortCaseLabelsOnASingleLine: false
AllowShortEnumsOnASingleLine: false
AllowShortFunctionsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: false
AllowShortLambdasOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: true
BinPackParameters: true
ExperimentalAutoDetectBinPacking: false
BitFieldColonSpacing: Both
BreakBeforeBraces: Linux
BreakBeforeBinaryOperators: All
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeComma
BreakInheritanceList: BeforeComma
BreakStringLiterals: true
ContinuationIndentWidth: 8
Cpp11BracedListStyle: true
IncludeBlocks: Regroup
SortIncludes: true
IndentRequires: true
NamespaceIndentation: Inner
ReflowComments: true
SpacesBeforeTrailingComments: 3
TabWidth: 8
UseTab: AlignWithSpaces
PenaltyReturnTypeOnItsOwnLine: 1000000
PenaltyExcessCharacter: 5
PenaltyBreakOpenParenthesis: 5
PenaltyBreakBeforeFirstCallParameter: 5
PenaltyIndentedWhitespace: 0
AttributeMacros:
- BLUELIB_API
ForEachMacros:
- b_btree_foreach
- b_queue_foreach
---
Language: ObjC
DerivePointerAlignment: false
PointerAlignment: Right
ColumnLimit: 80
AlignAfterOpenBracket: AlwaysBreak
AlignConsecutiveAssignments: None
AlignConsecutiveBitFields: None
AlignConsecutiveDeclarations: None
AlignConsecutiveMacros: AcrossEmptyLinesAndComments
AlignEscapedNewlines: Right
AlignOperands: AlignAfterOperator
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: false
AllowAllConstructorInitializersOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Empty
AllowShortCaseLabelsOnASingleLine: false
AllowShortEnumsOnASingleLine: false
AllowShortFunctionsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: false
AllowShortLambdasOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: true
BinPackParameters: true
ExperimentalAutoDetectBinPacking: false
BitFieldColonSpacing: Both
BreakBeforeBraces: Linux
BreakBeforeBinaryOperators: All
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeComma
BreakInheritanceList: BeforeComma
BreakStringLiterals: true
ContinuationIndentWidth: 8
Cpp11BracedListStyle: true
IncludeBlocks: Regroup
SortIncludes: true
IndentRequires: true
NamespaceIndentation: Inner
ReflowComments: true
SpacesBeforeTrailingComments: 3
TabWidth: 8
UseTab: AlignWithSpaces
PenaltyReturnTypeOnItsOwnLine: 1000000
PenaltyExcessCharacter: 5
PenaltyBreakOpenParenthesis: 5
PenaltyBreakBeforeFirstCallParameter: 5
PenaltyIndentedWhitespace: 0
AttributeMacros:
- BLUELIB_API
ForEachMacros:
- b_btree_foreach
- b_queue_foreach
MacroBlockBegin: "B_TYPE_.*_BEGIN"
MacroBlockEnd: "B_TYPE_.*_END"

View File

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

View File

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

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

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

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

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

530
doc/sample/ir/Person.2.mie Normal file
View File

@@ -0,0 +1,530 @@
meta.source-filename "Person.im"
ivy.package-scope "net.doorstuck.test"
ivy.package-ref "std.io"
ivy.module {
%cout = ivy.global-ref @cout -> ptr
%StringBuilder = ivy.global-ref @StringBuilder : ptr
ivy.class @Person {
%self.name = ivy.object-var @name : #ivy.id -> ptr
%self.age = ivy.object-var @age : #ivy.id -> ptr
%self.val = ivy.object-var @val : #ivy.id -> ptr
%self.__example-property-4 = ivy.object-var @val : #ivy.id -> ptr
%self.__example-property-5 = ivy.object-var @val : #ivy.id -> ptr
%lambda.0 = ivy.lambda.body <%env> (%i: #ivy.id) -> void {
%StringBuilder = ivy.global-ref @StringBuilder -> ptr
%0 = ivy.msg.send to %StringBuilder, new -> #ivy.id
%1 = ivy.str.constant "Count is "
ivy.msg.send to %0, append:%1 -> void
ivy.msg.send to %0, append:%i -> void
%2 = ivy.msg.send to %0, to-string -> #ivy.id
%cout = ivy.global-ref @cout -> ptr
%3 = ptr.load %cout : ptr -> #ivy.id
ivy.msg.send to %3, put:%2 -> void
func.return : ()
}
%lambda.1 = ivy.lambda.body <%env> () -> void {
%env.q = ivy.pkg.get %env[@q] : #ivy.id -> #ivy.id
%StringBuilder = ivy.global-ref @StringBuilder -> ptr
%0 = ivy.msg.send to %StringBuilder, new -> #ivy.id
%1 = ivy.str.constant "Value of q is "
ivy.msg.send to %0, append:%1 -> void
ivy.msg.send to %0, append:%env.q -> void
%2 = ivy.msg.send to %0, to-string -> #ivy.id
%cout = ivy.global-ref @cout -> ptr
%3 = ptr.load %cout : ptr -> #ivy.id
ivy.msg.send to %3, put:%2 -> void
}
ivy.method init(name:%name, age:%age) -> void {
ptr.store %name, %self.name : #ivy.id, ptr
ptr.store %age, %self.age : #ivy.id, ptr
func.return : ()
}
ivy.method test(param:%data, _:%extra) -> void {
%0 = ptr.load %StringBuilder : ptr -> #ivy.id
%1 = ivy.msg.send to %0, new -> #ivy.id
%2 = ivy.str.constant "Received "
ivy.msg.send to %1, append:%2 -> void
ivy.msg.send to %1, append:%data -> void
%3 = ivy.str.constant ", "
ivy.msg.send to %1, append:%3 -> void
ivy.msg.send to %1, append:%extra -> void
%4 = ivy.msg.send to %1, to-string -> #ivy.id
%5 = ptr.load %cout : ptr -> #ivy.id
ivy.msg.send to %5, put:%4 -> void
func.return : ()
}
ivy.method name -> #ivy.id {
%0 = ptr.load %self.name : ptr -> #ivy.id
func.return %0 : #ivy.id
}
ivy.method age -> #ivy.id {
%0 = ptr.load %self.age : ptr -> #ivy.id
func.return %0 : #ivy.id
}
ivy.method age-in-months -> #ivy.id {
%0 = ptr.load %self.age : ptr -> #ivy.id
%1 = i32.constant 12
%multmp = ivy.mul %0, %1 : (#ivy.id, i32) -> #ivy.id
func.return %multmp : #ivy.id
}
ivy.method set-name:%name -> void {
ptr.store %name, %self.name : #ivy.id, ptr
func.return : ()
}
ivy.method set-age:%age -> void {
ptr.store %age, %self.age : #ivy.id, ptr
func.return : ()
}
ivy.method set-age:%age in-units:%units -> void {
^switch.cond.0:
%0 = ivy.atom "years"
%cmptmp.0 = ivy.cmp eq %age, %0 : (#ivy.id, #ivy.atom) -> i1
cf.br-cond %cmptmp.0, ^switch.body.0, ^switch.cond.1
^switch.body.0:
ptr.store %age, %self.age : #ivy.id, ptr
cf.br ^switch.end.0
^switch.cond.1:
%1 = ivy.atom "months"
%cmptmp.1 = ivy.cmp eq %age, %1 : (#ivy.id, #ivy.atom) -> i1
cf.br-cond %cmptmp.1, ^switch.body.1, ^switch.cond.2
^switch.body.1:
%d0 = i32.constant 12
%divtmp.0 = ivy.div %age, %d0 : (#ivy.id, i32) -> #ivy.id
ptr.store %divtmp.0, %self.age : #ivy.id, ptr
cf.br ^switch.end.0
^switch.cond.2:
%2 = ivy.atom "days"
%cmptmp.2 = ivy.cmp eq %age, %2 : (#ivy.id, #ivy.atom) -> i1
cf.br-cond %cmptmp.2, ^switch.body.2, ^switch.default
^switch.body.2:
%d1 = i32.constant 365
%divtmp.1 = ivy.div %age, %d1 : (#ivy.id, i32) -> #ivy.id
ptr.store %divtmp.1, %self.age : #ivy.id, ptr
cf.br ^switch.end.0
^switch.default:
%d2 = i32.constant 0
cf.br ^switch.end.0
^switch.end:
func.return : ()
}
ivy.method get-age-in-units:%units -> #ivy.id {
^switch.cond.0:
%0 = ivy.atom "years"
%cmptmp.0 = ivy.cmp eq %age, %0 : (#ivy.id, #ivy.atom) -> i1
cf.br-cond %cmptmp.0, ^switch.body.0, ^switch.cond.1
^switch.body.0:
%v0 = ptr.load %self.age : ptr -> #ivy.id
cf.br ^switch.end(%v0: #ivy.id)
^switch.cond.0:
%1 = ivy.atom "months"
%cmptmp.1 = ivy.cmp eq %age, %1 : (#ivy.id, #ivy.atom) -> i1
cf.br-cond %cmptmp.1, ^switch.body.1, ^switch.cond.2
^switch.body.0:
%v0 = ptr.load %self.age : ptr -> #ivy.id
%d0 = i32.constant 12
%divtmp.0 = ivy.div %v0, %d0 : (#ivy.id, i32) -> #ivy.id
cf.br ^switch.end(%divtmp.0: #ivy.id)
^switch.cond.0:
%2 = ivy.atom "days"
%cmptmp.2 = ivy.cmp eq %age, %2 : (#ivy.id, #ivy.atom) -> i1
cf.br-cond %cmptmp.2, ^switch.body.2, ^switch.default
^switch.body.0:
%v1 = ptr.load %self.age : ptr -> #ivy.id
%d1 = i32.constant 365
%divtmp.1 = ivy.div %v1, %d1 : (#ivy.id, i32) -> #ivy.id
cf.br ^switch.end(%divtmp.1: #ivy.id)
^switch.default:
%d2 = i32.constant 0
cf.br ^switch.end(%d2.1: i32)
^switch.end(%result: #ivy.id):
func.return %result : #ivy.id
}
ivy.object-prop example-property
get {
%0 = ptr.load %self.val : ptr -> #ivy.id
func.return %0 : #ivy.id
}
set (%value: #ivy.id) {
ptr.store %value, %self.val : #ivy.id, ptr
func.return : ()
}
ivy.object-prop example-property-2 get {
%0 = ptr.load %self.val : ptr -> #ivy.id
func.return %0 : #ivy.id
} set (%x: #ivy.id) {
ptr.store %x, %self.val : #ivy.id, ptr
func.return : ()
}
ivy.object-prop example-property-3 get {
%0 = i32.constant 42
func.return %0 : i32
}
ivy.object-prop example-property-4 get {
%0 = ptr.load %self.p-example-property-4 : ptr -> #ivy.id
func.return %0 : #ivy.id
} set (%0: #ivy.id) {
ptr.store %0, %self.p-example-property-4 : #ivy.id, ptr
func.return : ()
}
ivy.object-prop example-property-5 get {
%0 = ptr.load %self.p-example-property-5 : ptr -> #ivy.id
func.return %0 : #ivy.id
}
}
ivy.init-text {
; p1 = Person new(name:'John Doe', age:34).
%Person = ivy.global-ref @Person : ptr
%0 = ivy.str.constant "John Doe"
%1 = i32.constant 34
%2 = ivy.msg.send to %Person, new(name:%0, age:%1) -> #ivy.id
%p1 = ptr.alloca #ivy.id -> ptr
ptr.store %2, %p1 : #ivy.id, ptr
; p1 set-age:100 in-unit:$months.
%3 = ptr.load %p1 : ptr -> #ivy.id
%4 = i32.constant 100
%5 = ivy.atom "months"
ivy.msg.send to %3, set-age:%4 in-units:%5 -> void
; p1 test(param:'Hello', 'World').
%6 = ptr.load %p1 : ptr -> #ivy.id
%7 = ivy.str.constant "Hello"
%8 = ivy.str.constant "World"
ivy.msg.send to %6, test(param:%7, _:%8) -> void
; i = 0.
%i = ptr.alloca i32 -> ptr
%9 = i32.constant 0
ptr.store %9, %i : i32, ptr
; while i < 100 do
^while.cond:
; i < 100
%10 = ptr.load %i : ptr -> i32
%11 = i32.constant 100
%cmptmp = ivy.cmp lt %10, %11 : (i32, i32) -> i1
scf.condition(%cmptmp)
cf.br-cond %cmptmp, ^while.body, ^while.end
^while.body:
; cout put:'Count is {i}'.
%12 = ivy.msg.send to %StringBuilder, new -> #ivy.id
%13 = ivy.str.constant "Count is "
ivy.msg.send to %12, append:%13 -> void
%14 = ptr.load %i : ptr -> i32
ivy.msg.send to %12, append:14 -> void
%15 = ivy.msg.send to %12, to-string -> #ivy.id
%16 = ptr.load %cout : ptr -> #ivy.id
ivy.msg.send to %16, put:%15 -> void
; i += 2
%17 = ptr.load %i : ptr -> i32
%18 = i32.constant 2
%addtmp = ivy.add %17, %18 : (i32, i32) -> i32
ptr.store %addtmp, %i : i32, ptr
cf.br ^while.cond
^while.end:
; 0 to:100 step:2
%19 = i32.constant 0
%20 = i32.constant 100
%21 = i32.constant 2
%22 = ivy.msg.send to %19, to:%20 step:%21 -> #ivy.id
%for.iv.0 = ivy.msg.send to %22, value -> #ivy.id
cf.br ^for.cond(%for.iv.0: #ivy.id)
^for.step:
ivy.msg.send to %22, move-next -> void
%for.iv.next = ivy.msg.send to %22, value -> #ivy.id
cf.br ^for.cond(%for.iv.next: #ivy.id)
^for.cond(%iv: #ivy.id):
%for.valid = ivy.is-null-ref %iv : #ivy.id -> i1
cf.br-cond %for.valid, ^for.body(%iv: #ivy.id), ^for.end
^for.body(%x: #ivy.id):
; for x in 0 to:100 step:2 do
%23 = ivy.msg.send to %StringBuilder, new -> #ivy.id
; 'Count is {x}'
%24 = ivy.str.constant "Count is "
ivy.msg.send to %23, append:%24 -> void
ivy.msg.send to %23, append:%x -> void
%25 = ivy.msg.send to %23, to-string -> #ivy.id
; cout put:"Count is {x}"
%26 = ptr.load %cout : ptr -> #ivy.id
ivy.msg.send to %26, put:%25 -> void
cf.br ^for.step
^for.end:
; 0 to:100 step:2 do:...
%27 = i32.constant 0
%28 = i32.constant 100
%29 = i32.constant 2
; [ :i | cout put:'Count: {i}' ]
%30 = ivy.lambda.create %lambda.0 -> #ivy.id
; 0 to:100 step:2 do:[ :i | cout put:'Count: {i}' ].
ivy.msg.send to %27, to:%28 step:%29 do:%30
; q = 32.
%q = ptr.alloca i32 -> ptr
%31 = i32.constant 32
ptr.store %31, %q : i32, ptr
; l = [ cout put:'Value of q is {q}' ].
%l = ptr.alloca #ivy.id
%32 = ptr.load %q : ptr -> i32
%lambda.env = ivy.pkg.create -> #ivy.id
ivy.pkg.put %lambda.env[@q] = %32 : (#ivy.id, #ivy.id)
%33 = ivy.lambda.create <%lambda.env> %lambda.1 -> #ivy.id
ptr.store %33, %l : #ivy.id, ptr
; q = 64.
%34 = i32.constant 64
ptr.store %34, %q : i32, ptr
; l call.
%35 = ptr.load %l : ptr -> #ivy.id
ivy.msg.send to %35, call -> void
%j = ptr.alloca i32 -> ptr
%36 = i32.constant 32
ptr.store %36, %j : i32, ptr
%37 = ptr.load %i : ptr -> i32
%38 = ptr.load %j : ptr -> i32
%cmptmp = arith.cmp lt %37, %38 : (i32, i32) -> i1
%39 = ivy.lambda : () -> void {
%cout = ivy.global-ref @cout -> ptr
%0 = ivy.str.constant "True!"
%1 = ptr.load %cout : ptr -> #ivy.id
ivy.msg.send to %1, put:%0 -> void
}
%40 = ivy.lambda : () -> void {
%cout = ivy.global-ref @cout -> ptr
%0 = ivy.str.constant "False!"
%1 = ptr.load %cout : ptr -> #ivy.id
ivy.msg.send to %1, put:%0 -> void
}
ivy.msg.send to %cmptmp, if:%39 else:%40 -> void
%41 = ptr.load %i : ptr -> i32
%42 = ptr.load %j : ptr -> i32
%cmptmp.0 = arith.cmp lt %41, %42 : (i32, i32) -> i1
scf.if %cmptmp.0 -> void {
%43 = ivy.str.constant "True!"
%44 = ptr.load %cout : ptr -> #ivy.id
ivy.msg.send to %44, put:%43 -> void
}
; pkg = {}.
%pkg = ptr.alloca #ivy.id -> ptr
%45 = ivy.pkg.create -> #ivy.id
ptr.store %45, %pkg : #ivy.id, ptr
; pkg[0] = 16.
%46 = ptr.load %pkg : ptr -> #ivy.id
%47 = i32.constant 0
%48 = i32.constant 16
ivy.msg.send to %46, at:%47 put:%48 -> void
; tuple = (32, 'a string')
%tuple = ptr.alloca #ivy.id -> ptr
%49 = i32.constant 32
%50 = ivy.str.constant "a string"
%51 = ivy.tuple.create %49, %50 : (i32, #ivy.id) -> #ivy.id
ptr.store %51, %tuple : #ivy.id, ptr
%52 = ptr.load %tuple : ptr -> #ivy.id
%53 = ivy.msg.send to %52, get-iterator -> #ivy.id
ivy.for %54 in %53 -> void {
%key = ivy.tuple.get-item %54[0] : #ivy.id -> #ivy.id
%val = ivy.tuple.get-item %54[1] : #ivy.id -> #ivy.id
; '{key} -> {val}'
%55 = ivy.msg.send to %StringBuilder, new -> #ivy.id
ivy.msg.send to %55, append:%key -> void
%56 = ivy.str.constant " -> "
ivy.msg.send to %55, append:%56 -> void
ivy.msg.send to %55, append:%val -> void
%57 = ivy.msg.send to %23, to-string -> #ivy.id
; cout put:'{key} -> {val}'
%58 = ptr.load %cout : ptr -> #ivy.id
ivy.msg.send to %58, put:%57 -> void
}
; _ = 3 * 2.
%59 = i32.constant 3
%60 = i32.constant 2
%multmp = arith.mul %59, %60 : (i32, i32) -> i32
; a = (32, 64).
%a = ptr.alloca #ivy.id -> ptr
%61 = i32.constant 32
%62 = i32.constant 64
%63 = ivy.tuple.create %61, %62 : (i32, i32) -> #ivy.id
ptr.store %63, %a : #ivy.id, ptr
%v = ptr.alloca #ivy.id -> ptr
%64 = ptr.load %a : ptr -> #ivy.id
%65 = ivy.tuple.get-item %64[1] : #ivy.id -> #ivy.id
ptr.store %65, %v : #ivy.id, ptr
%66 = ivy.atom "err:number-format"
ivy.try -> void {
} catch (%ex = %66), %data {
} catch-all %ex, %data {
}
%67 = ivy.lambda : () -> void {
%v = ptr.alloca #ivy.id -> ptr
%Int = ivy.global-ref @Int -> ptr
%0 = ivy.str.constant "342"
%1 = ivy.msg.send to %Int, parse:%0
ptr.store %1, %v : #ivy.id, ptr
}
%68 = ivy.lambda %err, %data : (#ivy.id, #ivy.id) -> void {
%0 = ivy.msg.send to %StringBuilder, new -> #ivy.id
ivy.msg.send to %0, append:%key -> void
%1 = ivy.str.constant "Cannot parse integer string ("
ivy.msg.send to %0, append:%1 -> void
ivy.msg.send to %0, append:%err -> void
%2 = ivy.str.constant ")"
ivy.msg.send to %0, append:%2 -> void
%3 = ivy.msg.send to %0, to-string -> #ivy.id
; cout put:'{key} -> {val}'
%4 = ptr.load %cout : ptr -> #ivy.id
ivy.msg.send to %4, put:%3 -> void
}
%69 = ivy.lambda %err, %data : (#ivy.id, #ivy.id) -> void {
%0 = ivy.msg.send to %StringBuilder, new -> #ivy.id
ivy.msg.send to %0, append:%key -> void
%1 = ivy.str.constant "Error "
ivy.msg.send to %0, append:%1 -> void
ivy.msg.send to %0, append:%err -> void
%2 = ivy.str.constant " occurred ("
ivy.msg.send to %0, append:%2 -> void
ivy.msg.send to %0, append:%data -> void
%3 = ivy.str.constant ")"
%4 = ivy.msg.send to %0, to-string -> #ivy.id
; cout put:'{key} -> {val}'
%5 = ptr.load %cout : ptr -> #ivy.id
ivy.msg.send to %5, put:%4 -> void
}
%70 = ivy.atom "err:number-format"
ivy.msg.send to %67, on:%70 do:%68 -> #ivy.id
ivy.msg.send to %67, on-error:%69 -> void
ivy.msg.send to %67, call -> void
}
}

535
doc/sample/ir/Person.3.mie Normal file
View File

@@ -0,0 +1,535 @@
meta.source-filename "Person.im"
ivy.package-scope "net.doorstuck.test"
ivy.package-ref "std.io"
ivy.module {
%cout = ivy.global-ref @cout -> ptr
%StringBuilder = ivy.global-ref @StringBuilder : ptr
ivy.class @Person {
%self.name = ivy.object-var @name : #ivy.id -> ptr
%self.age = ivy.object-var @age : #ivy.id -> ptr
%self.val = ivy.object-var @val : #ivy.id -> ptr
%self.__example-property-4 = ivy.object-var @val : #ivy.id -> ptr
%self.__example-property-5 = ivy.object-var @val : #ivy.id -> ptr
%lambda.0 = ivy.lambda.body <%env> (%i: #ivy.id) -> void {
%StringBuilder = ivy.global-ref @StringBuilder -> ptr
%0 = ivy.msg.send to %StringBuilder, new -> #ivy.id
%1 = ivy.str.constant "Count is "
ivy.msg.send to %0, append:%1 -> void
ivy.msg.send to %0, append:%i -> void
%2 = ivy.msg.send to %0, to-string -> #ivy.id
%cout = ivy.global-ref @cout -> ptr
%3 = ptr.load %cout : ptr -> #ivy.id
ivy.msg.send to %3, put:%2 -> void
func.return : ()
}
%lambda.1 = ivy.lambda.body <%env> () -> void {
%env.q = ivy.pkg.get %env[@q] : #ivy.id -> #ivy.id
%StringBuilder = ivy.global-ref @StringBuilder -> ptr
%0 = ivy.msg.send to %StringBuilder, new -> #ivy.id
%1 = ivy.str.constant "Value of q is "
ivy.msg.send to %0, append:%1 -> void
ivy.msg.send to %0, append:%env.q -> void
%2 = ivy.msg.send to %0, to-string -> #ivy.id
%cout = ivy.global-ref @cout -> ptr
%3 = ptr.load %cout : ptr -> #ivy.id
ivy.msg.send to %3, put:%2 -> void
}
ivy.object.func init(name:%name, age:%age) -> void {
ptr.store %name, %self.name : #ivy.id, ptr
ptr.store %age, %self.age : #ivy.id, ptr
func.return : ()
}
ivy.object.func test(param:%data, _:%extra) -> void {
%0 = ptr.load %StringBuilder : ptr -> #ivy.id
%1 = ivy.msg.send to %0, new -> #ivy.id
%2 = ivy.str.constant "Received "
ivy.msg.send to %1, append:%2 -> void
ivy.msg.send to %1, append:%data -> void
%3 = ivy.str.constant ", "
ivy.msg.send to %1, append:%3 -> void
ivy.msg.send to %1, append:%extra -> void
%4 = ivy.msg.send to %1, to-string -> #ivy.id
%5 = ptr.load %cout : ptr -> #ivy.id
ivy.msg.send to %5, put:%4 -> void
func.return : ()
}
ivy.object.func name -> #ivy.id {
%0 = ptr.load %self.name : ptr -> #ivy.id
func.return %0 : #ivy.id
}
ivy.object.func age -> #ivy.id {
%0 = ptr.load %self.age : ptr -> #ivy.id
func.return %0 : #ivy.id
}
ivy.object.func age-in-months -> #ivy.id {
%0 = ptr.load %self.age : ptr -> #ivy.id
%1 = i32.constant 12
%multmp = ivy.mul %0, %1 : (#ivy.id, i32) -> #ivy.id
func.return %multmp : #ivy.id
}
ivy.object.func set-name:%name -> void {
ptr.store %name, %self.name : #ivy.id, ptr
func.return : ()
}
ivy.object.func set-age:%age -> void {
ptr.store %age, %self.age : #ivy.id, ptr
func.return : ()
}
ivy.object.func set-age:%age in-units:%units -> void {
^switch.cond.0:
%0 = ivy.atom "years"
%cmptmp.0 = ivy.cmp eq %age, %0 : (#ivy.id, #ivy.atom) -> i1
cf.br-cond %cmptmp.0, ^switch.body.0, ^switch.cond.1
^switch.body.0:
ptr.store %age, %self.age : #ivy.id, ptr
cf.br ^switch.end.0
^switch.cond.1:
%1 = ivy.atom "months"
%cmptmp.1 = ivy.cmp eq %age, %1 : (#ivy.id, #ivy.atom) -> i1
cf.br-cond %cmptmp.1, ^switch.body.1, ^switch.cond.2
^switch.body.1:
%d0 = i32.constant 12
%divtmp.0 = ivy.div %age, %d0 : (#ivy.id, i32) -> #ivy.id
ptr.store %divtmp.0, %self.age : #ivy.id, ptr
cf.br ^switch.end.0
^switch.cond.2:
%2 = ivy.atom "days"
%cmptmp.2 = ivy.cmp eq %age, %2 : (#ivy.id, #ivy.atom) -> i1
cf.br-cond %cmptmp.2, ^switch.body.2, ^switch.default
^switch.body.2:
%d1 = i32.constant 365
%divtmp.1 = ivy.div %age, %d1 : (#ivy.id, i32) -> #ivy.id
ptr.store %divtmp.1, %self.age : #ivy.id, ptr
cf.br ^switch.end.0
^switch.default:
%d2 = i32.constant 0
ptr.store %d2, %self.age : #ivy.id, ptr
cf.br ^switch.end.0
^switch.end:
func.return : ()
}
ivy.object.func get-age-in-units:%units -> #ivy.id {
^switch.cond.0:
%0 = ivy.atom "years"
%cmptmp.0 = ivy.cmp eq %age, %0 : (#ivy.id, #ivy.atom) -> i1
cf.br-cond %cmptmp.0, ^switch.body.0, ^switch.cond.1
^switch.body.0:
%v0 = ptr.load %self.age : ptr -> #ivy.id
cf.br ^switch.end(%v0: #ivy.id)
^switch.cond.1:
%1 = ivy.atom "months"
%cmptmp.1 = ivy.cmp eq %age, %1 : (#ivy.id, #ivy.atom) -> i1
cf.br-cond %cmptmp.1, ^switch.body.1, ^switch.cond.2
^switch.body.1:
%v0 = ptr.load %self.age : ptr -> #ivy.id
%d0 = i32.constant 12
%divtmp.0 = ivy.div %v0, %d0 : (#ivy.id, i32) -> #ivy.id
cf.br ^switch.end(%divtmp.0: #ivy.id)
^switch.cond.2:
%2 = ivy.atom "days"
%cmptmp.2 = ivy.cmp eq %age, %2 : (#ivy.id, #ivy.atom) -> i1
cf.br-cond %cmptmp.2, ^switch.body.2, ^switch.default
^switch.body.2:
%v1 = ptr.load %self.age : ptr -> #ivy.id
%d1 = i32.constant 365
%divtmp.1 = ivy.div %v1, %d1 : (#ivy.id, i32) -> #ivy.id
cf.br ^switch.end(%divtmp.1: #ivy.id)
^switch.default:
%d2 = i32.constant 0
cf.br ^switch.end(%d2.1: i32)
^switch.end(%result: #ivy.id):
func.return %result : #ivy.id
}
ivy.object.prop example-property
get {
%0 = ptr.load %self.val : ptr -> #ivy.id
func.return %0 : #ivy.id
}
set (%value: #ivy.id) {
ptr.store %value, %self.val : #ivy.id, ptr
func.return : ()
}
ivy.object.prop example-property-2 get {
%0 = ptr.load %self.val : ptr -> #ivy.id
func.return %0 : #ivy.id
} set (%x: #ivy.id) {
ptr.store %x, %self.val : #ivy.id, ptr
func.return : ()
}
ivy.object.prop example-property-3 get {
%0 = i32.constant 42
func.return %0 : i32
}
ivy.object.prop example-property-4 get {
%0 = ptr.load %self.p-example-property-4 : ptr -> #ivy.id
func.return %0 : #ivy.id
} set (%0: #ivy.id) {
ptr.store %0, %self.p-example-property-4 : #ivy.id, ptr
func.return : ()
}
ivy.object.prop example-property-5 get {
%0 = ptr.load %self.p-example-property-5 : ptr -> #ivy.id
func.return %0 : #ivy.id
}
}
ivy.init-text {
; p1 = Person new(name:'John Doe', age:34).
%Person = ivy.global-ref @Person : ptr
%0 = ivy.str.constant "John Doe"
%1 = i32.constant 34
%2 = ivy.msg.send to %Person, new(name:%0, age:%1) -> #ivy.id
%p1 = ptr.alloca #ivy.id -> ptr
ptr.store %2, %p1 : #ivy.id, ptr
; p1 set-age:100 in-unit:$months.
%3 = ptr.load %p1 : ptr -> #ivy.id
%4 = i32.constant 100
%5 = ivy.atom "months"
ivy.msg.send to %3, set-age:%4 in-units:%5 -> void
; p1 test(param:'Hello', 'World').
%6 = ptr.load %p1 : ptr -> #ivy.id
%7 = ivy.str.constant "Hello"
%8 = ivy.str.constant "World"
ivy.msg.send to %6, test(param:%7, _:%8) -> void
; i = 0.
%i = ptr.alloca i32 -> ptr
%9 = i32.constant 0
ptr.store %9, %i : i32, ptr
cf.br ^while.cond
; while i < 100 do
^while.cond:
; i < 100
%10 = ptr.load %i : ptr -> i32
%11 = i32.constant 100
%cmptmp = ivy.cmp lt %10, %11 : (i32, i32) -> i1
scf.condition(%cmptmp)
cf.br-cond %cmptmp, ^while.body, ^while.end
^while.body:
; cout put:'Count is {i}'.
%12 = ivy.msg.send to %StringBuilder, new -> #ivy.id
%13 = ivy.str.constant "Count is "
ivy.msg.send to %12, append:%13 -> void
%14 = ptr.load %i : ptr -> i32
ivy.msg.send to %12, append:14 -> void
%15 = ivy.msg.send to %12, to-string -> #ivy.id
%16 = ptr.load %cout : ptr -> #ivy.id
ivy.msg.send to %16, put:%15 -> void
; i += 2
%17 = ptr.load %i : ptr -> i32
%18 = i32.constant 2
%addtmp = ivy.add %17, %18 : (i32, i32) -> i32
ptr.store %addtmp, %i : i32, ptr
cf.br ^while.cond
^while.end:
; 0 to:100 step:2
%19 = i32.constant 0
%20 = i32.constant 100
%21 = i32.constant 2
%22 = ivy.msg.send to %19, to:%20 step:%21 -> #ivy.id
cf.br ^for.init(%22: #ivy.id)
^for.init(%it: #ivy.id):
%for.iv.0 = ivy.msg.send to %it, value -> #ivy.id
cf.br ^for.cond(%it: #ivy.id, %for.iv.0: #ivy.id)
^for.step(%it: #ivy.id):
ivy.msg.send to %22, move-next -> void
%for.iv.next = ivy.msg.send to %22, value -> #ivy.id
cf.br ^for.cond(%it: #ivy.id, %for.iv.next: #ivy.id)
^for.cond(%it: #ivy.id, %iv: #ivy.id):
%for.valid = ivy.is-null-ref %iv : #ivy.id -> i1
cf.br-cond %for.valid, ^for.body(%it: #ivy.id, %iv: #ivy.id), ^for.end
^for.body(%it: #ivy.id, %x: #ivy.id):
; for x in 0 to:100 step:2 do
%23 = ivy.msg.send to %StringBuilder, new -> #ivy.id
; 'Count is {x}'
%24 = ivy.str.constant "Count is "
ivy.msg.send to %23, append:%24 -> void
ivy.msg.send to %23, append:%x -> void
%25 = ivy.msg.send to %23, to-string -> #ivy.id
; cout put:"Count is {x}"
%26 = ptr.load %cout : ptr -> #ivy.id
ivy.msg.send to %26, put:%25 -> void
cf.br ^for.step(%it: #ivy.id)
^for.end:
; 0 to:100 step:2 do:...
%27 = i32.constant 0
%28 = i32.constant 100
%29 = i32.constant 2
; [ :i | cout put:'Count: {i}' ]
%30 = ivy.lambda.create %lambda.0 -> #ivy.id
; 0 to:100 step:2 do:[ :i | cout put:'Count: {i}' ].
ivy.msg.send to %27, to:%28 step:%29 do:%30
; q = 32.
%q = ptr.alloca i32 -> ptr
%31 = i32.constant 32
ptr.store %31, %q : i32, ptr
; l = [ cout put:'Value of q is {q}' ].
%l = ptr.alloca #ivy.id
%32 = ptr.load %q : ptr -> i32
%lambda.env = ivy.pkg.create -> #ivy.id
ivy.pkg.put %lambda.env[@q] = %32 : (#ivy.id, #ivy.id)
%33 = ivy.lambda.create <%lambda.env> %lambda.1 -> #ivy.id
ptr.store %33, %l : #ivy.id, ptr
; q = 64.
%34 = i32.constant 64
ptr.store %34, %q : i32, ptr
; l call.
%35 = ptr.load %l : ptr -> #ivy.id
ivy.msg.send to %35, call -> void
%j = ptr.alloca i32 -> ptr
%36 = i32.constant 32
ptr.store %36, %j : i32, ptr
%37 = ptr.load %i : ptr -> i32
%38 = ptr.load %j : ptr -> i32
%cmptmp = arith.cmp lt %37, %38 : (i32, i32) -> i1
%39 = ivy.lambda : () -> void {
%cout = ivy.global-ref @cout -> ptr
%0 = ivy.str.constant "True!"
%1 = ptr.load %cout : ptr -> #ivy.id
ivy.msg.send to %1, put:%0 -> void
}
%40 = ivy.lambda : () -> void {
%cout = ivy.global-ref @cout -> ptr
%0 = ivy.str.constant "False!"
%1 = ptr.load %cout : ptr -> #ivy.id
ivy.msg.send to %1, put:%0 -> void
}
ivy.msg.send to %cmptmp, if:%39 else:%40 -> void
%41 = ptr.load %i : ptr -> i32
%42 = ptr.load %j : ptr -> i32
%cmptmp.0 = arith.cmp lt %41, %42 : (i32, i32) -> i1
scf.if %cmptmp.0 -> void {
%43 = ivy.str.constant "True!"
%44 = ptr.load %cout : ptr -> #ivy.id
ivy.msg.send to %44, put:%43 -> void
}
; pkg = {}.
%pkg = ptr.alloca #ivy.id -> ptr
%45 = ivy.pkg.create -> #ivy.id
ptr.store %45, %pkg : #ivy.id, ptr
; pkg[0] = 16.
%46 = ptr.load %pkg : ptr -> #ivy.id
%47 = i32.constant 0
%48 = i32.constant 16
ivy.msg.send to %46, at:%47 put:%48 -> void
; tuple = (32, 'a string')
%tuple = ptr.alloca #ivy.id -> ptr
%49 = i32.constant 32
%50 = ivy.str.constant "a string"
%51 = ivy.tuple.create %49, %50 : (i32, #ivy.id) -> #ivy.id
ptr.store %51, %tuple : #ivy.id, ptr
%52 = ptr.load %tuple : ptr -> #ivy.id
%53 = ivy.msg.send to %52, get-iterator -> #ivy.id
ivy.for %54 in %53 -> void {
%key = ivy.tuple.get-item %54[0] : #ivy.id -> #ivy.id
%val = ivy.tuple.get-item %54[1] : #ivy.id -> #ivy.id
; '{key} -> {val}'
%55 = ivy.msg.send to %StringBuilder, new -> #ivy.id
ivy.msg.send to %55, append:%key -> void
%56 = ivy.str.constant " -> "
ivy.msg.send to %55, append:%56 -> void
ivy.msg.send to %55, append:%val -> void
%57 = ivy.msg.send to %23, to-string -> #ivy.id
; cout put:'{key} -> {val}'
%58 = ptr.load %cout : ptr -> #ivy.id
ivy.msg.send to %58, put:%57 -> void
}
; _ = 3 * 2.
%59 = i32.constant 3
%60 = i32.constant 2
%multmp = arith.mul %59, %60 : (i32, i32) -> i32
; a = (32, 64).
%a = ptr.alloca #ivy.id -> ptr
%61 = i32.constant 32
%62 = i32.constant 64
%63 = ivy.tuple.create %61, %62 : (i32, i32) -> #ivy.id
ptr.store %63, %a : #ivy.id, ptr
%v = ptr.alloca #ivy.id -> ptr
%64 = ptr.load %a : ptr -> #ivy.id
%65 = ivy.tuple.get-item %64[1] : #ivy.id -> #ivy.id
ptr.store %65, %v : #ivy.id, ptr
%66 = ivy.atom "err:number-format"
ivy.try -> void {
} catch (%ex = %66), %data {
} catch-all %ex, %data {
}
%67 = ivy.lambda : () -> void {
%v = ptr.alloca #ivy.id -> ptr
%Int = ivy.global-ref @Int -> ptr
%0 = ivy.str.constant "342"
%1 = ivy.msg.send to %Int, parse:%0
ptr.store %1, %v : #ivy.id, ptr
}
%68 = ivy.lambda %err, %data : (#ivy.id, #ivy.id) -> void {
%0 = ivy.msg.send to %StringBuilder, new -> #ivy.id
ivy.msg.send to %0, append:%key -> void
%1 = ivy.str.constant "Cannot parse integer string ("
ivy.msg.send to %0, append:%1 -> void
ivy.msg.send to %0, append:%err -> void
%2 = ivy.str.constant ")"
ivy.msg.send to %0, append:%2 -> void
%3 = ivy.msg.send to %0, to-string -> #ivy.id
; cout put:'{key} -> {val}'
%4 = ptr.load %cout : ptr -> #ivy.id
ivy.msg.send to %4, put:%3 -> void
}
%69 = ivy.lambda %err, %data : (#ivy.id, #ivy.id) -> void {
%0 = ivy.msg.send to %StringBuilder, new -> #ivy.id
ivy.msg.send to %0, append:%key -> void
%1 = ivy.str.constant "Error "
ivy.msg.send to %0, append:%1 -> void
ivy.msg.send to %0, append:%err -> void
%2 = ivy.str.constant " occurred ("
ivy.msg.send to %0, append:%2 -> void
ivy.msg.send to %0, append:%data -> void
%3 = ivy.str.constant ")"
%4 = ivy.msg.send to %0, to-string -> #ivy.id
; cout put:'{key} -> {val}'
%5 = ptr.load %cout : ptr -> #ivy.id
ivy.msg.send to %5, put:%4 -> void
}
%70 = ivy.atom "err:number-format"
ivy.msg.send to %67, on:%70 do:%68 -> #ivy.id
ivy.msg.send to %67, on-error:%69 -> void
ivy.msg.send to %67, call -> void
}
}

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

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

View File

@@ -0,0 +1,46 @@
meta.source-filename "Simple.im"
ivy.package-scope "net.doorstuck.test"
ivy.package-ref "std.io"
ivy.module {
ivy.init-text {
%0 = i32.constant 32
%1 = i32.constant 64
%multmp = arith.mul %0, %1 : (i32, i32) -> i32
%y = ptr.alloca i32
ptr.store %multmp, %y : i32, ptr
%2 = i32.constant 64
%3 = i32.constant 4
%divtmp = arith.div %2, %3 : (i32, i32) -> i32
%z = ptr.alloca i32
ptr.store %divtmp, %z : i32, ptr
%4 = ptr.load %y : ptr -> i32
%5 = ptr.load %z : ptr -> i32
%addtmp = arith.add %4, %5 : (i32, i32) -> i32
%x = ptr.alloca i32
ptr.store %addtmp, %x : i32, ptr
%cout = ivy.global-ref @cout -> ptr
%6 = ivy.string-builder.begin
ivy.string-builder.add %6 << "Answer: "
%7 = ptr.load %x : ptr -> i32
ivy.string-builder.add %6 << %7 : i32
%8 = ivy.string-builder.end %6 -> #ivy.id
%9 = ptr.load %cout : ptr -> #ivy.id
ivy.msg.send to %9, put:%8 -> void
func.return : ()
}
}

View File

@@ -0,0 +1,50 @@
meta.source-filename "Simple.im"
ivy.package-scope "net.doorstuck.test"
ivy.package-ref "std.io"
ivy.module {
%cout = ivy.global-ref @cout -> ptr
%StringBuilder = ivy.global-ref @std.lang.StringBuilder -> ptr
%.str.0 = ivy.str.constant "Answer: "
ivy.init-text {
%0 = i32.constant 32
%1 = i32.constant 64
%multmp = arith.mul %0, %1 : (i32, i32) -> i32
%y = ptr.alloca i32
ptr.store %multmp, %y : i32, ptr
%2 = i32.constant 64
%3 = i32.constant 4
%divtmp = arith.div %2, %3 : (i32, i32) -> i32
%z = ptr.alloca i32
ptr.store %divtmp, %z : i32, ptr
%4 = ptr.load %y : ptr -> i32
%5 = ptr.load %z : ptr -> i32
%addtmp = arith.add %4, %5 : (i32, i32) -> i32
%x = ptr.alloca i32
ptr.store %addtmp, %x : i32, ptr
%10 = ptr.load %StringBuilder : ptr -> #ivy.id
ivy.msg.send to %10, append:%.str.0 -> void
%7 = ptr.load %x : ptr -> i32
ivy.msg.send to %10, append:%7 -> void
%8 = ivy.msg.send to %10, to-string -> #ivy.id
%9 = ptr.load %cout : ptr -> #ivy.id
ivy.msg.send to %9, put:%8 -> void
func.return : ()
}
}

View File

@@ -0,0 +1,63 @@
meta.source-filename "Simple.im"
ivy.package-scope "net.doorstuck.test"
ivy.package-ref "std.io"
ivy.module {
%cout = ivy.pool.ident @cout -> #ivy.pool-slot
%StringBuilder = ivy.pool.ident @std.lang.StringBuilder -> #ivy.pool-slot
%.str.0 = ivy.pool.string "Answer: " -> #ivy.pool-slot
%.sel.o-append = ivy.pool.selector append -> #ivy.pool-slot
%.sel.o-to-string = ivy.pool.selector to-string -> #ivy.pool-slot
%.sel.o-put = ivy.pool.selector put -> #ivy.pool-slot
ivy.init-text {
%0 = i32.constant 32
%1 = i32.constant 64
%multmp = *ivy.MUL %0, %1 : (i32, i32) -> i32
*ivy.PUSH %multmp : i32
%y = ivy.bp-slot 0 -> #ivy.bp-slot
%2 = i32.constant 64
%3 = i32.constant 4
%divtmp = *ivy.DIV %2, %3 : (i32, i32) -> i32
*ivy.PUSH %divtmp : i32
%z = ivy.bp-slot 1 -> #ivy.bp-slot
%4 = *ivy.LDR-BP %y : #ivy.bp-slot -> i32
%5 = *ivy.LDR-BP %z : #ivy.bp-slot -> i32
%addtmp = *ivy.ADD %4, %5 : (i32, i32) -> i32
*ivy.PUSH %addtmp : i32
%x = ivy.bp-slot 2 -> #ivy.bp-slot
%10 = *ivy.LDR-POOL %StringBuilder : #ivy.pool-slot -> #ivy.id
%20 = *ivy.LDR-POOL %.sel.o-append : #ivy.pool-slot -> #ivy.id
%21 = *ivy.LDR-POOL %.str.0 : #ivy.pool-slot -> #ivy.id
*ivy.PUSH %21 : #ivy.id
*ivy.MSG-I %10, %20, 1 : (#ivy.id, #ivy.id, i32) -> void
%7 = *ivy.LDR-BP %x : ptr -> i32
*ivy.PUSH %7 : i32
%22 = *ivy.LDR-POOL %.sel.o-append : #ivy.pool-slot -> #ivy.id
*ivy.MSG-I %10, %22, 1 : (#ivy.id, #ivy.id, i32) -> void
%23 = *ivy.LDR-POOL %.sel.o-to-string : #ivy.pool-slot -> #ivy.id
%8 = *ivy.MSG-I %10, %23, 0 : (#ivy.id, #ivy.id, i32) -> #ivy.id
%9 = *ivy.LDR-POOL %cout : #ivy.pool-slot -> #ivy.id
%24 = *ivy.LDR-POOL %.sel.o-put : #ivy.pool-slot -> #ivy.id
*ivy.PUSH %8 : #ivy.id
*ivy.MSG-I %9, %24, 1 : (#ivy.id, #ivy.id, i32) -> void
*ivy.RET-N : ()
}
}

View File

@@ -0,0 +1,62 @@
meta.source-filename "Simple.im"
ivy.package-scope "net.doorstuck.test"
ivy.package-ref "std.io"
ivy.module {
%cout = ivy.pool.ident @cout -> #ivy.pool-slot
%StringBuilder = ivy.pool.ident @std.lang.StringBuilder -> #ivy.pool-slot
%.str.0 = ivy.pool.string "Answer: " -> #ivy.pool-slot
%.sel.o-append = ivy.pool.selector append -> #ivy.pool-slot
%.sel.o-to-string = ivy.pool.selector to-string -> #ivy.pool-slot
%.sel.o-put = ivy.pool.selector put -> #ivy.pool-slot
ivy.init-text {
%0 = i32.constant 32
%1 = i32.constant 64
%multmp = *ivy.MUL %0, %1 : (i32, i32) -> i32
*ivy.PUSH %multmp : i32
%y = ivy.bp-slot 0 -> #ivy.bp-slot
%2 = i32.constant 64
%3 = i32.constant 4
%divtmp = *ivy.DIV %2, %3 : (i32, i32) -> i32
*ivy.PUSH %divtmp : i32
%z = ivy.bp-slot 1 -> #ivy.bp-slot
%4 = *ivy.LDR %y : #ivy.bp-slot -> i32
%5 = *ivy.LDR %z : #ivy.bp-slot -> i32
%addtmp = *ivy.ADD %4, %5 : (i32, i32) -> i32
*ivy.PUSH %addtmp : i32
%x = ivy.bp-slot 2 -> #ivy.bp-slot
%10 = *ivy.LDR %StringBuilder : #ivy.pool-slot -> #ivy.id
%20 = *ivy.LDR %.sel.o-append : #ivy.pool-slot -> #ivy.id
%21 = *ivy.LDR %.str.0 : #ivy.pool-slot -> #ivy.id
*ivy.PUSH %21 : #ivy.id
*ivy.MSG %10, %20, 1 : (#ivy.id, #ivy.id, i32) -> void
%7 = *ivy.LDR %x : ptr -> i32
*ivy.PUSH %7 : i32
*ivy.MSG %10, %20, 1 : (#ivy.id, #ivy.id, i32) -> void
%23 = *ivy.LDR %.sel.o-to-string : #ivy.pool-slot -> #ivy.id
%8 = *ivy.MSG %10, %23, 0 : (#ivy.id, #ivy.id, i32) -> #ivy.id
%9 = *ivy.LDR %cout : #ivy.pool-slot -> #ivy.id
%24 = *ivy.LDR %.sel.o-put : #ivy.pool-slot -> #ivy.id
*ivy.PUSH %8 : #ivy.id
*ivy.MSG %9, %24, 1 : (#ivy.id, #ivy.id, i32) -> void
*ivy.RET-N : ()
}
}

View File

@@ -0,0 +1,68 @@
meta.source-filename "Simple.im"
ivy.package-scope "net.doorstuck.test"
ivy.package-ref "std.io"
ivy.module {
%cout = ivy.pool.ident @cout -> #ivy.pool-slot
%StringBuilder = ivy.pool.ident @std.lang.StringBuilder -> #ivy.pool-slot
%.str.0 = ivy.pool.string "Answer: " -> #ivy.pool-slot
%.sel.o-append = ivy.pool.selector append -> #ivy.pool-slot
%.sel.o-to-string = ivy.pool.selector to-string -> #ivy.pool-slot
%.sel.o-put = ivy.pool.selector put -> #ivy.pool-slot
%.i.0 = i32.constant 0
%.i.1 = i32.constant 1
%.i.4 = i32.constant 4
%.i.32 = i32.constant 32
%.i.64 = i32.constant 64
ivy.init-text {
$X0 = *ivy.LDR %.i.32 -> i32
$X1 = *ivy.LDR %.i.64 -> i32
$X2 = *ivy.MUL $X0, $X1 : (i32, i32) -> i32
*ivy.PUSH $X2 : i32
%.bp.0 = ivy.bp-slot 0 -> #ivy.bp-slot
$X4 = *ivy.LDR %.i.64 -> i32
$X5 = *ivy.LDR %.i.4 -> i32
$X6 = *ivy.DIV $X4, $X5 : (i32, i32) -> i32
*ivy.PUSH $X6 : i32
%.bp.1 = ivy.bp-slot 1 -> #ivy.bp-slot
$X8 = *ivy.LDR %.bp.0 : #ivy.bp-slot -> i32
$X9 = *ivy.LDR %.bp.1 : #ivy.bp-slot -> i32
$X10 = *ivy.ADD $X8, $X9 : (i32, i32) -> i32
*ivy.PUSH $X10 : i32
%.bp.2 = ivy.bp-slot 2 -> #ivy.bp-slot
%10 = *ivy.LDR %StringBuilder : #ivy.pool-slot -> #ivy.id
%20 = *ivy.LDR %.sel.o-append : #ivy.pool-slot -> #ivy.id
%21 = *ivy.LDR %.str.0 : #ivy.pool-slot -> #ivy.id
*ivy.PUSH %21 : #ivy.id
*ivy.MSG %10, %20, %.i.1 : (#ivy.id, #ivy.id, i32) -> void
%7 = *ivy.LDR %.bp.2 : ptr -> i32
*ivy.PUSH %7 : i32
*ivy.MSG %10, %20, %.i.1 : (#ivy.id, #ivy.id, i32) -> void
%23 = *ivy.LDR %.sel.o-to-string : #ivy.pool-slot -> #ivy.id
%8 = *ivy.MSG %10, %23, %.i.0 : (#ivy.id, #ivy.id, i32) -> #ivy.id
%9 = *ivy.LDR %cout : #ivy.pool-slot -> #ivy.id
%24 = *ivy.LDR %.sel.o-put : #ivy.pool-slot -> #ivy.id
*ivy.PUSH %8 : #ivy.id
*ivy.MSG %9, %24, %.i.1 : (#ivy.id, #ivy.id, i32) -> void
*ivy.RET-N : ()
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -11,5 +11,5 @@ else ()
endif () endif ()
target_include_directories(mie PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include/) target_include_directories(mie PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include/)
target_link_libraries(mie Bluelib::Core Bluelib::Ds) target_link_libraries(mie Bluelib::Core Bluelib::Ds Bluelib::Io)
target_compile_definitions(mie PRIVATE MIE_EXPORT=1 MIE_STATIC=${MIE_STATIC}) target_compile_definitions(mie PRIVATE MIE_EXPORT=1 MIE_STATIC=${MIE_STATIC})

454
mie/ctx.c
View File

@@ -1,34 +1,29 @@
#include <blue/core/bstr.h>
#include <blue/ds/hashmap.h> #include <blue/ds/hashmap.h>
#include <blue/ds/list.h> #include <blue/ds/list.h>
#include <blue/ds/string.h> #include <blue/ds/string.h>
#include <mie/ctx.h> #include <mie/ctx.h>
#include <mie/ir/const.h> #include <mie/dialect/arith.h>
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
#include <mie/dialect/index.h>
#include <mie/ir/op.h>
#include <mie/trait/trait-definition.h>
#include <mie/trait/trait.h>
#include <mie/type/function.h>
#include <mie/type/storage.h>
#include <mie/type/type-definition.h>
#include <mie/type/type.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
struct ctx_int_cache_entry { #define DIALECT_NS_ID \
b_btree_node i_node; MIE_ID(0xa1, 0x35, 0x01, 0x1b, 0xe4, 0x71, 0x46, 0x08, 0x92, 0xd4, \
struct mie_type i_type; 0xe6, 0x5a, 0x40, 0xba, 0x7f, 0xee)
b_btree i_values;
};
struct ctx_int_value_cache_entry { #define TYPE_NS_ID \
b_btree_node i_node; MIE_ID(0xf5, 0x4e, 0xc5, 0x8c, 0xc0, 0x1e, 0x48, 0x47, 0xb5, 0xf4, \
struct mie_int i_value; 0x7b, 0xb9, 0x6b, 0x47, 0xca, 0x48)
};
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 *mie_ctx_create(void)
{ {
@@ -40,244 +35,289 @@ struct mie_ctx *mie_ctx_create(void)
memset(out, 0x0, sizeof *out); memset(out, 0x0, sizeof *out);
out->ctx_true = MIE_CONST(mie_ctx_get_int(out, 1, 1)); mie_id dialects_ns = DIALECT_NS_ID;
out->ctx_false = MIE_CONST(mie_ctx_get_int(out, 0, 1)); mie_id_map_init(&out->ctx_dialects, &dialects_ns);
out->ctx_null = malloc(sizeof *out->ctx_null); mie_id types_ns = TYPE_NS_ID;
if (!out->ctx_null) { mie_id_map_init(&out->ctx_types, &types_ns);
mie_ctx_destroy(out);
return NULL;
}
mie_value_init(out->ctx_null, MIE_VALUE_NONE); out->ctx_ints = mie_int_cache_create();
out->ctx_floats = mie_float_cache_create();
out->ctx_sel_cache = b_hashmap_create(free, free); out->ctx_indices = mie_index_cache_create();
out->ctx_string_cache = b_hashmap_create(free, free); out->ctx_strings = mie_string_cache_create();
return out; return out;
} }
void mie_ctx_destroy(struct mie_ctx *ctx) bool mie_ctx_resolve_op(const struct mie_ctx *ctx, struct mie_op *op)
{ {
ctx->ctx_true = NULL; bool fully_resolved = MIE_TEST_FLAGS(
ctx->ctx_false = NULL; op->op_flags, MIE_OP_F_OP_RESOLVED | MIE_OP_F_ARG_RESOLVED);
b_btree_node *node = b_btree_first(&ctx->ctx_int_cache); if (fully_resolved) {
while (node) { return true;
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]; const char *dialect_name = NULL, *op_name = NULL;
for (size_t i = 0; i < nr_types; i++) {
if (ctx->ctx_types[i]) { char *dot = strchr(op->op_name, '.');
mie_value_destroy(MIE_VALUE(ctx->ctx_types[i])); if (dot) {
ctx->ctx_types[i] = NULL; *dot = 0;
} dialect_name = op->op_name;
op_name = dot + 1;
} else {
dialect_name = NULL;
op_name = op->op_name;
} }
if (ctx->ctx_null) { const struct mie_dialect *dialect = mie_ctx_get_dialect(ctx, dialect_name);
mie_value_destroy(ctx->ctx_null); if (dot) {
*dot = '.';
} }
b_hashmap_unref(ctx->ctx_sel_cache); /* dialect_name is no longer valid after this point */
dialect_name = NULL;
free(ctx); if (!dialect) {
return false;
}
const struct mie_op_definition *op_info
= mie_dialect_get_op(dialect, op_name);
if (!op) {
return false;
}
op->op_dialect = dialect;
op->op_info = op_info;
free(op->op_name);
op->op_name = NULL;
op->op_flags |= MIE_OP_F_OP_RESOLVED;
return true;
} }
struct mie_type *mie_ctx_get_type(struct mie_ctx *ctx, enum mie_type_id type_id) struct mie_dialect *mie_ctx_get_dialect(const struct mie_ctx *ctx, const char *name)
{ {
if (type_id == MIE_TYPE_INT) { b_rope name_rope = B_ROPE_CSTR(name);
mie_id id;
mie_id_init_ns(&id, mie_id_map_get_ns(&ctx->ctx_dialects), &name_rope);
mie_id *target = mie_id_map_get(&ctx->ctx_dialects, &id);
return b_unbox(struct mie_dialect, target, d_id);
}
struct mie_type_definition *mie_ctx_get_type_definition(
const struct mie_ctx *ctx, const char *dialect_name, const char *type_name)
{
b_rope dialect_name_rope = B_ROPE_CSTR(dialect_name);
mie_id id;
mie_id_init_ns(
&id, mie_id_map_get_ns(&ctx->ctx_dialects), &dialect_name_rope);
mie_id *target = mie_id_map_get(&ctx->ctx_dialects, &id);
struct mie_dialect *dialect = b_unbox(struct mie_dialect, target, d_id);
if (!dialect) {
return NULL; return NULL;
} }
if (ctx->ctx_types[type_id]) { b_rope type_name_rope = B_ROPE_CSTR(type_name);
return ctx->ctx_types[type_id]; mie_id_init_ns(&id, mie_id_map_get_ns(&dialect->d_types), &type_name_rope);
target = mie_id_map_get(&dialect->d_types, &id);
return b_unbox(struct mie_type_definition, target, ty_id);
}
const struct mie_trait_definition *mie_ctx_get_trait_definition(
const struct mie_ctx *ctx, const char *dialect_name, const char *trait_name)
{
b_rope dialect_name_rope = B_ROPE_CSTR(dialect_name);
mie_id id;
mie_id_init_ns(
&id, mie_id_map_get_ns(&ctx->ctx_dialects), &dialect_name_rope);
mie_id *target = mie_id_map_get(&ctx->ctx_dialects, &id);
struct mie_dialect *dialect = b_unbox(struct mie_dialect, target, d_id);
if (!dialect) {
return NULL;
} }
struct mie_type *type = mie_type_create(); b_rope trait_name_rope = B_ROPE_CSTR(trait_name);
mie_id_init_ns(&id, mie_id_map_get_ns(&dialect->d_traits), &trait_name_rope);
target = mie_id_map_get(&dialect->d_traits, &id);
return b_unbox(struct mie_trait_definition, target, tr_id);
}
struct mie_type *mie_ctx_get_type(
struct mie_ctx *ctx, const char *dialect_name, const char *type_name)
{
char full_name[256];
snprintf(full_name, sizeof full_name, "%s.%s", dialect_name, type_name);
b_rope full_name_rope = B_ROPE_CSTR(full_name);
mie_id id;
mie_id_init_ns(&id, mie_id_map_get_ns(&ctx->ctx_types), &full_name_rope);
mie_id *target = mie_id_map_get(&ctx->ctx_types, &id);
struct mie_type *type = b_unbox(struct mie_type, target, ty_id);
if (type) {
return type;
}
struct mie_type_definition *type_info
= mie_ctx_get_type_definition(ctx, dialect_name, type_name);
if (!type_info /* || (type_info->ty_flags & MIE_DIALECT_TYPE_PARAMETISED) */) {
/* cannot initialise unknown or parametised types */
return NULL;
}
if (type_info->ty_data_size < sizeof(struct mie_type)) {
/* invalid type info */
return NULL;
}
type = malloc(type_info->ty_data_size);
if (!type) { if (!type) {
return NULL; return NULL;
} }
type->t_id = type_id; memset(type, 0x0, sizeof *type);
type->ty_def = type_info;
type->ty_name = b_bstr_fmt("%s.%s", dialect_name, type_name);
if (type_info->ty_init) {
type_info->ty_init(type_info, type);
}
mie_id_map_put(&ctx->ctx_types, &type->ty_id, &full_name_rope);
ctx->ctx_types[type_id] = type;
return type; return type;
} }
struct mie_value *mie_ctx_get_null(struct mie_ctx *ctx) const struct mie_trait *mie_ctx_get_trait(
struct mie_ctx *ctx, const char *dialect_name, const char *trait_name)
{ {
return ctx->ctx_null; char full_name[256];
} snprintf(full_name, sizeof full_name, "%s.%s", dialect_name, trait_name);
b_rope full_name_rope = B_ROPE_CSTR(full_name);
struct mie_type *mie_ctx_get_int_type(struct mie_ctx *ctx, unsigned int nr_bits) mie_id id;
{ mie_id_init_ns(&id, mie_id_map_get_ns(&ctx->ctx_traits), &full_name_rope);
struct ctx_int_cache_entry *entry
= get_cached_int_type(&ctx->ctx_int_cache, nr_bits);
if (entry) { mie_id *target = mie_id_map_get(&ctx->ctx_traits, &id);
return &entry->i_type; struct mie_trait *trait = b_unbox(struct mie_trait, target, tr_id);
if (trait) {
return trait;
} }
entry = malloc(sizeof *entry); const struct mie_trait_definition *trait_info
if (!entry) { = 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; return NULL;
} }
memset(entry, 0x0, sizeof *entry); if (trait_info->tr_data_size < sizeof(struct mie_trait)) {
/* invalid trait info */
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; return NULL;
} }
memset(value, 0x0, sizeof *value); trait = malloc(trait_info->tr_data_size);
if (!trait) {
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; return NULL;
} }
struct mie_type *sel_type = mie_ctx_get_type(ctx, MIE_TYPE_SELECTOR); memset(trait, 0x0, sizeof *trait);
mie_const_init(&sel_value->sel_base, sel_type);
sel_value->sel_value = b_strdup(sel);
key.key_data = sel_value->sel_value; trait->tr_def = trait_info;
trait->tr_name = b_bstr_fmt("%s.%s", dialect_name, trait_name);
b_hashmap_value hashmap_value = { if (trait_info->tr_init) {
.value_data = sel_value, trait_info->tr_init(trait_info, trait);
.value_size = sizeof *sel_value, }
};
b_hashmap_put(ctx->ctx_sel_cache, &key, &hashmap_value); mie_id_map_put(&ctx->ctx_traits, &trait->tr_id, &full_name_rope);
return MIE_VALUE(sel_value); return trait;
}
struct mie_type *mie_ctx_get_storage_type(
struct mie_ctx *ctx, const struct mie_type **parts, size_t nr_parts)
{
struct mie_id_builder id_builder;
mie_id_builder_begin(&id_builder, &ctx->ctx_types.map_ns_id);
mie_storage_type_build_id(&id_builder, parts, nr_parts);
mie_id id;
mie_id_builder_end(&id_builder, &id);
mie_id *target = mie_id_map_get(&ctx->ctx_types, &id);
struct mie_type *type = b_unbox(struct mie_type, target, ty_id);
if (type) {
return type;
}
struct mie_storage_type *new_type = mie_storage_type_create();
for (size_t i = 0; i < nr_parts; i++) {
mie_storage_type_add_part(new_type, parts[i]);
}
new_type->st_base.ty_id = id;
mie_id_map_put_id(&ctx->ctx_types, &new_type->st_base.ty_id);
return (struct mie_type *)new_type;
}
struct mie_type *mie_ctx_get_function_type(
struct mie_ctx *ctx, const struct mie_type **in, size_t nr_in,
const struct mie_type **out, size_t nr_out)
{
struct mie_id_builder id_builder;
mie_id_builder_begin(&id_builder, &ctx->ctx_types.map_ns_id);
mie_function_type_build_id(&id_builder, in, nr_in, out, nr_out);
mie_id id;
mie_id_builder_end(&id_builder, &id);
mie_id *target = mie_id_map_get(&ctx->ctx_types, &id);
struct mie_type *type = b_unbox(struct mie_type, target, ty_id);
if (type) {
return type;
}
struct mie_function_type *new_type = mie_function_type_create();
for (size_t i = 0; i < nr_in; i++) {
mie_function_type_add_in_part(new_type, in[i]);
}
for (size_t i = 0; i < nr_out; i++) {
mie_function_type_add_out_part(new_type, out[i]);
}
new_type->func_base.ty_id = id;
mie_id_map_put_id(&ctx->ctx_types, &new_type->func_base.ty_id);
return (struct mie_type *)new_type;
}
struct mie_value *mie_ctx_get_int(struct mie_ctx *ctx, long long val, size_t nr_bits)
{
return (struct mie_value *)mie_int_cache_get(
ctx->ctx_ints, ctx, val, nr_bits);
}
struct mie_value *mie_ctx_get_float(struct mie_ctx *ctx, double val, size_t nr_bits)
{
return (struct mie_value *)mie_float_cache_get(
ctx->ctx_floats, ctx, val, nr_bits);
} }
struct mie_value *mie_ctx_get_string(struct mie_ctx *ctx, const char *s) struct mie_value *mie_ctx_get_string(struct mie_ctx *ctx, const char *s)
{ {
b_hashmap_key key = { return (struct mie_value *)mie_string_cache_get(ctx->ctx_strings, ctx, s);
.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_value *mie_ctx_get_index(struct mie_ctx *ctx, size_t val)
{ {
struct mie_type *array_type = mie_ctx_get_type(ctx, MIE_TYPE_ARRAY); return (struct mie_value *)mie_index_cache_get(ctx->ctx_indices, ctx, val);
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);
} }

18
mie/dialect/arith/addf.c Normal file
View File

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

18
mie/dialect/arith/addi.c Normal file
View File

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

View File

@@ -0,0 +1,9 @@
#include <mie/dialect/dialect.h>
#include <mie/macros.h>
MIE_DIALECT_BEGIN(mie_arith, "arith")
MIE_DIALECT_ADD_TYPE(mie_arith_int);
MIE_DIALECT_ADD_TYPE(mie_arith_float);
MIE_DIALECT_ADD_OP(mie_arith_addi);
MIE_DIALECT_ADD_OP(mie_arith_addf);
MIE_DIALECT_END()

View File

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

106
mie/dialect/arith/float.c Normal file
View File

@@ -0,0 +1,106 @@
#include <blue/core/bstr.h>
#include <mie/ctx.h>
#include <mie/dialect/arith.h>
#include <mie/dialect/dialect.h>
#include <mie/macros.h>
#include <mie/type/type-definition.h>
#include <mie/type/type.h>
#include <mie/value.h>
struct float_type {
struct mie_type f_base;
size_t f_width;
};
static enum mie_status value_print(
const struct mie_type *ty, const struct mie_value *value, b_stream *out)
{
struct float_type *float_ty = (struct float_type *)ty;
struct mie_float *float_val = (struct mie_float *)value;
switch (float_ty->f_width) {
case MIE_FLOAT_32:
b_stream_write_fmt(
out, NULL, "%f : f%zu", float_val->f_val.v_32,
float_ty->f_width);
break;
case MIE_FLOAT_64:
b_stream_write_fmt(
out, NULL, "%lf : f%zu", float_val->f_val.v_64,
float_ty->f_width);
break;
default:
b_stream_write_fmt(out, NULL, "NaN : f%zu", float_ty->f_width);
break;
}
return MIE_SUCCESS;
}
struct mie_type *mie_arith_float_get_type(struct mie_ctx *ctx, size_t bit_width)
{
struct mie_type_definition *type_info
= mie_ctx_get_type_definition(ctx, "arith", "float");
if (!type_info) {
return NULL;
}
b_rope rope_i = B_ROPE_CHAR('f'), rope_width = B_ROPE_UINT(bit_width);
b_rope type_name;
b_rope_concat(&type_name, &rope_i, &rope_width);
mie_id id;
mie_id_init_ns(&id, mie_id_map_get_ns(&ctx->ctx_types), &type_name);
mie_id *target = mie_id_map_get(&ctx->ctx_types, &id);
if (target) {
return b_unbox(struct mie_type, target, ty_id);
}
struct float_type *type = (struct float_type *)mie_type_create(type_info);
if (!type) {
return NULL;
}
type->f_base.ty_name = b_bstr_fmt("arith.float<%zu>", bit_width);
type->f_base.ty_instance_size = sizeof(struct mie_float);
type->f_width = bit_width;
mie_id_map_put(&ctx->ctx_types, &type->f_base.ty_id, &type_name);
return (struct mie_type *)type;
}
size_t mie_arith_float_type_get_width(const struct mie_type *type)
{
if (strcmp(type->ty_def->ty_parent->d_name, "arith") != 0) {
return (size_t)-1;
}
if (strcmp(type->ty_def->ty_name, "float") != 0) {
return (size_t)-1;
}
const struct float_type *float_type = (const struct float_type *)type;
return float_type->f_width;
}
static enum mie_status print(
const struct mie_type_definition *def, const struct mie_type *ty,
b_stream *out)
{
return MIE_SUCCESS;
}
static enum mie_status parse(
const struct mie_type_definition *def, struct mie_parser *parser,
struct mie_type **out)
{
return MIE_SUCCESS;
}
MIE_TYPE_DEFINITION_BEGIN(mie_arith_float, "float")
// MIE_TYPE_DEFINITION_FLAGS(MIE_TYPE_DEFINITION_PARAMETISED);
MIE_TYPE_DEFINITION_STRUCT(struct float_type);
MIE_TYPE_DEFINITION_PRINT(print);
MIE_TYPE_DEFINITION_PARSE(parse);
MIE_TYPE_DEFINITION_VALUE_PRINT(value_print);
MIE_TYPE_DEFINITION_END()

View File

@@ -0,0 +1,139 @@
#include <blue/core/btree.h>
#include <mie/dialect/arith.h>
#include <stdlib.h>
#include <string.h>
struct int_width_cache_entry {
b_btree_node e_node;
struct mie_int e_value;
};
struct int_width_cache {
b_btree_node c_node;
size_t c_width;
b_btree c_ints;
};
struct mie_int_cache {
b_btree c_widths;
};
static B_BTREE_DEFINE_SIMPLE_INSERT(
struct int_width_cache, c_node, c_width, put_width_cache);
static B_BTREE_DEFINE_SIMPLE_GET(
struct int_width_cache, size_t, c_node, c_width, get_width_cache);
static B_BTREE_DEFINE_SIMPLE_INSERT(
struct int_width_cache_entry, e_node, e_value.i_val.v_small, put_int);
static B_BTREE_DEFINE_SIMPLE_GET(
struct int_width_cache_entry, uint64_t, e_node, e_value.i_val.v_small,
get_int);
static struct int_width_cache *int_width_cache_create(size_t width)
{
struct int_width_cache *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
memset(out, 0x0, sizeof *out);
out->c_width = width;
return out;
}
static void int_width_cache_destroy(struct int_width_cache *cache)
{
b_btree_node *cur = b_btree_first(&cache->c_ints);
while (cur) {
b_btree_node *next = b_btree_next(cur);
b_btree_delete(&cache->c_ints, cur);
struct int_width_cache_entry *entry
= b_unbox(struct int_width_cache_entry, cur, e_node);
free(entry);
cur = next;
}
free(cache);
}
static struct int_width_cache_entry *int_width_cache_entry_create(
struct mie_ctx *ctx, size_t width, size_t value)
{
struct int_width_cache_entry *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
memset(out, 0x0, sizeof *out);
out->e_value.i_val.v_small = value;
out->e_value.i_base.v_type = mie_arith_int_get_type(ctx, width);
if (!out->e_value.i_base.v_type) {
free(out);
return NULL;
}
return out;
}
struct mie_int_cache *mie_int_cache_create(void)
{
struct mie_int_cache *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
memset(out, 0x0, sizeof *out);
return out;
}
void mie_int_cache_destroy(struct mie_int_cache *cache)
{
b_btree_node *cur = b_btree_first(&cache->c_widths);
while (cur) {
b_btree_node *next = b_btree_next(cur);
b_btree_delete(&cache->c_widths, cur);
struct int_width_cache *width_cache
= b_unbox(struct int_width_cache, cur, c_node);
int_width_cache_destroy(width_cache);
cur = next;
}
free(cache);
}
struct mie_int *mie_int_cache_get(
struct mie_int_cache *cache, struct mie_ctx *ctx, size_t value,
size_t bit_width)
{
struct int_width_cache *width_cache
= get_width_cache(&cache->c_widths, bit_width);
if (!width_cache) {
width_cache = int_width_cache_create(bit_width);
if (!width_cache) {
return NULL;
}
put_width_cache(&cache->c_widths, width_cache);
}
struct int_width_cache_entry *entry = get_int(&width_cache->c_ints, value);
if (!entry) {
entry = int_width_cache_entry_create(ctx, bit_width, value);
if (!entry) {
return NULL;
}
put_int(&width_cache->c_ints, entry);
}
return &entry->e_value;
}

98
mie/dialect/arith/int.c Normal file
View File

@@ -0,0 +1,98 @@
#include <blue/core/bstr.h>
#include <mie/ctx.h>
#include <mie/dialect/arith.h>
#include <mie/dialect/dialect.h>
#include <mie/macros.h>
#include <mie/type/type-definition.h>
#include <mie/type/type.h>
#include <mie/value.h>
struct int_type {
struct mie_type i_base;
size_t i_width;
};
static enum mie_status value_print(
const struct mie_type *ty, const struct mie_value *value, b_stream *out)
{
struct int_type *int_ty = (struct int_type *)ty;
struct mie_int *int_val = (struct mie_int *)value;
if (int_ty->i_width <= 64) {
b_stream_write_fmt(
out, NULL, "%zu : i%zu", int_val->i_val.v_small,
int_ty->i_width);
} else {
b_stream_write_fmt(out, NULL, "INF : i%zu", int_ty->i_width);
}
return MIE_SUCCESS;
}
struct mie_type *mie_arith_int_get_type(struct mie_ctx *ctx, size_t bit_width)
{
struct mie_type_definition *type_info
= mie_ctx_get_type_definition(ctx, "arith", "int");
if (!type_info) {
return NULL;
}
b_rope rope_i = B_ROPE_CHAR('i'), rope_width = B_ROPE_UINT(bit_width);
b_rope type_name;
b_rope_concat(&type_name, &rope_i, &rope_width);
mie_id id;
mie_id_init_ns(&id, mie_id_map_get_ns(&ctx->ctx_types), &type_name);
mie_id *target = mie_id_map_get(&ctx->ctx_types, &id);
if (target) {
return b_unbox(struct mie_type, target, ty_id);
}
struct int_type *type = (struct int_type *)mie_type_create(type_info);
if (!type) {
return NULL;
}
type->i_base.ty_name = b_bstr_fmt("arith.int<%zu>", bit_width);
type->i_base.ty_instance_size = sizeof(struct mie_int);
type->i_width = bit_width;
mie_id_map_put(&ctx->ctx_types, &type->i_base.ty_id, &type_name);
return (struct mie_type *)type;
}
size_t mie_arith_int_type_get_width(const struct mie_type *type)
{
if (strcmp(type->ty_def->ty_parent->d_name, "arith") != 0) {
return (size_t)-1;
}
if (strcmp(type->ty_def->ty_name, "int") != 0) {
return (size_t)-1;
}
const struct int_type *int_type = (const struct int_type *)type;
return int_type->i_width;
}
static enum mie_status print(
const struct mie_type_definition *def, const struct mie_type *ty,
b_stream *out)
{
return MIE_SUCCESS;
}
static enum mie_status parse(
const struct mie_type_definition *def, struct mie_parser *parser,
struct mie_type **out)
{
return MIE_SUCCESS;
}
MIE_TYPE_DEFINITION_BEGIN(mie_arith_int, "int")
// MIE_TYPE_DEFINITION_FLAGS(MIE_TYPE_DEFINITION_PARAMETISED);
MIE_TYPE_DEFINITION_STRUCT(struct int_type);
MIE_TYPE_DEFINITION_PRINT(print);
MIE_TYPE_DEFINITION_PARSE(parse);
MIE_TYPE_DEFINITION_VALUE_PRINT(value_print);
MIE_TYPE_DEFINITION_END()

View File

@@ -0,0 +1,7 @@
#include <mie/dialect/dialect.h>
#include <mie/macros.h>
MIE_DIALECT_BEGIN(mie_builtin, "builtin")
MIE_DIALECT_ADD_TYPE(mie_builtin_string);
MIE_DIALECT_ADD_TRAIT(mie_builtin_isolated_from_above);
MIE_DIALECT_END()

View File

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

View File

@@ -0,0 +1,84 @@
#include <blue/core/btree.h>
#include <blue/ds/hashmap.h>
#include <mie/ctx.h>
#include <mie/dialect/builtin.h>
#include <stdlib.h>
#include <string.h>
struct mie_string_cache {
b_hashmap *c_entries;
};
static struct mie_string *mie_string_create(
struct mie_ctx *ctx, const char *s, size_t len)
{
struct mie_string *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
out->str_base.v_type = mie_ctx_get_type(ctx, "builtin", "string");
if (!out->str_base.v_type) {
free(out);
return NULL;
}
out->str_val = b_strdup(s);
if (!out->str_val) {
return NULL;
}
out->str_len = len;
return out;
}
static void mie_string_destroy(struct mie_string *str)
{
}
struct mie_string_cache *mie_string_cache_create(void)
{
struct mie_string_cache *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
memset(out, 0x0, sizeof *out);
out->c_entries = b_hashmap_create(
NULL, (b_hashmap_value_destructor)mie_string_destroy);
if (!out->c_entries) {
free(out);
return NULL;
}
return out;
}
void mie_string_cache_destroy(struct mie_string_cache *cache)
{
b_hashmap_unref(cache->c_entries);
free(cache);
}
struct mie_string *mie_string_cache_get(
struct mie_string_cache *cache, struct mie_ctx *ctx, const char *s)
{
size_t s_len = strlen(s);
b_hashmap_key key = {.key_data = s, .key_size = s_len};
const b_hashmap_value *value = b_hashmap_get(cache->c_entries, &key);
if (value) {
return value->value_data;
}
struct mie_string *str = mie_string_create(ctx, s, s_len);
if (!str) {
return NULL;
}
b_hashmap_value new_val = {.value_data = str, .value_size = sizeof *str};
b_hashmap_put(cache->c_entries, &key, &new_val);
return str;
}

View File

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

18
mie/dialect/cf/br-cond.c Normal file
View File

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

18
mie/dialect/cf/br.c Normal file
View File

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

7
mie/dialect/cf/cf.c Normal file
View File

@@ -0,0 +1,7 @@
#include <mie/dialect/dialect.h>
#include <mie/macros.h>
MIE_DIALECT_BEGIN(mie_cf, "cf")
MIE_DIALECT_ADD_OP(mie_cf_br);
MIE_DIALECT_ADD_OP(mie_cf_br_cond);
MIE_DIALECT_END()

61
mie/dialect/dialect.c Normal file
View File

@@ -0,0 +1,61 @@
#include <blue/ds/string.h>
#include <mie/ctx.h>
#include <mie/dialect/dialect.h>
#include <mie/ir/op-definition.h>
#include <mie/type/type-definition.h>
#define TYPE_NS_ID \
MIE_ID(0xe4, 0x99, 0x42, 0x58, 0x2b, 0xdb, 0x45, 0xa3, 0xbd, 0x4b, \
0x17, 0xe3, 0xc4, 0xa9, 0xbc, 0x30)
#define OP_NS_ID \
MIE_ID(0xb9, 0x97, 0xcf, 0xd3, 0x81, 0xd4, 0x45, 0x06, 0x9b, 0x44, \
0x05, 0x9f, 0xb4, 0x76, 0xf1, 0x2d)
struct mie_dialect *mie_dialect_create(struct mie_ctx *ctx, const char *name)
{
struct mie_dialect *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
memset(out, 0x0, sizeof *out);
out->d_name = b_strdup(name);
if (!out->d_name) {
free(out);
return NULL;
}
mie_id op_ns = OP_NS_ID;
mie_id_map_init(&out->d_ops, &op_ns);
mie_id type_ns = TYPE_NS_ID;
mie_id_map_init(&out->d_types, &type_ns);
b_rope name_rope = B_ROPE_CSTR(name);
mie_id_map_put(&ctx->ctx_dialects, &out->d_id, &name_rope);
return out;
}
const struct mie_op_definition *mie_dialect_get_op(
const struct mie_dialect *dialect, const char *name)
{
b_rope name_rope = B_ROPE_CSTR(name);
mie_id id;
mie_id_init_ns(&id, mie_id_map_get_ns(&dialect->d_ops), &name_rope);
mie_id *target = mie_id_map_get(&dialect->d_ops, &id);
return b_unbox(struct mie_op_definition, target, op_id);
}
const struct mie_type_definition *mie_dialect_get_type(
const struct mie_dialect *dialect, const char *name)
{
b_rope name_rope = B_ROPE_CSTR(name);
mie_id id;
mie_id_init_ns(&id, mie_id_map_get_ns(&dialect->d_types), &name_rope);
mie_id *target = mie_id_map_get(&dialect->d_types, &id);
return b_unbox(struct mie_type_definition, target, ty_id);
}

22
mie/dialect/func/func.c Normal file
View File

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

View File

@@ -0,0 +1,82 @@
#include <blue/core/btree.h>
#include <mie/ctx.h>
#include <mie/dialect/index.h>
#include <stdlib.h>
#include <string.h>
struct index_cache_entry {
b_btree_node e_node;
struct mie_index e_value;
};
struct mie_index_cache {
b_btree c_entries;
};
static B_BTREE_DEFINE_SIMPLE_INSERT(
struct index_cache_entry, e_node, e_value.i_value, put_index);
static B_BTREE_DEFINE_SIMPLE_GET(
struct index_cache_entry, size_t, e_node, e_value.i_value, get_index);
static struct index_cache_entry *index_cache_entry_create(
struct mie_ctx *ctx, size_t val)
{
struct index_cache_entry *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
out->e_value.i_value = val;
out->e_value.i_base.v_type = mie_ctx_get_type(ctx, "index", "index");
if (!out->e_value.i_base.v_type) {
free(out);
return NULL;
}
return out;
}
struct mie_index_cache *mie_index_cache_create(void)
{
struct mie_index_cache *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
memset(out, 0x0, sizeof *out);
return out;
}
void mie_index_cache_destroy(struct mie_index_cache *cache)
{
b_btree_node *cur = b_btree_first(&cache->c_entries);
while (cur) {
b_btree_node *next = b_btree_next(cur);
b_btree_delete(&cache->c_entries, cur);
struct index_cache_entry *entry
= b_unbox(struct index_cache_entry, cur, e_node);
free(entry);
cur = next;
}
free(cache);
}
struct mie_index *mie_index_cache_get(
struct mie_index_cache *cache, struct mie_ctx *ctx, size_t value)
{
struct index_cache_entry *entry = get_index(&cache->c_entries, value);
if (!entry) {
entry = index_cache_entry_create(ctx, value);
if (!entry) {
return NULL;
}
put_index(&cache->c_entries, entry);
}
return &entry->e_value;
}

53
mie/dialect/index/index.c Normal file
View File

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

6
mie/dialect/meta/meta.c Normal file
View File

@@ -0,0 +1,6 @@
#include <mie/dialect/dialect.h>
#include <mie/macros.h>
MIE_DIALECT_BEGIN(mie_meta, "meta")
MIE_DIALECT_ADD_OP(mie_meta_source_filename);
MIE_DIALECT_END()

View File

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

18
mie/dialect/ptr/load.c Normal file
View File

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

33
mie/dialect/ptr/ptr.c Normal file
View File

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

18
mie/dialect/ptr/store.c Normal file
View File

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

18
mie/dialect/scf/for.c Normal file
View File

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

18
mie/dialect/scf/if.c Normal file
View File

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

8
mie/dialect/scf/scf.c Normal file
View File

@@ -0,0 +1,8 @@
#include <mie/dialect/dialect.h>
#include <mie/macros.h>
MIE_DIALECT_BEGIN(mie_scf, "scf")
MIE_DIALECT_ADD_OP(mie_scf_if);
MIE_DIALECT_ADD_OP(mie_scf_for);
MIE_DIALECT_ADD_OP(mie_scf_yield);
MIE_DIALECT_END()

18
mie/dialect/scf/yield.c Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

217
mie/id.c Normal file
View File

@@ -0,0 +1,217 @@
#include <blue/core/bstr.h>
#include <blue/core/endian.h>
#include <blue/core/hash.h>
#include <blue/core/random.h>
#include <mie/id.h>
#include <string.h>
static inline int id_memcmp(const uint8_t *a, const uint8_t *b)
{
return memcmp(a, b, MIE_ID_NR_BYTES);
}
static mie_id *get_id(const b_btree *tree, mie_id *key)
{
b_btree_node *cur = tree->b_root;
while (cur) {
mie_id *cur_node = b_unbox(mie_id, cur, e_node);
int cmp = memcmp(
key->id_bytes, cur_node->id_bytes, sizeof key->id_bytes);
if (cmp > 0) {
cur = b_btree_right(cur);
} else if (cmp < 0) {
cur = b_btree_left(cur);
} else {
return cur_node;
}
}
return NULL;
}
void put_id(b_btree *tree, mie_id *node)
{
if (!tree->b_root) {
tree->b_root = &node->e_node;
b_btree_insert_fixup(tree, &node->e_node);
return;
}
b_btree_node *cur = tree->b_root;
while (1) {
mie_id *cur_node = b_unbox(mie_id, cur, e_node);
b_btree_node *next = NULL;
int cmp = memcmp(
node->id_bytes, cur_node->id_bytes, sizeof node->id_bytes);
if (cmp > 0) {
next = b_btree_right(cur);
if (!next) {
b_btree_put_right(cur, &node->e_node);
break;
}
} else if (cmp < 0) {
next = b_btree_left(cur);
if (!next) {
b_btree_put_left(cur, &node->e_node);
break;
}
} else {
return;
}
cur = next;
}
b_btree_insert_fixup(tree, &node->e_node);
}
void mie_id_init(
mie_id *out, uint32_t a, uint16_t b, uint16_t c, uint16_t d, uint64_t e)
{
b_i32 x_a = b_i32_htob(a);
b_i16 x_b = b_i16_htob(b);
b_i16 x_c = b_i16_htob(c);
b_i16 x_d = b_i16_htob(d);
b_i64 x_e = b_i64_htob(e);
memcpy(&out->id_bytes[0], x_a.i_bytes, sizeof x_a.i_bytes);
memcpy(&out->id_bytes[4], x_b.i_bytes, sizeof x_b.i_bytes);
memcpy(&out->id_bytes[6], x_c.i_bytes, sizeof x_c.i_bytes);
memcpy(&out->id_bytes[8], x_d.i_bytes, sizeof x_d.i_bytes);
memcpy(&out->id_bytes[10], &x_e.i_bytes[2], sizeof x_e.i_bytes - 2);
}
void mie_id_init_zero(mie_id *out)
{
memset(out, 0x0, sizeof *out);
}
void mie_id_init_random(mie_id *out)
{
b_random_ctx *random = b_random_global_ctx();
b_random_next_bytes(
random, (unsigned char *)out->id_bytes, sizeof out->id_bytes);
}
void mie_id_init_ns(mie_id *out, const mie_id *ns, const b_rope *name)
{
struct mie_id_builder ctx;
mie_id_builder_begin(&ctx, ns);
mie_id_builder_add_rope(&ctx, name);
mie_id_builder_end(&ctx, out);
}
void mie_id_to_string(const mie_id *id, char *out, size_t max)
{
b_bstr str;
b_bstr_begin(&str, out, max);
for (size_t i = 0; i < sizeof id->id_bytes; i++) {
if (i == 4 || i == 6 || i == 8 || i == 10) {
b_bstr_write_char(&str, '-');
}
b_bstr_write_fmt(&str, "%02x", id->id_bytes[i]);
}
}
void mie_id_builder_begin(struct mie_id_builder *builder, const mie_id *ns)
{
memset(builder, 0x0, sizeof *builder);
b_hash_ctx_init(&builder->b_hash, B_HASH_SHA1);
b_hash_ctx_update(&builder->b_hash, ns->id_bytes, sizeof ns->id_bytes);
}
void mie_id_builder_add(struct mie_id_builder *builder, const void *p, size_t len)
{
b_hash_ctx_update(&builder->b_hash, p, len);
}
void mie_id_builder_add_rope(struct mie_id_builder *builder, const b_rope *rope)
{
b_hash_ctx_update_rope(&builder->b_hash, rope);
}
void mie_id_builder_add_marker(
struct mie_id_builder *builder, enum mie_id_builder_marker marker)
{
unsigned char c = marker;
b_hash_ctx_update(&builder->b_hash, &c, sizeof c);
}
void mie_id_builder_end(struct mie_id_builder *builder, mie_id *out)
{
memset(out, 0x0, sizeof *out);
b_hash_ctx_finish(&builder->b_hash, out->id_bytes, sizeof out->id_bytes);
out->id_bytes[6] &= 0x0F;
out->id_bytes[6] |= 0x50;
out->id_bytes[8] &= 0x3F;
out->id_bytes[8] |= 0x80;
}
void mie_id_map_init(struct mie_id_map *map, const mie_id *ns)
{
memset(map, 0x0, sizeof *map);
map->map_ns_id = *ns;
}
const mie_id *mie_id_map_get_ns(const struct mie_id_map *map)
{
return &map->map_ns_id;
}
void mie_id_map_put(struct mie_id_map *map, mie_id *id, const b_rope *name)
{
mie_id_init_ns(id, &map->map_ns_id, name);
put_id(&map->map_entries, id);
}
void mie_id_map_put_id(struct mie_id_map *map, mie_id *node)
{
put_id(&map->map_entries, node);
}
mie_id *mie_id_map_get(const struct mie_id_map *map, mie_id *id)
{
return get_id(&map->map_entries, id);
}
enum mie_status mie_id_map_iterator_begin(
struct mie_id_map_iterator *it, const struct mie_id_map *map)
{
memset(it, 0x0, sizeof *it);
it->_n = b_btree_first(&map->map_entries);
if (!it->_n) {
return MIE_ERR_NO_DATA;
}
it->it_id = b_unbox(mie_id, it->_n, e_node);
return MIE_SUCCESS;
}
enum mie_status mie_id_map_iterator_move_next(struct mie_id_map_iterator *it)
{
if (!it->_n) {
it->it_id = NULL;
return MIE_ERR_NO_DATA;
}
it->_n = b_btree_next(it->_n);
if (!it->_n) {
it->it_id = NULL;
return MIE_ERR_NO_DATA;
}
it->it_id = b_unbox(mie_id, it->_n, e_node);
return MIE_SUCCESS;
}

View File

@@ -3,30 +3,63 @@
#include <blue/core/btree.h> #include <blue/core/btree.h>
#include <blue/ds/hashmap.h> #include <blue/ds/hashmap.h>
#include <mie/type.h> #include <mie/id.h>
struct mie_op;
struct mie_int_cache;
struct mie_index_cache;
struct mie_string_cache;
;
struct mie_ctx { struct mie_ctx {
#if 0
struct mie_const *ctx_true, *ctx_false; struct mie_const *ctx_true, *ctx_false;
struct mie_value *ctx_null; struct mie_value *ctx_null;
struct mie_type *ctx_types[__MIE_TYPE_COUNT]; struct mie_type *ctx_types[__MIE_TYPE_COUNT];
b_btree ctx_int_cache;
b_hashmap *ctx_sel_cache; b_hashmap *ctx_sel_cache;
b_hashmap *ctx_string_cache; b_hashmap *ctx_string_cache;
#endif
/* map of struct mie_dialect */
struct mie_id_map ctx_dialects;
/* map of struct mie_type */
struct mie_id_map ctx_types;
/* map of struct mie_trait */
struct mie_id_map ctx_traits;
struct mie_int_cache *ctx_ints;
struct mie_float_cache *ctx_floats;
struct mie_index_cache *ctx_indices;
struct mie_string_cache *ctx_strings;
}; };
extern struct mie_ctx *mie_ctx_create(void); MIE_API struct mie_ctx *mie_ctx_create(void);
extern void mie_ctx_destroy(struct mie_ctx *ctx); MIE_API void mie_ctx_destroy(struct mie_ctx *ctx);
extern struct mie_type *mie_ctx_get_type( MIE_API bool mie_ctx_resolve_op(const struct mie_ctx *ctx, struct mie_op *op);
struct mie_ctx *ctx, enum mie_type_id type_id);
extern struct mie_type *mie_ctx_get_int_type( MIE_API struct mie_dialect *mie_ctx_get_dialect(
struct mie_ctx *ctx, unsigned int nr_bits); const struct mie_ctx *ctx, const char *name);
extern struct mie_value *mie_ctx_get_null(struct mie_ctx *ctx); MIE_API struct mie_type_definition *mie_ctx_get_type_definition(
extern struct mie_value *mie_ctx_get_bool(struct mie_ctx *ctx, bool val); const struct mie_ctx *ctx, const char *dialect_name, const char *type_name);
extern struct mie_value *mie_ctx_get_int( MIE_API const struct mie_trait_definition *mie_ctx_get_trait_definition(
struct mie_ctx *ctx, long long val, unsigned int nr_bits); const struct mie_ctx *ctx, const char *dialect_name,
extern struct mie_value *mie_ctx_get_string(struct mie_ctx *ctx, const char *s); const char *trait_name);
extern struct mie_value *mie_ctx_get_selector(struct mie_ctx *ctx, const char *sel); MIE_API struct mie_type *mie_ctx_get_type(
extern struct mie_value *mie_ctx_create_array(struct mie_ctx *ctx); struct mie_ctx *ctx, const char *dialect_name, const char *type_name);
MIE_API const struct mie_trait *mie_ctx_get_trait(
struct mie_ctx *ctx, const char *dialect_name, const char *trait_name);
MIE_API struct mie_type *mie_ctx_get_storage_type(
struct mie_ctx *ctx, const struct mie_type **parts, size_t nr_parts);
MIE_API struct mie_type *mie_ctx_get_function_type(
struct mie_ctx *ctx, const struct mie_type **in, size_t nr_in,
const struct mie_type **out, size_t nr_out);
MIE_API struct mie_value *mie_ctx_get_null(struct mie_ctx *ctx);
MIE_API struct mie_value *mie_ctx_get_int(
struct mie_ctx *ctx, long long val, size_t nr_bits);
MIE_API struct mie_value *mie_ctx_get_float(
struct mie_ctx *ctx, double val, size_t nr_bits);
MIE_API struct mie_value *mie_ctx_get_string(struct mie_ctx *ctx, const char *s);
MIE_API struct mie_value *mie_ctx_get_index(struct mie_ctx *ctx, size_t val);
#endif #endif

View File

@@ -0,0 +1,62 @@
#ifndef MIE_DIALECT_ARITH_H_
#define MIE_DIALECT_ARITH_H_
#include <mie/misc.h>
#include <mie/value.h>
#include <stddef.h>
#include <stdint.h>
struct mie_ctx;
struct mie_dialect;
enum mie_float_width {
MIE_FLOAT_32 = 32,
MIE_FLOAT_64 = 64,
};
struct mie_int {
struct mie_value i_base;
union {
int64_t v_small;
struct {
long *a_parts;
size_t a_nr_parts;
} v_arbitrary;
} i_val;
};
struct mie_float {
struct mie_value f_base;
union {
float v_32;
double v_64;
} f_val;
};
struct mie_int_cache;
MIE_API struct mie_dialect *mie_arith_dialect_create(struct mie_ctx *ctx);
MIE_API struct mie_type *mie_arith_int_get_type(
struct mie_ctx *ctx, size_t bit_width);
MIE_API struct mie_type *mie_arith_float_get_type(
struct mie_ctx *ctx, size_t bit_width);
MIE_API size_t mie_arith_int_type_get_width(const struct mie_type *type);
MIE_API size_t mie_arith_float_type_get_width(const struct mie_type *type);
MIE_API struct mie_int_cache *mie_int_cache_create(void);
MIE_API void mie_int_cache_destroy(struct mie_int_cache *cache);
MIE_API struct mie_int *mie_int_cache_get(
struct mie_int_cache *cache, struct mie_ctx *ctx, size_t value,
size_t bit_width);
MIE_API struct mie_float_cache *mie_float_cache_create(void);
MIE_API void mie_float_cache_destroy(struct mie_float_cache *cache);
MIE_API struct mie_float *mie_float_cache_get(
struct mie_float_cache *cache, struct mie_ctx *ctx, double value,
size_t bit_width);
#endif

View File

@@ -0,0 +1,29 @@
#ifndef MIE_DIALECT_BUILTIN_H_
#define MIE_DIALECT_BUILTIN_H_
#include <blue/ds/string.h>
#include <mie/misc.h>
#include <mie/value.h>
struct mie_dialect;
struct mie_ctx;
struct mie_int_type;
struct mie_float_type;
struct mie_string {
struct mie_value str_base;
char *str_val;
size_t str_len;
};
struct mie_string_cache;
MIE_API struct mie_dialect *mie_builtin_dialect_create(struct mie_ctx *ctx);
MIE_API struct mie_string_cache *mie_string_cache_create(void);
MIE_API void mie_string_cache_destroy(struct mie_string_cache *cache);
MIE_API struct mie_string *mie_string_cache_get(
struct mie_string_cache *cache, struct mie_ctx *ctx, const char *val);
#endif

View File

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

View File

@@ -0,0 +1,38 @@
#ifndef MIE_DIALECT_DIALECT_H_
#define MIE_DIALECT_DIALECT_H_
#include <blue/core/btree.h>
#include <blue/core/queue.h>
#include <mie/id.h>
#include <mie/misc.h>
#include <mie/vector.h>
struct mie_ctx;
struct mie_op_definition;
struct mie_type_definition;
struct mie_trait_definition;
struct mie_dialect {
mie_id d_id;
char *d_name;
/* map of struct mie_op_definition */
struct mie_id_map d_ops;
/* map of struct mie_type_definition */
struct mie_id_map d_types;
/* map of struct mie_trait_definition */
struct mie_id_map d_traits;
};
MIE_API struct mie_dialect *mie_dialect_create(
struct mie_ctx *ctx, const char *name);
MIE_API const struct mie_op_definition *mie_dialect_get_op(
const struct mie_dialect *dialect, const char *name);
MIE_API const struct mie_type_definition *mie_dialect_get_type(
const struct mie_dialect *dialect, const char *name);
MIE_API const struct mie_trait_definition *mie_dialect_get_trait(
const struct mie_dialect *dialect, const char *name);
#endif

View File

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

View File

@@ -0,0 +1,26 @@
#ifndef MIE_DIALECT_INDEX_H_
#define MIE_DIALECT_INDEX_H_
#include <mie/misc.h>
#include <mie/value.h>
#include <stddef.h>
#include <stdint.h>
struct mie_ctx;
struct mie_dialect;
struct mie_index {
struct mie_value i_base;
size_t i_value;
};
struct mie_index_cache;
MIE_API struct mie_dialect *mie_index_dialect_create(struct mie_ctx *ctx);
MIE_API struct mie_index_cache *mie_index_cache_create(void);
MIE_API void mie_index_cache_destroy(struct mie_index_cache *cache);
MIE_API struct mie_index *mie_index_cache_get(
struct mie_index_cache *cache, struct mie_ctx *ctx, size_t value);
#endif

View File

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

View File

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

View File

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

View File

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

112
mie/include/mie/id.h Normal file
View File

@@ -0,0 +1,112 @@
#ifndef MIE_ID_H_
#define MIE_ID_H_
#include <blue/core/btree.h>
#include <blue/core/queue.h>
#include <blue/core/rope.h>
#include <mie/misc.h>
#include <mie/status.h>
#include <stddef.h>
#include <stdint.h>
#define MIE_ID(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) \
{ \
.id_bytes = {a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p}, \
}
#define MIE_ID_ZERO ((mie_id) {0})
#define MIE_ID_STRING_MAX 37
#define MIE_ID_NR_BYTES 16
#define MIE_ID_NR_WORDS (MIE_ID_NR_BYTES / sizeof(uintptr_t))
#define MIE_ID_NR_WORDS_16 (MIE_ID_NR_BYTES / sizeof(uint16_t))
#define MIE_ID_NR_WORDS_32 (MIE_ID_NR_BYTES / sizeof(uint32_t))
#define MIE_ID_NR_WORDS_64 (MIE_ID_NR_BYTES / sizeof(uint64_t))
enum mie_id_builder_marker {
MIE_ID_BUILDER_STORAGE_START = 0x32,
MIE_ID_BUILDER_STORAGE_END = 0x8a,
MIE_ID_BUILDER_FUNCTION_IN_START = 0x78,
MIE_ID_BUILDER_FUNCTION_IN_END = 0x55,
MIE_ID_BUILDER_FUNCTION_OUT_START = 0xa2,
MIE_ID_BUILDER_FUNCTION_OUT_END = 0xbc,
};
typedef struct mie_id {
union {
uint8_t id_bytes[MIE_ID_NR_BYTES];
uintptr_t id_words[MIE_ID_NR_WORDS];
uint16_t id_words_16[MIE_ID_NR_WORDS_16];
uint32_t id_words_32[MIE_ID_NR_WORDS_32];
uint64_t id_words_64[MIE_ID_NR_WORDS_64];
};
union {
b_btree_node e_node;
b_queue_entry e_entry;
};
} mie_id;
struct mie_id_builder {
b_hash_ctx b_hash;
};
struct mie_id_map {
mie_id map_ns_id;
b_btree map_entries;
};
struct mie_id_map_iterator {
mie_id *it_id;
b_btree_node *_n;
};
MIE_API void mie_id_init(
mie_id *out, uint32_t a, uint16_t b, uint16_t c, uint16_t d, uint64_t e);
MIE_API void mie_id_init_zero(mie_id *out);
MIE_API void mie_id_init_random(mie_id *out);
MIE_API void mie_id_init_ns(mie_id *out, const mie_id *ns, const b_rope *name);
static inline int mie_id_compare(const mie_id *a, const mie_id *b)
{
return memcmp(a->id_bytes, b->id_bytes, sizeof a->id_bytes);
}
MIE_API void mie_id_to_string(const mie_id *id, char *out, size_t max);
MIE_API void mie_id_builder_begin(struct mie_id_builder *builder, const mie_id *ns);
MIE_API void mie_id_builder_add(
struct mie_id_builder *builder, const void *p, size_t len);
static inline void mie_id_builder_add_char(struct mie_id_builder *builder, char c)
{
mie_id_builder_add(builder, &c, 1);
}
static inline void mie_id_builder_add_cstr(
struct mie_id_builder *builder, const char *s)
{
mie_id_builder_add(builder, s, strlen(s));
}
MIE_API void mie_id_builder_add_rope(
struct mie_id_builder *builder, const b_rope *rope);
MIE_API void mie_id_builder_add_marker(
struct mie_id_builder *builder, enum mie_id_builder_marker marker);
MIE_API void mie_id_builder_end(struct mie_id_builder *builder, mie_id *out);
MIE_API void mie_id_map_init(struct mie_id_map *map, const mie_id *ns);
static inline bool mie_id_map_empty(const struct mie_id_map *map)
{
return b_btree_empty(&map->map_entries);
}
MIE_API const mie_id *mie_id_map_get_ns(const struct mie_id_map *map);
MIE_API void mie_id_map_put(
struct mie_id_map *map, mie_id *node, const b_rope *name);
MIE_API void mie_id_map_put_id(struct mie_id_map *map, mie_id *node);
MIE_API mie_id *mie_id_map_get(const struct mie_id_map *map, mie_id *id);
MIE_API enum mie_status mie_id_map_iterator_begin(
struct mie_id_map_iterator *it, const struct mie_id_map *map);
MIE_API enum mie_status mie_id_map_iterator_move_next(
struct mie_id_map_iterator *it);
#endif

View File

@@ -1,12 +0,0 @@
#ifndef MIE_ALLOCA_H_
#define MIE_ALLOCA_H_
#include <mie/ir/instr.h>
#include <mie/type.h>
struct mie_alloca {
struct mie_instr a_base;
struct mie_type *a_type;
};
#endif

View File

@@ -1,15 +0,0 @@
#ifndef MIE_ARG_H_
#define MIE_ARG_H_
#include <mie/ir/value.h>
#define MIE_ARG(p) ((struct mie_arg *)(p))
struct mie_arg {
struct mie_value arg_base;
struct mie_type *arg_type;
};
extern struct mie_arg *mie_arg_create(struct mie_type *type);
#endif

View File

@@ -1,30 +1,21 @@
#ifndef MIE_BLOCK_H_ #ifndef MIE_IR_BLOCK_H_
#define MIE_BLOCK_H_ #define MIE_IR_BLOCK_H_
#define MIE_BLOCK(p) ((struct mie_block *)(p)) #include <blue/core/queue.h>
#include <mie/misc.h>
#include <mie/name.h>
#include <mie/vector.h>
#include <mie/ir/value.h> struct mie_op;
struct mie_register;
struct mie_block { struct mie_block {
struct mie_value b_base; struct mie_name b_name;
struct mie_func *b_parent;
/* the phi instruction(s). these must appear at the start of the block MIE_VECTOR_DECLARE(struct mie_register, b_params);
* and are separated to make traversing the CFG easier */ MIE_VECTOR_DECLARE(struct mie_op, b_ops);
b_queue b_phi;
/* the rest of the instructions in the block */
b_queue b_instr;
/* the instruction that transfers control to the next block,
* could be a switch, branch, or ret */
struct mie_instr *b_terminator;
}; };
MIE_API struct mie_block *mie_block_create( MIE_API struct mie_op *mie_block_add_op(struct mie_block *block);
struct mie_func *parent, const char *name);
MIE_API bool mie_block_add_instr(struct mie_block *block, struct mie_instr *instr);
static inline bool mie_block_is_terminated(const struct mie_block *block)
{
return block->b_terminator != NULL;
}
#endif #endif

View File

@@ -1,19 +0,0 @@
#ifndef MIE_BRANCH_H_
#define MIE_BRANCH_H_
#include <mie/ir/const.h>
#include <mie/ir/instr.h>
struct mie_branch {
struct mie_instr b_base;
struct mie_block *b_dest;
};
struct mie_branch_if {
struct mie_instr b_base;
struct mie_value *b_cond;
struct mie_block *b_true_block;
struct mie_block *b_false_block;
};
#endif

View File

@@ -1,119 +0,0 @@
#ifndef MIE_BUILDER_H_
#define MIE_BUILDER_H_
#include <blue/core/btree.h>
#include <mie/ir/switch.h>
#include <mie/ir/value.h>
#include <mie/misc.h>
#include <mie/type.h>
struct b_hashmap;
struct mie_block;
struct mie_module;
struct mie_data;
struct mie_type;
struct mie_phi;
struct mie_phi_edge;
struct mie_ctx;
struct mie_builder {
struct mie_ctx *b_ctx;
struct mie_module *b_module;
struct mie_block *b_current_block;
struct mie_instr *b_prev_instr;
};
enum mie_builder_flags {
MIE_BUILDER_IGNORE_RESULT = 0x01u,
};
extern struct mie_builder *mie_builder_create(
struct mie_ctx *ctx, struct mie_module *mod);
extern void mie_builder_destroy(struct mie_builder *builder);
extern struct mie_func *mie_builder_get_current_func(struct mie_builder *builder);
static inline struct mie_block *mie_builder_get_current_block(
struct mie_builder *builder)
{
return builder->b_current_block;
}
extern struct mie_record *mie_builder_put_record(
struct mie_builder *builder, struct mie_const *val, const char *name);
extern struct mie_record *mie_builder_get_record(
struct mie_builder *builder, const char *name);
extern void mie_builder_put_data(struct mie_builder *builder, struct mie_data *data);
extern void mie_builder_put_type(struct mie_builder *builder, struct mie_type *type);
extern void mie_builder_set_insert_point(
struct mie_builder *builder, struct mie_block *block);
extern struct mie_value *mie_builder_get_data_ptr(
struct mie_builder *builder, const char *data_ident);
extern struct mie_value *mie_builder_get_string_ptr(
struct mie_builder *builder, const char *s);
extern struct mie_value *mie_builder_ret(
struct mie_builder *builder, struct mie_value *val);
extern struct mie_value *mie_builder_add(
struct mie_builder *builder, struct mie_value *left,
struct mie_value *right, const char *name);
extern struct mie_value *mie_builder_sub(
struct mie_builder *builder, struct mie_value *left,
struct mie_value *right, const char *name);
extern struct mie_value *mie_builder_mul(
struct mie_builder *builder, struct mie_value *left,
struct mie_value *right, const char *name);
extern struct mie_value *mie_builder_div(
struct mie_builder *builder, struct mie_value *left,
struct mie_value *right, const char *name);
extern struct mie_value *mie_builder_load(
struct mie_builder *builder, struct mie_type *type,
struct mie_value *src, const char *name);
extern struct mie_value *mie_builder_store(
struct mie_builder *builder, struct mie_value *val, struct mie_value *dest);
extern struct mie_value *mie_builder_alloca(
struct mie_builder *builder, struct mie_type *type, const char *name);
extern struct mie_value *mie_builder_switch(
struct mie_builder *builder, struct mie_value *cond,
struct mie_switch_branch *branches, size_t nr_branches,
struct mie_block *default_block);
extern struct mie_value *mie_builder_br(
struct mie_builder *builder, struct mie_block *dest);
extern struct mie_value *mie_builder_br_if(
struct mie_builder *builder, struct mie_value *cond,
struct mie_block *if_true, struct mie_block *if_false);
extern struct mie_value *mie_builder_msg(
struct mie_builder *builder, struct mie_type *ret_type,
struct mie_value *recipient, struct mie_value *selector,
struct mie_value **args, size_t nr_args, enum mie_builder_flags flags,
const char *name);
extern struct mie_value *mie_builder_cmp_eq(
struct mie_builder *builder, struct mie_value *left,
struct mie_value *right, const char *name);
extern struct mie_value *mie_builder_cmp_neq(
struct mie_builder *builder, struct mie_value *left,
struct mie_value *right, const char *name);
extern struct mie_value *mie_builder_cmp_lt(
struct mie_builder *builder, struct mie_value *left,
struct mie_value *right, const char *name);
extern struct mie_value *mie_builder_cmp_gt(
struct mie_builder *builder, struct mie_value *left,
struct mie_value *right, const char *name);
extern struct mie_value *mie_builder_cmp_leq(
struct mie_builder *builder, struct mie_value *left,
struct mie_value *right, const char *name);
extern struct mie_value *mie_builder_cmp_geq(
struct mie_builder *builder, struct mie_value *left,
struct mie_value *right, const char *name);
extern struct mie_value *mie_builder_getelementptr(
struct mie_builder *builder, struct mie_type *container_type,
struct mie_value *container, struct mie_value *index, const char *name);
extern struct mie_value *mie_builder_setelementptr(
struct mie_builder *builder, struct mie_type *container_type,
struct mie_value *container, struct mie_value *index);
extern struct mie_value *mie_builder_phi(
struct mie_builder *builder, struct mie_type *type,
struct mie_phi_edge *edges, unsigned int nr_edges, const char *name);
#endif

View File

@@ -1,65 +0,0 @@
#ifndef MIE_CONST_H_
#define MIE_CONST_H_
#include <blue/ds/list.h>
#include <mie/ir/value.h>
#include <mie/type.h>
#define MIE_CONST(p) ((struct mie_const *)(p))
#define MIE_INT(p) ((struct mie_int *)(p))
#define MIE_DOUBLE(p) ((struct mie_double *)(p))
#define MIE_STRING(p) ((struct mie_string *)(p))
#define MIE_ATOM(p) ((struct mie_atom *)(p))
#define MIE_SELECTOR(p) ((struct mie_selector *)(p))
#define MIE_ARRAY(p) ((struct mie_array *)(p))
struct mie_const {
struct mie_value c_base;
struct mie_type *c_type;
};
struct mie_int {
struct mie_const i_base;
int64_t i_value;
};
struct mie_double {
struct mie_const d_base;
double d_value;
};
struct mie_string {
struct mie_const s_base;
char *s_value;
};
struct mie_atom {
struct mie_const a_base;
char *a_value;
};
struct mie_selector {
struct mie_const sel_base;
char *sel_value;
};
struct mie_array {
struct mie_const a_base;
b_list *a_values;
};
extern void mie_const_init(struct mie_const *c, struct mie_type *type);
static inline bool mie_value_is_selector(const struct mie_value *v)
{
if (v->v_type->t_id != MIE_VALUE_CONST) {
return false;
}
const struct mie_const *c = MIE_CONST(v);
return c->c_type->t_id == MIE_TYPE_SELECTOR;
}
#endif

View File

@@ -1,82 +0,0 @@
#ifndef MIE_CONVERT_H_
#define MIE_CONVERT_H_
#include <blue/core/stringstream.h>
#include <blue/ds/bitbuffer.h>
#include <blue/ds/string.h>
#include <mie/misc.h>
#include <stdio.h>
struct mie_value;
struct mie_ctx;
enum mie_ir_format {
MIE_IR_NONE = 0,
MIE_IR_MEM,
MIE_IR_BITCODE,
MIE_IR_TEXT,
};
enum mie_ir_converter_medium {
MIE_IR_CONVERTER_NONE = 0,
MIE_IR_CONVERTER_MIE_VALUE,
MIE_IR_CONVERTER_BITSTREAM,
MIE_IR_CONVERTER_BITBUFFER,
MIE_IR_CONVERTER_STRINGSTREAM,
MIE_IR_CONVERTER_STRING,
MIE_IR_CONVERTER_FILE,
};
struct mie_ir_converter {
struct mie_ctx *c_ctx;
enum mie_ir_format c_src_format, c_dest_format;
enum mie_ir_converter_medium c_src_medium, c_dest_medium;
union {
/* TODO bitstream */
struct mie_value *value;
b_bitbuffer *bitbuffer;
b_stringstream *stringstream;
b_string *string;
FILE *file;
} c_src;
union {
/* TODO bitstream */
struct mie_value **value;
b_bitbuffer *bitbuffer;
b_stringstream *stringstream;
b_string *string;
FILE *file;
} c_dest;
};
MIE_API struct mie_ir_converter *mie_ir_converter_create(
struct mie_ctx *ctx, enum mie_ir_format src, enum mie_ir_format dest);
MIE_API void mie_ir_converter_destroy(struct mie_ir_converter *converter);
MIE_API b_status mie_ir_converter_set_src_value(
struct mie_ir_converter *converter, struct mie_value *value);
MIE_API b_status mie_ir_converter_set_src_bitbuffer(
struct mie_ir_converter *converter, b_bitbuffer *bitbuffer);
MIE_API b_status mie_ir_converter_set_src_stringstream(
struct mie_ir_converter *converter, b_stringstream *stringstream);
MIE_API b_status mie_ir_converter_set_src_string(
struct mie_ir_converter *converter, b_string *string);
MIE_API b_status mie_ir_converter_set_src_file(
struct mie_ir_converter *converter, FILE *file);
MIE_API b_status mie_ir_converter_set_dest_value(
struct mie_ir_converter *converter, struct mie_value **value);
MIE_API b_status mie_ir_converter_set_dest_bitbuffer(
struct mie_ir_converter *converter, b_bitbuffer *bitbuffer);
MIE_API b_status mie_ir_converter_set_dest_stringstream(
struct mie_ir_converter *converter, b_stringstream *stringstream);
MIE_API b_status mie_ir_converter_set_dest_string(
struct mie_ir_converter *converter, b_string *string);
MIE_API b_status mie_ir_converter_set_dest_file(
struct mie_ir_converter *converter, FILE *file);
MIE_API b_status mie_ir_converter_process(struct mie_ir_converter *converter);
#endif

View File

@@ -1,32 +0,0 @@
#ifndef MIE_DATA_H_
#define MIE_DATA_H_
#include <mie/ir/value.h>
#define MIE_DATA(p) ((struct mie_data *)(p))
enum mie_data_type {
MIE_DATA_NONE = 0,
MIE_DATA_EXTERN_GLOBAL,
MIE_DATA_CONST,
};
struct mie_data {
struct mie_value d_base;
enum mie_data_type d_type;
union {
struct {
struct mie_const *c_value;
} d_const;
struct {
struct mie_type *g_type;
} d_extern_global;
};
};
extern struct mie_data *mie_data_create_extern_global(
struct mie_type *type, const char *ident);
extern struct mie_data *mie_data_create_const(struct mie_const *value);
#endif

View File

@@ -1,47 +0,0 @@
#ifndef MIE_FUNC_H_
#define MIE_FUNC_H_
#define MIE_FUNC(p) ((struct mie_func *)(p))
#include <mie/ir/value.h>
struct mie_name_map;
struct mie_type;
struct mie_arg;
struct mie_block;
struct b_dict;
enum mie_func_type {
MIE_FUNC_NONE = 0x00u,
MIE_FUNC_STATIC = 0x01u,
MIE_FUNC_INSTANCE = 0x02u,
MIE_FUNC_LAMBDA = 0x03u,
};
struct mie_func {
struct mie_value f_base;
enum mie_func_type f_type;
struct mie_type *f_ret;
struct mie_name_map *f_names;
b_queue f_args;
b_queue f_blocks;
};
extern struct mie_func *mie_func_create(
enum mie_func_type type, struct mie_type *ret_type);
extern struct mie_value *mie_func_add_arg(
struct mie_func *func, struct mie_type *type, const char *name);
extern struct mie_block *mie_func_create_block(
struct mie_func *func, const char *name);
extern void mie_func_insert_block(
struct mie_func *func, struct mie_block *block, struct mie_block *after);
extern struct mie_value *mie_func_generate_value_name(
struct mie_func *func, struct mie_value *val, const char *hint);
extern struct mie_block *mie_func_get_first_block(struct mie_func *func);
extern struct mie_block *mie_func_get_last_block(struct mie_func *func);
#endif

View File

@@ -1,45 +0,0 @@
#ifndef MIE_INSTR_H_
#define MIE_INSTR_H_
#include <mie/ir/value.h>
#define MIE_INSTR(p) ((struct mie_instr *)(p))
enum mie_instr_type {
MIE_INSTR_NONE = 0,
MIE_INSTR_RET,
MIE_INSTR_ADD,
MIE_INSTR_SUB,
MIE_INSTR_MUL,
MIE_INSTR_DIV,
MIE_INSTR_LOAD,
MIE_INSTR_STORE,
MIE_INSTR_ALLOCA,
MIE_INSTR_SWITCH,
MIE_INSTR_BR,
MIE_INSTR_BR_IF,
MIE_INSTR_MSG,
MIE_INSTR_CMP_EQ,
MIE_INSTR_CMP_NEQ,
MIE_INSTR_CMP_LT,
MIE_INSTR_CMP_GT,
MIE_INSTR_CMP_LEQ,
MIE_INSTR_CMP_GEQ,
MIE_INSTR_GETELEMENTPTR,
MIE_INSTR_SETELEMENTPTR,
MIE_INSTR_PHI,
};
struct mie_instr {
struct mie_value i_base;
enum mie_instr_type i_type;
};
struct mie_ret {
struct mie_instr r_base;
struct mie_value *r_val;
};
extern void mie_instr_init(struct mie_instr *instr, enum mie_instr_type type);
#endif

View File

@@ -1,37 +1,21 @@
#ifndef MIE_MODULE_H_ #ifndef MIE_IR_MODULE_H_
#define MIE_MODULE_H_ #define MIE_IR_MODULE_H_
#define MIE_MODULE(p) ((struct mie_module *)(p)) #include <mie/misc.h>
#include <blue/core/queue.h>
#include <blue/ds/hashmap.h>
#include <mie/ir/value.h>
#include <mie/name.h> #include <mie/name.h>
#include <mie/vector.h>
#include <stddef.h>
struct mie_func; struct mie_op;
struct mie_module { struct mie_module {
struct mie_value m_base;
struct mie_name_map *m_names; struct mie_name_map *m_names;
b_queue m_records; MIE_VECTOR_DECLARE(struct mie_op, m_ops);
b_queue m_types;
b_queue m_func;
b_hashmap *m_data;
b_hashmap *m_data_strings;
}; };
extern struct mie_module *mie_module_create(void); MIE_API struct mie_module *mie_module_create(void);
extern void mie_module_add_function( MIE_API void mie_module_destroy(struct mie_module *mod);
struct mie_module *mod, struct mie_func *func, const char *name);
extern struct mie_data *mie_module_get_string_ptr(
struct mie_module *mod, const char *s);
extern struct mie_data *mie_module_get_data(
struct mie_module *mod, const char *name);
extern enum b_status mie_module_put_data(
struct mie_module *mod, struct mie_data *data, const char *name);
extern struct mie_value *mie_module_generate_value_name( MIE_API struct mie_op *mie_module_add_op(struct mie_module *mod);
struct mie_module *mod, struct mie_value *val, const char *hint);
#endif #endif

View File

@@ -1,18 +0,0 @@
#ifndef MIE_MSG_H_
#define MIE_MSG_H_
#include <mie/ir/instr.h>
#include <mie/type.h>
#define MIE_MSG(p) ((struct mie_msg *)(p))
struct mie_msg {
struct mie_instr msg_base;
struct mie_type *msg_ret_type;
struct mie_value *msg_recipient;
struct mie_value *msg_selector;
size_t msg_nr_args;
struct mie_value **msg_args;
};
#endif

View File

@@ -0,0 +1,112 @@
#ifndef MIE_IR_OP_DEFINITION_H_
#define MIE_IR_OP_DEFINITION_H_
#include <blue/core/btree.h>
#include <blue/core/stream.h>
#include <mie/id.h>
#include <mie/status.h>
#include <mie/trait/trait-table.h>
#define MIE_OP_MAX_PARAMS 8
#define MIE_OP_MAX_RESULTS 8
struct mie_op;
struct mie_parser;
struct mie_dialect;
#if 0
enum mie_op_trait {
MIE_OP_TRAIT_NONE = 0x00u,
/* this is a graph op. references to it by name must be prefixed with +
* and the op can only be used within graph regions.
* a graph op can have the same name as a regular or non-graph op. */
MIE_OP_TRAIT_GRAPH_ONLY = 0x01u,
/* this is a non-graph op. this op cannot be used within graph regions */
MIE_OP_TRAIT_NO_GRAPH = 0x02u,
/* regions of an op that has this trait are graph regions. graph regions
* cannot have more than one block, and the entry block must be unnamed
* with no parameters. However, graph ops can be used. */
MIE_OP_TRAIT_GRAPH_SCOPE = 0x04u,
/* regions of an op that has this trait cannot capture or reference
* values defined in the enclosing scope. */
MIE_OP_TRAIT_ISOLATED_FROM_ABOVE = 0x08u,
};
#endif
enum mie_op_param_type {
/* op has no parameter */
MIE_OP_PARTYPE_NONE = 0,
/* op has a parameter of any type. */
MIE_OP_PARTYPE_ANY,
/* op has a parameter of a fixed, named type. */
MIE_OP_PARTYPE_TYPE_NAME,
/* op has a parameter whose type matches the type of an attribute value */
MIE_OP_PARTYPE_ATTRIB_VAL,
};
enum mie_op_result_type {
/* op has no result */
MIE_OP_RESTYPE_NONE = 0,
/* op has a result of any type. */
MIE_OP_RESTYPE_ANY,
/* op has a result of a fixed, named type. */
MIE_OP_RESTYPE_TYPE_NAME,
/* op has a result whose type matches the type of an input parameter */
MIE_OP_RESTYPE_IN_VAL,
/* op has a result whose type matches the type of an attribute value */
MIE_OP_RESTYPE_ATTRIB_VAL,
};
struct mie_op_param {
enum mie_op_param_type param_type;
union {
struct {
const char *t_dialect;
/* this can be NULL, in which case any type from the
* dialect named in t_dialect will be accepted. */
const char *t_name;
} param_type_name;
const char *param_attrib;
};
};
struct mie_op_result {
enum mie_op_result_type r_type;
union {
struct {
const char *t_dialect;
const char *t_name;
} r_type_name;
unsigned int r_in_index;
const char *r_attrib;
};
};
struct mie_op_definition {
mie_id op_id;
struct mie_dialect *op_parent;
char *op_name;
struct mie_trait_table op_traits;
const struct mie_op_param op_params[MIE_OP_MAX_PARAMS];
const struct mie_op_result op_results[MIE_OP_MAX_RESULTS];
enum mie_status (*op_print)(const struct mie_op *, b_stream *);
enum mie_status (*op_parse)(struct mie_parser *, struct mie_op *);
};
MIE_API struct mie_op_definition *mie_op_definition_create(
struct mie_dialect *parent, const char *name);
MIE_API enum mie_status mie_op_definition_add_trait(
struct mie_op_definition *op, const struct mie_trait *trait);
#endif

View File

@@ -1,13 +1,78 @@
#ifndef MIE_ARITH_H_ #ifndef MIE_IR_OP_H_
#define MIE_ARITH_H_ #define MIE_IR_OP_H_
#include <mie/ir/instr.h> #include "mie/vector.h"
struct mie_binary_op { #include <mie/ir/register.h>
struct mie_instr op_base; #include <mie/misc.h>
struct mie_type *op_type; #include <mie/name.h>
struct mie_value *op_left; #include <mie/parse/file-span.h>
struct mie_value *op_right;
struct mie_type;
struct mie_value;
struct mie_block;
struct mie_region;
struct mie_dialect;
struct mie_op_definition;
enum mie_op_flags {
MIE_OP_F_OP_RESOLVED = 0x01u,
MIE_OP_F_ARG_RESOLVED = 0x02u,
MIE_OP_F_SUCCESSOR_RESOLVED = 0x04u,
}; };
struct mie_op_attribute {
char *attrib_name;
struct mie_value *attrib_value;
};
struct mie_op_arg {
enum mie_op_flags arg_flags;
struct mie_file_span arg_span;
union {
/* only valid if F_ARG_RESOLVED is set in arg_flags */
struct mie_register *arg_value;
/* only valid if F_ARG_RESOLVED is NOT set in arg_flags */
struct mie_register_ref arg_unresolved;
};
};
struct mie_op_successor {
enum mie_op_flags s_flags;
union {
/* only valid if F_SUCCESSOR_RESOLVED is set in s_flags; */
struct mie_block *s_block;
/* only valid if F_SUCCESSOR_RESOLVED is NOT set in s_flags; */
char *s_block_name;
};
MIE_VECTOR_DECLARE(struct mie_op_arg, s_args);
};
struct mie_op {
enum mie_op_flags op_flags;
/* these pointers are only valid if the F_OP_RESOLVED flag is set */
const struct mie_dialect *op_dialect;
const struct mie_op_definition *op_info;
struct mie_file_span op_name_span;
/* only valid if the F_RESOLVED flag is NOT set */
char *op_name;
MIE_VECTOR_DECLARE(struct mie_region, op_regions);
MIE_VECTOR_DECLARE(struct mie_op_successor, op_successors);
MIE_VECTOR_DECLARE(struct mie_op_attribute, op_attrib);
MIE_VECTOR_DECLARE(struct mie_op_arg, op_args);
MIE_VECTOR_DECLARE(struct mie_register, op_result);
};
MIE_API void mie_op_destroy(struct mie_op *op);
MIE_API struct mie_region *mie_op_add_region(struct mie_op *op);
MIE_API struct mie_op_successor *mie_op_add_successor(struct mie_op *op);
#endif #endif

View File

@@ -1,25 +0,0 @@
#ifndef MIE_PHI_H_
#define MIE_PHI_H_
#include <blue/core/queue.h>
#include <mie/ir/instr.h>
#include <mie/misc.h>
struct mie_phi_edge {
b_queue_entry e_entry;
struct mie_block *e_incoming_block;
struct mie_value *e_value;
};
struct mie_phi {
struct mie_instr p_base;
struct mie_type *p_type;
unsigned int p_nr_edges;
struct mie_phi_edge *p_edges;
};
MIE_API struct mie_phi_edge *mie_phi_edge_create(
struct mie_block *incoming_block, struct mie_value *value);
#endif

View File

@@ -1,33 +0,0 @@
#ifndef MIE_PTR_H_
#define MIE_PTR_H_
#include <mie/ir/instr.h>
#include <mie/type.h>
struct mie_getelementptr {
struct mie_instr gep_base;
struct mie_type *gep_container_type;
struct mie_value *gep_container;
struct mie_value *gep_index;
};
struct mie_setelementptr {
struct mie_instr sep_base;
struct mie_type *sep_container_type;
struct mie_value *sep_container;
struct mie_value *sep_index;
};
struct mie_load {
struct mie_instr l_base;
struct mie_type *l_type;
struct mie_value *l_src;
};
struct mie_store {
struct mie_instr s_base;
struct mie_value *s_val;
struct mie_value *s_dest;
};
#endif

View File

@@ -1,16 +0,0 @@
#ifndef MIE_RECORD_H_
#define MIE_RECORD_H_
#define MIE_RECORD(p) ((struct mie_record *)(p))
#include <mie/ir/const.h>
#include <mie/ir/value.h>
struct mie_record {
struct mie_value r_base;
const struct mie_const *r_value;
};
extern struct mie_record *mie_record_create(const struct mie_const *val);
#endif

View File

@@ -0,0 +1,17 @@
#ifndef MIE_IR_REGION_H_
#define MIE_IR_REGION_H_
#include <mie/misc.h>
#include <mie/vector.h>
#include <stddef.h>
struct mie_block;
struct mie_region {
struct mie_name_map *r_names;
MIE_VECTOR_DECLARE(struct mie_block, r_blocks);
};
MIE_API struct mie_block *mie_region_add_block(struct mie_region *region);
#endif

View File

@@ -0,0 +1,51 @@
#ifndef MIE_IR_REGISTER_H_
#define MIE_IR_REGISTER_H_
#include <mie/name.h>
struct mie_target_register;
enum mie_register_flags {
MIE_REGISTER_F_NONE = 0,
MIE_REGISTER_F_OP_RESULT = 0x01u,
MIE_REGISTER_F_OP_PARAM = 0x02u,
MIE_REGISTER_F_BLOCK_PARAM = 0x04u,
/* only ONE of these two flags can be set at a time */
MIE_REGISTER_F_VIRTUAL = 0x10u,
MIE_REGISTER_F_MACHINE = 0x20u,
};
/* represents a yet-to-be-resolved reference to a mie_register */
struct mie_register_ref {
enum mie_register_flags reg_flags;
char *reg_name;
/* what we THINK the type of the register is.
* if this is set, it gets checked during the register resolution process. */
const struct mie_type *reg_type;
};
struct mie_register {
enum mie_register_flags reg_flags;
union {
/* only valid if F_VIRTUAL is set. */
struct mie_name reg_name;
/* only valid if F_MACHINE is set. */
struct mie_target_register *reg_mach;
};
const struct mie_type *reg_type;
/* if this is an OP_RESULT register, this points to the block within
* which this register is defined.
* if this is an OP_PARAM register, this pointer is NULL.
* if this is a BLOCK_PARAM register, this points to the block for
* which this register is a parameter. */
struct mie_block *reg_block;
/* if this is an OP_RESULT register, this points to the operation
* that defines the register.
* if this is an OP_PARAM register, this points to the operation
* for which this register is a parameter
* if this is a BLOCK_PARAM register, this pointer is NULL */
struct mie_op *reg_op;
};
#endif

View File

@@ -1,21 +0,0 @@
#ifndef MIE_SWITCH_H_
#define MIE_SWITCH_H_
#include <mie/ir/const.h>
#include <mie/ir/instr.h>
struct mie_switch_branch {
struct mie_value *b_value;
struct mie_block *b_jump_to;
};
struct mie_switch {
struct mie_instr s_base;
struct mie_value *s_src;
struct mie_block *s_default;
size_t s_nr_branches;
struct mie_switch_branch *s_branches;
};
#endif

View File

@@ -1,60 +0,0 @@
#ifndef MIE_VALUE_H_
#define MIE_VALUE_H_
#include <blue/core/queue.h>
#include <mie/misc.h>
#include <mie/name.h>
#define MIE_VALUE(p) ((struct mie_value *)(p))
struct mie_ctx;
struct mie_value;
enum mie_value_type_id {
MIE_VALUE_NONE = 0,
MIE_VALUE_MODULE,
MIE_VALUE_TYPE,
MIE_VALUE_RECORD,
MIE_VALUE_FUNC,
MIE_VALUE_ARG,
MIE_VALUE_BLOCK,
MIE_VALUE_INSTR,
MIE_VALUE_CONST,
MIE_VALUE_DATA,
};
enum mie_value_flags {
MIE_VALUE_F_NONE = 0x00u,
MIE_VALUE_F_STATIC = 0x01u,
};
struct mie_value_type {
enum mie_value_type_id t_id;
struct mie_type *(*t_get_type)(struct mie_value *, struct mie_ctx *);
void (*t_cleanup)(struct mie_value *);
};
struct mie_value {
struct mie_name v_name;
const struct mie_value_type *v_type;
enum mie_value_flags v_flags;
b_queue_entry v_entry;
};
MIE_API void mie_value_init(struct mie_value *val, enum mie_value_type_id type);
MIE_API void mie_value_destroy(struct mie_value *val);
MIE_API struct mie_type *mie_value_get_type(
struct mie_value *val, struct mie_ctx *ctx);
static inline bool mie_value_is(
const struct mie_value *val, enum mie_value_type_id type_id)
{
if (!val->v_type) {
return false;
}
return val->v_type->t_id == type_id;
}
#endif

116
mie/include/mie/macros.h Normal file
View File

@@ -0,0 +1,116 @@
#ifndef MIE_MACROS_H_
#define MIE_MACROS_H_
#define __MIE_DIALECT_BEGIN(func_prefix, dialect_name) \
struct mie_dialect *func_prefix##_dialect_create(struct mie_ctx *ctx) \
{ \
struct mie_dialect *self = mie_dialect_create(ctx, dialect_name); \
if (!self) { \
return NULL; \
} \
struct mie_op_definition *op = NULL; \
struct mie_type_definition *type = NULL; \
struct mie_trait_definition *trait = NULL;
#define __MIE_DIALECT_END() \
return self; \
}
#define __MIE_OP_DEFINITION_BEGIN(func_prefix, op_name) \
struct mie_op_definition *func_prefix##_op_create( \
struct mie_dialect *d, struct mie_ctx *ctx) \
{ \
struct mie_op_definition *op \
= mie_op_definition_create(d, op_name); \
if (!op) { \
return NULL; \
} \
const struct mie_trait *trait = NULL;
#define __MIE_OP_DEFINITION_END() \
return op; \
}
#define __MIE_TYPE_DEFINITION_BEGIN(func_prefix, type_name) \
struct mie_type_definition *func_prefix##_type_create( \
struct mie_dialect *d, struct mie_ctx *ctx) \
{ \
struct mie_type_definition *type \
= mie_type_definition_create(d, type_name); \
if (!type) { \
return NULL; \
} \
const struct mie_trait *trait = NULL;
#define __MIE_TYPE_DEFINITION_END() \
return type; \
}
#define __MIE_TRAIT_DEFINITION_BEGIN(func_prefix, trait_name) \
struct mie_trait_definition *func_prefix##_trait_create( \
struct mie_dialect *d, struct mie_ctx *ctx) \
{ \
struct mie_trait_definition *trait \
= mie_trait_definition_create(d, trait_name); \
if (!trait) { \
return NULL; \
}
#define __MIE_TRAIT_DEFINITION_END() \
return trait; \
}
#define __MIE_DIALECT_ADD_OP(op_id) \
extern struct mie_op_definition *op_id##_op_create( \
struct mie_dialect *, struct mie_ctx *); \
op = op_id##_op_create(self, ctx)
#define __MIE_DIALECT_ADD_TYPE(type_id) \
extern struct mie_type_definition *type_id##_type_create( \
struct mie_dialect *, struct mie_ctx *); \
type = type_id##_type_create(self, ctx)
#define __MIE_DIALECT_ADD_TRAIT(trait_id) \
extern struct mie_trait_definition *trait_id##_trait_create( \
struct mie_dialect *, struct mie_ctx *); \
trait = trait_id##_trait_create(self, ctx)
#define MIE_DIALECT_BEGIN(c_sym, name) __MIE_DIALECT_BEGIN(c_sym, name)
#define MIE_DIALECT_END() __MIE_DIALECT_END()
#define MIE_DIALECT_ADD_OP(c_sym) __MIE_DIALECT_ADD_OP(c_sym)
#define MIE_DIALECT_ADD_TYPE(c_sym) __MIE_DIALECT_ADD_TYPE(c_sym)
#define MIE_DIALECT_ADD_TRAIT(c_sym) __MIE_DIALECT_ADD_TRAIT(c_sym)
#define MIE_OP_DEFINITION_BEGIN(c_sym, op) __MIE_OP_DEFINITION_BEGIN(c_sym, op)
#define MIE_OP_DEFINITION_END() __MIE_OP_DEFINITION_END()
#define MIE_OP_DEFINITION_PRINT(func) op->op_print = (func)
#define MIE_OP_DEFINITION_PARSE(func) op->op_parse = (func)
#define MIE_OP_DEFINITION_TRAIT(trait_dialect, trait_name) \
trait = mie_ctx_get_trait(ctx, trait_dialect, trait_name); \
mie_op_definition_add_trait(op, trait);
#define MIE_TYPE_DEFINITION_BEGIN(c_sym, type) \
__MIE_TYPE_DEFINITION_BEGIN(c_sym, type)
#define MIE_TYPE_DEFINITION_END() __MIE_TYPE_DEFINITION_END()
#define MIE_TYPE_DEFINITION_FLAGS(flags) type->ty_flags = flags
#define MIE_TYPE_DEFINITION_STRUCT(name) type->ty_data_size = sizeof(name)
#define MIE_TYPE_DEFINITION_INIT(func) type->ty_init = (func)
#define MIE_TYPE_DEFINITION_PRINT(func) type->ty_print = (func)
#define MIE_TYPE_DEFINITION_VALUE_PRINT(func) type->ty_value_print = (func)
#define MIE_TYPE_DEFINITION_PARSE(func) type->ty_parse = (func)
#define MIE_TYPE_DEFINITION_BUILD_ID(func) type->ty_build_id = (func)
#define MIE_TYPE_DEFINITION_INIT(func) type->ty_init = (func)
#define MIE_TYPE_DEFINITION_CLEANUP(func) type->ty_cleanup = (func)
#define MIE_TYPE_DEFINITION_TRAIT(trait_dialect, trait_name) \
trait = mie_ctx_get_trait(ctx, trait_dialect, trait_name); \
mie_type_definition_add_trait(type, trait);
#define MIE_TRAIT_DEFINITION_BEGIN(c_sym, trait) \
__MIE_TRAIT_DEFINITION_BEGIN(c_sym, trait)
#define MIE_TRAIT_DEFINITION_END() __MIE_TRAIT_DEFINITION_END()
#define MIE_TRAIT_DEFINITION_TARGETS(targets) trait->tr_target = (targets)
#define MIE_TRAIT_DEFINITION_STRUCT(name) trait->tr_data_size = sizeof(name)
#define MIE_TRAIT_DEFINITION_PRINT(func) trait->tr_print = (func)
#define MIE_TRAIT_DEFINITION_BUILD_ID(func) trait->tr_build_id = (func)
#define MIE_TRAIT_DEFINITION_CLEANUP(func) trait->tr_cleanup = (func)
#define MIE_TRAIT_DEFINITION_VALIDATE(func) trait->tr_validate = (func)
#endif

View File

@@ -11,7 +11,9 @@
#define MIE_API extern #define MIE_API extern
#endif #endif
#define MIN(x, y) ((x) < (y) ? (x) : (y)) #define MIN(x, y) ((x) < (y) ? (x) : (y))
#define MAX(x, y) ((x) > (y) ? (x) : (y)) #define MAX(x, y) ((x) > (y) ? (x) : (y))
#define MIE_TEST_FLAGS(value, flags) (((value) & (flags)) == (flags))
#endif #endif

View File

@@ -3,13 +3,21 @@
#include <blue/core/btree.h> #include <blue/core/btree.h>
#include <blue/core/queue.h> #include <blue/core/queue.h>
#include <mie/misc.h>
#include <mie/parse/file-span.h>
#define MIE_NAME_VALID(p) (((p)->n_str) != NULL) #define MIE_NAME_VALID(p) (((p)->n_str) != NULL)
struct mie_name_map; struct mie_name_map;
enum mie_name_map_flags { enum mie_name_map_flags {
MIE_NAME_MAP_STRICT = 0x01u, /* put(): take the name hint as the required name, and don't amend it
* to ensure uniqueness. if the given name already exists, the operation
* fails. */
MIE_NAME_MAP_F_STRICT = 0x01u,
/* get(): if the given name does not exist in the name map, recursively
* search the parent map(s) until a result is found. */
MIE_NAME_MAP_F_RECURSIVE = 0x02u,
}; };
enum mie_name_map_entry_type { enum mie_name_map_entry_type {
@@ -31,6 +39,10 @@ struct mie_name {
struct mie_name_map_entry n_base; struct mie_name_map_entry n_base;
struct mie_name_map *n_parent; struct mie_name_map *n_parent;
char *n_str; char *n_str;
/* if this name was read from a file, these structs can be used to
* record the location within the file where the name is found. */
struct mie_file_span n_start, n_end;
}; };
struct mie_name_bucket { struct mie_name_bucket {
@@ -39,13 +51,17 @@ struct mie_name_bucket {
}; };
struct mie_name_map { struct mie_name_map {
const struct mie_name_map *m_parent;
b_btree m_entries; b_btree m_entries;
size_t m_next_id; size_t m_next_id;
}; };
extern struct mie_name_map *mie_name_map_create(void); extern struct mie_name_map *mie_name_map_create(const struct mie_name_map *parent);
extern void mie_name_map_destroy(struct mie_name_map *map); extern void mie_name_map_destroy(struct mie_name_map *map);
extern const struct mie_name *mie_name_map_get(
const struct mie_name_map *map, const char *name,
enum mie_name_map_flags flags);
extern struct mie_name *mie_name_map_put( extern struct mie_name *mie_name_map_put(
struct mie_name_map *map, struct mie_name *entry, const char *hint, struct mie_name_map *map, struct mie_name *entry, const char *hint,
enum mie_name_map_flags flags); enum mie_name_map_flags flags);

View File

@@ -0,0 +1,23 @@
#ifndef MIE_PARSE_FILE_SPAN_H_
#define MIE_PARSE_FILE_SPAN_H_
#include <mie/misc.h>
struct mie_token;
/* a single row/column pair, representing a location within a file.
* both values are 1-based (i.e. the first character in a file is at c_row=1,
* c_col=1*/
struct mie_file_cell {
unsigned int c_row, c_col;
};
/* represents a span of characters within a file.
* used for diagnostic reporting */
struct mie_file_span {
struct mie_file_cell s_start, s_end;
};
MIE_API void mie_file_span_init(struct mie_file_span *span, struct mie_token *tok);
#endif

View File

@@ -0,0 +1,18 @@
#ifndef MIE_PARSE_LEX_H_
#define MIE_PARSE_LEX_H_
#include <blue/core/stream.h>
#include <mie/misc.h>
#include <mie/status.h>
struct mie_lex;
struct mie_token;
MIE_API struct mie_lex *mie_lex_create(b_stream *src);
MIE_API void mie_lex_destroy(struct mie_lex *lex);
MIE_API enum mie_status mie_lex_get_status(const struct mie_lex *lex);
MIE_API struct mie_token *mie_lex_peek(struct mie_lex *lex);
MIE_API void mie_lex_advance(struct mie_lex *lex);
#endif

View File

@@ -0,0 +1,125 @@
#ifndef MIE_PARSE_PARSE_H_
#define MIE_PARSE_PARSE_H_
#include <blue/ds/string.h>
#include <mie/ir/register.h>
#include <mie/misc.h>
#include <mie/parse/token.h>
#include <mie/status.h>
#include <mie/vector.h>
#include <stdbool.h>
struct mie_parser;
struct mie_name_map;
struct mie_lex;
struct mie_ctx;
struct mie_type;
struct mie_module;
struct mie_region;
struct mie_op;
struct mie_op_arg;
struct mie_op_attribute;
struct mie_op_successor;
struct mie_register;
struct mie_value;
MIE_API struct mie_parser *mie_parser_create(
struct mie_ctx *ctx, struct mie_lex *lex);
MIE_API void mie_parser_destroy(struct mie_parser *ctx);
MIE_API enum mie_status mie_parser_get_status(const struct mie_parser *ctx);
MIE_API struct mie_token *mie_parser_peek(struct mie_parser *ctx);
MIE_API enum mie_token_type mie_parser_peek_type(struct mie_parser *ctx);
MIE_API enum mie_token_symbol mie_parser_peek_symbol(struct mie_parser *ctx);
MIE_API bool mie_parser_advance(struct mie_parser *ctx);
MIE_API bool mie_parser_check_eof(struct mie_parser *ctx);
MIE_API bool mie_parser_check_type(struct mie_parser *ctx, enum mie_token_type type);
MIE_API bool mie_parser_check_symbol(
struct mie_parser *ctx, enum mie_token_symbol sym);
MIE_API bool mie_parser_parse_int(
struct mie_parser *ctx, long long *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_float(
struct mie_parser *ctx, double *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_word(
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_instname(
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_graphname(
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_opname(
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_vregname(
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_mregname(
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_blockname(
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_typename(
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_symname(
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_string(
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_keyword(struct mie_parser *ctx, const char *kw);
MIE_API bool mie_parser_parse_symbol(
struct mie_parser *ctx, enum mie_token_symbol sym);
MIE_API bool mie_parser_parse_linefeed(struct mie_parser *ctx);
MIE_API bool mie_parser_parse_type(
struct mie_parser *ctx, const struct mie_type **out);
MIE_API bool mie_parser_parse_type_list(
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(const struct mie_type *, out));
MIE_API bool mie_parser_parse_function_type(
struct mie_parser *ctx, struct mie_type **out);
MIE_API bool mie_parser_parse_operand(
struct mie_parser *ctx, struct mie_op_arg *out);
MIE_API bool mie_parser_parse_operand_list(
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_arg, out));
MIE_API bool mie_parser_parse_parameter(
struct mie_parser *ctx, struct mie_op_arg *out);
MIE_API bool mie_parser_parse_parameter_list(
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_arg, out));
MIE_API bool mie_parser_parse_unknown_keyword(struct mie_parser *ctx, b_string *out);
MIE_API bool mie_parser_parse_unknown_symbol(
struct mie_parser *ctx, enum mie_token_symbol sym);
MIE_API bool mie_parser_parse_register(
struct mie_parser *ctx, struct mie_name_map *names,
struct mie_register *out);
MIE_API bool mie_parser_parse_register_list(
struct mie_parser *ctx, struct mie_name_map *names,
MIE_VECTOR_REF_PARAM(struct mie_register, out));
MIE_API bool mie_parser_parse_region(
struct mie_parser *ctx, struct mie_region *region);
MIE_API bool mie_parser_parse_region_list(
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_region, out));
MIE_API bool mie_parser_parse_anonymous_block(
struct mie_parser *ctx, struct mie_name_map *names,
struct mie_block *block);
MIE_API bool mie_parser_parse_block(
struct mie_parser *ctx, struct mie_name_map *names,
struct mie_block *block);
MIE_API bool mie_parser_parse_attribute(
struct mie_parser *ctx, struct mie_op_attribute *attrib);
MIE_API bool mie_parser_parse_attribute_list(
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_attribute, out));
MIE_API bool mie_parser_parse_successor(
struct mie_parser *ctx, struct mie_op_successor *successor);
MIE_API bool mie_parser_parse_successor_list(
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_successor, out));
MIE_API bool mie_parser_parse_module(struct mie_parser *ctx, struct mie_module *mod);
MIE_API bool mie_parser_parse_op(
struct mie_parser *ctx, struct mie_name_map *names, struct mie_op *dest);
MIE_API bool mie_parser_parse_value(struct mie_parser *ctx, struct mie_value **dest);
#endif

View File

@@ -0,0 +1,94 @@
#ifndef MIE_PARSE_TOKEN_H_
#define MIE_PARSE_TOKEN_H_
#include <blue/core/queue.h>
#include <mie/misc.h>
#include <mie/parse/file-span.h>
#define MIE_TOKEN_TYPE(tok) ((tok) ? (tok)->tok_type : MIE_TOK_NONE)
#define MIE_TOKEN_IS(tok, type) ((tok) && ((tok)->tok_type & (type)) != 0)
#define MIE_TOKEN_IS_SYMBOL(tok, sym) \
((tok) && (tok)->tok_type == MIE_TOK_SYMBOL && (tok)->tok_sym == (sym))
enum mie_token_type {
MIE_TOK_NONE = 0,
MIE_TOK_LINEFEED = 0x0001u,
MIE_TOK_INT = 0x0002u,
MIE_TOK_FLOAT = 0x0004u,
MIE_TOK_SYMBOL = 0x0008u,
MIE_TOK_STRING = 0x0010u,
/* single words, not dot-delimited */
MIE_TOK_WORD = 0x0020u,
/* set of words with at least one dot */
MIE_TOK_NAME = 0x0040u,
/* word or name, prefixed with an * asterisk */
MIE_TOK_INSTNAME = 0x0080u,
/* word or name, prefixed with an @ at */
MIE_TOK_SYMNAME = 0x0100u,
/* word or name, prefixed with a ~ tilde */
MIE_TOK_OPNAME = 0x0200u,
/* word or name, prefixed with a + plus */
MIE_TOK_GRAPHNAME = 0x0400u,
/* word or name, prefixed with a % percent */
MIE_TOK_VREGNAME = 0x0800u,
/* word or name, prefixed with a $ dollar */
MIE_TOK_MREGNAME = 0x1000u,
/* word or name, prefixed with a ^ caret */
MIE_TOK_BLOCKNAME = 0x2000u,
/* word or name, prefixed with a # hash */
MIE_TOK_TYPENAME = 0x4000u,
};
enum mie_token_value_type {
MIE_TOK_V_NONE = 0,
MIE_TOK_V_INT,
MIE_TOK_V_FLOAT,
MIE_TOK_V_STRING,
MIE_TOK_V_SYMBOL,
};
enum mie_token_symbol {
MIE_SYM_NONE = 0,
MIE_SYM_COLON,
MIE_SYM_EQUAL,
MIE_SYM_COMMA,
MIE_SYM_HYPHEN,
MIE_SYM_ASTERISK,
MIE_SYM_PLUS,
MIE_SYM_PERCENT,
MIE_SYM_DOLLAR,
MIE_SYM_CARET,
MIE_SYM_HASH,
MIE_SYM_TILDE,
MIE_SYM_ATSIGN,
MIE_SYM_LEFT_BRACE,
MIE_SYM_RIGHT_BRACE,
MIE_SYM_LEFT_BRACKET,
MIE_SYM_RIGHT_BRACKET,
MIE_SYM_LEFT_PAREN,
MIE_SYM_RIGHT_PAREN,
MIE_SYM_LEFT_ANGLE,
MIE_SYM_RIGHT_ANGLE,
MIE_SYM_HYPHEN_RIGHT_ANGLE,
MIE_SYM_OTHER,
};
struct mie_token {
struct mie_file_span tok_location;
enum mie_token_type tok_type;
enum mie_token_value_type tok_value_type;
b_queue_entry tok_entry;
union {
char *tok_str;
enum mie_token_symbol tok_sym;
long long tok_int;
double tok_float;
};
};
MIE_API void mie_token_destroy(struct mie_token *tok);
MIE_API const char *mie_token_type_to_string(enum mie_token_type type);
MIE_API const char *mie_token_symbol_to_string(enum mie_token_symbol sym);
#endif

View File

@@ -1,55 +0,0 @@
#ifndef MIE_SELECT_BUILDER_H_
#define MIE_SELECT_BUILDER_H_
#include <mie/misc.h>
#include <mie/status.h>
struct mie_ctx;
struct mie_instr;
struct mie_value;
struct mie_select_builder;
struct mie_select_node;
struct mie_select_graph;
struct mie_select_value;
struct mie_target;
MIE_API struct mie_select_builder *mie_select_builder_create(
struct mie_ctx *ctx, const struct mie_target *target);
MIE_API void mie_select_builder_destroy(struct mie_select_builder *builder);
MIE_API struct mie_select_graph *mie_select_builder_get_graph(
struct mie_select_builder *builder);
MIE_API struct mie_ctx *mie_select_builder_get_ctx(
struct mie_select_builder *builder);
MIE_API const struct mie_target *mie_select_builder_get_target(
struct mie_select_builder *builder);
MIE_API struct mie_select_graph *mie_select_builder_finish(
struct mie_select_builder *builder);
MIE_API enum mie_status mie_select_builder_get_const(
struct mie_select_builder *builder, long long value,
struct mie_select_value *out);
MIE_API enum mie_status mie_select_builder_push_instr(
struct mie_select_builder *builder, struct mie_instr *instr);
MIE_API struct mie_select_node *mie_select_builder_find_node_with_ivalue(
struct mie_select_builder *builder, const struct mie_target *target,
unsigned int opcode, long long val);
MIE_API struct mie_select_value *mie_select_builder_get_value(
struct mie_select_builder *builder, struct mie_value *ir_val);
MIE_API enum mie_status mie_select_builder_set_value(
struct mie_select_builder *builder, struct mie_value *ir_val,
struct mie_select_value *graph_val);
MIE_API struct mie_select_value *mie_select_builder_get_mem_access(
struct mie_select_builder *builder, struct mie_value *ir_val);
MIE_API enum mie_status mie_select_builder_set_mem_access(
struct mie_select_builder *builder, struct mie_value *ir_val,
struct mie_select_value *graph_val);
MIE_API enum mie_status mie_select_builder_collapse_chain_ends(
struct mie_select_builder *builder, struct mie_select_value *out);
#endif

View File

@@ -1,54 +0,0 @@
#ifndef MIE_SELECT_GRAPH_H_
#define MIE_SELECT_GRAPH_H_
#include <blue/core/btree.h>
#include <blue/core/queue.h>
#include <mie/misc.h>
#include <mie/target/target.h>
struct mie_ctx;
struct mie_type;
struct mie_instr;
struct mie_select_value {
struct mie_select_node *v_node;
unsigned int v_index;
};
struct mie_select_use {
struct mie_select_node *u_user;
struct mie_select_value u_value;
b_queue_entry u_entry;
};
struct mie_select_chain_end {
struct mie_select_value c_value;
b_queue_entry c_entry;
};
struct mie_select_graph {
b_queue g_nodes;
struct mie_select_node *g_root;
struct mie_select_value g_entry;
b_queue g_chain_ends;
size_t g_frame_index;
size_t g_node_id;
};
struct mie_select_use_iterator {
b_queue_entry *it_ptr;
};
MIE_API struct mie_select_graph *mie_select_graph_create(struct mie_ctx *ctx);
MIE_API void mie_select_graph_destroy(struct mie_select_graph *graph);
MIE_API enum mie_status mie_select_graph_get_node(
struct mie_select_graph *graph, const struct mie_target *target,
unsigned int op, struct mie_select_value **operands, size_t nr_operands,
struct mie_type **values, size_t nr_values, struct mie_select_node **out);
MIE_API void mie_select_graph_dump_text(struct mie_select_graph *graph);
MIE_API void mie_select_graph_dump_dot(
struct mie_select_graph *graph, const char *filename);
#endif

View File

@@ -1,104 +0,0 @@
#ifndef MIE_SELECT_NODE_H_
#define MIE_SELECT_NODE_H_
#include <blue/core/queue.h>
#include <mie/status.h>
#include <mie/type.h>
#define MIE_SELECT_NODE_OUTPUT_MAX 4
struct mie_target;
struct mie_value;
struct mie_select_value;
enum mie_select_node_flags {
MIE_SELECT_NODE_F_IVALUE = 0x01u,
MIE_SELECT_NODE_F_PVALUE = 0x02u,
};
struct mie_select_node {
size_t n_id;
unsigned long n_opcode;
enum mie_select_node_flags n_flags;
char *n_description;
/* certain "builtin" parameters that can be used by opcodes */
struct {
struct mie_value *v;
long long i;
void *p;
} n_value;
/* queue entry, links to mie_select_graph.g_nodes */
b_queue_entry n_entry;
/* linked lists of struct mie_select_use,
* listing all the places where this node is being used as an
* operand.
* these pointers point to data in another node's n_operands,
* and the memory belongs to these other nodes, not us.
*/
b_queue n_use;
/* array of struct mie_select_use
* listing all the nodes that are being used as operands by
* this node. other nodes hold pointers to these mie_select_use array
* entries as part of their n_use queue.
*/
struct mie_select_use *n_operands;
size_t n_nr_operands;
/* array of struct mie_type pointers
* listing the types of the values that are produced as outputs by
* this node. the type pointers themselves are owned by a mie_ctx.
*/
struct mie_type **n_results;
size_t n_nr_results;
/* the target system that provides the operation described by n_opcode. */
const struct mie_target *n_target;
};
struct mie_select_node_iterator {
b_queue_entry *it_ptr;
};
static inline struct mie_select_node *mie_select_node_iterator_unbox(
struct mie_select_node_iterator *it)
{
return b_unbox(struct mie_select_node, it->it_ptr, n_entry);
}
MIE_API void mie_select_node_iterator_next(struct mie_select_node_iterator *it);
MIE_API bool mie_select_node_iterator_is_valid(
const struct mie_select_node_iterator *it);
MIE_API struct mie_select_node *mie_select_node_create(
const struct mie_target *target, unsigned int op,
struct mie_type **results, size_t nr_results);
MIE_API void mie_select_node_destroy(struct mie_select_node *node);
MIE_API enum mie_status mie_select_node_set_operands(
struct mie_select_node *node, struct mie_select_value *operands,
size_t nr_operands);
MIE_API enum mie_status mie_select_node_clear_operands(struct mie_select_node *node);
MIE_API void mie_select_node_get_users(
struct mie_select_node *node, struct mie_select_node_iterator *it);
MIE_API void mie_select_node_get_uses(
struct mie_select_node *node, struct mie_select_node_iterator *it);
MIE_API enum mie_status mie_select_node_get_value(
struct mie_select_node *node, struct mie_type *type, size_t index,
struct mie_select_value *out);
MIE_API enum mie_status mie_select_node_set_description(
struct mie_select_node *node, const char *format, ...);
MIE_API struct mie_select_node *mie_select_node_get_glued_node(
struct mie_select_node *node);
MIE_API struct mie_select_node *mie_select_node_get_glued_user(
struct mie_select_node *node);
#endif

View File

@@ -1,33 +0,0 @@
#ifndef MIE_SELECT_OPCODE_H_
#define MIE_SELECT_OPCODE_H_
enum mie_select_opcode {
MIE_SELECT_OP_NONE = 0,
MIE_SELECT_OP_ENTRY,
MIE_SELECT_OP_ROOT,
MIE_SELECT_OP_BLOCK,
MIE_SELECT_OP_CONSTANT,
MIE_SELECT_OP_FRAME_INDEX,
MIE_SELECT_OP_REGISTER,
MIE_SELECT_OP_COPY_FROM_REG,
MIE_SELECT_OP_COPY_TO_REG,
MIE_SELECT_OP_GLOBAL_ADDRESS,
MIE_SELECT_OP_CHAIN_GROUP,
MIE_SELECT_OP_LOAD,
MIE_SELECT_OP_STORE,
MIE_SELECT_OP_ADD,
MIE_SELECT_OP_SUB,
MIE_SELECT_OP_MUL,
MIE_SELECT_OP_DIV,
MIE_SELECT_OP_XOR,
MIE_SELECT_OP_CMP_EQ,
MIE_SELECT_OP_CMP_NEQ,
MIE_SELECT_OP_CMP_LT,
MIE_SELECT_OP_CMP_GT,
MIE_SELECT_OP_CMP_LEQ,
MIE_SELECT_OP_CMP_GEQ,
MIE_SELECT_OP_BR,
MIE_SELECT_OP_BR_COND,
};
#endif

Some files were not shown because too many files have changed in this diff Show More