Compare commits

50 Commits

Author SHA1 Message Date
50f4be621b mie: move all builtin types (int, float, index, etc) and attributes to the builtin dialect 2026-01-14 09:45:14 +00:00
da630ce382 mie: replace fixed value system with an extensible attribute interface
under this new system, dialects can define their own custom attributes,
complete with their own print() and parse() callbacks, which can then be
used as values in an op's attribute dictionary.

alongside custom dialect attributes, the former int, float, and string
constant values have been converted to attributes provided by the
arith and builtin dialects respectively. the caches for these attributes
have also been moved from mie_ctx to their respective dialect data
structures.

this system will allow new types of attributes to be implemented,
including dictionaries, arrays, and references to types themselves
(rather than just particular values of a given type).
2026-01-13 22:37:43 +00:00
d19e8626da mie: stop using movable memory for mie_name instances.
any struct that contains a mie_name cannot be stored in movable memory
(i.e. any memory that may be re-allocated using realloc(), or whose
contents may be moved to a different buffer).

mie_names form part of a bst when they are added to a mie_name_map,
and moving them after this happens will result in the bst pointers
being invalidated. this causes some obscure and hard-to-debug
memory errors.

all structs that contain a mie_name (including named IR objects like
mie_register and mie_block) are no longer stored directly in vectors.
rather, vectors of pointers are used instead.
2026-01-12 10:40:57 +00:00
0fdadb3250 mie: trait: fix trait definitions not being initialised correctly 2026-01-12 10:40:14 +00:00
2d903f4a94 mie: type: fix type definitions not being initialised correctly 2026-01-12 10:37:49 +00:00
3aad8fd4a3 mie: index: cache: fix cache entries not being initialised correctly 2026-01-12 10:36:32 +00:00
49df8616a8 mie: implement a printer system for converting IR to textual form 2026-01-12 10:33:08 +00:00
826380ea34 mie: ctx: fix new mie_trait instances not being fully initialised 2026-01-12 10:05:12 +00:00
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
188 changed files with 10041 additions and 5562 deletions

174
.clang-format Normal file
View File

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

View File

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

View File

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

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

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

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

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

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

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

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

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

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,27 @@
#include <blue/ds/string.h>
#include <mie/attribute/attribute-definition.h>
#include <mie/dialect/dialect.h>
struct mie_attribute_definition *mie_attribute_definition_create(
struct mie_dialect *parent, const char *name)
{
struct mie_attribute_definition *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
memset(out, 0x0, sizeof *out);
out->a_name = b_strdup(name);
if (!out->a_name) {
free(out);
return NULL;
}
out->a_parent = parent;
b_rope name_rope = B_ROPE_CSTR(name);
mie_id_map_put(&parent->d_attributes, &out->a_id, &name_rope);
return out;
}

View File

@@ -0,0 +1,252 @@
#include <blue/core/hash.h>
#include <blue/core/queue.h>
#include <blue/ds/string.h>
#include <mie/attribute/attribute-map.h>
enum attribute_map_entry_type {
ATTRMAP_ENTRY_NONE = 0,
ATTRMAP_ENTRY_BUCKET,
ATTRMAP_ENTRY_ITEM,
};
struct attribute_map_entry {
enum attribute_map_entry_type e_type;
uint64_t e_hash;
union {
b_btree_node e_node;
b_queue_entry e_entry;
};
};
struct attribute_map_bucket {
struct attribute_map_entry b_base;
b_queue b_items;
};
struct attribute_map_item {
struct attribute_map_entry i_base;
char *i_name;
const struct mie_attribute *i_value;
};
static B_BTREE_DEFINE_SIMPLE_INSERT(
struct attribute_map_entry, e_node, e_hash, put_entry);
static B_BTREE_DEFINE_SIMPLE_GET(
struct attribute_map_entry, uint64_t, e_node, e_hash, get_entry);
void mie_attribute_map_init(struct mie_attribute_map *map)
{
memset(map, 0x0, sizeof *map);
}
void mie_attribute_map_cleanup(struct mie_attribute_map *map)
{
/* TODO */
}
static const struct mie_attribute *get_attribute_from_item(
const struct attribute_map_item *item, const char *name)
{
if (!strcmp(item->i_name, name)) {
return item->i_value;
}
return NULL;
}
static const struct mie_attribute *get_attribute_from_bucket(
const struct attribute_map_bucket *bucket, const char *name)
{
b_queue_entry *cur = b_queue_first(&bucket->b_items);
while (cur) {
const struct attribute_map_item *item = b_unbox(
const struct attribute_map_item, cur, i_base.e_entry);
if (!strcmp(item->i_name, name)) {
return item->i_value;
}
cur = b_queue_next(cur);
}
return NULL;
}
static const struct mie_attribute *get_attribute_from_entry(
const struct attribute_map_entry *entry, const char *name)
{
switch (entry->e_type) {
case ATTRMAP_ENTRY_ITEM:
return get_attribute_from_item(
(const struct attribute_map_item *)entry, name);
case ATTRMAP_ENTRY_BUCKET:
return get_attribute_from_bucket(
(const struct attribute_map_bucket *)entry, name);
default:
return NULL;
}
}
const struct mie_attribute *mie_attribute_map_get(
const struct mie_attribute_map *map, const char *name)
{
uint64_t name_hash = b_hash_cstr(name);
struct attribute_map_entry *entry = get_entry(&map->m_entries, name_hash);
if (!entry) {
return NULL;
}
return get_attribute_from_entry(entry, name);
}
static struct attribute_map_bucket *convert_item_to_bucket(
struct mie_attribute_map *map, struct attribute_map_item *item)
{
struct attribute_map_bucket *bucket = malloc(sizeof *bucket);
if (!bucket) {
return NULL;
}
b_btree_delete(&map->m_entries, &item->i_base.e_node);
memset(bucket, 0x0, sizeof *bucket);
bucket->b_base.e_type = ATTRMAP_ENTRY_BUCKET;
bucket->b_base.e_hash = item->i_base.e_hash;
b_queue_push_back(&bucket->b_items, &item->i_base.e_entry);
put_entry(&map->m_entries, &bucket->b_base);
return bucket;
}
static struct attribute_map_item *create_item(
const char *name, uint64_t name_hash, const struct mie_attribute *attrib)
{
struct attribute_map_item *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
memset(out, 0x0, sizeof *out);
out->i_value = attrib;
out->i_base.e_type = ATTRMAP_ENTRY_ITEM;
out->i_base.e_hash = name_hash;
out->i_name = b_strdup(name);
if (!out->i_name) {
free(out);
return NULL;
}
return out;
}
enum mie_status mie_attribute_map_put(
struct mie_attribute_map *map, const char *name,
const struct mie_attribute *value, enum mie_attribute_map_flags flags)
{
uint64_t name_hash = b_hash_cstr(name);
struct attribute_map_entry *entry = get_entry(&map->m_entries, name_hash);
struct attribute_map_item *item = NULL;
struct attribute_map_bucket *bucket = NULL;
if (!entry) {
item = create_item(name, name_hash, value);
if (!item) {
return MIE_ERR_NO_MEMORY;
}
put_entry(&map->m_entries, &item->i_base);
return MIE_SUCCESS;
}
if (entry->e_type == ATTRMAP_ENTRY_ITEM) {
item = (struct attribute_map_item *)entry;
bucket = convert_item_to_bucket(map, item);
} else {
bucket = (struct attribute_map_bucket *)entry;
}
item = create_item(name, name_hash, value);
if (!item) {
return MIE_ERR_NO_MEMORY;
}
b_queue_push_back(&bucket->b_items, &item->i_base.e_entry);
return MIE_SUCCESS;
}
enum mie_status mie_attribute_map_iterator_begin(
struct mie_attribute_map_iterator *it, const struct mie_attribute_map *map)
{
memset(it, 0x0, sizeof *it);
it->_n = b_btree_first(&map->m_entries);
if (!it->_n) {
return MIE_ERR_NO_DATA;
}
struct attribute_map_entry *entry
= b_unbox(struct attribute_map_entry, it->_n, e_node);
struct attribute_map_item *item = NULL;
struct attribute_map_bucket *bucket = NULL;
switch (entry->e_type) {
case ATTRMAP_ENTRY_ITEM:
item = (struct attribute_map_item *)entry;
it->it_name = item->i_name;
it->it_value = item->i_value;
return MIE_SUCCESS;
case ATTRMAP_ENTRY_BUCKET:
bucket = (struct attribute_map_bucket *)entry;
it->_e = b_queue_first(&bucket->b_items);
item = b_unbox(struct attribute_map_item, it->_e, i_base.e_entry);
it->it_name = item->i_name;
it->it_value = item->i_value;
return MIE_SUCCESS;
default:
return MIE_ERR_BAD_STATE;
}
}
enum mie_status mie_attribute_map_iterator_move_next(
struct mie_attribute_map_iterator *it)
{
struct attribute_map_entry *next_entry = NULL;
struct attribute_map_item *next_item = NULL;
struct attribute_map_bucket *next_bucket = NULL;
if (it->_e) {
it->_e = b_queue_next(it->_e);
next_entry = b_unbox(struct attribute_map_entry, it->_e, e_entry);
} else if (it->_n) {
it->_n = b_btree_next(it->_n);
next_entry = b_unbox(struct attribute_map_entry, it->_n, e_node);
} else {
memset(it, 0x0, sizeof *it);
return MIE_ERR_NO_DATA;
}
if (!next_entry) {
memset(it, 0x0, sizeof *it);
return MIE_ERR_NO_DATA;
}
switch (next_entry->e_type) {
case ATTRMAP_ENTRY_ITEM:
next_item = (struct attribute_map_item *)next_entry;
break;
case ATTRMAP_ENTRY_BUCKET:
next_bucket = (struct attribute_map_bucket *)next_item;
it->_e = b_queue_first(&next_bucket->b_items);
next_item = b_unbox(
struct attribute_map_item, it->_e, i_base.e_entry);
break;
default:
memset(it, 0x0, sizeof *it);
return MIE_ERR_BAD_STATE;
}
it->it_name = next_item->i_name;
it->it_value = next_item->i_value;
return MIE_SUCCESS;
}

438
mie/ctx.c
View File

@@ -1,34 +1,38 @@
#include <blue/core/bstr.h>
#include <blue/ds/hashmap.h>
#include <blue/ds/list.h>
#include <blue/ds/string.h>
#include <mie/attribute/attribute-definition.h>
#include <mie/ctx.h>
#include <mie/ir/const.h>
#include <mie/dialect/arith.h>
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
#include <mie/dialect/index.h>
#include <mie/ir/op.h>
#include <mie/trait/trait-definition.h>
#include <mie/trait/trait.h>
#include <mie/type/function.h>
#include <mie/type/storage.h>
#include <mie/type/type-definition.h>
#include <mie/type/type.h>
#include <stdlib.h>
#include <string.h>
struct ctx_int_cache_entry {
b_btree_node i_node;
struct mie_type i_type;
b_btree i_values;
};
#define DIALECT_NS_ID \
MIE_ID(0xa1, 0x35, 0x01, 0x1b, 0xe4, 0x71, 0x46, 0x08, 0x92, 0xd4, \
0xe6, 0x5a, 0x40, 0xba, 0x7f, 0xee)
struct ctx_int_value_cache_entry {
b_btree_node i_node;
struct mie_int i_value;
};
#define TYPE_NS_ID \
MIE_ID(0xf5, 0x4e, 0xc5, 0x8c, 0xc0, 0x1e, 0x48, 0x47, 0xb5, 0xf4, \
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)
#define TRAIT_NS_ID \
MIE_ID(0xeb, 0x02, 0xcc, 0xe5, 0x32, 0x80, 0x4e, 0xc3, 0x84, 0xf3, \
0xc0, 0x07, 0x72, 0xf0, 0x4c, 0xca)
B_BTREE_DEFINE_SIMPLE_INSERT(
struct ctx_int_value_cache_entry, i_node, i_value.i_value,
put_cached_int_value)
B_BTREE_DEFINE_SIMPLE_GET(
struct ctx_int_value_cache_entry, int64_t, i_node, i_value.i_value,
get_cached_int_value)
#define ATTRIBUTE_NS_ID \
MIE_ID(0xc6, 0x94, 0x38, 0x34, 0xdb, 0x08, 0x45, 0xc7, 0xb9, 0x89, \
0x69, 0x82, 0x7a, 0x9d, 0x42, 0xd8)
struct mie_ctx *mie_ctx_create(void)
{
@@ -40,244 +44,292 @@ struct mie_ctx *mie_ctx_create(void)
memset(out, 0x0, sizeof *out);
out->ctx_true = MIE_CONST(mie_ctx_get_int(out, 1, 1));
out->ctx_false = MIE_CONST(mie_ctx_get_int(out, 0, 1));
mie_id dialects_ns = DIALECT_NS_ID;
mie_id_map_init(&out->ctx_dialects, &dialects_ns);
out->ctx_null = malloc(sizeof *out->ctx_null);
if (!out->ctx_null) {
mie_ctx_destroy(out);
return NULL;
}
mie_id types_ns = TYPE_NS_ID;
mie_id_map_init(&out->ctx_types, &types_ns);
mie_value_init(out->ctx_null, MIE_VALUE_NONE);
mie_id traits_ns = TRAIT_NS_ID;
mie_id_map_init(&out->ctx_traits, &traits_ns);
out->ctx_sel_cache = b_hashmap_create(free, free);
out->ctx_string_cache = b_hashmap_create(free, free);
mie_id attributes_ns = ATTRIBUTE_NS_ID;
mie_id_map_init(&out->ctx_attributes, &attributes_ns);
return out;
}
void mie_ctx_destroy(struct mie_ctx *ctx)
bool mie_ctx_resolve_op(const struct mie_ctx *ctx, struct mie_op *op)
{
ctx->ctx_true = NULL;
ctx->ctx_false = NULL;
bool fully_resolved = MIE_TEST_FLAGS(
op->op_flags, MIE_OP_F_OP_RESOLVED | MIE_OP_F_ARG_RESOLVED);
b_btree_node *node = b_btree_first(&ctx->ctx_int_cache);
while (node) {
struct ctx_int_cache_entry *entry
= b_unbox(struct ctx_int_cache_entry, node, i_node);
b_btree_node *next = b_btree_next(node);
b_btree_delete(&ctx->ctx_int_cache, node);
b_btree_node *node2 = b_btree_first(&entry->i_values);
while (node2) {
struct ctx_int_value_cache_entry *value = b_unbox(
struct ctx_int_value_cache_entry, node2, i_node);
b_btree_node *next2 = b_btree_next(node2);
b_btree_delete(&entry->i_values, node2);
free(value);
node2 = next2;
if (fully_resolved) {
return true;
}
free(entry);
node = next;
const char *dialect_name = NULL, *op_name = NULL;
char *dot = strchr(op->op_name, '.');
if (dot) {
*dot = 0;
dialect_name = op->op_name;
op_name = dot + 1;
} else {
dialect_name = NULL;
op_name = op->op_name;
}
const size_t nr_types = sizeof ctx->ctx_types / sizeof ctx->ctx_types[0];
for (size_t i = 0; i < nr_types; i++) {
if (ctx->ctx_types[i]) {
mie_value_destroy(MIE_VALUE(ctx->ctx_types[i]));
ctx->ctx_types[i] = NULL;
}
const struct mie_dialect *dialect = mie_ctx_get_dialect(ctx, dialect_name);
if (dot) {
*dot = '.';
}
if (ctx->ctx_null) {
mie_value_destroy(ctx->ctx_null);
/* dialect_name is no longer valid after this point */
dialect_name = NULL;
if (!dialect) {
return false;
}
b_hashmap_unref(ctx->ctx_sel_cache);
const struct mie_op_definition *op_info
= mie_dialect_get_op(dialect, op_name);
if (!op) {
return false;
}
free(ctx);
op->op_dialect = dialect;
op->op_info = op_info;
free(op->op_name);
op->op_name = NULL;
op->op_flags |= MIE_OP_F_OP_RESOLVED;
return true;
}
struct mie_type *mie_ctx_get_type(struct mie_ctx *ctx, enum mie_type_id type_id)
struct mie_dialect *mie_ctx_get_dialect(const struct mie_ctx *ctx, const char *name)
{
if (type_id == MIE_TYPE_INT) {
b_rope name_rope = B_ROPE_CSTR(name);
mie_id id;
mie_id_init_ns(&id, mie_id_map_get_ns(&ctx->ctx_dialects), &name_rope);
mie_id *target = mie_id_map_get(&ctx->ctx_dialects, &id);
return b_unbox(struct mie_dialect, target, d_id);
}
struct mie_type_definition *mie_ctx_get_type_definition(
const struct mie_ctx *ctx, const char *dialect_name, const char *type_name)
{
b_rope dialect_name_rope = B_ROPE_CSTR(dialect_name);
mie_id id;
mie_id_init_ns(
&id, mie_id_map_get_ns(&ctx->ctx_dialects), &dialect_name_rope);
mie_id *target = mie_id_map_get(&ctx->ctx_dialects, &id);
struct mie_dialect *dialect = b_unbox(struct mie_dialect, target, d_id);
if (!dialect) {
return NULL;
}
if (ctx->ctx_types[type_id]) {
return ctx->ctx_types[type_id];
b_rope type_name_rope = B_ROPE_CSTR(type_name);
mie_id_init_ns(&id, mie_id_map_get_ns(&dialect->d_types), &type_name_rope);
target = mie_id_map_get(&dialect->d_types, &id);
return b_unbox(struct mie_type_definition, target, ty_id);
}
const struct mie_trait_definition *mie_ctx_get_trait_definition(
const struct mie_ctx *ctx, const char *dialect_name, const char *trait_name)
{
b_rope dialect_name_rope = B_ROPE_CSTR(dialect_name);
mie_id id;
mie_id_init_ns(
&id, mie_id_map_get_ns(&ctx->ctx_dialects), &dialect_name_rope);
mie_id *target = mie_id_map_get(&ctx->ctx_dialects, &id);
struct mie_dialect *dialect = b_unbox(struct mie_dialect, target, d_id);
if (!dialect) {
return NULL;
}
struct mie_type *type = mie_type_create();
b_rope trait_name_rope = B_ROPE_CSTR(trait_name);
mie_id_init_ns(&id, mie_id_map_get_ns(&dialect->d_traits), &trait_name_rope);
target = mie_id_map_get(&dialect->d_traits, &id);
return b_unbox(struct mie_trait_definition, target, tr_id);
}
const struct mie_attribute_definition *mie_ctx_get_attribute_definition(
const struct mie_ctx *ctx, const char *dialect_name,
const char *attribute_name)
{
b_rope dialect_name_rope = B_ROPE_CSTR(dialect_name);
mie_id id;
mie_id_init_ns(
&id, mie_id_map_get_ns(&ctx->ctx_dialects), &dialect_name_rope);
mie_id *target = mie_id_map_get(&ctx->ctx_dialects, &id);
struct mie_dialect *dialect = b_unbox(struct mie_dialect, target, d_id);
if (!dialect) {
return NULL;
}
b_rope attribute_name_rope = B_ROPE_CSTR(attribute_name);
mie_id_init_ns(
&id, mie_id_map_get_ns(&dialect->d_attributes),
&attribute_name_rope);
target = mie_id_map_get(&dialect->d_attributes, &id);
return b_unbox(struct mie_attribute_definition, target, a_id);
}
struct mie_type *mie_ctx_get_type(
struct mie_ctx *ctx, const char *dialect_name, const char *type_name)
{
char full_name[256];
snprintf(full_name, sizeof full_name, "%s.%s", dialect_name, type_name);
b_rope full_name_rope = B_ROPE_CSTR(full_name);
mie_id id;
mie_id_init_ns(&id, mie_id_map_get_ns(&ctx->ctx_types), &full_name_rope);
mie_id *target = mie_id_map_get(&ctx->ctx_types, &id);
struct mie_type *type = b_unbox(struct mie_type, target, ty_id);
if (type) {
return type;
}
struct mie_type_definition *type_info
= mie_ctx_get_type_definition(ctx, dialect_name, type_name);
if (!type_info /* || (type_info->ty_flags & MIE_DIALECT_TYPE_PARAMETISED) */) {
/* cannot initialise unknown or parametised types */
return NULL;
}
if (type_info->ty_data_size < sizeof(struct mie_type)) {
/* invalid type info */
return NULL;
}
type = malloc(type_info->ty_data_size);
if (!type) {
return NULL;
}
type->t_id = type_id;
memset(type, 0x0, sizeof *type);
type->ty_def = type_info;
type->ty_name = b_bstr_fmt("%s.%s", dialect_name, type_name);
if (type_info->ty_init) {
type_info->ty_init(type_info, type);
}
mie_id_map_put(&ctx->ctx_types, &type->ty_id, &full_name_rope);
ctx->ctx_types[type_id] = type;
return type;
}
struct mie_value *mie_ctx_get_null(struct mie_ctx *ctx)
const struct mie_trait *mie_ctx_get_trait(
struct mie_ctx *ctx, const char *dialect_name, const char *trait_name)
{
return ctx->ctx_null;
}
char full_name[256];
snprintf(full_name, sizeof full_name, "%s.%s", dialect_name, trait_name);
b_rope full_name_rope = B_ROPE_CSTR(full_name);
struct mie_type *mie_ctx_get_int_type(struct mie_ctx *ctx, unsigned int nr_bits)
{
struct ctx_int_cache_entry *entry
= get_cached_int_type(&ctx->ctx_int_cache, nr_bits);
mie_id id;
mie_id_init_ns(&id, mie_id_map_get_ns(&ctx->ctx_traits), &full_name_rope);
if (entry) {
return &entry->i_type;
mie_id *target = mie_id_map_get(&ctx->ctx_traits, &id);
struct mie_trait *trait = b_unbox(struct mie_trait, target, tr_id);
if (trait) {
return trait;
}
entry = malloc(sizeof *entry);
if (!entry) {
const struct mie_trait_definition *trait_info
= mie_ctx_get_trait_definition(ctx, dialect_name, trait_name);
if (!trait_info /* || (trait_info->ty_flags & MIE_DIALECT_TYPE_PARAMETISED) */) {
/* cannot initialise unknown or parametised traits */
return NULL;
}
memset(entry, 0x0, sizeof *entry);
entry->i_type.t_id = MIE_TYPE_INT;
entry->i_type.t_width = nr_bits;
put_cached_int_type(&ctx->ctx_int_cache, entry);
return &entry->i_type;
}
struct mie_value *mie_ctx_get_bool(struct mie_ctx *ctx, bool val)
{
return MIE_VALUE(val ? ctx->ctx_true : ctx->ctx_false);
}
struct mie_value *mie_ctx_get_int(
struct mie_ctx *ctx, long long val, unsigned int nr_bits)
{
struct ctx_int_cache_entry *entry
= get_cached_int_type(&ctx->ctx_int_cache, nr_bits);
if (!entry) {
entry = malloc(sizeof *entry);
if (!entry) {
if (trait_info->tr_data_size < sizeof(struct mie_trait)) {
/* invalid trait info */
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) {
trait = malloc(trait_info->tr_data_size);
if (!trait) {
return NULL;
}
memset(value, 0x0, sizeof *value);
memset(trait, 0x0, sizeof trait_info->tr_data_size);
mie_const_init(&value->i_value.i_base, &entry->i_type);
value->i_value.i_value = val;
trait->tr_def = trait_info;
trait->tr_name = b_bstr_fmt("%s.%s", dialect_name, trait_name);
put_cached_int_value(&entry->i_values, value);
if (trait_info->tr_init) {
trait_info->tr_init(trait_info, trait);
}
return MIE_VALUE(&value->i_value);
mie_id_map_put(&ctx->ctx_traits, &trait->tr_id, &full_name_rope);
return trait;
}
struct mie_value *mie_ctx_get_selector(struct mie_ctx *ctx, const char *sel)
struct mie_type *mie_ctx_get_storage_type(
struct mie_ctx *ctx, const struct mie_type **parts, size_t nr_parts)
{
b_hashmap_key key = {
.key_data = sel,
.key_size = strlen(sel),
};
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);
const b_hashmap_value *cache_entry
= b_hashmap_get(ctx->ctx_sel_cache, &key);
if (cache_entry) {
return cache_entry->value_data;
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_selector *sel_value = malloc(sizeof *sel_value);
if (!sel_value) {
return NULL;
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]);
}
struct mie_type *sel_type = mie_ctx_get_type(ctx, MIE_TYPE_SELECTOR);
mie_const_init(&sel_value->sel_base, sel_type);
sel_value->sel_value = b_strdup(sel);
key.key_data = sel_value->sel_value;
b_hashmap_value hashmap_value = {
.value_data = sel_value,
.value_size = sizeof *sel_value,
};
b_hashmap_put(ctx->ctx_sel_cache, &key, &hashmap_value);
return MIE_VALUE(sel_value);
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_value *mie_ctx_get_string(struct mie_ctx *ctx, const char *s)
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)
{
b_hashmap_key key = {
.key_data = s,
.key_size = strlen(s),
};
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);
const b_hashmap_value *cache_entry
= b_hashmap_get(ctx->ctx_string_cache, &key);
if (cache_entry) {
return cache_entry->value_data;
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_string *string_value = malloc(sizeof *string_value);
if (!string_value) {
return NULL;
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]);
}
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);
for (size_t i = 0; i < nr_out; i++) {
mie_function_type_add_out_part(new_type, out[i]);
}
key.key_data = string_value->s_value;
b_hashmap_value hashmap_value = {
.value_data = string_value,
.value_size = sizeof *string_value,
};
b_hashmap_put(ctx->ctx_string_cache, &key, &hashmap_value);
return MIE_VALUE(string_value);
}
struct mie_value *mie_ctx_create_array(struct mie_ctx *ctx)
{
struct mie_type *array_type = mie_ctx_get_type(ctx, MIE_TYPE_ARRAY);
struct mie_array *array = malloc(sizeof *array);
if (!array) {
return NULL;
}
memset(array, 0x0, sizeof *array);
mie_const_init(&array->a_base, array_type);
array->a_values = b_list_create();
return MIE_VALUE(array);
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;
}

View File

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

View File

@@ -0,0 +1,218 @@
#include <blue/core/btree.h>
#include <mie/ctx.h>
#include <mie/dialect/builtin.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.a_def
= mie_ctx_get_attribute_definition(ctx, "builtin", "float");
out->e_value.f_type = mie_ctx_get_float_type(ctx, width);
if (!out->e_value.f_type) {
free(out);
return NULL;
}
return out;
}
struct mie_float_cache *mie_float_cache_create(void)
{
struct mie_float_cache *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
memset(out, 0x0, sizeof *out);
return out;
}
void mie_float_cache_destroy(struct mie_float_cache *cache)
{
b_btree_node *cur = b_btree_first(&cache->c_widths);
while (cur) {
b_btree_node *next = b_btree_next(cur);
b_btree_delete(&cache->c_widths, cur);
struct float_width_cache *width_cache
= b_unbox(struct float_width_cache, cur, c_node);
float_width_cache_destroy(width_cache);
cur = next;
}
free(cache);
}
struct mie_float *mie_float_cache_get(
struct mie_float_cache *cache, struct mie_ctx *ctx, double value,
size_t bit_width)
{
struct float_width_cache *width_cache
= get_width_cache(&cache->c_widths, bit_width);
if (!width_cache) {
width_cache = float_width_cache_create(bit_width);
if (!width_cache) {
return NULL;
}
put_width_cache(&cache->c_widths, width_cache);
}
float_key key = {.f = value};
struct float_width_cache_entry *entry
= get_float(&width_cache->c_floats, key);
if (!entry) {
entry = float_width_cache_entry_create(ctx, bit_width, value);
if (!entry) {
return NULL;
}
put_float(&width_cache->c_floats, entry);
}
return &entry->e_value;
}

View File

@@ -0,0 +1,142 @@
#include <blue/core/btree.h>
#include <mie/ctx.h>
#include <mie/dialect/builtin.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_base.a_def
= mie_ctx_get_attribute_definition(ctx, "builtin", "int");
out->e_value.i_val.v_small = value;
out->e_value.i_type = mie_ctx_get_int_type(ctx, width);
if (!out->e_value.i_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;
}

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()

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,85 @@
#include "../float.h"
#include <blue/core/bstr.h>
#include <mie/attribute/attribute-definition.h>
#include <mie/attribute/attribute.h>
#include <mie/ctx.h>
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
#include <mie/macros.h>
#include <mie/parse/parser.h>
#include <mie/print/printer.h>
static enum mie_status print(
const struct mie_attribute *value, struct mie_printer *out)
{
const struct mie_float *float_val = (const struct mie_float *)value;
const struct float_type *float_ty
= (const struct float_type *)float_val->f_type;
if (!(out->p_flags & MIE_PRINT_F_ABBREVIATED)) {
b_stream_write_string(out->p_stream, "#builtin.float<", NULL);
}
switch (float_ty->f_width) {
case MIE_FLOAT_32:
b_stream_write_fmt(
out->p_stream, NULL, "%f : f%zu", float_val->f_val.v_32,
float_ty->f_width);
break;
case MIE_FLOAT_64:
b_stream_write_fmt(
out->p_stream, NULL, "%lf : f%zu",
float_val->f_val.v_64, float_ty->f_width);
break;
default:
b_stream_write_fmt(
out->p_stream, NULL, "NaN : f%zu", float_ty->f_width);
break;
}
if (!(out->p_flags & MIE_PRINT_F_ABBREVIATED)) {
b_stream_write_string(out->p_stream, ">", NULL);
}
return MIE_SUCCESS;
}
static enum mie_status parse(
struct mie_parser *ctx, const struct mie_attribute **out)
{
double value = 0;
struct mie_file_span span;
if (!mie_parser_parse_float(ctx, &value, &span)) {
return false;
}
if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)) {
return false;
}
const struct mie_type *type = NULL;
if (!mie_parser_parse_type(ctx, &type)) {
return false;
}
size_t width = mie_float_type_get_width(type);
if (width == (size_t)-1) {
return false;
}
struct mie_attribute *v
= mie_ctx_get_float(mie_parser_get_mie_ctx(ctx), value, width);
if (!v) {
return false;
}
*out = v;
return true;
}
MIE_ATTRIBUTE_DEFINITION_BEGIN(mie_builtin_float, "float")
MIE_ATTRIBUTE_DEFINITION_STRUCT(struct mie_float);
MIE_ATTRIBUTE_DEFINITION_PRINT(print);
MIE_ATTRIBUTE_DEFINITION_PARSE(parse);
MIE_ATTRIBUTE_DEFINITION_END()

View File

@@ -0,0 +1,76 @@
#include "../int.h"
#include <blue/core/bstr.h>
#include <mie/attribute/attribute-definition.h>
#include <mie/attribute/attribute.h>
#include <mie/ctx.h>
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
#include <mie/macros.h>
#include <mie/parse/parser.h>
#include <mie/print/printer.h>
static enum mie_status print(
const struct mie_attribute *value, struct mie_printer *out)
{
const struct mie_int *int_val = (const struct mie_int *)value;
const struct int_type *int_ty = (const struct int_type *)int_val->i_type;
if (!(out->p_flags & MIE_PRINT_F_ABBREVIATED)) {
b_stream_write_string(out->p_stream, "#builtin.int<", NULL);
}
if (int_ty->i_width <= 64) {
b_stream_write_fmt(
out->p_stream, NULL, "%zu : i%zu",
int_val->i_val.v_small, int_ty->i_width);
} else {
b_stream_write_fmt(
out->p_stream, NULL, "INF : i%zu", int_ty->i_width);
}
if (!(out->p_flags & MIE_PRINT_F_ABBREVIATED)) {
b_stream_write_string(out->p_stream, ">", NULL);
}
return MIE_SUCCESS;
}
static enum mie_status parse(
struct mie_parser *ctx, const struct mie_attribute **out)
{
long long value = 0;
struct mie_file_span span;
if (!mie_parser_parse_int(ctx, &value, &span)) {
return false;
}
if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)) {
return false;
}
const struct mie_type *type = NULL;
if (!mie_parser_parse_type(ctx, &type)) {
return false;
}
size_t width = mie_int_type_get_width(type);
if (width == (size_t)-1) {
return false;
}
struct mie_attribute *v
= mie_ctx_get_int(mie_parser_get_mie_ctx(ctx), value, width);
if (!v) {
return false;
}
*out = v;
return true;
}
MIE_ATTRIBUTE_DEFINITION_BEGIN(mie_builtin_int, "int")
MIE_ATTRIBUTE_DEFINITION_STRUCT(struct mie_int);
MIE_ATTRIBUTE_DEFINITION_PRINT(print);
MIE_ATTRIBUTE_DEFINITION_PARSE(parse);
MIE_ATTRIBUTE_DEFINITION_END()

View File

@@ -0,0 +1,47 @@
#include <mie/attribute/attribute-definition.h>
#include <mie/attribute/attribute.h>
#include <mie/ctx.h>
#include <mie/dialect/builtin.h>
#include <mie/macros.h>
#include <mie/parse/parser.h>
#include <mie/print/printer.h>
static enum mie_status print(
const struct mie_attribute *value, struct mie_printer *out)
{
const struct mie_string *str = (const struct mie_string *)value;
if (out->p_flags & MIE_PRINT_F_ABBREVIATED) {
b_stream_write_fmt(out->p_stream, NULL, "\"%s\"", str->str_val);
} else {
b_stream_write_fmt(
out->p_stream, NULL, "#builtin.string<\"%s\">",
str->str_val);
}
return MIE_SUCCESS;
}
static enum mie_status parse(
struct mie_parser *ctx, const struct mie_attribute **out)
{
b_string *str = mie_parser_get_tempstr(ctx);
struct mie_file_span span;
if (!mie_parser_parse_string(ctx, str, &span)) {
return false;
}
struct mie_attribute *v = mie_ctx_get_string(
mie_parser_get_mie_ctx(ctx), b_string_ptr(str));
if (!v) {
return false;
}
*out = v;
return true;
}
MIE_ATTRIBUTE_DEFINITION_BEGIN(mie_builtin_string, "string")
MIE_ATTRIBUTE_DEFINITION_STRUCT(struct mie_string);
MIE_ATTRIBUTE_DEFINITION_PRINT(print);
MIE_ATTRIBUTE_DEFINITION_PARSE(parse);
MIE_ATTRIBUTE_DEFINITION_END();

View File

@@ -0,0 +1,95 @@
#include <mie/ctx.h>
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
#include <mie/macros.h>
struct builtin_dialect {
struct mie_dialect d_base;
struct mie_string_cache *ctx_strings;
struct mie_int_cache *ctx_ints;
struct mie_float_cache *ctx_floats;
struct mie_index_cache *ctx_indices;
};
static enum mie_status init(struct mie_dialect *d)
{
struct builtin_dialect *dialect = (struct builtin_dialect *)d;
dialect->ctx_strings = mie_string_cache_create();
dialect->ctx_ints = mie_int_cache_create();
dialect->ctx_floats = mie_float_cache_create();
dialect->ctx_indices = mie_index_cache_create();
return MIE_SUCCESS;
}
static enum mie_status cleanup(struct mie_dialect *d)
{
struct builtin_dialect *dialect = (struct builtin_dialect *)d;
mie_string_cache_destroy(dialect->ctx_strings);
mie_int_cache_destroy(dialect->ctx_ints);
mie_float_cache_destroy(dialect->ctx_floats);
mie_index_cache_destroy(dialect->ctx_indices);
return MIE_SUCCESS;
}
struct mie_attribute *mie_ctx_get_int(
struct mie_ctx *ctx, long long val, size_t nr_bits)
{
struct builtin_dialect *dialect
= (struct builtin_dialect *)mie_ctx_get_dialect(ctx, "builtin");
if (!dialect) {
return NULL;
}
return (struct mie_attribute *)mie_int_cache_get(
dialect->ctx_ints, ctx, val, nr_bits);
}
struct mie_attribute *mie_ctx_get_float(
struct mie_ctx *ctx, double val, size_t nr_bits)
{
struct builtin_dialect *dialect
= (struct builtin_dialect *)mie_ctx_get_dialect(ctx, "builtin");
if (!dialect) {
return NULL;
}
return (struct mie_attribute *)mie_float_cache_get(
dialect->ctx_floats, ctx, val, nr_bits);
}
struct mie_attribute *mie_ctx_get_string(struct mie_ctx *ctx, const char *s)
{
struct builtin_dialect *dialect
= (struct builtin_dialect *)mie_ctx_get_dialect(ctx, "builtin");
if (!dialect) {
return NULL;
}
return (struct mie_attribute *)mie_string_cache_get(
dialect->ctx_strings, ctx, s);
}
struct mie_attribute *mie_ctx_get_index(struct mie_ctx *ctx, size_t val)
{
struct builtin_dialect *dialect
= (struct builtin_dialect *)mie_ctx_get_dialect(ctx, "builtin");
if (!dialect) {
return NULL;
}
return (struct mie_attribute *)mie_index_cache_get(
dialect->ctx_indices, ctx, val);
}
MIE_DIALECT_BEGIN(mie_builtin, struct builtin_dialect, "builtin")
MIE_DIALECT_INIT(init);
MIE_DIALECT_CLEANUP(cleanup);
MIE_DIALECT_ADD_TYPE(mie_builtin_string);
MIE_DIALECT_ADD_TYPE(mie_builtin_int);
MIE_DIALECT_ADD_TYPE(mie_builtin_float);
MIE_DIALECT_ADD_TYPE(mie_builtin_index);
MIE_DIALECT_ADD_ATTRIBUTE(mie_builtin_string);
MIE_DIALECT_ADD_ATTRIBUTE(mie_builtin_int);
MIE_DIALECT_ADD_ATTRIBUTE(mie_builtin_float);
MIE_DIALECT_ADD_TRAIT(mie_builtin_isolated_from_above);
MIE_DIALECT_END()

View File

@@ -0,0 +1,12 @@
#ifndef _BUILTIN_FLOAT_H_
#define _BUILTIN_FLOAT_H_
#include <mie/attribute/attribute.h>
#include <mie/type/type.h>
struct float_type {
struct mie_type f_base;
size_t f_width;
};
#endif

View File

@@ -0,0 +1,81 @@
#include <blue/core/btree.h>
#include <mie/ctx.h>
#include <mie/dialect/builtin.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;
}
memset(out, 0x0, sizeof *out);
out->e_value.i_base.a_def
= mie_ctx_get_attribute_definition(ctx, "builtin", "index");
out->e_value.i_value = val;
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;
}

12
mie/dialect/builtin/int.h Normal file
View File

@@ -0,0 +1,12 @@
#ifndef _BUILTIN_INT_H_
#define _BUILTIN_INT_H_
#include <mie/attribute/attribute.h>
#include <mie/type/type.h>
struct int_type {
struct mie_type i_base;
size_t i_width;
};
#endif

View File

@@ -0,0 +1,80 @@
#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.a_def
= mie_ctx_get_attribute_definition(ctx, "builtin", "string");
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,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,80 @@
#include "../float.h"
#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/print/printer.h>
#include <mie/type/type-definition.h>
#include <mie/type/type.h>
struct mie_type *mie_ctx_get_float_type(struct mie_ctx *ctx, size_t bit_width)
{
struct mie_type_definition *type_info
= mie_ctx_get_type_definition(ctx, "builtin", "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("builtin.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_float_type_get_width(const struct mie_type *type)
{
if (strcmp(type->ty_def->ty_parent->d_name, "builtin") != 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 *ty, struct mie_printer *out)
{
const struct float_type *float_type = (const struct float_type *)ty;
b_stream_write_fmt(
out->p_stream, NULL,
(out->p_flags & MIE_PRINT_F_ABBREVIATED) ? "f%zu" : "!builtin.float<%zu>",
float_type->f_width);
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, const struct mie_type **out)
{
return MIE_SUCCESS;
}
MIE_TYPE_DEFINITION_BEGIN(mie_builtin_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_END()

View File

@@ -0,0 +1,31 @@
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
#include <mie/macros.h>
#include <mie/print/printer.h>
#include <mie/type/type-definition.h>
#include <mie/type/type.h>
struct index_type {
struct mie_type i_base;
};
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 *ty, struct mie_printer *out)
{
b_stream_write_string(
out->p_stream,
(out->p_flags & MIE_PRINT_F_ABBREVIATED) ? "index" : "!builtin.index",
NULL);
return MIE_SUCCESS;
}
MIE_TYPE_DEFINITION_BEGIN(mie_builtin_index, "index")
MIE_TYPE_DEFINITION_STRUCT(struct index_type);
MIE_TYPE_DEFINITION_INIT(type_init);
MIE_TYPE_DEFINITION_PRINT(print);
MIE_TYPE_DEFINITION_END()

View File

@@ -0,0 +1,81 @@
#include "../int.h"
#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/print/printer.h>
#include <mie/type/type-definition.h>
#include <mie/type/type.h>
struct mie_type *mie_ctx_get_int_type(struct mie_ctx *ctx, size_t bit_width)
{
struct mie_type_definition *type_info
= mie_ctx_get_type_definition(ctx, "builtin", "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("builtin.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_int_type_get_width(const struct mie_type *type)
{
if (strcmp(type->ty_def->ty_parent->d_name, "builtin") != 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 *ty, struct mie_printer *out)
{
const struct int_type *int_type = (const struct int_type *)ty;
b_stream_write_fmt(
out->p_stream, NULL,
(out->p_flags & MIE_PRINT_F_ABBREVIATED) ? "i%zu"
: "!builtin.int<%zu>",
int_type->i_width);
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, const struct mie_type **out)
{
return MIE_SUCCESS;
}
MIE_TYPE_DEFINITION_BEGIN(mie_builtin_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_END()

View File

@@ -0,0 +1,25 @@
#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/print/printer.h>
#include <mie/type/type-definition.h>
#include <mie/type/type.h>
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 *ty, struct mie_printer *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_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, struct mie_dialect, "cf")
MIE_DIALECT_ADD_OP(mie_cf_br);
MIE_DIALECT_ADD_OP(mie_cf_br_cond);
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_cf_br_cond, "br-cond")
MIE_OP_DEFINITION_PRINT(print);
MIE_OP_DEFINITION_PARSE(parse);
MIE_OP_DEFINITION_END()

18
mie/dialect/cf/op/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()

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

@@ -0,0 +1,80 @@
#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)
#define TRAIT_NS_ID \
MIE_ID(0x5a, 0x11, 0x68, 0x8e, 0x21, 0x1d, 0x4d, 0x5f, 0xb8, 0x6b, \
0x39, 0x73, 0xb0, 0x1f, 0xce, 0xf7)
#define ATTRIBUTE_NS_ID \
MIE_ID(0x86, 0x76, 0xcb, 0xfb, 0xc8, 0xe5, 0x40, 0x7d, 0xa3, 0x84, \
0x93, 0xe3, 0xa5, 0x29, 0x74, 0xfe)
struct mie_dialect *mie_dialect_create(
struct mie_ctx *ctx, const char *name, size_t size)
{
if (size < sizeof(struct mie_dialect)) {
return NULL;
}
struct mie_dialect *out = malloc(size);
if (!out) {
return NULL;
}
memset(out, 0x0, size);
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);
mie_id trait_ns = TRAIT_NS_ID;
mie_id_map_init(&out->d_traits, &trait_ns);
mie_id attribute_ns = ATTRIBUTE_NS_ID;
mie_id_map_init(&out->d_attributes, &attribute_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);
}

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

@@ -0,0 +1,7 @@
#include <mie/dialect/dialect.h>
#include <mie/ir/op-definition.h>
#include <mie/macros.h>
MIE_DIALECT_BEGIN(mie_func, struct mie_dialect, "func")
MIE_DIALECT_ADD_OP(mie_func_func);
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_func_func, "func")
MIE_OP_DEFINITION_PRINT(print);
MIE_OP_DEFINITION_PARSE(parse);
MIE_OP_DEFINITION_END()

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

@@ -0,0 +1,10 @@
#include <mie/ctx.h>
#include <mie/dialect/dialect.h>
#include <mie/dialect/index.h>
#include <mie/macros.h>
#include <mie/print/printer.h>
#include <mie/type/type-definition.h>
#include <mie/type/type.h>
MIE_DIALECT_BEGIN(mie_index, struct mie_dialect, "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, struct mie_dialect, "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/op/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()

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()

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

@@ -0,0 +1,9 @@
#include <mie/dialect/dialect.h>
#include <mie/macros.h>
#include <mie/type/type-definition.h>
MIE_DIALECT_BEGIN(mie_ptr, struct mie_dialect, "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()

View File

@@ -0,0 +1,17 @@
#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 *ty, struct mie_printer *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_END()

18
mie/dialect/scf/op/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/op/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()

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()

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, struct mie_dialect, "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()

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, struct mie_dialect, "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

@@ -0,0 +1,29 @@
#ifndef MIE_ATTRIBUTE_ATTRIBUTE_DEFINITION_H_
#define MIE_ATTRIBUTE_ATTRIBUTE_DEFINITION_H_
#include <mie/id.h>
struct mie_dialect;
struct mie_attribute;
struct mie_parser;
struct mie_printer;
struct mie_attribute_definition {
mie_id a_id;
struct mie_dialect *a_parent;
char *a_name;
size_t a_data_size;
void (*a_init)(struct mie_attribute *);
void (*a_cleanup)(struct mie_attribute *);
enum mie_status (*a_print)(
const struct mie_attribute *, struct mie_printer *);
enum mie_status (*a_parse)(
struct mie_parser *, const struct mie_attribute **);
};
MIE_API struct mie_attribute_definition *mie_attribute_definition_create(
struct mie_dialect *parent, const char *name);
#endif

View File

@@ -0,0 +1,44 @@
#ifndef MIE_ATTRIBUTE_ATTRIBUTE_MAP_H_
#define MIE_ATTRIBUTE_ATTRIBUTE_MAP_H_
#include <blue/core/btree.h>
#include <mie/misc.h>
#include <mie/status.h>
struct b_queue_entry;
struct mie_attribute_map {
b_btree m_entries;
};
enum mie_attribute_map_flags {
MIE_ATTRMAP_F_REPLACE = 0x01u,
};
struct mie_attribute_map_iterator {
const char *it_name;
const struct mie_attribute *it_value;
b_btree_node *_n;
struct b_queue_entry *_e;
};
MIE_API void mie_attribute_map_init(struct mie_attribute_map *map);
MIE_API void mie_attribute_map_cleanup(struct mie_attribute_map *map);
static inline bool mie_attribute_map_empty(const struct mie_attribute_map *map)
{
return b_btree_empty(&map->m_entries);
}
MIE_API const struct mie_attribute *mie_attribute_map_get(
const struct mie_attribute_map *map, const char *name);
MIE_API enum mie_status mie_attribute_map_put(
struct mie_attribute_map *map, const char *name,
const struct mie_attribute *value, enum mie_attribute_map_flags flags);
MIE_API enum mie_status mie_attribute_map_iterator_begin(
struct mie_attribute_map_iterator *it, const struct mie_attribute_map *map);
MIE_API enum mie_status mie_attribute_map_iterator_move_next(
struct mie_attribute_map_iterator *it);
#endif

View File

@@ -0,0 +1,10 @@
#ifndef MIE_ATTRIBUTE_ATTRIBUTE_H_
#define MIE_ATTRIBUTE_ATTRIBUTE_H_
struct mie_attribute_definition;
struct mie_attribute {
const struct mie_attribute_definition *a_def;
};
#endif

View File

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

View File

@@ -0,0 +1,14 @@
#ifndef MIE_DIALECT_ARITH_H_
#define MIE_DIALECT_ARITH_H_
#include <mie/attribute/attribute.h>
#include <mie/misc.h>
#include <stddef.h>
#include <stdint.h>
struct mie_ctx;
struct mie_dialect;
MIE_API struct mie_dialect *mie_arith_dialect_create(struct mie_ctx *ctx);
#endif

View File

@@ -0,0 +1,98 @@
#ifndef MIE_DIALECT_BUILTIN_H_
#define MIE_DIALECT_BUILTIN_H_
#include <blue/ds/string.h>
#include <mie/attribute/attribute.h>
#include <mie/misc.h>
struct mie_dialect;
struct mie_ctx;
struct mie_int_type;
struct mie_float_type;
enum mie_float_width {
MIE_FLOAT_32 = 32,
MIE_FLOAT_64 = 64,
};
struct mie_string {
struct mie_attribute str_base;
char *str_val;
size_t str_len;
};
struct mie_int {
struct mie_attribute i_base;
const struct mie_type *i_type;
union {
int64_t v_small;
struct {
long *a_parts;
size_t a_nr_parts;
} v_arbitrary;
} i_val;
};
struct mie_float {
struct mie_attribute f_base;
const struct mie_type *f_type;
union {
float v_32;
double v_64;
} f_val;
};
struct mie_index {
struct mie_attribute i_base;
size_t i_value;
};
struct mie_int_cache;
struct mie_float_cache;
struct mie_string_cache;
struct mie_index_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);
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);
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);
MIE_API struct mie_attribute *mie_ctx_get_int(
struct mie_ctx *ctx, long long val, size_t nr_bits);
MIE_API struct mie_attribute *mie_ctx_get_float(
struct mie_ctx *ctx, double val, size_t nr_bits);
MIE_API struct mie_attribute *mie_ctx_get_string(
struct mie_ctx *ctx, const char *s);
MIE_API struct mie_attribute *mie_ctx_get_index(struct mie_ctx *ctx, size_t val);
MIE_API struct mie_type *mie_ctx_get_int_type(struct mie_ctx *ctx, size_t bit_width);
MIE_API struct mie_type *mie_ctx_get_float_type(
struct mie_ctx *ctx, size_t bit_width);
MIE_API size_t mie_int_type_get_width(const struct mie_type *type);
MIE_API size_t mie_float_type_get_width(const struct mie_type *type);
#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,44 @@
#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;
/* map of struct mie_attribute_definition */
struct mie_id_map d_attributes;
enum mie_status (*d_cleanup)(struct mie_dialect *);
};
MIE_API struct mie_dialect *mie_dialect_create(
struct mie_ctx *ctx, const char *name, size_t size);
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);
MIE_API const struct mie_attribute_definition *mie_dialect_get_attribute(
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,14 @@
#ifndef MIE_DIALECT_INDEX_H_
#define MIE_DIALECT_INDEX_H_
#include <mie/attribute/attribute.h>
#include <mie/misc.h>
#include <stddef.h>
#include <stdint.h>
struct mie_ctx;
struct mie_dialect;
MIE_API struct mie_dialect *mie_index_dialect_create(struct mie_ctx *ctx);
#endif

View File

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

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

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,74 @@
#ifndef MIE_ARITH_H_
#define MIE_ARITH_H_
#ifndef MIE_IR_OP_H_
#define MIE_IR_OP_H_
#include <mie/ir/instr.h>
#include "mie/vector.h"
struct mie_binary_op {
struct mie_instr op_base;
struct mie_type *op_type;
struct mie_value *op_left;
struct mie_value *op_right;
#include <mie/attribute/attribute-map.h>
#include <mie/ir/register.h>
#include <mie/misc.h>
#include <mie/name.h>
#include <mie/parse/file-span.h>
struct mie_type;
struct mie_value;
struct mie_block;
struct mie_region;
struct mie_dialect;
struct mie_op_definition;
enum mie_op_flags {
MIE_OP_F_OP_RESOLVED = 0x01u,
MIE_OP_F_ARG_RESOLVED = 0x02u,
MIE_OP_F_SUCCESSOR_RESOLVED = 0x04u,
};
struct mie_op_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);
struct mie_attribute_map 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

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

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