Compare commits

104 Commits

Author SHA1 Message Date
ef858dd061 meta: replace bluelib references with fx 2026-03-16 13:59:14 +00:00
73b4b77816 doc: sample: update sample ir files 2026-03-16 12:09:37 +00:00
a29779aa83 tool: diag: output formatting fixes 2026-03-16 12:09:11 +00:00
778835032d tool: validate: resolve ops and references; report any diagnostics 2026-03-16 12:08:41 +00:00
540c8e6d8b tool: optimise: add flags to control ir output format 2026-03-16 12:07:36 +00:00
1c44c3e5c8 tool: optimise: resolve ops; report any diagnostic messages 2026-03-16 12:07:17 +00:00
28b72cbf1e tool: add resolution helper functions 2026-03-16 12:05:58 +00:00
8c9cab7408 pass: convert-scf-to-cf: implement for-loop rewriting 2026-03-16 12:05:14 +00:00
4d315d6abe pass: handle null items in schedule_passes 2026-03-16 12:04:48 +00:00
a99610ac02 dialect: select: update parse callback prototype 2026-03-16 12:04:00 +00:00
6bebcbfdf6 scf: implement print/parse for for, if, yield 2026-03-16 12:03:02 +00:00
ab7ccfcfef dialect: meta: update parse callback prototype 2026-03-16 12:02:45 +00:00
a27375ac2e func: implement print/parse for func, return 2026-03-16 12:02:19 +00:00
ef4349b732 cf: implement print/parse for br, br-cond 2026-03-16 12:01:50 +00:00
639652b083 arith: implement print/parse for addf, addi, cmpi, constant 2026-03-16 12:00:59 +00:00
fc610a6605 memref: implement print/parse for memref.load() 2026-03-16 12:00:10 +00:00
f88d537043 ptr: update parse callback prototypes 2026-03-16 11:59:30 +00:00
fe1e7d81c4 builtin: add diag definitions and parser callbacks 2026-03-16 11:58:56 +00:00
000a9c2671 vector: add a macro to forward a vector-ref to another function 2026-03-16 11:57:48 +00:00
8a50445dd8 memref: move memref type to builtin dialect 2026-03-16 11:56:51 +00:00
81fde5d43b rewrite: add functions to add new args to ops 2026-03-16 11:55:28 +00:00
06101b6316 print: add nullptr handling 2026-03-16 11:54:55 +00:00
7b729c49fa type: add functions to determine what kind of type a type is 2026-03-16 11:54:07 +00:00
51c8d2744c parse: generate diags to report parse errors 2026-03-16 11:53:35 +00:00
2858323eca diag: add function to append a simple string to a diag 2026-03-16 11:51:14 +00:00
fed4cad7e8 id: add missing functions to header 2026-03-16 11:41:41 +00:00
a107964e2b ir: add some manipulation functions 2026-03-16 11:38:37 +00:00
6abdf8f993 mie: implement block dominance calculation using lengauer-tarjan algorithm 2026-02-01 10:33:36 +00:00
870b2bfbac mie: memref: add load op 2026-02-01 10:33:03 +00:00
5344c02b48 mie: builtin: add some diagnostics for value resolution 2026-02-01 10:25:43 +00:00
4a4f0c483a mie: ir: op: remove redundant op_dialect pointer 2026-02-01 10:24:06 +00:00
f37ee90b0e mie: func: add function-like trait 2026-01-31 23:29:17 +00:00
3f901ed83a doc: update type prefix in sample graph files 2026-01-27 20:52:35 +00:00
b28efa2d08 tool: optimise: update mie_lex usage 2026-01-27 20:51:31 +00:00
5835d25679 tool: validate: if parse fails, print any diagnostic messages 2026-01-27 20:51:18 +00:00
d4fbd75a59 tool: implement a diagnostic message printer 2026-01-27 20:48:04 +00:00
0b1d4697a2 tool: ctx-dump: show registered diag classes/messages 2026-01-27 20:47:10 +00:00
cd49417972 mie: add a system for registering and producing detailed diagnostic messages 2026-01-27 20:46:44 +00:00
bd5ba9e9fd mie: lex: move file i/o handling to a separate struct 2026-01-27 20:46:08 +00:00
b5fa40d4d8 mie: tool: add command to run optimisations on an input IR file 2026-01-25 15:12:07 +00:00
a67e4b6688 mie: tool: validate: remove functionality that was moved to internal subcommands 2026-01-25 15:11:06 +00:00
5873326138 mie: tool: split internal command into several different subcommands 2026-01-25 15:10:23 +00:00
00152cac56 mie: convert-scf-to-cf: implement if match/rewrite using new interface 2026-01-25 15:08:19 +00:00
287983fa95 mie: implement a full rewriter with pattern-matching and rewriting support
the new rewriter interface supports running patterns over an Op's children
matching Ops that conform to a pattern, and rewriting Ops in arbitrary ways.
2026-01-25 15:06:43 +00:00
8cdbf5389c mie: pass: manager: update mie_walker usage 2026-01-25 15:05:44 +00:00
00c7c3d5ea mie: parse: update parse_region_list to use new Op->Region linking mechanism 2026-01-25 15:05:18 +00:00
9e546ee32f mie: name: fix crash when destroying a zeroed mie_name 2026-01-25 15:04:37 +00:00
00ba3a3d87 mie: print: implement exception-printing of resolved, but null, op args
this is to make it easier to spot mistakes made when modifying IR.
2026-01-25 15:02:48 +00:00
d44bc8c5c0 mie: ir: op: fix crash when checking if an unresolved op is isolated 2026-01-25 15:02:17 +00:00
a22e95d88d mie: ir: op: add functions to check what an Op is, and add successors with args 2026-01-25 15:01:41 +00:00
0a791fdfb2 mie: dialect: update Op emitter functions to use mie_emitter 2026-01-25 15:00:37 +00:00
fe511011ec mie: ir: walk: implement non-recursive traversal
struct mie_walker is now a public struct that can (and should) be stack
allocated. this means that non-recursive traversal of an Op's children
uses no dynamically allocated memory.
2026-01-25 14:58:51 +00:00
e8534f8d70 mie: ir: Op->Region, Region->Block, and Block->Op lists are now b_queues rather than mie_vectors
this change has two key benefits:
 1. we no longer need to allocate large contigious buffers for Regions with lots
    of Blocks, or Blocks with lots of Ops.
 2. this simplifies re-arranging, inserting, and moving parts of the IR structure.
2026-01-25 14:56:47 +00:00
bf8c966c03 mie: ir: builder: add mie_emitter support 2026-01-25 14:53:24 +00:00
7d30e8f3ff mie: ir: add an emitter interface for emitting IR constructs
mie_emitter can be inherited from by any structure that supports
emitting IR constructs like Ops and Blocks. Dialect Op emitter
functions can wrap mie_emitter to simplify emitting specific Ops,
and these functions can then be used with any struct that inherits
from mie_emitter.
2026-01-25 14:51:36 +00:00
e9d2c0fbc7 mie: scf: implement lots of print and emit functions 2026-01-23 23:33:16 +00:00
a710ef0b24 mie: func: implement lots of print and emit functions 2026-01-23 23:22:57 +00:00
0277931ca1 mie: builtin: implement lots of print and emit functions 2026-01-23 23:22:47 +00:00
ac7860b6bd mie: ir: rewrite: add pattern and rewriter interface 2026-01-23 23:21:42 +00:00
29984307aa mie: pass: support filtering passes to any op of a given dialect 2026-01-23 23:21:16 +00:00
ac96248d7e mie: ir: builder: support adding names to non-isolated op regions 2026-01-23 23:19:29 +00:00
593eda2797 mie: trait: table: fix get_unique() unboxing the wrong pointer 2026-01-23 23:17:39 +00:00
d0ac8a9fed mie: ir: walk: re-implement walker with a stack rather than a queue 2026-01-23 22:50:05 +00:00
89ebbcc462 mie: parse: replace all op-creation with mie_block_add_op calls 2026-01-23 22:42:39 +00:00
554a1e7342 mie: ir: op: keep a pointer to the block that contains the op 2026-01-23 22:42:05 +00:00
6d1e308ff1 mie: ir: op: only create a name map if the op is isolated-from-above 2026-01-23 22:41:03 +00:00
58bd336eb8 mie: dialect: add emitter functions for various ops 2026-01-21 14:42:22 +00:00
008966e046 mie: ir: add ir builder interface 2026-01-21 14:40:22 +00:00
83343a5eea mie: ir: block: add function to create block parameters 2026-01-21 14:39:56 +00:00
76166167c9 mie: builtin: improve int attribute print callback 2026-01-21 14:39:12 +00:00
f6f6131f52 mie: builtin: add function to create mie_type_attr instances 2026-01-21 14:38:01 +00:00
33f9ccd871 mie: ir: register: implement moving and cleanup of mie_register_use 2026-01-21 14:36:24 +00:00
0c4ebe7f39 mie: ctx: add function to create ops 2026-01-21 14:17:43 +00:00
72de4ce845 mie: ir: op: add function to add op arguments 2026-01-21 14:15:02 +00:00
937dc57c4e tool: validate: resolve op definitions; run test pass 2026-01-19 14:00:25 +00:00
b8c0d139a8 vim: update type and attribute prefixes 2026-01-19 14:00:04 +00:00
abf43a9022 doc: update ir sample files 2026-01-19 13:59:43 +00:00
4700ce7778 build: bump minimum CMake version 2026-01-19 13:59:14 +00:00
95c51045b6 meta: update clang-format config 2026-01-19 13:59:00 +00:00
e62c9c4775 mie: ir: add stub rewriter interface 2026-01-19 13:58:24 +00:00
a97678a1c2 mie: add stub memref dialect 2026-01-19 13:58:12 +00:00
5e13824706 mie: add parent pointers to region and block; two-way link between a register and its users 2026-01-19 13:57:25 +00:00
da140ed0d1 mie: parse: remove duplicate sub-parsers in parse_generic_op 2026-01-19 13:52:21 +00:00
cb3d37043c mie: update b_bstr usage 2026-01-19 13:51:27 +00:00
55161cd6c8 mie: re-implement vectors of blocks and registers using vector move callbacks
vector move callbacks allow mie_name instances to be stored in movable memory,
as the internal bst pointers can now be fixed during vector resize operations.
2026-01-18 22:58:17 +00:00
759aaf9fd8 mie: vector: add copy- and move-constructor support 2026-01-18 21:52:39 +00:00
04af390fe8 mie: pass: add a group of builtin passes
right now, the group only contains a single pass: prefix-func-with-underscore.
this is a test pass that visits instances of func.func and prepends
an underscore to the func's symbol name.
2026-01-18 21:19:15 +00:00
0add39f304 mie: implement a pass system
passes allow defined units of functionality to be applied
on an IR structure. the pass manager can be used to schedule
passes at certain depths of the IR structure and/or on or within
certain types of ops (or ops that have certain traits/interfaces).
2026-01-18 21:17:44 +00:00
429ec770b5 mie: attribute: map: implement REPLACE flag in put() 2026-01-18 21:16:28 +00:00
092c9969cf mie: add NAME_EXISTS status code 2026-01-18 21:16:10 +00:00
6fcc3c8edd mie: ir: op: add functions to query a certain trait or interface 2026-01-18 21:14:50 +00:00
d335cd9823 mie: ir: walk: walk is no longer recursive by default 2026-01-18 20:27:55 +00:00
c014895051 mie: func: add return op 2026-01-17 10:31:52 +00:00
76477be5bd mie: arith: add cmpi and constant ops 2026-01-17 10:31:39 +00:00
ee9e2d3050 mie: arith: implement op printer callbacks 2026-01-17 10:31:08 +00:00
e5ecdd40e8 mie: cf: implement op printer callbacks 2026-01-17 10:29:47 +00:00
c410e0a6e3 mie: builtin: implement op printer callbacks 2026-01-17 10:28:51 +00:00
3ba20e5ed4 mie: print: add more functions to printer interface 2026-01-17 10:27:23 +00:00
f19dfaa050 mie: ctx: fix mie_ctx_resolve_op not checking op-definition pointer properly 2026-01-17 10:26:37 +00:00
2869e98556 mie: builtin: add function to get int/float value from an attribute 2026-01-17 10:25:49 +00:00
b289c6e2de mie: ir: op: add function to get type from mie_op_arg 2026-01-17 10:22:38 +00:00
fd72d217f6 mie: ir: implement a walker interface for traversing ir structures 2026-01-17 10:21:58 +00:00
e1f7f46d3e mie: ir: replace mie_module ir object with a builtin generic "module" op
the builtin.module op behaves exactly like any other op, and is designed
to be a container for other ops of any type. it can be used as the
top-level container for other ops (other top-level containers can be used
instead).

this also changes the file format. now, an ir file can only contain a
single top-level op. any other ops in the ir must be contained
directly or indirectly by this top-level op.
2026-01-16 10:01:19 +00:00
65905bc55b mie: implement support for custom op print formats 2026-01-15 14:20:13 +00:00
173 changed files with 12337 additions and 2124 deletions

View File

@@ -1,64 +1,6 @@
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
@@ -114,61 +56,5 @@ AttributeMacros:
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"
MacroBlockBegin: "MIE_.*_BEGIN"
MacroBlockEnd: "MIE_.*_END"

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.14)
project(mie C)
if (WIN32)
@@ -24,10 +24,10 @@ if (NOT MIE_STATIC)
endif ()
if (MIE_STATIC)
set(Bluelib_STATIC TRUE)
set(FX_STATIC TRUE)
endif ()
find_package(Bluelib REQUIRED)
find_package(FX REQUIRED)
add_subdirectory(mie)
add_subdirectory(tool)

View File

@@ -1,189 +0,0 @@
#[=======================================================================[.rst:
FindBluelib
------------
Find the Bluelib library and header directories
Imported Targets
^^^^^^^^^^^^^^^^
This module defines the following :prop_tgt:`IMPORTED` target:
``Bluelib::Bluelib``
The Bluelib library, if found
Result Variables
^^^^^^^^^^^^^^^^
This module will set the following variables in your project:
``Bluelib_FOUND``
true if the Bluelib C headers and libraries were found
``Bluelib_INCLUDE_DIR``
directories containing the Bluelib C headers.
``Bluelib_LIBRARY``
the C library to link against
Hints
^^^^^
The user may set the environment variable ``Bluelib_PREFIX`` to the root
directory of a Bluelib library installation.
#]=======================================================================]
set (Bluelib_SEARCH_PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr/local/share
/usr
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
/opt
${Bluelib_PREFIX}
$ENV{Bluelib_PREFIX})
if (Bluelib_STATIC)
set(_lib_suffix "-s")
endif ()
set(supported_components Core Ds Term Cmd Io Serial Compress)
set(components ${Bluelib_FIND_COMPONENTS})
string(REPLACE ";" ", " supported_components_string_list "${supported_components}")
if (NOT components)
set(components ${supported_components})
endif ()
set(required_vars)
foreach (component ${components})
if (NOT "${component}" IN_LIST supported_components)
message(FATAL_ERROR "'${component}' is not a valid Bluelib module.\nSupported modules: ${supported_components_string_list}")
endif ()
string(TOLOWER ${component} header_name)
set(lib_name ${header_name}${_lib_suffix})
if (NOT Bluelib_${component}_INCLUDE_DIR)
find_path(Bluelib_${component}_INCLUDE_DIR
NAMES blue/${header_name}.h ${Bluelib_FIND_ARGS}
PATH_SUFFIXES include
PATHS ${Bluelib_SEARCH_PATHS})
endif ()
if (NOT Bluelib_${component}_LIBRARY)
find_library(Bluelib_${component}_LIBRARY
NAMES blue-${lib_name} ${Bluelib_FIND_ARGS}
PATH_SUFFIXES lib
PATHS ${Bluelib_SEARCH_PATHS})
else ()
# on Windows, ensure paths are in canonical format (forward slahes):
file(TO_CMAKE_PATH "${Bluelib_${component}_LIBRARY}" Bluelib_${component}_LIBRARY)
endif()
list(APPEND required_vars Bluelib_${component}_INCLUDE_DIR Bluelib_${component}_LIBRARY)
endforeach (component)
unset(Bluelib_FIND_ARGS)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Bluelib
REQUIRED_VARS ${required_vars})
if (Bluelib_FOUND)
set(created_targets)
foreach (component ${components})
string(TOLOWER ${component} header_name)
set(lib_name ${header_name}${_lib_suffix})
if(NOT TARGET Bluelib::${component})
add_library(Bluelib::${component} UNKNOWN IMPORTED)
set_target_properties(Bluelib::${component} PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${Bluelib_${component}_INCLUDE_DIR}")
target_compile_definitions(Bluelib::${component} INTERFACE _CRT_SECURE_NO_WARNINGS=1)
if (Bluelib_STATIC)
target_compile_definitions(Bluelib::${component} INTERFACE BLUELIB_STATIC=1)
endif ()
set_target_properties(Bluelib::${component} PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
IMPORTED_LOCATION "${Bluelib_${component}_LIBRARY}")
set(created_targets ${created_targets} ${component})
endif ()
endforeach (component)
foreach (component ${created_targets})
if ("${component}" STREQUAL "Ds")
if (NOT TARGET Bluelib::Core)
message(FATAL_ERROR "Bluelib: Module 'Ds' depends on 'Core', which was not specified in find_package()")
endif ()
target_link_libraries(Bluelib::Ds INTERFACE Bluelib::Core)
endif ()
if ("${component}" STREQUAL "Term")
if (NOT TARGET Bluelib::Core)
message(FATAL_ERROR "Bluelib: Module 'Term' depends on 'Core', which was not specified in find_package()")
endif ()
if (NOT TARGET Bluelib::Ds)
message(FATAL_ERROR "Bluelib: Module 'Term' depends on 'Ds', which was not specified in find_package()")
endif ()
target_link_libraries(Bluelib::Term INTERFACE Bluelib::Core Bluelib::Ds)
endif ()
if ("${component}" STREQUAL "Serial")
if (NOT TARGET Bluelib::Core)
message(FATAL_ERROR "Bluelib: Module 'Serial' depends on 'Core', which was not specified in find_package()")
endif ()
if (NOT TARGET Bluelib::Ds)
message(FATAL_ERROR "Bluelib: Module 'Serial' depends on 'Ds', which was not specified in find_package()")
endif ()
target_link_libraries(Bluelib::Serial INTERFACE Bluelib::Core Bluelib::Ds)
endif ()
if ("${component}" STREQUAL "Cmd")
if (NOT TARGET Bluelib::Core)
message(FATAL_ERROR "Bluelib: Module 'Cmd' depends on 'Core', which was not specified in find_package()")
endif ()
if (NOT TARGET Bluelib::Ds)
message(FATAL_ERROR "Bluelib: Module 'Cmd' depends on 'Ds', which was not specified in find_package()")
endif ()
if (NOT TARGET Bluelib::Term)
message(FATAL_ERROR "Bluelib: Module 'Cmd' depends on 'Term', which was not specified in find_package()")
endif ()
target_link_libraries(Bluelib::Cmd INTERFACE Bluelib::Core Bluelib::Ds Bluelib::Term)
endif ()
if ("${component}" STREQUAL "Io")
if (NOT TARGET Bluelib::Core)
message(FATAL_ERROR "Bluelib: Module 'Io' depends on 'Core', which was not specified in find_package()")
endif ()
if (NOT TARGET Bluelib::Ds)
message(FATAL_ERROR "Bluelib: Module 'Io' depends on 'Ds', which was not specified in find_package()")
endif ()
target_link_libraries(Bluelib::Io INTERFACE Bluelib::Core Bluelib::Ds)
endif ()
if ("${component}" STREQUAL "Compress")
if (NOT TARGET Bluelib::Core)
message(FATAL_ERROR "Bluelib: Module 'Compress' depends on 'Core', which was not specified in find_package()")
endif ()
target_link_libraries(Bluelib::Compress INTERFACE Bluelib::Core Bluelib::Ds)
endif ()
endforeach (component)
endif()

189
cmake/FindFX.cmake Normal file
View File

@@ -0,0 +1,189 @@
#[=======================================================================[.rst:
FindFX
------------
Find the FX library and header directories
Imported Targets
^^^^^^^^^^^^^^^^
This module defines the following :prop_tgt:`IMPORTED` target:
``FX::FX``
The FX library, if found
Result Variables
^^^^^^^^^^^^^^^^
This module will set the following variables in your project:
``FX_FOUND``
true if the FX C headers and libraries were found
``FX_INCLUDE_DIR``
directories containing the FX C headers.
``FX_LIBRARY``
the C library to link against
Hints
^^^^^
The user may set the environment variable ``FX_PREFIX`` to the root
directory of a FX library installation.
#]=======================================================================]
set (FX_SEARCH_PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr/local/share
/usr
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
/opt
${FX_PREFIX}
$ENV{FX_PREFIX})
if (FX_STATIC)
set(_lib_suffix "-s")
endif ()
set(supported_components Core Ds Term Cmd Io Serial Compress)
set(components ${FX_FIND_COMPONENTS})
string(REPLACE ";" ", " supported_components_string_list "${supported_components}")
if (NOT components)
set(components ${supported_components})
endif ()
set(required_vars)
foreach (component ${components})
if (NOT "${component}" IN_LIST supported_components)
message(FATAL_ERROR "'${component}' is not a valid FX module.\nSupported modules: ${supported_components_string_list}")
endif ()
string(TOLOWER ${component} header_name)
set(lib_name ${header_name}${_lib_suffix})
if (NOT FX_${component}_INCLUDE_DIR)
find_path(FX_${component}_INCLUDE_DIR
NAMES fx/${header_name}.h ${FX_FIND_ARGS}
PATH_SUFFIXES include
PATHS ${FX_SEARCH_PATHS})
endif ()
if (NOT FX_${component}_LIBRARY)
find_library(FX_${component}_LIBRARY
NAMES fx-${lib_name} ${FX_FIND_ARGS}
PATH_SUFFIXES lib
PATHS ${FX_SEARCH_PATHS})
else ()
# on Windows, ensure paths are in canonical format (forward slahes):
file(TO_CMAKE_PATH "${FX_${component}_LIBRARY}" FX_${component}_LIBRARY)
endif()
list(APPEND required_vars FX_${component}_INCLUDE_DIR FX_${component}_LIBRARY)
endforeach (component)
unset(FX_FIND_ARGS)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(FX
REQUIRED_VARS ${required_vars})
if (FX_FOUND)
set(created_targets)
foreach (component ${components})
string(TOLOWER ${component} header_name)
set(lib_name ${header_name}${_lib_suffix})
if(NOT TARGET FX::${component})
add_library(FX::${component} UNKNOWN IMPORTED)
set_target_properties(FX::${component} PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${FX_${component}_INCLUDE_DIR}")
target_compile_definitions(FX::${component} INTERFACE _CRT_SECURE_NO_WARNINGS=1)
if (FX_STATIC)
target_compile_definitions(FX::${component} INTERFACE FX_STATIC=1)
endif ()
set_target_properties(FX::${component} PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
IMPORTED_LOCATION "${FX_${component}_LIBRARY}")
set(created_targets ${created_targets} ${component})
endif ()
endforeach (component)
foreach (component ${created_targets})
if ("${component}" STREQUAL "Ds")
if (NOT TARGET FX::Core)
message(FATAL_ERROR "FX: Module 'Ds' depends on 'Core', which was not specified in find_package()")
endif ()
target_link_libraries(FX::Ds INTERFACE FX::Core)
endif ()
if ("${component}" STREQUAL "Term")
if (NOT TARGET FX::Core)
message(FATAL_ERROR "FX: Module 'Term' depends on 'Core', which was not specified in find_package()")
endif ()
if (NOT TARGET FX::Ds)
message(FATAL_ERROR "FX: Module 'Term' depends on 'Ds', which was not specified in find_package()")
endif ()
target_link_libraries(FX::Term INTERFACE FX::Core FX::Ds)
endif ()
if ("${component}" STREQUAL "Serial")
if (NOT TARGET FX::Core)
message(FATAL_ERROR "FX: Module 'Serial' depends on 'Core', which was not specified in find_package()")
endif ()
if (NOT TARGET FX::Ds)
message(FATAL_ERROR "FX: Module 'Serial' depends on 'Ds', which was not specified in find_package()")
endif ()
target_link_libraries(FX::Serial INTERFACE FX::Core FX::Ds)
endif ()
if ("${component}" STREQUAL "Cmd")
if (NOT TARGET FX::Core)
message(FATAL_ERROR "FX: Module 'Cmd' depends on 'Core', which was not specified in find_package()")
endif ()
if (NOT TARGET FX::Ds)
message(FATAL_ERROR "FX: Module 'Cmd' depends on 'Ds', which was not specified in find_package()")
endif ()
if (NOT TARGET FX::Term)
message(FATAL_ERROR "FX: Module 'Cmd' depends on 'Term', which was not specified in find_package()")
endif ()
target_link_libraries(FX::Cmd INTERFACE FX::Core FX::Ds FX::Term)
endif ()
if ("${component}" STREQUAL "Io")
if (NOT TARGET FX::Core)
message(FATAL_ERROR "FX: Module 'Io' depends on 'Core', which was not specified in find_package()")
endif ()
if (NOT TARGET FX::Ds)
message(FATAL_ERROR "FX: Module 'Io' depends on 'Ds', which was not specified in find_package()")
endif ()
target_link_libraries(FX::Io INTERFACE FX::Core FX::Ds)
endif ()
if ("${component}" STREQUAL "Compress")
if (NOT TARGET FX::Core)
message(FATAL_ERROR "FX: Module 'Compress' depends on 'Core', which was not specified in find_package()")
endif ()
target_link_libraries(FX::Compress INTERFACE FX::Core FX::Ds)
endif ()
endforeach (component)
endif()

View File

@@ -1,22 +1,22 @@
select.graph {
%entry = +select.entry -> #select.chain
%entry = +select.entry -> !select.chain
%0 = +select.register @0 : i32 -> #select.register
%1 = +select.register @1 : i32 -> #select.register
%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)
: (!select.chain, !select.register) \
-> (i32, !select.chain)
%v.1, %c.1 = +select.register.read %entry, %1 \
: (#select.chain, #select.register) \
-> (i32, #select.chain)
: (!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)
: (!select.chain, !select.register) \
-> (!select.register, !select.chain)
%v.3 = arith.build-pair %v.0, %v.1 : (i32, i32) -> i64
@@ -24,15 +24,15 @@ select.graph {
%v.5 = arith.mul %v.4, %v.3 : (i32, i32) -> i32
%x0 = +select.mach-register @x0 : i32 -> #select.register
%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)
: (!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.chain, !select.register, !select.glue) \
-> !select.chain
+select.graph-root %c.4 : #select.chain
+select.graph-root %c.4 : !select.chain
}

View File

@@ -1,31 +1,31 @@
select.graph {
%entry = +select.entry -> #select.chain
%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
%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
%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)
%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
%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
%N10.c = +select.chain-group %N7.c, %N6.c : (!select.chain, !select.chain) -> !select.chain
%N11 = +select.block-ref @if.true -> #select.block
%N11 = +select.block-ref @if.true -> !select.block
%N12.c = +cf.br-cond %N10.c, %N9, %N11 : (#select.chain, i1, #select.block) -> #select.chain
%N12.c = +cf.br-cond %N10.c, %N9, %N11 : (!select.chain, i1, !select.block) -> !select.chain
%N13 = +select.block-ref @if.false -> #select.block
%N13 = +select.block-ref @if.false -> !select.block
%N14.c = cf.br %N12.c, %N13

View File

@@ -8,15 +8,15 @@ 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
%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
ptr.store %name, %self.name : !ivy.id, ptr
ptr.store %age, %self.age : !ivy.id, ptr
func.return : ()
}
@@ -24,41 +24,41 @@ ivy.module {
%0 = ivy.string-builder.begin
ivy.string-builder.add %0 << "Received "
ivy.string-builder.add %0 << %data : #ivy.id
ivy.string-builder.add %0 << %data : !ivy.id
ivy.string-builder.add %0 << ", "
ivy.string-builder.add %0 << %extra : #ivy.id
ivy.string-builder.add %0 << %extra : !ivy.id
%1 = ivy.string-builder.end %0 -> #ivy.id
%1 = ivy.string-builder.end %0 -> !ivy.id
%2 = ptr.load %cout : ptr -> #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 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 -> !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
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
%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
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
ptr.store %age, %self.age : !ivy.id, ptr
func.return : ()
}
@@ -66,28 +66,28 @@ ivy.module {
scf.switch : () -> void
case {
%0 = ivy.atom "years"
%cmptmp.0 = ivy.cmp eq %age, %0 : (#ivy.id, #ivy.atom) -> i1
%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
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
%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
%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
%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
%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
@@ -97,56 +97,56 @@ ivy.module {
func.return : ()
}
ivy.msgh.object get-age-in-units:%units -> #ivy.id {
%result = scf.switch : () -> #ivy.id
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
%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
%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
%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
%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
%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
%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
%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
%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
scf.switch-break %d2 : !ivy.id
}
func.return %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
%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
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
%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 : ()
}
@@ -156,16 +156,16 @@ ivy.module {
}
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
%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
%0 = ptr.load %self.__example-property-5 : ptr -> !ivy.id
func.return %0 : !ivy.id
}
}
@@ -175,19 +175,19 @@ ivy.module {
%0 = ivy.str.constant "John Doe"
%1 = arith.constant 34 : i32
%2 = ivy.msg.send to %Person, new(name:%0, age:%1) -> #ivy.id
%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 = 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
%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
%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
@@ -213,9 +213,9 @@ ivy.module {
%14 = ptr.load %i : ptr -> i32
ivy.string-builder.add %12 << %14 : i32
%15 = ivy.string-builder.end %12 -> #ivy.id
%15 = ivy.string-builder.end %12 -> !ivy.id
%16 = ptr.load %cout : ptr -> #ivy.id
%16 = ptr.load %cout : ptr -> !ivy.id
ivy.msg.send to %16, put:%15 -> void
; i += 2
@@ -229,7 +229,7 @@ ivy.module {
%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
%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 {
@@ -237,12 +237,12 @@ ivy.module {
; 'Count is {x}'
ivy.string-builder.add %23 << "Count is "
ivy.string-builder.add %23 << %x : #ivy.id
ivy.string-builder.add %23 << %x : !ivy.id
%25 = ivy.string-builder.end %23 -> #ivy.id
%25 = ivy.string-builder.end %23 -> !ivy.id
; cout put:"Count is {x}"
%26 = ptr.load %cout : ptr -> #ivy.id
%26 = ptr.load %cout : ptr -> !ivy.id
ivy.msg.send to %26, put:%25 -> void
}
@@ -251,16 +251,16 @@ ivy.module {
%28 = arith.constant 100 : i32
%29 = arith.constant 2 : i32
; [ :i | cout put:'Count: {i}' ]
%30 = ivy.lambda %i : (#ivy.id) -> void {
%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
ivy.string-builder.add %0 << %i : !ivy.id
%2 = ivy.string-builder.end %0 -> #ivy.id
%2 = ivy.string-builder.end %0 -> !ivy.id
%cout = ivy.global-ref @cout -> ptr
%3 = ptr.load %cout : ptr -> #ivy.id
%3 = ptr.load %cout : ptr -> !ivy.id
ivy.msg.send to %3, put:%2 -> void
}
@@ -273,29 +273,29 @@ ivy.module {
ptr.store %31, %q : i32, ptr
; l = [ cout put:'Value of q is {q}' ].
%l = ptr.alloca #ivy.id
%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
ivy.string-builder.add %0 << %env.q : !ivy.id
%2 = ivy.string-builder.end %0 -> #ivy.id
%2 = ivy.string-builder.end %0 -> !ivy.id
%cout = ivy.global-ref @cout -> ptr
%3 = ptr.load %cout : ptr -> #ivy.id
%3 = ptr.load %cout : ptr -> !ivy.id
ivy.msg.send to %3, put:%2 -> void
}
ptr.store %33, %l : #ivy.id, ptr
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
%35 = ptr.load %l : ptr -> !ivy.id
ivy.msg.send to %35, call -> void
%j = ptr.alloca i32 -> ptr
@@ -311,14 +311,14 @@ ivy.module {
%39 = ivy.lambda : () -> void {
%cout = ivy.global-ref @cout -> ptr
%0 = ivy.str.constant "True!"
%1 = ptr.load %cout : ptr -> #ivy.id
%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
%1 = ptr.load %cout : ptr -> !ivy.id
ivy.msg.send to %1, put:%0 -> void
}
@@ -331,53 +331,53 @@ ivy.module {
scf.if %cmptmp.0 -> void {
%43 = ivy.str.constant "True!"
%44 = ptr.load %cout : ptr -> #ivy.id
%44 = ptr.load %cout : ptr -> !ivy.id
ivy.msg.send to %44, put:%43 -> void
}
; pkg = {}.
%pkg = ptr.alloca #ivy.id -> ptr
%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
%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
%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
%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
%51 = ivy.tuple.create %49, %50 : (i32, !ivy.id) -> !ivy.id
ptr.store %51, %tuple : #ivy.id, ptr
ptr.store %51, %tuple : !ivy.id, ptr
%52 = ptr.load %tuple : ptr -> #ivy.id
%53 = ivy.msg.send to %52, get-iterator -> #ivy.id
%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 = 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 << %key : !ivy.id
ivy.string-builder.add %55 << " -> "
ivy.string-builder.add %55 << %val : #ivy.id
ivy.string-builder.add %55 << %val : !ivy.id
%57 = ivy.string-builder.end %55 -> #ivy.id
%57 = ivy.string-builder.end %55 -> !ivy.id
; cout put:'{key} -> {val}'
%58 = ptr.load %cout : ptr -> #ivy.id
%58 = ptr.load %cout : ptr -> !ivy.id
ivy.msg.send to %58, put:%57 -> void
}
@@ -387,20 +387,20 @@ ivy.module {
%multmp = arith.mul %59, %60 : (i32, i32) -> i32
; a = (32, 64).
%a = ptr.alloca #ivy.id -> ptr
%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
%63 = ivy.tuple.create %61, %62 : (i32, i32) -> !ivy.id
ptr.store %63, %a : #ivy.id, ptr
ptr.store %63, %a : !ivy.id, ptr
%v = ptr.alloca #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
%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
ptr.store %65, %v : !ivy.id, ptr
%66 = ivy.atom "err:number-format"
@@ -413,47 +413,47 @@ ivy.module {
}
%67 = ivy.lambda : () -> void {
%v = ptr.alloca #ivy.id -> ptr
%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
ptr.store %1, %v : !ivy.id, ptr
}
%68 = ivy.lambda %err, %data : (#ivy.id, #ivy.id) -> void {
%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 << %err : !ivy.id
ivy.string-builder.add %0 << ")"
%3 = ivy.string-builder.end %0 -> #ivy.id
%3 = ivy.string-builder.end %0 -> !ivy.id
; cout put:'{key} -> {val}'
%4 = ptr.load %cout : ptr -> #ivy.id
%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 {
%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 << %err : !ivy.id
ivy.string-builder.add %0 << " occurred ("
ivy.string-builder.add %0 << %data : #ivy.id
ivy.string-builder.add %0 << %data : !ivy.id
ivy.string-builder.add %0 << ")"
%4 = ivy.string-builder.end %0 -> #ivy.id
%4 = ivy.string-builder.end %0 -> !ivy.id
; cout put:'{key} -> {val}'
%5 = ptr.load %cout : ptr -> #ivy.id
%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:%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,30 @@
~func.func() ({
^R:
%0 = ~arith.constant() {value = 0 : i32} : () -> i32
~cf.br-cond(%0) [ ^A, ^B, ^C ] : (i32) -> ()
^A:
~cf.br() [ ^D ] : () -> ()
^B:
~cf.br-cond(%0) [ ^D, ^A, ^E ] : (i32) -> ()
^C:
~cf.br-cond(%0) [ ^G, ^F ] : (i32) -> ()
^D:
~cf.br() [ ^L ] : () -> ()
^E:
~cf.br() [ ^H ] : () -> ()
^F:
~cf.br() [ ^I ] : () -> ()
^G:
~cf.br-cond(%0) [ ^I, ^J ] : (i32) -> ()
^H:
~cf.br-cond(%0) [ ^E, ^K ] : (i32) -> ()
^I:
~cf.br() [ ^K ] : () -> ()
^J:
~cf.br() [ ^I ] : () -> ()
^K:
~cf.br-cond(%0) [ ^R, ^I ] : (i32) -> ()
^L:
~cf.br() [ ^H ] : () -> ()
}) {sym_name = "test", function_type = () -> () } : () -> ()

View File

@@ -1,15 +1,17 @@
; Comment
func.func @reduce(%buffer: memref<1024*f32>, %lb: index, %ub: index, %step: index) -> f32 {
; Initial sum set to 0.
%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>
%sum.next = arith.addf %sum.iter, %t : f32
; Yield current iteration sum to next iteration %sum.iter or to %sum
; if final iteration.
scf.yield %sum.next : f32
}
module {
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
; 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>
%sum.next = arith.addf %sum.iter, %t : f32
; Yield current iteration sum to next iteration %sum.iter or to %sum
; if final iteration.
scf.yield %sum.next : f32
}
func.return %sum : f32
func.return %sum : f32
}
}

View File

@@ -1,25 +1,16 @@
~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
module {
func.func @_reduce(%buffer: memref<1024*f32>, %lb: index, %ub: index, %step: index) -> f32 {
%sum.0 = arith.constant 0 : 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>
%sum.next = arith.addf %sum.iter, %t : f32
cf.br ^for.cond(%iv: index, %sum.next: f32)
^for.cond(%iv.0: index, %sum.iter.0: index):
%iv.next = arith.addi %iv.0, %step : index
%stop = arith.cmpi uge %iv.next, %ub : index
cf.br-cond %stop, ^for.end(%sum.iter.0: index), ^for.entry(%iv.next: index, %sum.iter.0: index)
^for.end(%sum: f32):
func.return %sum : f32
}
}

View File

@@ -0,0 +1,26 @@
~builtin.module() ({
~func.func() ({
^entry(%buffer: i32, %lb: index, %ub: index, %step: index):
; 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, %x, %z = ~memref.load(%buffer, %iv) : (i32, index) -> (f32, i1, i1)
%sum.next = ~arith.addf(%sum.iter, %t) : (f32, f32) -> f32
~cf.br() [ ^for.cond:(%iv: index, %sum.next: f32) ] : () -> ()
^for.cond(%iv2: index, %sum.next2: 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 } : (index, index) -> i1
~cf.br-cond(%stop) [ ^for.end, ^for.entry:(%iv.next: index, %sum.next: f32) ] : (i1) -> ()
^for.end(%sum: f32):
~func.return(%sum) : (f32) -> ()
}) {sym_name = "reduce", function_type = (i32, index, index, index) -> f32 } : () -> ()
}) : () -> ()

View File

@@ -1,6 +1,25 @@
%1, %reg.2, $X0 = ~scf.for(%a, %b) ({
^b0:
~arith.constant() : () -> ()
^b1:
~arith.constant() : () -> ()
}) {test_attrib = 2 : i32 } : (i8, i1) -> (i32, i32, i32)
module {
func.func @reduce(%buffer: memref<?*f32>, %lb: index, %ub: index, %step: index) -> f32 {
; Initial sum set to 0.
%sum.0 = arith.constant 0.0 : 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<?*f32>
%sum.next = arith.addf %sum.iter, %t : f32
cf.br ^for.cond(%iv: index, %sum.next: f32)
^for.cond(%iv2: index, %sum.next2: f32):
; Yield current iteration sum to next iteration %sum.iter or to %sum
; if final iteration.
%iv.next = arith.addi %iv, %step : index
%stop = arith.cmpi uge %iv.next, %ub : index
cf.br-cond %stop, ^for.end, ^for.entry(%iv.next: index, %sum.next: f32)
^for.end(%sum: f32):
func.return %sum : f32
}
}

View File

@@ -31,7 +31,8 @@ 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 mieDialectType /![A-Za-z][A-Za-z0-9\-]*\(\.[A-Za-z][A-Za-z0-9\-]*\)\+/
syn match mieDialectAttribute /#[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\-]*\)\+\([>\*]\)\@!\>/
@@ -77,6 +78,7 @@ hi def link mieBrackets Delimiter
hi def link mieAngleBrackets StorageClass
hi def link mieDialectType Type
hi def link mieDialectAttribute @attribute
hi def link mieGenericOperation @function.builtin
hi def link mieGraphOperation Statement

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 Bluelib::Io)
target_link_libraries(mie FX::Core FX::Ds FX::Io)
target_compile_definitions(mie PRIVATE MIE_EXPORT=1 MIE_STATIC=${MIE_STATIC})

View File

@@ -1,4 +1,4 @@
#include <blue/ds/string.h>
#include <fx/ds/string.h>
#include <mie/attribute/attribute-definition.h>
#include <mie/dialect/dialect.h>
@@ -12,7 +12,7 @@ struct mie_attribute_definition *mie_attribute_definition_create(
memset(out, 0x0, sizeof *out);
out->a_name = b_strdup(name);
out->a_name = fx_strdup(name);
if (!out->a_name) {
free(out);
return NULL;
@@ -20,8 +20,20 @@ struct mie_attribute_definition *mie_attribute_definition_create(
out->a_parent = parent;
b_rope name_rope = B_ROPE_CSTR(name);
fx_rope name_rope = FX_ROPE_CSTR(name);
mie_id_map_put(&parent->d_attributes, &out->a_id, &name_rope);
return out;
}
bool mie_attribute_definition_check_name(
const struct mie_attribute_definition *def, const char *dialect_name,
const char *attrib_name)
{
if (!def || !def->a_parent) {
return false;
}
return (!strcmp(def->a_name, attrib_name)
&& !strcmp(def->a_parent->d_name, dialect_name));
}

View File

@@ -1,6 +1,6 @@
#include <blue/core/hash.h>
#include <blue/core/queue.h>
#include <blue/ds/string.h>
#include <fx/core/hash.h>
#include <fx/core/queue.h>
#include <fx/ds/string.h>
#include <mie/attribute/attribute-map.h>
enum attribute_map_entry_type {
@@ -13,14 +13,14 @@ 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;
fx_bst_node e_node;
fx_queue_entry e_entry;
};
};
struct attribute_map_bucket {
struct attribute_map_entry b_base;
b_queue b_items;
fx_queue b_items;
};
struct attribute_map_item {
@@ -29,9 +29,9 @@ struct attribute_map_item {
const struct mie_attribute *i_value;
};
static B_BTREE_DEFINE_SIMPLE_INSERT(
static FX_BST_DEFINE_SIMPLE_INSERT(
struct attribute_map_entry, e_node, e_hash, put_entry);
static B_BTREE_DEFINE_SIMPLE_GET(
static FX_BST_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)
@@ -57,16 +57,16 @@ static const struct mie_attribute *get_attribute_from_item(
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);
fx_queue_entry *cur = fx_queue_first(&bucket->b_items);
while (cur) {
const struct attribute_map_item *item = b_unbox(
const struct attribute_map_item *item = fx_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);
cur = fx_queue_next(cur);
}
return NULL;
@@ -90,7 +90,7 @@ static const struct mie_attribute *get_attribute_from_entry(
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);
uint64_t name_hash = fx_hash_cstr(name);
struct attribute_map_entry *entry = get_entry(&map->m_entries, name_hash);
if (!entry) {
return NULL;
@@ -107,13 +107,13 @@ static struct attribute_map_bucket *convert_item_to_bucket(
return NULL;
}
b_btree_delete(&map->m_entries, &item->i_base.e_node);
fx_bst_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);
fx_queue_push_back(&bucket->b_items, &item->i_base.e_entry);
put_entry(&map->m_entries, &bucket->b_base);
return bucket;
@@ -132,7 +132,7 @@ static struct attribute_map_item *create_item(
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);
out->i_name = fx_strdup(name);
if (!out->i_name) {
free(out);
return NULL;
@@ -145,10 +145,11 @@ 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);
uint64_t name_hash = fx_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;
enum mie_status status = MIE_SUCCESS;
if (!entry) {
item = create_item(name, name_hash, value);
@@ -162,6 +163,17 @@ enum mie_status mie_attribute_map_put(
if (entry->e_type == ATTRMAP_ENTRY_ITEM) {
item = (struct attribute_map_item *)entry;
if (!strcmp(item->i_name, name)) {
status = MIE_ERR_NAME_EXISTS;
if (flags & MIE_ATTRMAP_F_REPLACE) {
item->i_value = value;
status = MIE_SUCCESS;
}
return status;
}
bucket = convert_item_to_bucket(map, item);
} else {
bucket = (struct attribute_map_bucket *)entry;
@@ -172,7 +184,7 @@ enum mie_status mie_attribute_map_put(
return MIE_ERR_NO_MEMORY;
}
b_queue_push_back(&bucket->b_items, &item->i_base.e_entry);
fx_queue_push_back(&bucket->b_items, &item->i_base.e_entry);
return MIE_SUCCESS;
}
@@ -180,13 +192,13 @@ 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);
it->_n = fx_bst_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);
= fx_unbox(struct attribute_map_entry, it->_n, e_node);
struct attribute_map_item *item = NULL;
struct attribute_map_bucket *bucket = NULL;
@@ -198,8 +210,8 @@ enum mie_status mie_attribute_map_iterator_begin(
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->_e = fx_queue_first(&bucket->b_items);
item = fx_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;
@@ -216,11 +228,11 @@ enum mie_status mie_attribute_map_iterator_move_next(
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);
it->_e = fx_queue_next(it->_e);
next_entry = fx_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);
it->_n = fx_bst_next(it->_n);
next_entry = fx_unbox(struct attribute_map_entry, it->_n, e_node);
} else {
memset(it, 0x0, sizeof *it);
return MIE_ERR_NO_DATA;
@@ -237,8 +249,8 @@ enum mie_status mie_attribute_map_iterator_move_next(
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(
it->_e = fx_queue_first(&next_bucket->b_items);
next_item = fx_unbox(
struct attribute_map_item, it->_e, i_base.e_entry);
break;
default:

View File

@@ -0,0 +1,14 @@
#include <mie/attribute/attribute-definition.h>
#include <mie/attribute/attribute.h>
bool mie_attribute_check_name(
const struct mie_attribute *attrib, const char *dialect_name,
const char *attrib_name)
{
if (!attrib || !attrib->a_def) {
return false;
}
return mie_attribute_definition_check_name(
attrib->a_def, dialect_name, attrib_name);
}

239
mie/ctx.c
View File

@@ -1,15 +1,20 @@
#include <blue/core/bstr.h>
#include <blue/ds/hashmap.h>
#include <blue/ds/list.h>
#include <blue/ds/string.h>
#include <fx/core/bstr.h>
#include <fx/ds/hashmap.h>
#include <fx/ds/list.h>
#include <fx/ds/string.h>
#include <mie/attribute/attribute-definition.h>
#include <mie/ctx.h>
#include <mie/diag/class.h>
#include <mie/diag/diag.h>
#include <mie/dialect/arith.h>
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
#include <mie/dialect/index.h>
#include <mie/interface/interface-definition.h>
#include <mie/ir/op-definition.h>
#include <mie/ir/op.h>
#include <mie/pass/pass-definition.h>
#include <mie/pass/pass.h>
#include <mie/trait/trait-definition.h>
#include <mie/trait/trait.h>
#include <mie/type/function.h>
@@ -35,6 +40,10 @@
MIE_ID(0xc6, 0x94, 0x38, 0x34, 0xdb, 0x08, 0x45, 0xc7, 0xb9, 0x89, \
0x69, 0x82, 0x7a, 0x9d, 0x42, 0xd8)
#define PASS_NS_ID \
MIE_ID(0x76, 0xfc, 0xdd, 0xb5, 0xc0, 0x20, 0x47, 0x13, 0x8d, 0xfa, \
0x3f, 0x28, 0x2f, 0x81, 0x6d, 0x7d)
struct mie_ctx *mie_ctx_create(void)
{
struct mie_ctx *out = malloc(sizeof *out);
@@ -57,15 +66,35 @@ struct mie_ctx *mie_ctx_create(void)
mie_id attributes_ns = ATTRIBUTE_NS_ID;
mie_id_map_init(&out->ctx_attributes, &attributes_ns);
mie_id pass_ns = PASS_NS_ID;
mie_id_map_init(&out->ctx_passes, &pass_ns);
return out;
}
struct mie_op *mie_ctx_create_op(
const struct mie_ctx *ctx, const char *dialect, const char *op)
{
const struct mie_op_definition *def
= mie_ctx_get_op_definition(ctx, dialect, op);
if (!def) {
return NULL;
}
struct mie_op *out = mie_op_create();
if (!out) {
return NULL;
}
out->op_flags |= MIE_OP_F_OP_RESOLVED;
out->op_info = def;
return out;
}
bool mie_ctx_resolve_op(const struct mie_ctx *ctx, struct mie_op *op)
{
bool fully_resolved = MIE_TEST_FLAGS(
op->op_flags, MIE_OP_F_OP_RESOLVED | MIE_OP_F_ARG_RESOLVED);
if (fully_resolved) {
if (op->op_flags & MIE_OP_F_OP_RESOLVED) {
return true;
}
@@ -95,11 +124,10 @@ bool mie_ctx_resolve_op(const struct mie_ctx *ctx, struct mie_op *op)
const struct mie_op_definition *op_info
= mie_dialect_get_op(dialect, op_name);
if (!op) {
if (!op_info) {
return false;
}
op->op_dialect = dialect;
op->op_info = op_info;
free(op->op_name);
@@ -112,102 +140,123 @@ bool mie_ctx_resolve_op(const struct mie_ctx *ctx, struct mie_op *op)
struct mie_dialect *mie_ctx_get_dialect(const struct mie_ctx *ctx, const char *name)
{
b_rope name_rope = B_ROPE_CSTR(name);
fx_rope name_rope = FX_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);
return fx_unbox(struct mie_dialect, target, d_id);
}
const struct mie_op_definition *mie_ctx_get_op_definition(
const struct mie_ctx *ctx, const char *dialect_name, const char *op_name)
{
fx_rope dialect_name_rope = FX_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 = fx_unbox(struct mie_dialect, target, d_id);
if (!dialect) {
return NULL;
}
fx_rope op_name_rope = FX_ROPE_CSTR(op_name);
mie_id_init_ns(&id, mie_id_map_get_ns(&dialect->d_ops), &op_name_rope);
target = mie_id_map_get(&dialect->d_ops, &id);
return fx_unbox(struct mie_op_definition, target, op_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);
fx_rope dialect_name_rope = FX_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);
struct mie_dialect *dialect = fx_unbox(struct mie_dialect, target, d_id);
if (!dialect) {
return NULL;
}
b_rope type_name_rope = B_ROPE_CSTR(type_name);
fx_rope type_name_rope = FX_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);
return fx_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);
fx_rope dialect_name_rope = FX_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);
struct mie_dialect *dialect = fx_unbox(struct mie_dialect, target, d_id);
if (!dialect) {
return NULL;
}
b_rope trait_name_rope = B_ROPE_CSTR(trait_name);
fx_rope trait_name_rope = FX_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);
return fx_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);
fx_rope dialect_name_rope = FX_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);
struct mie_dialect *dialect = fx_unbox(struct mie_dialect, target, d_id);
if (!dialect) {
return NULL;
}
b_rope attribute_name_rope = B_ROPE_CSTR(attribute_name);
fx_rope attribute_name_rope = FX_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);
return fx_unbox(struct mie_attribute_definition, target, a_id);
}
const struct mie_interface_definition *mie_ctx_get_interface_definition(
const struct mie_ctx *ctx, const char *dialect_name,
const char *interface_name)
{
b_rope dialect_name_rope = B_ROPE_CSTR(dialect_name);
fx_rope dialect_name_rope = FX_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);
struct mie_dialect *dialect = fx_unbox(struct mie_dialect, target, d_id);
if (!dialect) {
return NULL;
}
b_rope interface_name_rope = B_ROPE_CSTR(interface_name);
fx_rope interface_name_rope = FX_ROPE_CSTR(interface_name);
mie_id_init_ns(
&id, mie_id_map_get_ns(&dialect->d_interfaces),
&interface_name_rope);
target = mie_id_map_get(&dialect->d_interfaces, &id);
return b_unbox(struct mie_interface_definition, target, if_id);
return fx_unbox(struct mie_interface_definition, target, if_id);
}
struct mie_type *mie_ctx_get_type(
@@ -215,13 +264,13 @@ struct mie_type *mie_ctx_get_type(
{
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);
fx_rope full_name_rope = FX_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);
struct mie_type *type = fx_unbox(struct mie_type, target, ty_id);
if (type) {
return type;
}
@@ -246,7 +295,7 @@ struct mie_type *mie_ctx_get_type(
memset(type, 0x0, sizeof *type);
type->ty_def = type_info;
type->ty_name = b_bstr_fmt("%s.%s", dialect_name, type_name);
type->ty_name = fx_bstr_fmt(NULL, "%s.%s", dialect_name, type_name);
if (type_info->ty_init) {
type_info->ty_init(type_info, type);
@@ -262,13 +311,13 @@ const struct mie_trait *mie_ctx_get_trait(
{
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);
fx_rope full_name_rope = FX_ROPE_CSTR(full_name);
mie_id id;
mie_id_init_ns(&id, mie_id_map_get_ns(&ctx->ctx_traits), &full_name_rope);
mie_id *target = mie_id_map_get(&ctx->ctx_traits, &id);
struct mie_trait *trait = b_unbox(struct mie_trait, target, tr_id);
struct mie_trait *trait = fx_unbox(struct mie_trait, target, tr_id);
if (trait) {
return trait;
}
@@ -293,7 +342,7 @@ const struct mie_trait *mie_ctx_get_trait(
memset(trait, 0x0, sizeof trait_info->tr_data_size);
trait->tr_def = trait_info;
trait->tr_name = b_bstr_fmt("%s.%s", dialect_name, trait_name);
trait->tr_name = fx_bstr_fmt(NULL, "%s.%s", dialect_name, trait_name);
if (trait_info->tr_init) {
trait_info->tr_init(trait_info, trait);
@@ -314,7 +363,7 @@ struct mie_type *mie_ctx_get_storage_type(
mie_id_builder_end(&id_builder, &id);
mie_id *target = mie_id_map_get(&ctx->ctx_types, &id);
struct mie_type *type = b_unbox(struct mie_type, target, ty_id);
struct mie_type *type = fx_unbox(struct mie_type, target, ty_id);
if (type) {
return type;
}
@@ -340,7 +389,7 @@ struct mie_type *mie_ctx_get_function_type(
mie_id_builder_end(&id_builder, &id);
mie_id *target = mie_id_map_get(&ctx->ctx_types, &id);
struct mie_type *type = b_unbox(struct mie_type, target, ty_id);
struct mie_type *type = fx_unbox(struct mie_type, target, ty_id);
if (type) {
return type;
}
@@ -358,3 +407,121 @@ struct mie_type *mie_ctx_get_function_type(
mie_id_map_put_id(&ctx->ctx_types, &new_type->func_base.ty_id);
return (struct mie_type *)new_type;
}
enum mie_status mie_ctx_register_pass(
struct mie_ctx *ctx, struct mie_pass_definition *pass)
{
if (pass->p_data_size < sizeof(struct mie_pass)) {
return MIE_ERR_INVALID_ARGUMENT;
}
switch (pass->p_type) {
case MIE_PASS_ANALYSE:
case MIE_PASS_TRANSFORM:
break;
default:
return MIE_ERR_INVALID_ARGUMENT;
}
mie_id id;
struct mie_id_builder id_builder;
mie_id_builder_begin(&id_builder, mie_id_map_get_ns(&ctx->ctx_passes));
mie_id_builder_add_cstr(&id_builder, pass->p_name);
mie_id_builder_end(&id_builder, &id);
mie_id *target = mie_id_map_get(&ctx->ctx_passes, &id);
if (target) {
return MIE_ERR_NAME_EXISTS;
}
pass->p_id = id;
mie_id_map_put_id(&ctx->ctx_passes, &pass->p_id);
return MIE_SUCCESS;
}
enum mie_status mie_ctx_get_pass(
struct mie_ctx *ctx, const char *name,
const struct mie_attribute_map *args, struct mie_pass **out)
{
mie_id id;
struct mie_id_builder id_builder;
mie_id_builder_begin(&id_builder, mie_id_map_get_ns(&ctx->ctx_passes));
mie_id_builder_add_cstr(&id_builder, name);
mie_id_builder_end(&id_builder, &id);
mie_id *target = mie_id_map_get(&ctx->ctx_passes, &id);
if (!target) {
return MIE_ERR_NO_ENTRY;
}
struct mie_pass_definition *pass_def
= fx_unbox(struct mie_pass_definition, target, p_id);
if (pass_def->p_data_size < sizeof(struct mie_pass)) {
return MIE_ERR_BAD_STATE;
}
struct mie_pass *pass = malloc(pass_def->p_data_size);
if (!pass) {
return MIE_ERR_NO_MEMORY;
}
memset(pass, 0x0, pass_def->p_data_size);
pass->p_def = pass_def;
enum mie_status status = MIE_SUCCESS;
if (pass_def->p_init) {
status = pass_def->p_init(pass, args);
}
if (status != MIE_SUCCESS) {
free(pass);
pass = NULL;
}
*out = pass;
return status;
}
struct mie_diag *mie_ctx_push_diag(
struct mie_ctx *ctx, struct mie_line_source *src,
const struct mie_file_cell *loc, const char *dialect_name,
unsigned long diag_class)
{
struct mie_diag *diag = malloc(sizeof *diag);
if (!diag) {
return NULL;
}
struct mie_dialect *dialect = mie_ctx_get_dialect(ctx, dialect_name);
if (!dialect) {
return NULL;
}
if (diag_class >= dialect->d_nr_diag_classes) {
return NULL;
}
memset(diag, 0x0, sizeof *diag);
diag->diag_src = src;
diag->diag_loc = *loc;
diag->diag_parent = dialect;
diag->diag_class = &dialect->d_diag_classes[diag_class];
fx_queue_push_back(&ctx->ctx_diag, &diag->diag_entry);
return diag;
}
struct mie_diag *mie_ctx_pop_diag(struct mie_ctx *ctx)
{
fx_queue_entry *entry = fx_queue_pop_front(&ctx->ctx_diag);
if (!entry) {
return NULL;
}
return fx_unbox(struct mie_diag, entry, diag_entry);
}

124
mie/diag/diag.c Normal file
View File

@@ -0,0 +1,124 @@
#include <fx/ds/string.h>
#include <mie/ctx.h>
#include <mie/diag/amendment.h>
#include <mie/diag/component.h>
#include <mie/diag/diag.h>
#include <mie/diag/highlight.h>
#include <mie/diag/msg.h>
#include <mie/dialect/dialect.h>
#include <stdlib.h>
#include <string.h>
struct mie_diag_c_msg *diag_msg_create(const struct mie_diag_msg *content)
{
struct mie_diag_c_msg *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
memset(out, 0x0, sizeof *out);
out->msg_base.c_type = MIE_DIAG_COMPONENT_MSG;
out->msg_content = fx_strdup(content->msg_content);
return out;
}
struct mie_diag_c_snippet *diag_snippet_create(
unsigned long first_line, unsigned long last_line,
const struct mie_diag_amendment *amendments, size_t nr_amendments,
const struct mie_diag_highlight *highlights, size_t nr_highlights)
{
struct mie_diag_c_snippet *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
memset(out, 0x0, sizeof *out);
out->s_base.c_type = MIE_DIAG_COMPONENT_SNIPPET;
out->s_first_line = first_line;
out->s_last_line = last_line;
out->s_nr_amendments = nr_amendments;
out->s_amendments = calloc(nr_amendments, sizeof *amendments);
if (!out->s_amendments) {
free(out);
return NULL;
}
memcpy(out->s_amendments, amendments, nr_amendments * sizeof *amendments);
out->s_nr_highlights = nr_highlights;
out->s_highlights = calloc(nr_highlights, sizeof *highlights);
if (!out->s_highlights) {
free(out->s_amendments);
free(out);
return NULL;
}
memcpy(out->s_highlights, highlights, nr_highlights * sizeof *highlights);
return out;
}
void mie_diag_set_location(
struct mie_diag *diag, unsigned long row, unsigned long col)
{
diag->diag_loc.c_row = row;
diag->diag_loc.c_row = col;
}
void mie_diag_push_msg(
struct mie_diag *diag, struct mie_ctx *ctx, const char *dialect_name,
unsigned long msg, ...)
{
struct mie_dialect *dialect = mie_ctx_get_dialect(ctx, dialect_name);
if (!dialect) {
return;
}
if (msg >= dialect->d_nr_diag_msgs
|| !dialect->d_diag_msgs[msg].msg_content) {
fprintf(stderr, "FATAL: %lu is not a valid %s diag msg\n", msg,
dialect_name);
abort();
return;
}
const struct mie_diag_msg *msg_info = &dialect->d_diag_msgs[msg];
struct mie_diag_c_msg *c_msg = diag_msg_create(msg_info);
if (!c_msg) {
return;
}
fx_queue_push_back(&diag->diag_components, &c_msg->msg_base.c_entry);
}
void mie_diag_push_string(struct mie_diag *diag, const char *str)
{
struct mie_diag_c_msg *c_msg = malloc(sizeof *c_msg);
if (!c_msg) {
return;
}
memset(c_msg, 0x0, sizeof *c_msg);
c_msg->msg_base.c_type = MIE_DIAG_COMPONENT_MSG;
c_msg->msg_content = fx_strdup(str);
fx_queue_push_back(&diag->diag_components, &c_msg->msg_base.c_entry);
}
void mie_diag_push_snippet(
struct mie_diag *diag, unsigned long first_line, unsigned long last_line,
const struct mie_diag_amendment *amendments, size_t nr_amendments,
const struct mie_diag_highlight *highlights, size_t nr_highlights)
{
struct mie_diag_c_snippet *c_snippet = diag_snippet_create(
first_line, last_line, amendments, nr_amendments, highlights,
nr_highlights);
if (!c_snippet) {
return;
}
fx_queue_push_back(&diag->diag_components, &c_snippet->s_base.c_entry);
}

6
mie/diag/diag.h Normal file
View File

@@ -0,0 +1,6 @@
#ifndef _DIAG_DIAG_H_
#define _DIAG_DIAG_H_
#include <fx/core/queue.h>
#endif

View File

@@ -1,9 +1,18 @@
#include <mie/ctx.h>
#include <mie/diag/class.h>
#include <mie/diag/msg.h>
#include <mie/dialect/arith.h>
#include <mie/dialect/dialect.h>
#include <mie/macros.h>
MIE_DIAG_CLASS_LIST_EXTERN(mie_arith_diag);
MIE_DIAG_MSG_LIST_EXTERN(mie_arith_msg);
MIE_DIALECT_BEGIN(mie_arith, struct mie_dialect, "arith")
MIE_DIALECT_DIAG_CLASS_LIST(mie_arith_diag);
MIE_DIALECT_DIAG_MSG_LIST(mie_arith_msg);
MIE_DIALECT_ADD_OP(mie_arith_addi);
MIE_DIALECT_ADD_OP(mie_arith_cmpi);
MIE_DIALECT_ADD_OP(mie_arith_addf);
MIE_DIALECT_ADD_OP(mie_arith_constant);
MIE_DIALECT_END()

29
mie/dialect/arith/diag.c Normal file
View File

@@ -0,0 +1,29 @@
#include <mie/diag/class.h>
#include <mie/diag/msg.h>
#include <mie/dialect/arith.h>
#include <mie/macros.h>
#define MIE_DIAG_CLASS_PREFIX MIE_ARITH_E
#define MIE_DIAG_MSG_PREFIX MIE_ARITH_MSG
MIE_DIAG_CLASS_LIST_BEGIN(mie_arith_diag)
MIE_DIAG_CLASS(INVALID_INTEGER_TYPE, ERROR, "Invalid integer type")
MIE_DIAG_CLASS(INVALID_FLOAT_TYPE, ERROR, "Invalid floating-point type")
MIE_DIAG_CLASS(
INVALID_COMPARISON_PREDICATE, ERROR,
"Invalid comparison predicate")
MIE_DIAG_CLASS_LIST_END(mie_arith_diag)
MIE_DIAG_MSG_LIST_BEGIN(mie_arith_msg)
MIE_DIAG_MSG(EXPECTED_INTEGER_TYPE, "expected an integer or index type.")
MIE_DIAG_MSG(EXPECTED_FLOAT_TYPE, "expected a floating-point type.")
MIE_DIAG_MSG(
INVALID_COMPARISON_PREDICATE,
"this is not a valid comparison predicate.")
MIE_DIAG_MSG(
VALID_COMPARISON_PREDICATES,
"valid comparison predicates include: [blue]eq[reset], "
"[blue]ne[reset], [blue]slt[reset], [blue]sle[reset], "
"[blue]sgt[reset], [blue]sge[reset], [blue]ult[reset], "
"[blue]ule[reset], [blue]ugt[reset], [blue]uge[reset]")
MIE_DIAG_MSG_LIST_END(mie_arith_msg)

View File

@@ -1,4 +1,4 @@
#include <blue/core/btree.h>
#include <fx/core/bst.h>
#include <mie/ctx.h>
#include <mie/dialect/builtin.h>
#include <stdlib.h>
@@ -10,19 +10,19 @@ typedef union float_key {
} float_key;
struct float_width_cache_entry {
b_btree_node e_node;
fx_bst_node e_node;
float_key e_key;
struct mie_float e_value;
};
struct float_width_cache {
b_btree_node c_node;
fx_bst_node c_node;
size_t c_width;
b_btree c_floats;
fx_bst c_floats;
};
struct mie_float_cache {
b_btree c_widths;
fx_bst c_widths;
};
static int float_key_compare(const float_key *a, const float_key *b)
@@ -30,38 +30,38 @@ 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(
static FX_BST_DEFINE_SIMPLE_INSERT(
struct float_width_cache, c_node, c_width, put_width_cache);
static B_BTREE_DEFINE_SIMPLE_GET(
static FX_BST_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)
void put_float(fx_bst *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);
if (!tree->bst_root) {
tree->bst_root = &node->e_node;
fx_bst_insert_fixup(tree, &node->e_node);
return;
}
b_btree_node *cur = tree->b_root;
fx_bst_node *cur = tree->bst_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;
= fx_unbox(struct float_width_cache_entry, cur, e_node);
fx_bst_node *next = NULL;
int cmp = float_key_compare(&node->e_key, &cur_node->e_key);
if (cmp >= 0) {
next = b_btree_right(cur);
next = fx_bst_right(cur);
if (!next) {
b_btree_put_right(cur, &node->e_node);
fx_bst_put_right(cur, &node->e_node);
break;
}
} else if (cmp < 0) {
next = b_btree_left(cur);
next = fx_bst_left(cur);
if (!next) {
b_btree_put_left(cur, &node->e_node);
fx_bst_put_left(cur, &node->e_node);
break;
}
} else {
@@ -71,20 +71,20 @@ void put_float(b_btree *tree, struct float_width_cache_entry *node)
cur = next;
}
b_btree_insert_fixup(tree, &node->e_node);
fx_bst_insert_fixup(tree, &node->e_node);
}
static struct float_width_cache_entry *get_float(const b_btree *tree, float_key key)
static struct float_width_cache_entry *get_float(const fx_bst *tree, float_key key)
{
b_btree_node *cur = tree->b_root;
fx_bst_node *cur = tree->bst_root;
while (cur) {
struct float_width_cache_entry *cur_node
= b_unbox(struct float_width_cache_entry, cur, e_node);
= fx_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);
cur = fx_bst_right(cur);
} else if (cmp < 0) {
cur = b_btree_left(cur);
cur = fx_bst_left(cur);
} else {
return cur_node;
}
@@ -109,13 +109,13 @@ static struct float_width_cache *float_width_cache_create(size_t width)
static void float_width_cache_destroy(struct float_width_cache *cache)
{
b_btree_node *cur = b_btree_first(&cache->c_floats);
fx_bst_node *cur = fx_bst_first(&cache->c_floats);
while (cur) {
b_btree_node *next = b_btree_next(cur);
b_btree_delete(&cache->c_floats, cur);
fx_bst_node *next = fx_bst_next(cur);
fx_bst_delete(&cache->c_floats, cur);
struct float_width_cache_entry *entry
= b_unbox(struct float_width_cache_entry, cur, e_node);
= fx_unbox(struct float_width_cache_entry, cur, e_node);
free(entry);
cur = next;
@@ -170,13 +170,13 @@ struct mie_float_cache *mie_float_cache_create(void)
void mie_float_cache_destroy(struct mie_float_cache *cache)
{
b_btree_node *cur = b_btree_first(&cache->c_widths);
fx_bst_node *cur = fx_bst_first(&cache->c_widths);
while (cur) {
b_btree_node *next = b_btree_next(cur);
b_btree_delete(&cache->c_widths, cur);
fx_bst_node *next = fx_bst_next(cur);
fx_bst_delete(&cache->c_widths, cur);
struct float_width_cache *width_cache
= b_unbox(struct float_width_cache, cur, c_node);
= fx_unbox(struct float_width_cache, cur, c_node);
float_width_cache_destroy(width_cache);
cur = next;

View File

@@ -1,32 +1,32 @@
#include <blue/core/btree.h>
#include <fx/core/bst.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;
fx_bst_node e_node;
struct mie_int e_value;
};
struct int_width_cache {
b_btree_node c_node;
fx_bst_node c_node;
size_t c_width;
b_btree c_ints;
fx_bst c_ints;
};
struct mie_int_cache {
b_btree c_widths;
fx_bst c_widths;
};
static B_BTREE_DEFINE_SIMPLE_INSERT(
static FX_BST_DEFINE_SIMPLE_INSERT(
struct int_width_cache, c_node, c_width, put_width_cache);
static B_BTREE_DEFINE_SIMPLE_GET(
static FX_BST_DEFINE_SIMPLE_GET(
struct int_width_cache, size_t, c_node, c_width, get_width_cache);
static B_BTREE_DEFINE_SIMPLE_INSERT(
static FX_BST_DEFINE_SIMPLE_INSERT(
struct int_width_cache_entry, e_node, e_value.i_val.v_small, put_int);
static B_BTREE_DEFINE_SIMPLE_GET(
static FX_BST_DEFINE_SIMPLE_GET(
struct int_width_cache_entry, uint64_t, e_node, e_value.i_val.v_small,
get_int);
@@ -46,13 +46,13 @@ static struct int_width_cache *int_width_cache_create(size_t width)
static void int_width_cache_destroy(struct int_width_cache *cache)
{
b_btree_node *cur = b_btree_first(&cache->c_ints);
fx_bst_node *cur = fx_bst_first(&cache->c_ints);
while (cur) {
b_btree_node *next = b_btree_next(cur);
b_btree_delete(&cache->c_ints, cur);
fx_bst_node *next = fx_bst_next(cur);
fx_bst_delete(&cache->c_ints, cur);
struct int_width_cache_entry *entry
= b_unbox(struct int_width_cache_entry, cur, e_node);
= fx_unbox(struct int_width_cache_entry, cur, e_node);
free(entry);
cur = next;
@@ -96,13 +96,13 @@ struct mie_int_cache *mie_int_cache_create(void)
void mie_int_cache_destroy(struct mie_int_cache *cache)
{
b_btree_node *cur = b_btree_first(&cache->c_widths);
fx_bst_node *cur = fx_bst_first(&cache->c_widths);
while (cur) {
b_btree_node *next = b_btree_next(cur);
b_btree_delete(&cache->c_widths, cur);
fx_bst_node *next = fx_bst_next(cur);
fx_bst_delete(&cache->c_widths, cur);
struct int_width_cache *width_cache
= b_unbox(struct int_width_cache, cur, c_node);
= fx_unbox(struct int_width_cache, cur, c_node);
int_width_cache_destroy(width_cache);
cur = next;

View File

@@ -1,14 +1,86 @@
#include <mie/dialect/arith.h>
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
#include <mie/ir/op-definition.h>
#include <mie/ir/op.h>
#include <mie/macros.h>
#include <mie/parse/parser.h>
#include <mie/print/printer.h>
#include <mie/type/type.h>
static enum mie_status print(const struct mie_op *op, b_stream *out)
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
if (MIE_VECTOR_COUNT(op->op_args) != 2) {
return MIE_SUCCESS;
}
const struct mie_op_arg *left = &op->op_args.items[0];
const struct mie_op_arg *right = &op->op_args.items[1];
fx_stream_write_char(printer->p_stream, ' ');
mie_printer_print_op_arg(printer, left, false);
fx_stream_write_string(printer->p_stream, ", ", NULL);
mie_printer_print_op_arg(printer, right, false);
fx_stream_write_string(printer->p_stream, " : ", NULL);
mie_printer_print_type(printer, mie_op_arg_get_type(left));
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
static enum mie_status parse(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out)
{
struct mie_file_span span;
if (MIE_VECTOR_COUNT(out->op_result) != 1) {
mie_op_get_results_span(out, &span);
mie_parser_report_error_simple(
parser, "builtin",
MIE_BUILTIN_E_INCORRECT_NUMBER_OF_RESULTS,
MIE_BUILTIN_MSG_OP_INCORRECT_NUMBER_OF_RESULTS, &span);
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_parameter_list(
parser, false, MIE_VECTOR_REF(out->op_args),
"arithmetic operation arguments")) {
return MIE_ERR_BAD_SYNTAX;
}
if (MIE_VECTOR_COUNT(out->op_args) != 2) {
mie_op_get_args_span(out, &span);
mie_parser_report_error_simple(
parser, "builtin",
MIE_BUILTIN_E_INCORRECT_NUMBER_OF_ARGUMENTS,
MIE_BUILTIN_MSG_OP_INCORRECT_NUMBER_OF_ARGS, &span);
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_COLON)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_COLON, "arithmetic operation type");
return MIE_ERR_BAD_SYNTAX;
}
const struct mie_type *type = NULL;
if (!mie_parser_parse_type(
parser, "arithmetic operation type", &type, &span)) {
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_type_is(type, "builtin", "float")) {
mie_parser_report_error_simple(
parser, "arith", MIE_ARITH_E_INVALID_FLOAT_TYPE,
MIE_ARITH_MSG_EXPECTED_FLOAT_TYPE, &span);
return MIE_ERR_BAD_SYNTAX;
}
for (size_t i = 0; i < MIE_VECTOR_COUNT(out->op_args); i++) {
out->op_args.items[i].arg_unresolved.reg_type = type;
}
out->op_result.items[0].reg_type = type;
return MIE_SUCCESS;
}

View File

@@ -1,17 +1,110 @@
#include <mie/ctx.h>
#include <mie/dialect/arith.h>
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
#include <mie/ir/emit.h>
#include <mie/ir/op-definition.h>
#include <mie/ir/op.h>
#include <mie/macros.h>
#include <mie/parse/parser.h>
#include <mie/print/printer.h>
#include <mie/type/type.h>
static enum mie_status print(const struct mie_op *op, b_stream *out)
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
if (MIE_VECTOR_COUNT(op->op_args) != 2) {
return MIE_SUCCESS;
}
const struct mie_op_arg *left = &op->op_args.items[0];
const struct mie_op_arg *right = &op->op_args.items[1];
fx_stream_write_char(printer->p_stream, ' ');
mie_printer_print_op_arg(printer, left, false);
fx_stream_write_string(printer->p_stream, ", ", NULL);
mie_printer_print_op_arg(printer, right, false);
fx_stream_write_string(printer->p_stream, " : ", NULL);
mie_printer_print_type(printer, mie_op_arg_get_type(left));
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
static enum mie_status parse(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out)
{
struct mie_file_span span;
if (MIE_VECTOR_COUNT(out->op_result) != 1) {
mie_op_get_results_span(out, &span);
mie_parser_report_error_simple(
parser, "builtin",
MIE_BUILTIN_E_INCORRECT_NUMBER_OF_RESULTS,
MIE_BUILTIN_MSG_OP_INCORRECT_NUMBER_OF_RESULTS, &span);
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_parameter_list(
parser, false, MIE_VECTOR_REF(out->op_args),
"arithmetic operation arguments")) {
return MIE_ERR_BAD_SYNTAX;
}
if (MIE_VECTOR_COUNT(out->op_args) != 2) {
mie_op_get_args_span(out, &span);
mie_parser_report_error_simple(
parser, "builtin",
MIE_BUILTIN_E_INCORRECT_NUMBER_OF_ARGUMENTS,
MIE_BUILTIN_MSG_OP_INCORRECT_NUMBER_OF_ARGS, &span);
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_COLON)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_COLON, "arithmetic operation type");
return MIE_ERR_BAD_SYNTAX;
}
const struct mie_type *type = NULL;
if (!mie_parser_parse_type(
parser, "arithmetic operation type", &type, &span)) {
return MIE_ERR_BAD_SYNTAX;
}
bool is_int_type = mie_type_is(type, "builtin", "int")
|| mie_type_is(type, "builtin", "index");
if (!is_int_type) {
mie_parser_report_error_simple(
parser, "arith", MIE_ARITH_E_INVALID_INTEGER_TYPE,
MIE_ARITH_MSG_EXPECTED_INTEGER_TYPE, &span);
return MIE_ERR_BAD_SYNTAX;
}
for (size_t i = 0; i < MIE_VECTOR_COUNT(out->op_args); i++) {
out->op_args.items[i].arg_unresolved.reg_type = type;
}
out->op_result.items[0].reg_type = type;
return MIE_SUCCESS;
}
struct mie_register *mie_arith_addi_put(
struct mie_emitter *e, struct mie_register *left,
struct mie_register *right, const char *name)
{
struct mie_register *args[] = {left, right};
const size_t nr_args = sizeof args / sizeof args[0];
struct mie_op *op = mie_emitter_put_op(e, "arith", "addi", args, nr_args);
const struct mie_type *ty = left->reg_type;
struct mie_register *result = mie_op_add_result(op, ty);
mie_emitter_put_name(e, &result->reg_name, name);
return result;
}
MIE_OP_DEFINITION_BEGIN(mie_arith_addi, "addi")
MIE_OP_DEFINITION_PRINT(print);
MIE_OP_DEFINITION_PARSE(parse);

176
mie/dialect/arith/op/cmpi.c Normal file
View File

@@ -0,0 +1,176 @@
#include <mie/diag/diag.h>
#include <mie/dialect/arith.h>
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
#include <mie/ir/emit.h>
#include <mie/ir/op-definition.h>
#include <mie/ir/op.h>
#include <mie/macros.h>
#include <mie/parse/parser.h>
#include <mie/print/printer.h>
#include <mie/type/type.h>
#define PREDICATE(id, str) [MIE_ARITH_CMPI_##id] = str
static const char *predicates[] = {
PREDICATE(EQ, "eq"), PREDICATE(NE, "ne"), PREDICATE(SLT, "slt"),
PREDICATE(SLE, "sle"), PREDICATE(SGT, "sgt"), PREDICATE(SGE, "sge"),
PREDICATE(ULT, "ult"), PREDICATE(ULE, "ule"), PREDICATE(UGT, "ugt"),
PREDICATE(UGE, "uge"),
};
static const size_t nr_predicates = sizeof predicates / sizeof predicates[0];
static int find_predicate(const char *pred)
{
for (size_t i = 0; i < nr_predicates; i++) {
if (!strcmp(pred, predicates[i])) {
return i;
}
}
return -1;
}
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
if (MIE_VECTOR_COUNT(op->op_args) != 2
|| MIE_VECTOR_COUNT(op->op_result) != 1) {
return MIE_SUCCESS;
}
const struct mie_op_arg *left = &op->op_args.items[0];
const struct mie_op_arg *right = &op->op_args.items[1];
const struct mie_register *result = &op->op_result.items[0];
const struct mie_attribute *pred_attr
= mie_attribute_map_get(&op->op_attrib, "predicate");
long long pred;
if (!mie_int_get_value(pred_attr, &pred)) {
return MIE_SUCCESS;
}
fx_stream_write_char(printer->p_stream, ' ');
if (pred < 0 || pred >= nr_predicates) {
return MIE_ERR_BAD_STATE;
}
fx_stream_write_string(printer->p_stream, predicates[pred], NULL);
fx_stream_write_char(printer->p_stream, ' ');
mie_printer_print_op_arg(printer, left, false);
fx_stream_write_string(printer->p_stream, ", ", NULL);
mie_printer_print_op_arg(printer, right, false);
fx_stream_write_string(printer->p_stream, " : ", NULL);
mie_printer_print_type(printer, mie_op_arg_get_type(left));
return MIE_SUCCESS;
}
static enum mie_status parse(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out)
{
struct mie_file_span span;
if (MIE_VECTOR_COUNT(out->op_result) != 1) {
mie_op_get_results_span(out, &span);
mie_parser_report_error_simple(
parser, "builtin",
MIE_BUILTIN_E_INCORRECT_NUMBER_OF_RESULTS,
MIE_BUILTIN_MSG_OP_INCORRECT_NUMBER_OF_RESULTS, &span);
return MIE_ERR_BAD_SYNTAX;
}
fx_string *tmp = mie_parser_get_tempstr(parser);
if (!mie_parser_parse_word(parser, tmp, &span)) {
mie_parser_report_unexpected_token_s(
parser, "predicate word", "comparison operation");
return MIE_ERR_BAD_SYNTAX;
}
int pred = find_predicate(fx_string_ptr(tmp));
if (pred == -1) {
struct mie_diag *diag = mie_parser_report_error_simple(
parser, "arith", MIE_ARITH_E_INVALID_COMPARISON_PREDICATE,
MIE_ARITH_MSG_INVALID_COMPARISON_PREDICATE, &span);
mie_diag_push_msg(
diag, mie_parser_get_mie_ctx(parser), "arith",
MIE_ARITH_MSG_VALID_COMPARISON_PREDICATES);
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_parameter_list(
parser, false, MIE_VECTOR_REF(out->op_args),
"comparison operands")) {
return MIE_ERR_BAD_SYNTAX;
}
if (MIE_VECTOR_COUNT(out->op_args) != 2) {
mie_op_get_args_span(out, &span);
mie_parser_report_error_simple(
parser, "builtin",
MIE_BUILTIN_E_INCORRECT_NUMBER_OF_ARGUMENTS,
MIE_BUILTIN_MSG_OP_INCORRECT_NUMBER_OF_ARGS, &span);
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_COLON)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_COLON, "comparison operand type");
return MIE_ERR_BAD_SYNTAX;
}
const struct mie_type *type;
if (!mie_parser_parse_type(parser, "comparison operand type", &type, &span)) {
return MIE_ERR_BAD_SYNTAX;
}
bool is_int_type = mie_type_is(type, "builtin", "int")
|| mie_type_is(type, "builtin", "index");
if (!is_int_type) {
mie_parser_report_error_simple(
parser, "arith", MIE_ARITH_E_INVALID_INTEGER_TYPE,
MIE_ARITH_MSG_EXPECTED_INTEGER_TYPE, &span);
return MIE_ERR_BAD_SYNTAX;
}
for (size_t i = 0; i < MIE_VECTOR_COUNT(out->op_args); i++) {
out->op_args.items[i].arg_unresolved.reg_type = type;
}
out->op_result.items[0].reg_type
= mie_ctx_get_int_type(mie_parser_get_mie_ctx(parser), 1);
struct mie_attribute *pred_attribute
= mie_ctx_get_int(mie_parser_get_mie_ctx(parser), pred, 64);
mie_attribute_map_put(
&out->op_attrib, "predicate", pred_attribute,
MIE_ATTRMAP_F_REPLACE);
return MIE_SUCCESS;
}
struct mie_register *mie_arith_cmpi_put(
struct mie_emitter *e, enum mie_arith_cmpi_predicate pred,
struct mie_register *left, struct mie_register *right, const char *name)
{
struct mie_register *args[] = {left, right};
const size_t nr_args = sizeof args / sizeof args[0];
struct mie_op *op = mie_emitter_put_op(e, "arith", "cmpi", args, nr_args);
const struct mie_type *ty = left->reg_type;
struct mie_register *result = mie_op_add_result(op, ty);
mie_emitter_put_name(e, &result->reg_name, name);
struct mie_attribute *pred_attribute
= mie_ctx_get_int(mie_emitter_get_ctx(e), pred, 64);
mie_attribute_map_put(
&op->op_attrib, "predicate", pred_attribute, MIE_ATTRMAP_F_REPLACE);
return result;
}
MIE_OP_DEFINITION_BEGIN(mie_arith_cmpi, "cmpi")
MIE_OP_DEFINITION_PRINT(print);
MIE_OP_DEFINITION_PARSE(parse);
MIE_OP_DEFINITION_END()

View File

@@ -0,0 +1,199 @@
#include <mie/attribute/attribute.h>
#include <mie/dialect/arith.h>
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
#include <mie/ir/emit.h>
#include <mie/ir/op-definition.h>
#include <mie/ir/op.h>
#include <mie/macros.h>
#include <mie/parse/parser.h>
#include <mie/print/printer.h>
#include <mie/type/type.h>
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
const struct mie_attribute *value
= mie_attribute_map_get(&op->op_attrib, "value");
if (!value) {
return MIE_SUCCESS;
}
const struct mie_type *type = NULL;
if (mie_attribute_check_name(value, "builtin", "int")) {
const struct mie_int *i = (const struct mie_int *)value;
fx_stream_write_fmt(
printer->p_stream, NULL, " %lld : ", i->i_val.v_small);
type = i->i_type;
} else if (mie_attribute_check_name(value, "builtin", "float")) {
const struct mie_float *f = (const struct mie_float *)value;
double d;
mie_float_get_value(value, &d);
fx_stream_write_fmt(printer->p_stream, NULL, " %g : ", d);
type = f->f_type;
} else {
return MIE_SUCCESS;
}
mie_printer_print_type(printer, type);
return MIE_SUCCESS;
}
static enum mie_status parse_int(
struct mie_parser *parser, long long i, struct mie_file_span *loc,
struct mie_op *out)
{
if (!mie_parser_parse_symbol(parser, MIE_SYM_COLON)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_COLON, "arithmetic constant type");
return MIE_ERR_BAD_SYNTAX;
}
const struct mie_type *type = NULL;
struct mie_file_span type_span;
if (!mie_parser_parse_type(
parser, "arithmetic constant type", &type, &type_span)) {
mie_parser_report_unexpected_token(
parser, MIE_TOK_TYPENAME, "arithmetic constant type");
return MIE_ERR_BAD_SYNTAX;
}
struct mie_attribute *value = NULL;
if (mie_type_is(type, "builtin", "int")) {
value = mie_ctx_get_int(
mie_parser_get_mie_ctx(parser), i,
mie_int_type_get_width(type));
} else if (mie_type_is(type, "builtin", "index")) {
value = mie_ctx_get_index(mie_parser_get_mie_ctx(parser), i);
} else {
mie_parser_report_error_simple(
parser, "arith", MIE_ARITH_E_INVALID_INTEGER_TYPE,
MIE_ARITH_MSG_EXPECTED_INTEGER_TYPE, &type_span);
}
if (MIE_VECTOR_COUNT(out->op_result) != 1) {
mie_parser_report_error_simple(
parser, "builtin",
MIE_BUILTIN_E_INCORRECT_NUMBER_OF_RESULTS,
MIE_BUILTIN_MSG_OP_EXPECTS_X_RESULTS, &type_span);
return MIE_ERR_BAD_SYNTAX;
}
mie_attribute_map_put(
&out->op_attrib, "value", value, MIE_ATTRMAP_F_REPLACE);
out->op_result.items[0].reg_type = type;
return MIE_SUCCESS;
}
static enum mie_status parse_float(
struct mie_parser *parser, double d, struct mie_file_span *loc,
struct mie_op *out)
{
if (!mie_parser_parse_symbol(parser, MIE_SYM_COLON)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_COLON, "arithmetic constant type");
return MIE_ERR_BAD_SYNTAX;
}
const struct mie_type *type = NULL;
struct mie_file_span type_span;
if (!mie_parser_parse_type(
parser, "arithmetic constant type", &type, &type_span)) {
mie_parser_report_unexpected_token(
parser, MIE_TOK_TYPENAME, "arithmetic constant type");
return MIE_ERR_BAD_SYNTAX;
}
struct mie_attribute *value = NULL;
if (mie_type_is(type, "builtin", "float")) {
value = mie_ctx_get_float(
mie_parser_get_mie_ctx(parser), d,
mie_float_type_get_width(type));
} else {
mie_parser_report_error_simple(
parser, "arith", MIE_ARITH_E_INVALID_FLOAT_TYPE,
MIE_ARITH_MSG_EXPECTED_FLOAT_TYPE, &type_span);
return MIE_ERR_BAD_SYNTAX;
}
if (MIE_VECTOR_COUNT(out->op_result) != 1) {
mie_parser_report_error_simple(
parser, "builtin",
MIE_BUILTIN_E_INCORRECT_NUMBER_OF_RESULTS,
MIE_BUILTIN_MSG_OP_EXPECTS_X_RESULTS, &type_span);
return MIE_ERR_BAD_SYNTAX;
}
mie_attribute_map_put(
&out->op_attrib, "value", value, MIE_ATTRMAP_F_REPLACE);
out->op_result.items[0].reg_type = type;
return MIE_SUCCESS;
}
static enum mie_status parse(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out)
{
double d;
long long i;
struct mie_file_span span;
if (mie_parser_parse_int(parser, &i, &span)) {
return parse_int(parser, i, &span, out);
} else if (mie_parser_parse_float(parser, &d, &span)) {
return parse_float(parser, d, &span, out);
} else {
struct mie_parser_item required[] = {
MIE_PARSE_ITEM_TOKEN(MIE_TOK_INT),
MIE_PARSE_ITEM_TOKEN(MIE_TOK_FLOAT),
MIE_PARSE_ITEM_NONE,
};
mie_parser_report_unexpected_token_v(
parser, required, "arithmetic constant");
return MIE_ERR_BAD_SYNTAX;
}
}
struct mie_register *mie_arith_constant_i_put(
struct mie_emitter *e, long long value, const char *name)
{
struct mie_op *op = mie_emitter_put_op(e, "arith", "constant", NULL, 0);
const struct mie_type *ty
= mie_ctx_get_int_type(mie_emitter_get_ctx(e), 32);
struct mie_register *result = mie_op_add_result(op, ty);
mie_emitter_put_name(e, &result->reg_name, name);
struct mie_attribute *val
= mie_ctx_get_int(mie_emitter_get_ctx(e), value, 32);
mie_attribute_map_put(&op->op_attrib, "value", val, MIE_ATTRMAP_F_REPLACE);
return result;
}
struct mie_register *mie_arith_constant_f_put(
struct mie_emitter *e, long long value, const char *name)
{
struct mie_op *op = mie_emitter_put_op(e, "arith", "constant", NULL, 0);
const struct mie_type *ty
= mie_ctx_get_int_type(mie_emitter_get_ctx(e), 32);
struct mie_register *result = mie_op_add_result(op, ty);
mie_emitter_put_name(e, &result->reg_name, name);
struct mie_attribute *val
= mie_ctx_get_float(mie_emitter_get_ctx(e), value, 32);
mie_attribute_map_put(&op->op_attrib, "value", val, MIE_ATTRMAP_F_REPLACE);
return result;
}
MIE_OP_DEFINITION_BEGIN(mie_arith_constant, "constant")
MIE_OP_DEFINITION_PRINT(print);
MIE_OP_DEFINITION_PARSE(parse);
MIE_OP_DEFINITION_END()

View File

@@ -0,0 +1,103 @@
#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_array *array = (const struct mie_array *)value;
if (!(out->p_flags & MIE_PRINT_F_ABBREVIATED)) {
fx_stream_write_string(out->p_stream, "#builtin.array<", NULL);
}
fx_stream_write_char(out->p_stream, '[');
for (size_t i = 0; i < MIE_VECTOR_COUNT(array->a_items); i++) {
if (i > 0) {
fx_stream_write_char(out->p_stream, ',');
}
fx_stream_write_char(out->p_stream, ' ');
mie_printer_print_attribute(out, array->a_items.items[i]);
}
if (MIE_VECTOR_COUNT(array->a_items) != 0) {
fx_stream_write_char(out->p_stream, ' ');
}
fx_stream_write_char(out->p_stream, ']');
if (!(out->p_flags & MIE_PRINT_F_ABBREVIATED)) {
fx_stream_write_char(out->p_stream, '>');
}
return MIE_SUCCESS;
}
static struct mie_array *array_create(struct mie_ctx *ctx)
{
struct mie_array *array = malloc(sizeof *array);
if (!array) {
return NULL;
}
memset(array, 0x0, sizeof *array);
array->a_base.a_def
= mie_ctx_get_attribute_definition(ctx, "builtin", "array");
return array;
}
static enum mie_status parse(
struct mie_parser *ctx, const struct mie_attribute **out)
{
if (!mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_BRACKET)) {
return MIE_ERR_BAD_SYNTAX;
}
struct mie_array *array = array_create(mie_parser_get_mie_ctx(ctx));
if (!array) {
return MIE_ERR_NO_MEMORY;
}
const struct mie_attribute *item = NULL;
if (!mie_parser_parse_attribute(ctx, &item)) {
free(array);
return MIE_ERR_BAD_FORMAT;
}
mie_vector_push_back(array->a_items, &item, NULL);
while (1) {
if (mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_BRACKET)) {
break;
}
if (!mie_parser_parse_symbol(ctx, MIE_SYM_COMMA)) {
return false;
}
if (!mie_parser_parse_attribute(ctx, &item)) {
free(array);
return MIE_ERR_BAD_FORMAT;
}
mie_vector_push_back(array->a_items, &item, NULL);
}
*out = (struct mie_attribute *)array;
return MIE_SUCCESS;
}
MIE_ATTRIBUTE_DEFINITION_BEGIN(mie_builtin_array, "array")
MIE_ATTRIBUTE_DEFINITION_STRUCT(struct mie_array);
MIE_ATTRIBUTE_DEFINITION_PRINT(print);
MIE_ATTRIBUTE_DEFINITION_PARSE(parse);
MIE_ATTRIBUTE_DEFINITION_END()

View File

@@ -1,6 +1,6 @@
#include "../float.h"
#include <blue/core/bstr.h>
#include <fx/core/bstr.h>
#include <mie/attribute/attribute-definition.h>
#include <mie/attribute/attribute.h>
#include <mie/ctx.h>
@@ -17,28 +17,28 @@ static enum mie_status print(
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);
fx_stream_write_string(out->p_stream, "#builtin.float<", NULL);
}
switch (float_ty->f_width) {
case MIE_FLOAT_32:
b_stream_write_fmt(
fx_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(
fx_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(
fx_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);
fx_stream_write_string(out->p_stream, ">", NULL);
}
return MIE_SUCCESS;
@@ -51,30 +51,52 @@ static enum mie_status parse(
struct mie_file_span span;
if (!mie_parser_parse_float(ctx, &value, &span)) {
return false;
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)) {
return false;
return MIE_ERR_BAD_SYNTAX;
}
const struct mie_type *type = NULL;
if (!mie_parser_parse_type(ctx, &type)) {
return false;
if (!mie_parser_parse_type(ctx, NULL, &type, NULL)) {
return MIE_ERR_BAD_SYNTAX;
}
size_t width = mie_float_type_get_width(type);
if (width == (size_t)-1) {
return false;
return MIE_ERR_BAD_SYNTAX;
}
struct mie_attribute *v
= mie_ctx_get_float(mie_parser_get_mie_ctx(ctx), value, width);
if (!v) {
return false;
return MIE_ERR_NO_MEMORY;
}
*out = v;
return MIE_SUCCESS;
}
bool mie_float_get_value(const struct mie_attribute *attrib, double *out)
{
if (!mie_attribute_check_name(attrib, "builtin", "float")) {
return false;
}
const struct mie_float *v = (const struct mie_float *)attrib;
switch (mie_float_type_get_width(v->f_type)) {
case MIE_FLOAT_32:
*out = v->f_val.v_32;
break;
case MIE_FLOAT_64:
*out = v->f_val.v_64;
break;
default:
return false;
}
return true;
}

View File

@@ -1,6 +1,6 @@
#include "../int.h"
#include <blue/core/bstr.h>
#include <fx/core/bstr.h>
#include <mie/attribute/attribute-definition.h>
#include <mie/attribute/attribute.h>
#include <mie/ctx.h>
@@ -15,21 +15,35 @@ static enum mie_status print(
{
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);
bool abbrev = ((out->p_flags & MIE_PRINT_F_ABBREVIATED) != 0);
if (!abbrev) {
fx_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);
fx_stream_write_fmt(
out->p_stream, NULL, "%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);
fx_stream_write_fmt(out->p_stream, NULL, "INF", int_ty->i_width);
}
if (!(out->p_flags & MIE_PRINT_F_ABBREVIATED)) {
b_stream_write_string(out->p_stream, ">", NULL);
if (int_ty->i_width != 64 || !abbrev) {
fx_stream_write_string(out->p_stream, " : ", NULL);
if (abbrev) {
fx_stream_write_fmt(
out->p_stream, NULL, "i%zu", int_ty->i_width);
} else {
fx_stream_write_fmt(
out->p_stream, NULL, "!builtin.int<%zu>",
int_ty->i_width);
}
}
if (!abbrev) {
fx_stream_write_string(out->p_stream, ">", NULL);
}
return MIE_SUCCESS;
@@ -42,30 +56,43 @@ static enum mie_status parse(
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;
return MIE_ERR_BAD_SYNTAX;
}
const struct mie_type *type = NULL;
if (!mie_parser_parse_type(ctx, &type)) {
size_t width = (size_t)-1;
if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)) {
width = 64;
} else if (!mie_parser_parse_type(ctx, NULL, &type, NULL)) {
return false;
} else {
width = mie_int_type_get_width(type);
}
size_t width = mie_int_type_get_width(type);
if (width == (size_t)-1) {
return false;
return MIE_ERR_BAD_SYNTAX;
}
struct mie_attribute *v
= mie_ctx_get_int(mie_parser_get_mie_ctx(ctx), value, width);
if (!v) {
return false;
return MIE_ERR_NO_MEMORY;
}
*out = v;
return MIE_SUCCESS;
}
bool mie_int_get_value(const struct mie_attribute *attrib, long long *out)
{
if (!mie_attribute_check_name(attrib, "builtin", "int")) {
return false;
}
const struct mie_int *v = (const struct mie_int *)attrib;
*out = v->i_val.v_small;
return true;
}

View File

@@ -11,9 +11,9 @@ static enum mie_status print(
{
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);
fx_stream_write_fmt(out->p_stream, NULL, "\"%s\"", str->str_val);
} else {
b_stream_write_fmt(
fx_stream_write_fmt(
out->p_stream, NULL, "#builtin.string<\"%s\">",
str->str_val);
}
@@ -23,21 +23,31 @@ static enum mie_status print(
static enum mie_status parse(
struct mie_parser *ctx, const struct mie_attribute **out)
{
b_string *str = mie_parser_get_tempstr(ctx);
fx_string *str = mie_parser_get_tempstr(ctx);
struct mie_file_span span;
if (!mie_parser_parse_string(ctx, str, &span)) {
return false;
return MIE_ERR_BAD_SYNTAX;
}
struct mie_attribute *v = mie_ctx_get_string(
mie_parser_get_mie_ctx(ctx), b_string_ptr(str));
mie_parser_get_mie_ctx(ctx), fx_string_ptr(str));
if (!v) {
return false;
return MIE_ERR_NO_MEMORY;
}
*out = v;
return true;
return MIE_SUCCESS;
}
const char *mie_string_get_cstr(const struct mie_attribute *attrib)
{
if (!mie_attribute_check_name(attrib, "builtin", "string")) {
return NULL;
}
const struct mie_string *str = (const struct mie_string *)attrib;
return str->str_val;
}
MIE_ATTRIBUTE_DEFINITION_BEGIN(mie_builtin_string, "string")

View File

@@ -0,0 +1,81 @@
#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>
struct mie_attribute *mie_type_attr_create(
struct mie_ctx *ctx, const struct mie_type *ty)
{
struct mie_type_attr *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
memset(out, 0x0, sizeof *out);
out->ty_base.a_def
= mie_ctx_get_attribute_definition(ctx, "builtin", "type");
out->ty_value = ty;
return (struct mie_attribute *)out;
}
static enum mie_status print(
const struct mie_attribute *value, struct mie_printer *out)
{
const struct mie_type_attr *ty = (const struct mie_type_attr *)value;
if (!(out->p_flags & MIE_PRINT_F_ABBREVIATED)) {
fx_stream_write_string(out->p_stream, "#builtin.type<", NULL);
}
mie_printer_print_type(out, ty->ty_value);
if (!(out->p_flags & MIE_PRINT_F_ABBREVIATED)) {
fx_stream_write_char(out->p_stream, '>');
}
return MIE_SUCCESS;
}
static enum mie_status parse(
struct mie_parser *ctx, const struct mie_attribute **out)
{
struct mie_type_attr *ty = (struct mie_type_attr *)mie_type_attr_create(
mie_parser_get_mie_ctx(ctx), NULL);
if (!ty) {
return MIE_ERR_NO_MEMORY;
}
const struct mie_type *type = NULL;
if (!mie_parser_parse_type(ctx, NULL, &type, NULL)) {
free(ty);
return MIE_ERR_BAD_FORMAT;
}
ty->ty_value = type;
*out = (struct mie_attribute *)ty;
return MIE_SUCCESS;
}
const struct mie_type *mie_type_attr_get_type(const struct mie_attribute *attrib)
{
if (!mie_attribute_check_name(attrib, "builtin", "type")) {
return NULL;
}
const struct mie_type_attr *ty = (const struct mie_type_attr *)attrib;
return ty->ty_value;
}
MIE_ATTRIBUTE_DEFINITION_BEGIN(mie_builtin_type, "type")
MIE_ATTRIBUTE_DEFINITION_STRUCT(struct mie_type_attr);
MIE_ATTRIBUTE_DEFINITION_PRINT(print);
MIE_ATTRIBUTE_DEFINITION_PARSE(parse);
MIE_ATTRIBUTE_DEFINITION_END()

View File

@@ -1,4 +1,6 @@
#include <mie/ctx.h>
#include <mie/diag/class.h>
#include <mie/diag/msg.h>
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
#include <mie/macros.h>
@@ -81,17 +83,26 @@ struct mie_attribute *mie_ctx_get_index(struct mie_ctx *ctx, size_t val)
dialect->ctx_indices, ctx, val);
}
MIE_DIAG_CLASS_LIST_EXTERN(mie_builtin_diag);
MIE_DIAG_MSG_LIST_EXTERN(mie_builtin_msg);
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_DIAG_CLASS_LIST(mie_builtin_diag);
MIE_DIALECT_DIAG_MSG_LIST(mie_builtin_msg);
MIE_DIALECT_ADD_TRAIT(mie_builtin_isolated_from_above);
MIE_DIALECT_ADD_TRAIT(mie_builtin_symbol_table);
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_TYPE(mie_builtin_string);
MIE_DIALECT_ADD_TYPE(mie_builtin_memref);
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_ADD_TRAIT(mie_builtin_symbol_table);
MIE_DIALECT_ADD_ATTRIBUTE(mie_builtin_type);
MIE_DIALECT_ADD_ATTRIBUTE(mie_builtin_string);
MIE_DIALECT_ADD_INTERFACE(mie_builtin_symbol);
MIE_DIALECT_ADD_ATTRIBUTE(mie_builtin_array);
MIE_DIALECT_ADD_OP(mie_builtin_module);
MIE_DIALECT_END()

View File

@@ -0,0 +1,99 @@
#include <mie/diag/class.h>
#include <mie/diag/msg.h>
#include <mie/dialect/builtin.h>
#include <mie/macros.h>
#define MIE_DIAG_CLASS_PREFIX MIE_BUILTIN_E
#define MIE_DIAG_MSG_PREFIX MIE_BUILTIN_MSG
MIE_DIAG_CLASS_LIST_BEGIN(mie_builtin_diag)
MIE_DIAG_CLASS(UNRECOGNISED_TOKEN, ERROR, "Unrecognised token")
MIE_DIAG_CLASS(UNEXPECTED_TOKEN, ERROR, "Unexpected token")
MIE_DIAG_CLASS(UNRESOLVED_TYPE, ERROR, "Unresolved type")
MIE_DIAG_CLASS(UNRESOLVED_VALUE, ERROR, "Unresolved value")
MIE_DIAG_CLASS(UNRESOLVED_SUCCESSOR, ERROR, "Unresolved successor")
MIE_DIAG_CLASS(UNKNOWN_OP, ERROR, "Unknown op")
MIE_DIAG_CLASS(
OP_REQUIRES_PARENT_SCOPE, ERROR, "Op requires parent scope")
MIE_DIAG_CLASS(
INCORRECT_NUMBER_OF_RESULTS, ERROR,
"Incorrect number of results")
MIE_DIAG_CLASS(
INCORRECT_NUMBER_OF_ARGUMENTS, ERROR,
"Incorrect number of arguments")
MIE_DIAG_CLASS(
INCORRECT_NUMBER_OF_TYPES, ERROR, "Incorrect number of types")
MIE_DIAG_CLASS(INCORRECT_TYPE, ERROR, "Incorrect type")
MIE_DIAG_CLASS(INVALID_TYPE, ERROR, "Invalid type")
MIE_DIAG_CLASS(NAME_ALREADY_IN_USE, ERROR, "Name already in use")
MIE_DIAG_CLASS(INTERNAL_ERROR, ERROR, "Internal error")
MIE_DIAG_CLASS_LIST_END(mie_builtin_diag)
MIE_DIAG_MSG_LIST_BEGIN(mie_builtin_msg)
MIE_DIAG_MSG(UNRECOGNISED_TOKEN, "encountered an unrecognised token.")
MIE_DIAG_MSG(UNEXPECTED_TOKEN, "encountered an unexpected token.")
MIE_DIAG_MSG(UNRESOLVED_VALUE, "cannot resolve this value reference.")
MIE_DIAG_MSG(
UNRESOLVED_BUILTIN_TYPE,
"cannot resolve this builtin type reference.")
MIE_DIAG_MSG(
UNRESOLVED_DIALECT_TYPE,
"cannot resolve this dialect type reference.")
MIE_DIAG_MSG(
CANNOT_FIND_BLOCK,
"cannot find a block with this name in this region.")
MIE_DIAG_MSG(
VALUE_DEFINED_IN_NON_DOMINANT_BLOCK,
"this value cannot be referenced here, as it is defined in a "
"block that does not dominate this block.")
MIE_DIAG_MSG(
VALUE_DEFINED_AFTER_USE,
"this value cannot be referenced here, as it is not defined "
"until later in this block.")
MIE_DIAG_MSG(
VALUE_DEFINED_OUTSIDE_ISOLATED_REGION,
"this value cannot be referenced here, as this region is "
"isolated from above, and the definition for this value is "
"outside of this region.")
MIE_DIAG_MSG(
VALUE_DEFINED_IN_BLOCK, "the value is defined in this block.")
MIE_DIAG_MSG(UNKNOWN_OP, "encountered an unknown operation.")
MIE_DIAG_MSG(
OP_REQUIRES_PARENT_SCOPE,
"this operation requires a parent scope.")
MIE_DIAG_MSG(
OP_PARENT_SCOPE_EXAMPLE,
"operations that require a parent scope cannot be used as a "
"top-level operation. try wrapping this operation in a "
"[blue]module[reset].")
MIE_DIAG_MSG(
USE_GENERIC_OP_SYNTAX,
"if this op belongs to an unknown dialect, you can use generic "
"op syntax to represent it.")
MIE_DIAG_MSG(
OP_HAS_NO_PARSER,
"this operation has no associated parser functionality.")
MIE_DIAG_MSG(
DIALECT_INTERNAL_ERROR,
"this error is caused by an internal problem with the relevant "
"dialect. please report the issue to the dialect vendor.")
MIE_DIAG_MSG(
COMPILER_INTERNAL_ERROR,
"this error is caused by an internal compiler issue. please "
"report the issue to the compiler vendor.")
MIE_DIAG_MSG(
NR_RESULT_NAME_OUTPUT_MISMATCH,
"the number of [red]output value names[reset] does not match "
"the number of results.")
MIE_DIAG_MSG(
OP_INCORRECT_NUMBER_OF_ARGS,
"this operation does not have the correct number of arguments.")
MIE_DIAG_MSG(
OP_NR_TYPES_DOESNT_MATCH_NR_ARGS,
"the number of types specified does not match the number of "
"arguments.")
MIE_DIAG_MSG(
OP_NR_TYPES_DOESNT_MATCH_NR_RESULTS,
"the number of types specified does not match the number of "
"results.")
MIE_DIAG_MSG_LIST_END(mie_builtin_msg)

View File

@@ -1,21 +1,21 @@
#include <blue/core/btree.h>
#include <fx/core/bst.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;
fx_bst_node e_node;
struct mie_index e_value;
};
struct mie_index_cache {
b_btree c_entries;
fx_bst c_entries;
};
static B_BTREE_DEFINE_SIMPLE_INSERT(
static FX_BST_DEFINE_SIMPLE_INSERT(
struct index_cache_entry, e_node, e_value.i_value, put_index);
static B_BTREE_DEFINE_SIMPLE_GET(
static FX_BST_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(
@@ -48,13 +48,13 @@ struct mie_index_cache *mie_index_cache_create(void)
void mie_index_cache_destroy(struct mie_index_cache *cache)
{
b_btree_node *cur = b_btree_first(&cache->c_entries);
fx_bst_node *cur = fx_bst_first(&cache->c_entries);
while (cur) {
b_btree_node *next = b_btree_next(cur);
b_btree_delete(&cache->c_entries, cur);
fx_bst_node *next = fx_bst_next(cur);
fx_bst_delete(&cache->c_entries, cur);
struct index_cache_entry *entry
= b_unbox(struct index_cache_entry, cur, e_node);
= fx_unbox(struct index_cache_entry, cur, e_node);
free(entry);
cur = next;

View File

@@ -0,0 +1,44 @@
#include <mie/ctx.h>
#include <mie/dialect/dialect.h>
#include <mie/ir/op-definition.h>
#include <mie/ir/op.h>
#include <mie/ir/region.h>
#include <mie/macros.h>
#include <mie/parse/parser.h>
#include <mie/print/printer.h>
static enum mie_status print(struct mie_printer *out, const struct mie_op *op)
{
fx_stream_write_char(out->p_stream, ' ');
struct mie_region *region = mie_op_get_first_region(op);
if (region) {
mie_printer_print_region(out, region, 0);
}
return MIE_SUCCESS;
}
static enum mie_status parse(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out)
{
struct mie_region *region = mie_op_add_region(out);
if (mie_parser_peek_symbol(parser) != MIE_SYM_LEFT_BRACE) {
mie_parser_report_unexpected_token_s(
parser, "region", "module body");
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_region(parser, out, region, NULL)) {
return MIE_ERR_BAD_SYNTAX;
}
return MIE_SUCCESS;
}
MIE_OP_DEFINITION_BEGIN(mie_builtin_module, "module")
MIE_OP_DEFINITION_PRINT(print);
MIE_OP_DEFINITION_PARSE(parse);
MIE_OP_DEFINITION_TRAIT("builtin", "isolated-from-above");
MIE_OP_DEFINITION_END()

View File

@@ -1,12 +1,12 @@
#include <blue/core/btree.h>
#include <blue/ds/hashmap.h>
#include <fx/core/bst.h>
#include <fx/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;
fx_hashmap *c_entries;
};
static struct mie_string *mie_string_create(
@@ -19,7 +19,7 @@ static struct mie_string *mie_string_create(
out->str_base.a_def
= mie_ctx_get_attribute_definition(ctx, "builtin", "string");
out->str_val = b_strdup(s);
out->str_val = fx_strdup(s);
if (!out->str_val) {
return NULL;
}
@@ -42,8 +42,8 @@ struct mie_string_cache *mie_string_cache_create(void)
memset(out, 0x0, sizeof *out);
out->c_entries = b_hashmap_create(
NULL, (b_hashmap_value_destructor)mie_string_destroy);
out->c_entries = fx_hashmap_create(
NULL, (fx_hashmap_value_destructor)mie_string_destroy);
if (!out->c_entries) {
free(out);
return NULL;
@@ -54,7 +54,7 @@ struct mie_string_cache *mie_string_cache_create(void)
void mie_string_cache_destroy(struct mie_string_cache *cache)
{
b_hashmap_unref(cache->c_entries);
fx_hashmap_unref(cache->c_entries);
free(cache);
}
@@ -62,8 +62,8 @@ 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);
fx_hashmap_key key = {.key_data = s, .key_size = s_len};
const fx_hashmap_value *value = fx_hashmap_get(cache->c_entries, &key);
if (value) {
return value->value_data;
}
@@ -73,8 +73,8 @@ struct mie_string *mie_string_cache_get(
return NULL;
}
b_hashmap_value new_val = {.value_data = str, .value_size = sizeof *str};
b_hashmap_put(cache->c_entries, &key, &new_val);
fx_hashmap_value new_val = {.value_data = str, .value_size = sizeof *str};
fx_hashmap_put(cache->c_entries, &key, &new_val);
return str;
}

View File

@@ -1,6 +1,6 @@
#include "../float.h"
#include <blue/core/bstr.h>
#include <fx/core/bstr.h>
#include <mie/ctx.h>
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
@@ -17,16 +17,16 @@ struct mie_type *mie_ctx_get_float_type(struct mie_ctx *ctx, size_t bit_width)
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);
fx_rope rope_i = FX_ROPE_CHAR('f'), rope_width = FX_ROPE_UINT(bit_width);
fx_rope type_name;
fx_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);
return fx_unbox(struct mie_type, target, ty_id);
}
struct float_type *type = (struct float_type *)mie_type_create(type_info);
@@ -34,7 +34,7 @@ struct mie_type *mie_ctx_get_float_type(struct mie_ctx *ctx, size_t bit_width)
return NULL;
}
type->f_base.ty_name = b_bstr_fmt("builtin.float<%zu>", bit_width);
type->f_base.ty_name = fx_bstr_fmt(NULL, "builtin.float<%zu>", bit_width);
type->f_base.ty_instance_size = sizeof(struct mie_float);
type->f_width = bit_width;
@@ -59,7 +59,7 @@ size_t mie_float_type_get_width(const struct mie_type *type)
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(
fx_stream_write_fmt(
out->p_stream, NULL,
(out->p_flags & MIE_PRINT_F_ABBREVIATED) ? "f%zu" : "!builtin.float<%zu>",
float_type->f_width);

View File

@@ -15,17 +15,7 @@ static void type_init(
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

@@ -1,6 +1,6 @@
#include "../int.h"
#include <blue/core/bstr.h>
#include <fx/core/bstr.h>
#include <mie/ctx.h>
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
@@ -17,16 +17,16 @@ struct mie_type *mie_ctx_get_int_type(struct mie_ctx *ctx, size_t bit_width)
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);
fx_rope rope_i = FX_ROPE_CHAR('i'), rope_width = FX_ROPE_UINT(bit_width);
fx_rope type_name;
fx_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);
return fx_unbox(struct mie_type, target, ty_id);
}
struct int_type *type = (struct int_type *)mie_type_create(type_info);
@@ -34,7 +34,7 @@ struct mie_type *mie_ctx_get_int_type(struct mie_ctx *ctx, size_t bit_width)
return NULL;
}
type->i_base.ty_name = b_bstr_fmt("builtin.int<%zu>", bit_width);
type->i_base.ty_name = fx_bstr_fmt(NULL, "builtin.int<%zu>", bit_width);
type->i_base.ty_instance_size = sizeof(struct mie_int);
type->i_width = bit_width;
@@ -59,7 +59,7 @@ size_t mie_int_type_get_width(const struct mie_type *type)
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(
fx_stream_write_fmt(
out->p_stream, NULL,
(out->p_flags & MIE_PRINT_F_ABBREVIATED) ? "i%zu"
: "!builtin.int<%zu>",

View File

@@ -0,0 +1,290 @@
#include <fx/core/bstr.h>
#include <mie/ctx.h>
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
#include <mie/dialect/memref.h>
#include <mie/macros.h>
#include <mie/parse/parser.h>
#include <mie/print/printer.h>
#include <mie/type/type-definition.h>
#include <mie/type/type.h>
struct memref_type {
struct mie_type m_base;
MIE_VECTOR_DECLARE(struct mie_memref_rank, m_rank);
};
struct mie_type *mie_ctx_get_memref_type(
struct mie_ctx *ctx, const struct mie_memref_rank *ranks, size_t nr_ranks)
{
struct mie_type_definition *type_info
= mie_ctx_get_type_definition(ctx, "builtin", "memref");
if (!type_info) {
return NULL;
}
struct mie_id_builder id_ctx;
mie_id_builder_begin(&id_ctx, mie_id_map_get_ns(&ctx->ctx_types));
mie_id_builder_add_cstr(&id_ctx, "memref");
for (size_t i = 0; i < nr_ranks; i++) {
switch (ranks[i].r_ranktype) {
case MIE_MEMREF_RANK_UNKNOWN:
mie_id_builder_add_char(&id_ctx, '?');
break;
case MIE_MEMREF_RANK_TYPE:
mie_id_builder_add_id(&id_ctx, &ranks[i].r_type->ty_id);
break;
case MIE_MEMREF_RANK_STATIC:
mie_id_builder_add_int(&id_ctx, ranks[i].r_static);
break;
default:
return NULL;
}
}
mie_id id;
mie_id_builder_end(&id_ctx, &id);
mie_id *target = mie_id_map_get(&ctx->ctx_types, &id);
if (target) {
return fx_unbox(struct mie_type, target, ty_id);
}
struct memref_type *type
= (struct memref_type *)mie_type_create(type_info);
if (!type) {
return NULL;
}
fx_bstr type_name;
fx_bstr_begin_dynamic(&type_name);
fx_bstr_write_cstr(&type_name, "builtin.memref<", NULL);
struct mie_printer printer;
mie_printer_init(
&printer, ctx, (fx_stream *)&type_name, MIE_PRINT_F_ABBREVIATED);
for (size_t i = 0; i < nr_ranks; i++) {
mie_vector_push_back(type->m_rank, &ranks[i], NULL);
if (i > 0) {
fx_bstr_write_char(&type_name, '*');
}
switch (ranks[i].r_ranktype) {
case MIE_MEMREF_RANK_UNKNOWN:
fx_bstr_write_char(&type_name, '?');
break;
case MIE_MEMREF_RANK_TYPE:
mie_printer_print_type(&printer, ranks[i].r_type);
break;
case MIE_MEMREF_RANK_STATIC:
fx_bstr_write_fmt(&type_name, NULL, "%zu", ranks[i].r_static);
break;
default:
break;
}
}
fx_bstr_write_char(&type_name, '>');
type->m_base.ty_name = fx_bstr_end(&type_name);
type->m_base.ty_instance_size = 0;
fx_rope name_rope = FX_ROPE_CSTR(type->m_base.ty_name);
mie_id_map_put(&ctx->ctx_types, &type->m_base.ty_id, &name_rope);
return (struct mie_type *)type;
}
static void type_init(
const struct mie_type_definition *type_info, struct mie_type *type)
{
}
static enum mie_status print(const struct mie_type *ty, struct mie_printer *out)
{
const struct memref_type *memref_ty = (const struct memref_type *)ty;
fx_stream_write_string(
out->p_stream,
(out->p_flags & MIE_PRINT_F_ABBREVIATED) ? "memref"
: "builtin.memref",
NULL);
fx_stream_write_char(out->p_stream, '<');
for (size_t i = 0; i < MIE_VECTOR_COUNT(memref_ty->m_rank); i++) {
const struct mie_memref_rank *rank = &memref_ty->m_rank.items[i];
if (i > 0) {
fx_stream_write_char(out->p_stream, '*');
}
switch (rank->r_ranktype) {
case MIE_MEMREF_RANK_UNKNOWN:
fx_stream_write_char(out->p_stream, '?');
break;
case MIE_MEMREF_RANK_TYPE:
mie_printer_print_type(out, rank->r_type);
break;
case MIE_MEMREF_RANK_STATIC:
fx_stream_write_fmt(
out->p_stream, NULL, "%zu", rank->r_static);
break;
default:
break;
}
}
fx_stream_write_char(out->p_stream, '>');
return MIE_SUCCESS;
}
static bool parse_rank(struct mie_parser *parser, struct mie_memref_rank *out)
{
enum mie_token_type tok_type = mie_parser_peek_type(parser);
struct mie_parser_item expected_tokens[] = {
MIE_PARSE_ITEM_TOKEN(MIE_TOK_TYPENAME),
MIE_PARSE_ITEM_TOKEN(MIE_TOK_INT),
MIE_PARSE_ITEM_TOKEN(MIE_SYM_QUESTION),
MIE_PARSE_ITEM_NONE,
};
long long v;
switch (tok_type) {
case MIE_TOK_INT:
out->r_ranktype = MIE_MEMREF_RANK_STATIC;
out->r_type = mie_ctx_get_type(
mie_parser_get_mie_ctx(parser), "builtin", "index");
mie_parser_parse_int(parser, &v, &out->r_span);
out->r_static = v;
break;
case MIE_TOK_SYMBOL:
switch (mie_parser_peek_symbol(parser)) {
case MIE_SYM_QUESTION:
out->r_span = mie_parser_peek(parser)->tok_location;
mie_parser_parse_symbol(parser, MIE_SYM_QUESTION);
out->r_ranktype = MIE_MEMREF_RANK_UNKNOWN;
break;
case MIE_SYM_LEFT_PAREN:
out->r_ranktype = MIE_MEMREF_RANK_TYPE;
if (!mie_parser_parse_type(
parser, "memref type rank", &out->r_type,
&out->r_span)) {
return false;
}
break;
default:
mie_parser_report_unexpected_token_v(
parser, expected_tokens, "memref rank");
return false;
}
break;
case MIE_TOK_WORD:
case MIE_TOK_TYPENAME:
out->r_ranktype = MIE_MEMREF_RANK_TYPE;
if (!mie_parser_parse_type(
parser, "memref type rank", &out->r_type, &out->r_span)) {
return false;
}
break;
default:
mie_parser_report_unexpected_token_v(
parser, expected_tokens, "memref rank");
return false;
}
return true;
}
static bool parse_ranks(
struct mie_parser *parser,
MIE_VECTOR_REF_PARAM(struct mie_memref_rank, ranks))
{
struct mie_memref_rank rank;
if (!parse_rank(parser, &rank)) {
return false;
}
mie_vector_ref_push_back(ranks, &rank, NULL);
while (1) {
if (mie_parser_peek_symbol(parser) == MIE_SYM_RIGHT_ANGLE) {
break;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_ASTERISK)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_ASTERISK, "memref rank list");
return false;
}
if (!parse_rank(parser, &rank)) {
return false;
}
mie_vector_ref_push_back(ranks, &rank, NULL);
}
return true;
}
static enum mie_status parse(struct mie_parser *parser, const struct mie_type **out)
{
if (!mie_parser_parse_symbol(parser, MIE_SYM_LEFT_ANGLE)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_LEFT_ANGLE, "memref type");
return MIE_ERR_BAD_SYNTAX;
}
MIE_VECTOR_DEFINE(struct mie_memref_rank, ranks);
if (!parse_ranks(parser, MIE_VECTOR_REF(ranks))) {
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_RIGHT_ANGLE)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_RIGHT_ANGLE, "memref type");
return MIE_ERR_BAD_SYNTAX;
}
const struct mie_type *type = mie_ctx_get_memref_type(
mie_parser_get_mie_ctx(parser), ranks.items, ranks.count);
mie_vector_destroy(ranks, NULL);
*out = type;
return MIE_SUCCESS;
}
size_t mie_memref_type_get_nr_ranks(const struct mie_type *type)
{
if (!mie_type_is(type, "builtin", "memref")) {
return 0;
}
const struct memref_type *memref = (const struct memref_type *)type;
return MIE_VECTOR_COUNT(memref->m_rank);
}
const struct mie_memref_rank *mie_memref_type_get_rank(
const struct mie_type *type, size_t i)
{
if (!mie_type_is(type, "builtin", "memref")) {
return 0;
}
const struct memref_type *memref = (const struct memref_type *)type;
if (i >= MIE_VECTOR_COUNT(memref->m_rank)) {
return NULL;
}
return &memref->m_rank.items[i];
}
const struct mie_memref_rank *mie_memref_type_get_rank(
const struct mie_type *type, size_t i);
MIE_TYPE_DEFINITION_BEGIN(mie_builtin_memref, "memref")
MIE_TYPE_DEFINITION_INIT(type_init);
MIE_TYPE_DEFINITION_STRUCT(struct memref_type);
MIE_TYPE_DEFINITION_PRINT(print);
MIE_TYPE_DEFINITION_PARSE(parse);
MIE_TYPE_DEFINITION_END()

View File

@@ -1,4 +1,4 @@
#include <blue/core/bstr.h>
#include <fx/core/bstr.h>
#include <mie/ctx.h>
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
@@ -15,6 +15,10 @@ static void type_init(
static enum mie_status print(const struct mie_type *ty, struct mie_printer *out)
{
fx_stream_write_string(
out->p_stream,
(out->p_flags & MIE_PRINT_F_ABBREVIATED) ? "str" : "!builtin.string",
NULL);
return MIE_SUCCESS;
}

View File

@@ -1,17 +1,154 @@
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
#include <mie/ir/emit.h>
#include <mie/ir/op-definition.h>
#include <mie/ir/op.h>
#include <mie/macros.h>
#include <mie/parse/parser.h>
#include <mie/print/printer.h>
static enum mie_status print(const struct mie_op *op, b_stream *out)
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
if (MIE_VECTOR_COUNT(op->op_args) != 1) {
return MIE_SUCCESS;
}
if (MIE_VECTOR_COUNT(op->op_successors) != 2) {
return MIE_SUCCESS;
}
const struct mie_op_arg *cond = &op->op_args.items[0];
const struct mie_op_successor *if_true = &op->op_successors.items[0];
const struct mie_op_successor *if_false = &op->op_successors.items[1];
fx_stream_write_char(printer->p_stream, ' ');
mie_printer_print_op_arg(printer, cond, false);
fx_stream_write_string(printer->p_stream, ", ", NULL);
mie_printer_print_op_successor(printer, if_true, true);
fx_stream_write_string(printer->p_stream, ", ", NULL);
mie_printer_print_op_successor(printer, if_false, true);
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
static bool parse_successor(struct mie_parser *ctx, struct mie_op_successor *out)
{
memset(out, 0x0, sizeof *out);
fx_string *str = mie_parser_get_tempstr(ctx);
bool result = false;
if (!mie_parser_parse_blockname(ctx, str, &out->s_name_span)) {
mie_parser_report_unexpected_token(
ctx, MIE_TOK_BLOCKNAME, "branch destination");
return false;
}
out->s_block_name = fx_string_steal(str);
if (mie_parser_peek_type(ctx) == MIE_TOK_LINEFEED
|| mie_parser_peek_symbol(ctx) == MIE_SYM_COMMA) {
goto ok;
}
if (!mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_PAREN)) {
struct mie_parser_item expected[] = {
MIE_PARSE_ITEM_TOKEN(MIE_SYM_COMMA),
MIE_PARSE_ITEM_TOKEN(MIE_SYM_LEFT_PAREN),
MIE_PARSE_ITEM_TOKEN(MIE_TOK_LINEFEED),
MIE_PARSE_ITEM_NONE,
};
mie_parser_report_unexpected_token_v(
ctx, expected, "branch destination/arguments");
goto fail;
}
if (!mie_parser_parse_parameter_list(
ctx, true, MIE_VECTOR_REF(out->s_args),
"branch successor arguments")) {
goto fail;
}
if (!mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_PAREN)) {
mie_parser_report_unexpected_token(
ctx, MIE_SYM_RIGHT_PAREN, "branch arguments");
goto fail;
}
ok:
return true;
fail:
if (out->s_block_name) {
free(out->s_block_name);
out->s_block_name = NULL;
}
if (MIE_VECTOR_MAX(out->s_args) > 0) {
mie_vector_destroy(out->s_args, NULL);
}
return false;
}
static enum mie_status parse(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out)
{
struct mie_op_arg *cond = mie_op_add_arg(out);
struct mie_file_span span;
if (!mie_parser_parse_parameter(
parser, false, cond, "branch condition")) {
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_COMMA)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_COMMA, "branch destination list");
return MIE_ERR_BAD_SYNTAX;
}
struct mie_op_successor *true_branch
= mie_vector_emplace_back(out->op_successors, NULL);
if (!parse_successor(parser, true_branch)) {
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_COMMA)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_COMMA, "branch destination list");
return MIE_ERR_BAD_SYNTAX;
}
struct mie_op_successor *false_branch
= mie_vector_emplace_back(out->op_successors, NULL);
if (!parse_successor(parser, false_branch)) {
return MIE_ERR_BAD_SYNTAX;
}
cond->arg_unresolved.reg_type
= mie_ctx_get_int_type(mie_parser_get_mie_ctx(parser), 1);
return MIE_SUCCESS;
}
struct mie_op *mie_cf_br_cond_put(
struct mie_emitter *e, struct mie_register *cond,
struct mie_block *true_block, struct mie_register **true_args,
size_t nr_true_args, struct mie_block *false_block,
struct mie_register **false_args, size_t nr_false_args)
{
struct mie_op *op = mie_emitter_put_op(e, "cf", "br-cond", &cond, 1);
if (!op) {
return NULL;
}
mie_op_add_successor(op, true_block, true_args, nr_true_args);
mie_op_add_successor(op, false_block, false_args, nr_false_args);
return op;
}
MIE_OP_DEFINITION_BEGIN(mie_cf_br_cond, "br-cond")
MIE_OP_DEFINITION_PRINT(print);
MIE_OP_DEFINITION_PARSE(parse);

View File

@@ -1,17 +1,112 @@
#include <mie/dialect/dialect.h>
#include <mie/ir/block.h>
#include <mie/ir/emit.h>
#include <mie/ir/op-definition.h>
#include <mie/ir/op.h>
#include <mie/macros.h>
#include <mie/parse/parser.h>
#include <mie/print/printer.h>
static enum mie_status print(const struct mie_op *op, b_stream *out)
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
fx_stream_write_char(printer->p_stream, ' ');
const struct mie_op_successor *successor = &op->op_successors.items[0];
mie_printer_print_op_successor(printer, successor, true);
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
static bool parse_successor(struct mie_parser *ctx, struct mie_op_successor *out)
{
memset(out, 0x0, sizeof *out);
fx_string *str = mie_parser_get_tempstr(ctx);
bool result = false;
if (!mie_parser_parse_blockname(ctx, str, &out->s_name_span)) {
mie_parser_report_unexpected_token(
ctx, MIE_TOK_BLOCKNAME, "branch destination");
return false;
}
out->s_block_name = fx_string_steal(str);
if (mie_parser_peek_type(ctx) == MIE_TOK_LINEFEED) {
goto ok;
}
if (!mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_PAREN)) {
struct mie_parser_item expected[] = {
MIE_PARSE_ITEM_TOKEN(MIE_TOK_LINEFEED),
MIE_PARSE_ITEM_TOKEN(MIE_SYM_LEFT_PAREN),
MIE_PARSE_ITEM_NONE,
};
mie_parser_report_unexpected_token_v(
ctx, expected, "branch destination/arguments");
goto fail;
}
if (!mie_parser_parse_parameter_list(
ctx, true, MIE_VECTOR_REF(out->s_args),
"branch successor arguments")) {
goto fail;
}
if (!mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_PAREN)) {
mie_parser_report_unexpected_token(
ctx, MIE_SYM_RIGHT_PAREN, "branch arguments");
goto fail;
}
ok:
return true;
fail:
if (out->s_block_name) {
free(out->s_block_name);
out->s_block_name = NULL;
}
if (MIE_VECTOR_MAX(out->s_args) > 0) {
mie_vector_destroy(out->s_args, NULL);
}
return false;
}
static enum mie_status parse(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out)
{
struct mie_op_successor *s
= mie_vector_emplace_back(out->op_successors, NULL);
if (!s) {
return MIE_ERR_NO_MEMORY;
}
if (!parse_successor(parser, s)) {
return MIE_ERR_BAD_SYNTAX;
}
return MIE_SUCCESS;
}
struct mie_op *mie_cf_br_put(
struct mie_emitter *e, struct mie_block *dest,
struct mie_register **dest_args, size_t nr_dest_args)
{
struct mie_op *op = mie_emitter_put_op(e, "cf", "br", NULL, 0);
if (!op) {
return NULL;
}
struct mie_op_successor *s
= mie_op_add_successor(op, dest, dest_args, nr_dest_args);
return op;
}
MIE_OP_DEFINITION_BEGIN(mie_cf_br, "br")
MIE_OP_DEFINITION_PRINT(print);
MIE_OP_DEFINITION_PARSE(parse);

View File

@@ -1,4 +1,4 @@
#include <blue/ds/string.h>
#include <fx/ds/string.h>
#include <mie/ctx.h>
#include <mie/dialect/dialect.h>
#include <mie/ir/op-definition.h>
@@ -37,7 +37,7 @@ struct mie_dialect *mie_dialect_create(
memset(out, 0x0, size);
out->d_name = b_strdup(name);
out->d_name = fx_strdup(name);
if (!out->d_name) {
free(out);
return NULL;
@@ -58,7 +58,7 @@ struct mie_dialect *mie_dialect_create(
mie_id interface_ns = INTERFACE_NS_ID;
mie_id_map_init(&out->d_interfaces, &interface_ns);
b_rope name_rope = B_ROPE_CSTR(name);
fx_rope name_rope = FX_ROPE_CSTR(name);
mie_id_map_put(&ctx->ctx_dialects, &out->d_id, &name_rope);
return out;
@@ -67,21 +67,21 @@ struct mie_dialect *mie_dialect_create(
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);
fx_rope name_rope = FX_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);
return fx_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);
fx_rope name_rope = FX_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);
return fx_unbox(struct mie_type_definition, target, ty_id);
}

View File

@@ -3,5 +3,7 @@
#include <mie/macros.h>
MIE_DIALECT_BEGIN(mie_func, struct mie_dialect, "func")
MIE_DIALECT_ADD_TRAIT(mie_func_function_like);
MIE_DIALECT_ADD_OP(mie_func_func);
MIE_DIALECT_ADD_OP(mie_func_return);
MIE_DIALECT_END()

View File

@@ -1,24 +1,256 @@
#include <mie/attribute/attribute-map.h>
#include <mie/ctx.h>
#include <mie/diag/diag.h>
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
#include <mie/dialect/func.h>
#include <mie/interface/interface-definition.h>
#include <mie/interface/interface.h>
#include <mie/ir/block.h>
#include <mie/ir/emit.h>
#include <mie/ir/op-definition.h>
#include <mie/ir/op.h>
#include <mie/ir/region.h>
#include <mie/macros.h>
#include <mie/parse/parser.h>
#include <mie/print/printer.h>
#include <mie/type/function.h>
static enum mie_status print(const struct mie_op *op, b_stream *out)
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
const struct mie_attribute *sym_name
= mie_attribute_map_get(&op->op_attrib, "sym_name");
const struct mie_attribute *function_type_attr
= mie_attribute_map_get(&op->op_attrib, "function_type");
const char *sym_name_cstr = mie_string_get_cstr(sym_name);
const struct mie_type *function_type_g
= mie_type_attr_get_type(function_type_attr);
const struct mie_function_type *function_ty
= (const struct mie_function_type *)function_type_g;
fx_stream_write_fmt(printer->p_stream, NULL, " @%s(", sym_name_cstr);
const struct mie_region *code = mie_op_get_first_region(op);
const struct mie_block *entry = mie_region_get_first_block(code);
for (size_t i = 0; i < MIE_VECTOR_COUNT(entry->b_params); i++) {
if (i > 0) {
fx_stream_write_string(printer->p_stream, ", ", NULL);
}
const struct mie_register *param = &entry->b_params.items[i];
mie_printer_print_register(printer, param, MIE_PRINT_F_INCLUDE_TYPE);
}
fx_stream_write_string(printer->p_stream, ") -> ", NULL);
if (MIE_VECTOR_COUNT(function_ty->func_out) != 1) {
fx_stream_write_char(printer->p_stream, '(');
}
for (size_t i = 0; i < MIE_VECTOR_COUNT(function_ty->func_out); i++) {
if (i > 0) {
fx_stream_write_string(printer->p_stream, ", ", NULL);
}
const struct mie_type *ty = function_ty->func_out.items[i];
mie_printer_print_type(printer, ty);
}
if (MIE_VECTOR_COUNT(function_ty->func_out) != 1) {
fx_stream_write_char(printer->p_stream, ')');
}
fx_stream_write_char(printer->p_stream, ' ');
mie_printer_print_region(
printer, code, MIE_PRINT_F_EXCLUDE_FIRST_BLOCK_HEADER);
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
static enum mie_status parse_return_type(
struct mie_parser *parser,
MIE_VECTOR_REF_PARAM(const struct mie_type *, out))
{
bool ok = true;
if (mie_parser_peek_symbol(parser) == MIE_SYM_LEFT_PAREN) {
ok = mie_parser_parse_type_list(
parser, "function return type", MIE_VECTOR_REF2(out), NULL);
} else {
const struct mie_type *tmp;
ok = mie_parser_parse_type(
parser, "function return type", &tmp, NULL);
if (ok) {
mie_vector_ref_push_back(out, &tmp, NULL);
}
}
return ok ? MIE_SUCCESS : MIE_ERR_BAD_SYNTAX;
}
static enum mie_status parse(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out)
{
if (!scope) {
struct mie_diag *diag = mie_parser_report_error_simple(
parser, "builtin", MIE_BUILTIN_E_OP_REQUIRES_PARENT_SCOPE,
MIE_BUILTIN_MSG_OP_REQUIRES_PARENT_SCOPE,
&out->op_name_span);
mie_diag_push_msg(
diag, mie_parser_get_mie_ctx(parser), "builtin",
MIE_BUILTIN_MSG_OP_PARENT_SCOPE_EXAMPLE);
return MIE_ERR_BAD_SYNTAX;
}
fx_string *temp = mie_parser_get_tempstr(parser);
if (!mie_parser_parse_symname(parser, temp, NULL)) {
mie_parser_report_unexpected_token(
parser, MIE_TOK_SYMNAME, "function signature");
return MIE_ERR_BAD_SYNTAX;
}
struct mie_attribute *sym_name = mie_ctx_get_string(
mie_parser_get_mie_ctx(parser), fx_string_ptr(temp));
if (!mie_parser_parse_symbol(parser, MIE_SYM_LEFT_PAREN)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_LEFT_PAREN, "function parameter list");
return MIE_ERR_BAD_SYNTAX;
}
MIE_VECTOR_DEFINE(struct mie_op_arg, block_params);
MIE_VECTOR_DEFINE(const struct mie_type *, in_types);
MIE_VECTOR_DEFINE(const struct mie_type *, out_types);
if (!mie_parser_parse_parameter_list(
parser, true, MIE_VECTOR_REF(block_params),
"function parameter list")) {
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_RIGHT_PAREN)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_LEFT_PAREN, "function parameter list");
return MIE_ERR_BAD_SYNTAX;
}
struct mie_region *body = mie_op_add_region(out);
struct mie_block *entry = mie_region_add_block(body);
for (size_t i = 0; i < MIE_VECTOR_COUNT(block_params); i++) {
struct mie_register *param_reg = mie_vector_emplace_back(
entry->b_params, &mie_register_vector_ops);
param_reg->reg_flags = block_params.items[i].arg_unresolved.reg_flags
| MIE_REGISTER_F_BLOCK_PARAM;
param_reg->reg_type = block_params.items[i].arg_unresolved.reg_type;
param_reg->reg_block = entry;
if (!mie_parser_scope_put_name(
scope, &param_reg->reg_name,
block_params.items[i].arg_unresolved.reg_name,
MIE_NAME_MAP_F_STRICT)) {
return false;
}
mie_vector_push_back(in_types, &param_reg->reg_type, NULL);
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_HYPHEN_RIGHT_ANGLE)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_HYPHEN_RIGHT_ANGLE,
"function signature");
return MIE_ERR_BAD_SYNTAX;
}
if (parse_return_type(parser, MIE_VECTOR_REF(out_types)) != MIE_SUCCESS) {
return MIE_ERR_BAD_SYNTAX;
}
const struct mie_type *func_type = mie_ctx_get_function_type(
mie_parser_get_mie_ctx(parser), in_types.items, in_types.count,
out_types.items, out_types.count);
mie_vector_destroy(in_types, NULL);
mie_vector_destroy(out_types, NULL);
struct mie_attribute *function_type
= mie_type_attr_create(mie_parser_get_mie_ctx(parser), func_type);
mie_attribute_map_put(
&out->op_attrib, "sym_name", sym_name, MIE_ATTRMAP_F_REPLACE);
mie_attribute_map_put(
&out->op_attrib, "function_type", function_type,
MIE_ATTRMAP_F_REPLACE);
if (!mie_parser_parse_region(parser, out, body, entry)) {
return MIE_ERR_BAD_SYNTAX;
}
return MIE_SUCCESS;
}
struct mie_op *mie_func_func_put(
struct mie_emitter *e, const char *name, struct mie_func_parameter *params,
size_t nr_params, const struct mie_type **ret_types, size_t nr_ret_types)
{
const struct mie_type **param_types
= calloc(nr_params, sizeof *param_types);
if (!param_types) {
return NULL;
}
for (size_t i = 0; i < nr_params; i++) {
param_types[i] = params[i].param_type;
}
const struct mie_type *func_type = mie_ctx_get_function_type(
mie_emitter_get_ctx(e), param_types, nr_params, ret_types,
nr_ret_types);
free(param_types);
if (!func_type) {
return NULL;
}
struct mie_op *op = mie_emitter_put_op(e, "func", "func", NULL, 0);
struct mie_region *region = mie_op_add_region(op);
struct mie_block *entry = mie_region_add_block(region);
mie_name_map_put(region->r_names, &entry->b_name, "entry", 0);
for (size_t i = 0; i < nr_params; i++) {
struct mie_register *param_reg = mie_block_add_param(entry);
mie_name_map_put(
region->r_names, &param_reg->reg_name,
params[i].param_name, 0);
param_reg->reg_type = params[i].param_type;
params[i].param_reg = param_reg;
}
struct mie_attribute *sym_name
= mie_ctx_get_string(mie_emitter_get_ctx(e), name);
struct mie_attribute *function_type
= mie_type_attr_create(mie_emitter_get_ctx(e), func_type);
mie_attribute_map_put(
&op->op_attrib, "sym_name", sym_name, MIE_ATTRMAP_F_REPLACE);
mie_attribute_map_put(
&op->op_attrib, "function_type", function_type,
MIE_ATTRMAP_F_REPLACE);
return op;
}
MIE_OP_DEFINITION_BEGIN(mie_func_func, "func")
MIE_OP_DEFINITION_PRINT(print);
MIE_OP_DEFINITION_PARSE(parse);
MIE_OP_DEFINITION_TRAIT("builtin", "isolated-from-above");
MIE_OP_DEFINITION_TRAIT("func", "function-like");
MIE_OP_INTERFACE_BEGIN("builtin", "symbol", struct mie_symbol)
MIE_OP_INTERFACE_FUNC(sym_get_name) = NULL;
MIE_OP_INTERFACE_END()

View File

@@ -0,0 +1,123 @@
#include <mie/attribute/attribute-map.h>
#include <mie/ctx.h>
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
#include <mie/interface/interface-definition.h>
#include <mie/interface/interface.h>
#include <mie/ir/block.h>
#include <mie/ir/op-definition.h>
#include <mie/ir/op.h>
#include <mie/ir/region.h>
#include <mie/macros.h>
#include <mie/parse/parser.h>
#include <mie/print/printer.h>
#include <mie/type/function.h>
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
fx_stream_write_char(printer->p_stream, ' ');
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_args); i++) {
if (i > 0) {
fx_stream_write_string(printer->p_stream, ", ", NULL);
}
mie_printer_print_op_arg(printer, &op->op_args.items[i], false);
}
fx_stream_write_string(printer->p_stream, " : ", NULL);
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_args); i++) {
if (i > 0) {
fx_stream_write_string(printer->p_stream, ", ", NULL);
}
mie_printer_print_type(
printer, mie_op_arg_get_type(&op->op_args.items[i]));
}
return MIE_SUCCESS;
}
static enum mie_status parse(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out)
{
if (!mie_parser_parse_parameter_list(
parser, false, MIE_VECTOR_REF(out->op_args),
"function return values")) {
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_COLON)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_COLON, "function return type");
return MIE_ERR_BAD_SYNTAX;
}
MIE_VECTOR_DEFINE(const struct mie_type *, types);
const struct mie_type *tmp = NULL;
struct mie_file_span first_span, last_span;
if (!mie_parser_parse_type(
parser, "function return type", &tmp, &first_span)) {
return MIE_ERR_BAD_SYNTAX;
}
mie_vector_push_back(types, &tmp, NULL);
bool ok = true;
while (1) {
if (mie_parser_peek_type(parser) == MIE_TOK_LINEFEED) {
break;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_COMMA)) {
struct mie_parser_item expected[] = {
MIE_PARSE_ITEM_TOKEN(MIE_SYM_COMMA),
MIE_PARSE_ITEM_TOKEN(MIE_TOK_LINEFEED),
MIE_PARSE_ITEM_NONE,
};
mie_parser_report_unexpected_token_v(
parser, expected, "function return type list");
ok = false;
break;
}
if (!mie_parser_parse_type(
parser, "function return type", &tmp, &last_span)) {
ok = false;
break;
}
mie_vector_push_back(types, &tmp, NULL);
}
if (!ok) {
mie_vector_destroy(types, NULL);
return MIE_ERR_BAD_SYNTAX;
}
if (MIE_VECTOR_COUNT(types) != MIE_VECTOR_COUNT(out->op_args)) {
struct mie_file_span span = {
.s_start = first_span.s_start,
.s_end = last_span.s_end,
};
mie_parser_report_error_simple(
parser, "builtin", MIE_BUILTIN_E_INCORRECT_NUMBER_OF_TYPES,
MIE_BUILTIN_MSG_OP_NR_TYPES_DOESNT_MATCH_NR_ARGS, &span);
return MIE_ERR_BAD_SYNTAX;
}
for (size_t i = 0; i < MIE_VECTOR_COUNT(types); i++) {
out->op_args.items[i].arg_unresolved.reg_type = types.items[i];
}
return MIE_SUCCESS;
}
MIE_OP_DEFINITION_BEGIN(mie_func_return, "return")
MIE_OP_DEFINITION_PRINT(print);
MIE_OP_DEFINITION_PARSE(parse);
MIE_OP_DEFINITION_END()

View File

@@ -0,0 +1,23 @@
#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;
}
/* func.function-like trait:
* the op behaves like a func.func. this means that it:
* a) has a single region
* b) that region has one or more blocks representing the body of a function.
* c) the op has sym_name, function_type, and other function-related attributes.
*/
MIE_TRAIT_DEFINITION_BEGIN(mie_func_function_like, "function-like")
MIE_TRAIT_DEFINITION_TARGETS(MIE_TRAIT_TARGET_OP);
MIE_TRAIT_DEFINITION_STRUCT(struct mie_trait);
MIE_TRAIT_DEFINITION_VALIDATE(validate);
MIE_TRAIT_DEFINITION_END()

27
mie/dialect/memref/diag.c Normal file
View File

@@ -0,0 +1,27 @@
#include <mie/diag/class.h>
#include <mie/diag/msg.h>
#include <mie/dialect/memref.h>
#include <mie/macros.h>
#define MIE_DIAG_CLASS_PREFIX MIE_MEMREF_E
#define MIE_DIAG_MSG_PREFIX MIE_MEMREF_MSG
MIE_DIAG_CLASS_LIST_BEGIN(mie_memref_diag)
MIE_DIAG_CLASS_LIST_END(mie_memref_diag)
MIE_DIAG_MSG_LIST_BEGIN(mie_memref_msg)
MIE_DIAG_MSG(
OP_EXPECTS_MEMREF_ARGUMENT,
"this operation requires a memref parameter.")
MIE_DIAG_MSG(
LAST_MEMREF_RANK_MUST_BE_TYPE,
"the last rank of a memref type must be a type.")
MIE_DIAG_MSG(
MEMREF_MUST_HAVE_AT_LEAST_ONE_RANK,
"memref type must have at least one rank.")
MIE_DIAG_MSG(
OP_RESULT_DETERMINED_BY_LAST_MEMREF_RANK,
"the number and type of operation results is determined by "
"[blue]the "
"type of the last memref rank[reset].")
MIE_DIAG_MSG_LIST_END(mie_memref_msg)

View File

@@ -0,0 +1,17 @@
#include <mie/diag/class.h>
#include <mie/diag/msg.h>
#include <mie/dialect/dialect.h>
#include <mie/dialect/memref.h>
#include <mie/macros.h>
#include <mie/print/printer.h>
#include <mie/type/type-definition.h>
#include <mie/type/type.h>
MIE_DIAG_CLASS_LIST_EXTERN(mie_memref_diag);
MIE_DIAG_MSG_LIST_EXTERN(mie_memref_msg);
MIE_DIALECT_BEGIN(mie_memref, struct mie_dialect, "memref")
MIE_DIALECT_DIAG_CLASS_LIST(mie_memref_diag);
MIE_DIALECT_DIAG_MSG_LIST(mie_memref_msg);
MIE_DIALECT_ADD_OP(mie_memref_load);
MIE_DIALECT_END()

View File

@@ -0,0 +1,214 @@
#include <mie/ctx.h>
#include <mie/diag/diag.h>
#include <mie/diag/highlight.h>
#include <mie/dialect/builtin.h>
#include <mie/dialect/memref.h>
#include <mie/ir/op-definition.h>
#include <mie/ir/op.h>
#include <mie/macros.h>
#include <mie/parse/parser.h>
#include <mie/print/printer.h>
#include <mie/type/storage.h>
#include <mie/type/type.h>
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
fx_stream_write_char(printer->p_stream, ' ');
const struct mie_type *memref_type = NULL;
if (MIE_VECTOR_COUNT(op->op_args) > 0) {
mie_printer_print_op_arg(printer, &op->op_args.items[0], false);
memref_type = mie_op_arg_get_type(&op->op_args.items[0]);
}
fx_stream_write_char(printer->p_stream, '[');
for (size_t i = 1; i < MIE_VECTOR_COUNT(op->op_args); i++) {
if (i > 1) {
fx_stream_write_string(printer->p_stream, ", ", NULL);
}
mie_printer_print_op_arg(printer, &op->op_args.items[i], false);
}
fx_stream_write_char(printer->p_stream, ']');
if (memref_type) {
fx_stream_write_string(printer->p_stream, " : ", NULL);
mie_printer_print_type(printer, memref_type);
}
return MIE_SUCCESS;
}
static bool parse_param_name(
struct mie_parser *ctx, struct mie_op_arg *out, const char *context)
{
memset(out, 0x0, sizeof *out);
fx_string *str = mie_parser_get_tempstr(ctx);
struct mie_file_span loc;
if (mie_parser_parse_vregname(ctx, str, &loc)) {
out->arg_unresolved.reg_name = fx_string_steal(str);
out->arg_unresolved.reg_flags = MIE_REGISTER_F_VIRTUAL;
} else if (mie_parser_parse_mregname(ctx, str, &loc)) {
out->arg_unresolved.reg_name = fx_string_steal(str);
out->arg_unresolved.reg_flags = MIE_REGISTER_F_MACHINE;
} else {
struct mie_parser_item required[] = {
MIE_PARSE_ITEM_TOKEN(MIE_TOK_VREGNAME),
MIE_PARSE_ITEM_TOKEN(MIE_TOK_MREGNAME),
MIE_PARSE_ITEM_NONE,
};
mie_parser_report_unexpected_token_v(ctx, required, context);
return false;
}
out->arg_span = loc;
return true;
}
static bool apply_op_result_types(
const struct mie_op *op, const struct mie_type *result_type)
{
size_t nr_results = 0;
if (!mie_type_is_storage(result_type)) {
if (MIE_VECTOR_COUNT(op->op_result) != 1) {
return false;
}
op->op_result.items[0].reg_type = result_type;
return true;
}
const struct mie_storage_type *storage
= (const struct mie_storage_type *)result_type;
nr_results = mie_storage_type_get_nr_parts(storage);
if (MIE_VECTOR_COUNT(op->op_result) != nr_results) {
return false;
}
for (size_t i = 0; i < nr_results; i++) {
op->op_result.items[i].reg_type = storage->st_parts.items[i];
}
return true;
}
static enum mie_status parse(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out)
{
struct mie_op_arg *buf_arg = mie_op_add_arg(out);
if (!mie_parser_parse_parameter(
parser, false, buf_arg, "memref load source")) {
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_LEFT_BRACKET)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_LEFT_BRACKET, "memref load index list");
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_parameter_list(
parser, false, MIE_VECTOR_REF(out->op_args),
"memref load index")) {
return MIE_ERR_BAD_SYNTAX;
}
#if 0
while (1) {
if (mie_parser_parse_symbol(parser, MIE_SYM_RIGHT_BRACKET)) {
break;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_COMMA)) {
unsigned int expected[] = {
MIE_SYM_COMMA,
MIE_SYM_RIGHT_BRACKET,
MIE_TOK_NONE,
};
mie_parser_report_unexpected_token_v(
parser, expected, "memref load index list");
return MIE_ERR_BAD_SYNTAX;
}
struct mie_op_arg *index_arg = mie_op_add_arg(out);
if (!parse_param_name(parser, index_arg, "memref load index")) {
return MIE_ERR_BAD_SYNTAX;
}
}
#endif
if (!mie_parser_parse_symbol(parser, MIE_SYM_RIGHT_BRACKET)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_RIGHT_BRACKET, "memref load index list");
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_COLON)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_COLON, "memref type");
return MIE_ERR_BAD_SYNTAX;
}
const struct mie_type *type = NULL;
struct mie_file_span type_span;
if (!mie_parser_parse_type(parser, "memref type", &type, &type_span)) {
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_type_is(type, "builtin", "memref")) {
mie_parser_report_error_simple(
parser, "builtin", MIE_BUILTIN_E_INCORRECT_TYPE,
MIE_MEMREF_MSG_OP_EXPECTS_MEMREF_ARGUMENT, &type_span);
return MIE_ERR_BAD_SYNTAX;
}
size_t nr_ranks = mie_memref_type_get_nr_ranks(type);
if (!nr_ranks) {
mie_parser_report_error_simple(
parser, "builtin", MIE_BUILTIN_E_INVALID_TYPE,
MIE_MEMREF_MSG_MEMREF_MUST_HAVE_AT_LEAST_ONE_RANK,
&type_span);
return MIE_ERR_BAD_SYNTAX;
}
const struct mie_memref_rank *type_rank
= mie_memref_type_get_rank(type, nr_ranks - 1);
if (type_rank->r_ranktype != MIE_MEMREF_RANK_TYPE) {
mie_parser_report_error_simple(
parser, "builtin", MIE_BUILTIN_E_INVALID_TYPE,
MIE_MEMREF_MSG_LAST_MEMREF_RANK_MUST_BE_TYPE,
&type_rank->r_span);
return MIE_ERR_BAD_SYNTAX;
}
if (!apply_op_result_types(out, type_rank->r_type)) {
struct mie_file_span results_span;
mie_op_get_results_span(out, &results_span);
struct mie_diag *diag = mie_parser_report_error_simple(
parser, "builtin",
MIE_BUILTIN_E_INCORRECT_NUMBER_OF_RESULTS,
MIE_BUILTIN_MSG_NR_RESULT_NAME_OUTPUT_MISMATCH,
&results_span);
mie_diag_push_msg(
diag, mie_parser_get_mie_ctx(parser), "memref",
MIE_MEMREF_MSG_OP_RESULT_DETERMINED_BY_LAST_MEMREF_RANK);
struct mie_diag_highlight hl[] = {
MIE_DIAG_HL(HINT, type_rank->r_span),
};
mie_diag_push_snippet(
diag, type_rank->r_span.s_start.c_row,
type_rank->r_span.s_end.c_row, NULL, 0, hl, 1);
return MIE_ERR_BAD_SYNTAX;
}
return MIE_SUCCESS;
}
MIE_OP_DEFINITION_BEGIN(mie_memref_load, "load")
MIE_OP_DEFINITION_PRINT(print);
MIE_OP_DEFINITION_PARSE(parse);
MIE_OP_DEFINITION_END()

View File

@@ -2,12 +2,14 @@
#include <mie/ir/op-definition.h>
#include <mie/macros.h>
static enum mie_status print(const struct mie_op *op, b_stream *out)
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
static enum mie_status parse(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out)
{
return MIE_SUCCESS;
}

View File

@@ -2,12 +2,14 @@
#include <mie/ir/op-definition.h>
#include <mie/macros.h>
static enum mie_status print(const struct mie_op *op, b_stream *out)
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
static enum mie_status parse(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out)
{
return MIE_SUCCESS;
}

View File

@@ -2,12 +2,14 @@
#include <mie/ir/op-definition.h>
#include <mie/macros.h>
static enum mie_status print(const struct mie_op *op, b_stream *out)
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
static enum mie_status parse(
struct mie_parser *parser, struct mie_parser_scope *names,
struct mie_op *out)
{
return MIE_SUCCESS;
}

View File

@@ -1,14 +1,281 @@
#include <mie/ctx.h>
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
#include <mie/ir/block.h>
#include <mie/ir/op-definition.h>
#include <mie/ir/op.h>
#include <mie/ir/region.h>
#include <mie/macros.h>
#include <mie/parse/parser.h>
#include <mie/print/printer.h>
#include <mie/type/function.h>
#include <mie/type/storage.h>
static enum mie_status print(const struct mie_op *op, b_stream *out)
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
struct mie_region *body = mie_op_get_first_region(op);
struct mie_block *entry = NULL;
struct mie_register *iv = NULL;
struct mie_op_arg *lb = NULL, *ub = NULL, *step = NULL;
if (!body) {
return MIE_ERR_BAD_STATE;
}
entry = mie_region_get_first_block(body);
if (!entry) {
return MIE_ERR_BAD_STATE;
}
if (MIE_VECTOR_COUNT(op->op_args) < 3) {
return MIE_ERR_BAD_STATE;
}
if (MIE_VECTOR_COUNT(entry->b_params) < 1) {
return MIE_ERR_BAD_STATE;
}
iv = &entry->b_params.items[0];
lb = &op->op_args.items[0];
ub = &op->op_args.items[1];
step = &op->op_args.items[2];
fx_stream_write_char(printer->p_stream, ' ');
mie_printer_print_register(printer, iv, 0);
fx_stream_write_string(printer->p_stream, " = ", NULL);
mie_printer_print_op_arg(printer, lb, 0);
fx_stream_write_string(printer->p_stream, " to ", NULL);
mie_printer_print_op_arg(printer, ub, 0);
fx_stream_write_string(printer->p_stream, " step ", NULL);
mie_printer_print_op_arg(printer, step, 0);
if (MIE_VECTOR_COUNT(entry->b_params) > 1) {
fx_stream_write_string(printer->p_stream, " iter-args(", NULL);
for (size_t i = 1; i < MIE_VECTOR_COUNT(entry->b_params); i++) {
if (i > 1) {
fx_stream_write_string(printer->p_stream, ", ", NULL);
}
mie_printer_print_register(
printer, &entry->b_params.items[i], 0);
fx_stream_write_string(printer->p_stream, " = ", NULL);
mie_printer_print_op_arg(
printer, &op->op_args.items[i + 2], false);
}
fx_stream_write_char(printer->p_stream, ')');
}
if (MIE_VECTOR_COUNT(op->op_result) > 0) {
fx_stream_write_string(printer->p_stream, " -> ", NULL);
if (MIE_VECTOR_COUNT(op->op_result) > 1) {
fx_stream_write_char(printer->p_stream, '(');
}
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_result); i++) {
mie_printer_print_type(
printer, op->op_result.items[i].reg_type);
}
if (MIE_VECTOR_COUNT(op->op_result) > 1) {
fx_stream_write_char(printer->p_stream, ')');
}
}
fx_stream_write_char(printer->p_stream, ' ');
mie_printer_print_region(
printer, body, MIE_PRINT_F_EXCLUDE_FIRST_BLOCK_HEADER);
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
static bool parse_result_type(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out, struct mie_block *entry)
{
const struct mie_type *type = NULL;
struct mie_file_span span;
if (!mie_parser_parse_type(parser, "loop result type", &type, &span)) {
return false;
}
const struct mie_type **types;
size_t nr_types;
if (mie_type_is_storage(type)) {
const struct mie_storage_type *storage
= (const struct mie_storage_type *)type;
types = storage->st_parts.items;
nr_types = storage->st_parts.count;
} else if (!mie_type_is_function(type)) {
types = &type;
nr_types = 1;
} else {
mie_parser_report_error_simple(
parser, "builtin", MIE_BUILTIN_E_INVALID_TYPE,
MIE_BUILTIN_MSG_CANNOT_USE_FUNCTION_TYPE_HERE, &span);
}
if (MIE_VECTOR_COUNT(out->op_result) != nr_types) {
mie_parser_report_error_simple(
parser, "builtin", MIE_BUILTIN_E_INCORRECT_NUMBER_OF_TYPES,
MIE_BUILTIN_MSG_OP_NR_TYPES_DOESNT_MATCH_NR_RESULTS,
&span);
return false;
}
for (size_t i = 0; i < nr_types; i++) {
out->op_result.items[i].reg_type = types[i];
}
return true;
}
static bool parse_iter_arg(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out, struct mie_block *entry)
{
struct mie_register *reg = mie_block_add_param(entry);
struct mie_op_arg *arg = mie_op_add_arg(out);
if (!mie_parser_parse_register(
parser, scope, "iterator parameter name", reg)) {
return false;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_EQUAL)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_EQUAL, "iterator parameter");
return false;
}
if (!mie_parser_parse_parameter(
parser, false, arg, "iterator parameter value")) {
return false;
}
struct mie_register *value = mie_parser_scope_find_value(
scope, arg->arg_unresolved.reg_name);
if (value) {
reg->reg_type = value->reg_type;
}
return true;
}
static bool parse_iter_args(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out, struct mie_block *entry)
{
if (!mie_parser_parse_keyword(parser, "iter-args", NULL)) {
return true;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_LEFT_PAREN)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_LEFT_PAREN, "iterator parameter list");
return false;
}
if (!parse_iter_arg(parser, scope, out, entry)) {
return false;
}
while (1) {
if (mie_parser_parse_symbol(parser, MIE_SYM_RIGHT_PAREN)) {
break;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_COMMA)) {
struct mie_parser_item expected[] = {
MIE_PARSE_ITEM_TOKEN(MIE_SYM_COMMA),
MIE_PARSE_ITEM_TOKEN(MIE_SYM_RIGHT_PAREN),
MIE_PARSE_ITEM_NONE,
};
mie_parser_report_unexpected_token_v(
parser, expected, "iterator parameter list");
return false;
}
if (!parse_iter_arg(parser, scope, out, entry)) {
return false;
}
}
return true;
}
static enum mie_status parse(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out)
{
struct mie_region *body = mie_op_add_region(out);
struct mie_block *entry = mie_region_add_block(body);
struct mie_register *iv = mie_block_add_param(entry);
mie_parser_scope_put_name(scope, &entry->b_name, "for.entry", 0);
if (!mie_parser_parse_register(parser, scope, "induction variable", iv)) {
return MIE_ERR_BAD_SYNTAX;
}
iv->reg_type = mie_ctx_get_type(
mie_parser_get_mie_ctx(parser), "builtin", "index");
if (!mie_parser_parse_symbol(parser, MIE_SYM_EQUAL)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_EQUAL, "for-loop");
return MIE_ERR_BAD_SYNTAX;
}
struct mie_op_arg *lb = mie_op_add_arg(out);
if (!mie_parser_parse_parameter(parser, false, lb, "lower bound")) {
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_keyword(parser, "to", NULL)) {
mie_parser_report_unexpected_token_s(parser, "to", "for-loop");
return MIE_ERR_BAD_SYNTAX;
}
struct mie_op_arg *ub = mie_op_add_arg(out);
if (!mie_parser_parse_parameter(parser, false, ub, "upper bound")) {
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_keyword(parser, "step", NULL)) {
mie_parser_report_unexpected_token_s(parser, "step", "for-loop");
return MIE_ERR_BAD_SYNTAX;
}
struct mie_op_arg *step = mie_op_add_arg(out);
if (!mie_parser_parse_parameter(parser, false, step, "step")) {
return MIE_ERR_BAD_SYNTAX;
}
if (!parse_iter_args(parser, scope, out, entry)) {
return MIE_ERR_BAD_SYNTAX;
}
if (mie_parser_parse_symbol(parser, MIE_SYM_HYPHEN_RIGHT_ANGLE)) {
if (!parse_result_type(parser, scope, out, entry)) {
return MIE_ERR_BAD_SYNTAX;
}
} else if (MIE_VECTOR_COUNT(out->op_result) > 0) {
struct mie_file_span span;
mie_op_get_results_span(out, &span);
mie_parser_report_error_simple(
parser, "builtin",
MIE_BUILTIN_E_INCORRECT_NUMBER_OF_RESULTS,
MIE_BUILTIN_MSG_OP_NR_TYPES_DOESNT_MATCH_NR_RESULTS,
&span);
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_region(parser, out, body, entry)) {
return MIE_ERR_BAD_SYNTAX;
}
return MIE_SUCCESS;
}

View File

@@ -1,15 +1,85 @@
#include <mie/dialect/dialect.h>
#include <mie/ir/emit.h>
#include <mie/ir/op-definition.h>
#include <mie/ir/op.h>
#include <mie/ir/region.h>
#include <mie/macros.h>
#include <mie/print/printer.h>
static enum mie_status print(const struct mie_op *op, b_stream *out)
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
fx_stream_write_char(printer->p_stream, ' ');
mie_printer_print_op_arg(printer, &op->op_args.items[0], false);
if (MIE_VECTOR_COUNT(op->op_result) > 0) {
fx_stream_write_string(printer->p_stream, " -> ", NULL);
if (MIE_VECTOR_COUNT(op->op_result) > 1) {
fx_stream_write_char(printer->p_stream, '(');
}
}
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_result); i++) {
if (i > 0) {
fx_stream_write_string(printer->p_stream, ", ", NULL);
}
mie_printer_print_type(printer, op->op_result.items[i].reg_type);
}
if (MIE_VECTOR_COUNT(op->op_result) > 1) {
fx_stream_write_char(printer->p_stream, '(');
}
fx_stream_write_char(printer->p_stream, ' ');
struct mie_region *if_region = mie_op_get_first_region(op);
struct mie_region *else_region = mie_op_get_next_region(op, if_region);
mie_printer_print_region(printer, if_region, 0);
if (else_region) {
fx_stream_write_string(printer->p_stream, " else ", NULL);
mie_printer_print_region(printer, else_region, 0);
}
return MIE_SUCCESS;
}
static enum mie_status parse(
struct mie_parser *parser, struct mie_parser_scope *names,
struct mie_op *out)
{
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
struct mie_op *mie_scf_if_put(
struct mie_emitter *e, struct mie_register *cond,
const struct mie_type *result_type, struct mie_region **out_true,
struct mie_region **out_false, const char *name)
{
return MIE_SUCCESS;
struct mie_op *op = mie_emitter_put_op(e, "scf", "if", &cond, 1);
if (!op) {
return NULL;
}
if (result_type) {
struct mie_register *result = mie_op_add_result(op, result_type);
mie_emitter_put_name(e, &result->reg_name, name);
}
struct mie_region *r_true = mie_op_add_region(op);
struct mie_region *r_false = mie_op_add_region(op);
if (out_true) {
*out_true = r_true;
}
if (out_false) {
*out_false = r_false;
}
return op;
}
MIE_OP_DEFINITION_BEGIN(mie_scf_if, "if")

View File

@@ -1,17 +1,120 @@
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
#include <mie/ir/emit.h>
#include <mie/ir/op-definition.h>
#include <mie/ir/op.h>
#include <mie/macros.h>
#include <mie/parse/parser.h>
#include <mie/print/printer.h>
static enum mie_status print(const struct mie_op *op, b_stream *out)
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
fx_stream_write_char(printer->p_stream, ' ');
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_args); i++) {
if (i > 0) {
fx_stream_write_string(printer->p_stream, ", ", NULL);
}
mie_printer_print_op_arg(printer, &op->op_args.items[i], false);
}
fx_stream_write_string(printer->p_stream, " : ", NULL);
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_args); i++) {
if (i > 0) {
fx_stream_write_string(printer->p_stream, ", ", NULL);
}
mie_printer_print_type(
printer, mie_op_arg_get_type(&op->op_args.items[i]));
}
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
static enum mie_status parse(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out)
{
if (!mie_parser_parse_parameter_list(
parser, false, MIE_VECTOR_REF(out->op_args),
"yield value(s)")) {
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_COLON)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_COLON, "yield value type(s)");
return MIE_ERR_BAD_SYNTAX;
}
MIE_VECTOR_DEFINE(const struct mie_type *, types);
const struct mie_type *tmp = NULL;
struct mie_file_span first_span, last_span;
if (!mie_parser_parse_type(
parser, "yield value type(s)", &tmp, &first_span)) {
return MIE_ERR_BAD_SYNTAX;
}
mie_vector_push_back(types, &tmp, NULL);
bool ok = true;
while (1) {
if (mie_parser_peek_type(parser) == MIE_TOK_LINEFEED) {
break;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_COMMA)) {
struct mie_parser_item expected[] = {
MIE_PARSE_ITEM_TOKEN(MIE_SYM_COMMA),
MIE_PARSE_ITEM_TOKEN(MIE_TOK_LINEFEED),
MIE_PARSE_ITEM_NONE,
};
mie_parser_report_unexpected_token_v(
parser, expected, "yield value type list");
ok = false;
break;
}
if (!mie_parser_parse_type(
parser, "yield value type", &tmp, &last_span)) {
ok = false;
break;
}
mie_vector_push_back(types, &tmp, NULL);
}
if (!ok) {
mie_vector_destroy(types, NULL);
return MIE_ERR_BAD_SYNTAX;
}
if (MIE_VECTOR_COUNT(types) != MIE_VECTOR_COUNT(out->op_args)) {
struct mie_file_span span = {
.s_start = first_span.s_start,
.s_end = last_span.s_end,
};
mie_parser_report_error_simple(
parser, "builtin", MIE_BUILTIN_E_INCORRECT_NUMBER_OF_TYPES,
MIE_BUILTIN_MSG_OP_NR_TYPES_DOESNT_MATCH_NR_ARGS, &span);
return MIE_ERR_BAD_SYNTAX;
}
for (size_t i = 0; i < MIE_VECTOR_COUNT(types); i++) {
out->op_args.items[i].arg_unresolved.reg_type = types.items[i];
}
return MIE_SUCCESS;
}
struct mie_op *mie_scf_yield_put(struct mie_emitter *e, struct mie_register *value)
{
return mie_emitter_put_op(e, "scf", "yield", &value, 1);
}
MIE_OP_DEFINITION_BEGIN(mie_scf_yield, "yield")
MIE_OP_DEFINITION_PRINT(print);
MIE_OP_DEFINITION_PARSE(parse);

View File

@@ -4,12 +4,14 @@
#include <mie/macros.h>
#include <mie/trait/trait.h>
static enum mie_status print(const struct mie_op *op, b_stream *out)
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
static enum mie_status parse(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out)
{
return MIE_SUCCESS;
}

View File

@@ -1,7 +1,7 @@
#include <blue/core/bstr.h>
#include <blue/core/endian.h>
#include <blue/core/hash.h>
#include <blue/core/random.h>
#include <fx/core/bstr.h>
#include <fx/core/endian.h>
#include <fx/core/hash.h>
#include <fx/core/random.h>
#include <mie/id.h>
#include <string.h>
@@ -10,18 +10,18 @@ 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)
static mie_id *get_id(const fx_bst *tree, mie_id *key)
{
b_btree_node *cur = tree->b_root;
fx_bst_node *cur = tree->bst_root;
while (cur) {
mie_id *cur_node = b_unbox(mie_id, cur, e_node);
mie_id *cur_node = fx_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);
cur = fx_bst_right(cur);
} else if (cmp < 0) {
cur = b_btree_left(cur);
cur = fx_bst_left(cur);
} else {
return cur_node;
}
@@ -30,33 +30,33 @@ static mie_id *get_id(const b_btree *tree, mie_id *key)
return NULL;
}
void put_id(b_btree *tree, mie_id *node)
void put_id(fx_bst *tree, mie_id *node)
{
if (!tree->b_root) {
tree->b_root = &node->e_node;
b_btree_insert_fixup(tree, &node->e_node);
if (!tree->bst_root) {
tree->bst_root = &node->e_node;
fx_bst_insert_fixup(tree, &node->e_node);
return;
}
b_btree_node *cur = tree->b_root;
fx_bst_node *cur = tree->bst_root;
while (1) {
mie_id *cur_node = b_unbox(mie_id, cur, e_node);
b_btree_node *next = NULL;
mie_id *cur_node = fx_unbox(mie_id, cur, e_node);
fx_bst_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);
next = fx_bst_right(cur);
if (!next) {
b_btree_put_right(cur, &node->e_node);
fx_bst_put_right(cur, &node->e_node);
break;
}
} else if (cmp < 0) {
next = b_btree_left(cur);
next = fx_bst_left(cur);
if (!next) {
b_btree_put_left(cur, &node->e_node);
fx_bst_put_left(cur, &node->e_node);
break;
}
} else {
@@ -66,17 +66,17 @@ void put_id(b_btree *tree, mie_id *node)
cur = next;
}
b_btree_insert_fixup(tree, &node->e_node);
fx_bst_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);
fx_i32 x_a = fx_i32_htob(a);
fx_i16 x_b = fx_i16_htob(b);
fx_i16 x_c = fx_i16_htob(c);
fx_i16 x_d = fx_i16_htob(d);
fx_i64 x_e = fx_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);
@@ -92,12 +92,12 @@ void mie_id_init_zero(mie_id *out)
void mie_id_init_random(mie_id *out)
{
b_random_ctx *random = b_random_global_ctx();
b_random_next_bytes(
fx_random_ctx *random = fx_random_global_ctx();
fx_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)
void mie_id_init_ns(mie_id *out, const mie_id *ns, const fx_rope *name)
{
struct mie_id_builder ctx;
mie_id_builder_begin(&ctx, ns);
@@ -107,45 +107,45 @@ void mie_id_init_ns(mie_id *out, const mie_id *ns, const b_rope *name)
void mie_id_to_string(const mie_id *id, char *out, size_t max)
{
b_bstr str;
b_bstr_begin(&str, out, max);
fx_bstr str;
fx_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, '-');
fx_bstr_write_char(&str, '-');
}
b_bstr_write_fmt(&str, "%02x", id->id_bytes[i]);
fx_bstr_write_fmt(&str, NULL, "%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);
fx_hash_ctx_init(&builder->b_hash, FX_HASH_SHA1);
fx_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);
fx_hash_ctx_update(&builder->b_hash, p, len);
}
void mie_id_builder_add_rope(struct mie_id_builder *builder, const b_rope *rope)
void mie_id_builder_add_rope(struct mie_id_builder *builder, const fx_rope *rope)
{
b_hash_ctx_update_rope(&builder->b_hash, rope);
fx_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);
fx_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);
fx_hash_ctx_finish(&builder->b_hash, out->id_bytes, sizeof out->id_bytes);
out->id_bytes[6] &= 0x0F;
out->id_bytes[6] |= 0x50;
@@ -166,7 +166,7 @@ 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)
void mie_id_map_put(struct mie_id_map *map, mie_id *id, const fx_rope *name)
{
mie_id_init_ns(id, &map->map_ns_id, name);
put_id(&map->map_entries, id);
@@ -187,13 +187,13 @@ enum mie_status mie_id_map_iterator_begin(
{
memset(it, 0x0, sizeof *it);
it->_n = b_btree_first(&map->map_entries);
it->_n = fx_bst_first(&map->map_entries);
if (!it->_n) {
return MIE_ERR_NO_DATA;
}
it->it_id = b_unbox(mie_id, it->_n, e_node);
it->it_id = fx_unbox(mie_id, it->_n, e_node);
return MIE_SUCCESS;
}
@@ -205,13 +205,13 @@ enum mie_status mie_id_map_iterator_move_next(struct mie_id_map_iterator *it)
return MIE_ERR_NO_DATA;
}
it->_n = b_btree_next(it->_n);
it->_n = fx_bst_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);
it->it_id = fx_unbox(mie_id, it->_n, e_node);
return MIE_SUCCESS;
}

View File

@@ -26,4 +26,8 @@ struct mie_attribute_definition {
MIE_API struct mie_attribute_definition *mie_attribute_definition_create(
struct mie_dialect *parent, const char *name);
MIE_API bool mie_attribute_definition_check_name(
const struct mie_attribute_definition *def, const char *dialect_name,
const char *attrib_name);
#endif

View File

@@ -1,14 +1,14 @@
#ifndef MIE_ATTRIBUTE_ATTRIBUTE_MAP_H_
#define MIE_ATTRIBUTE_ATTRIBUTE_MAP_H_
#include <blue/core/btree.h>
#include <fx/core/bst.h>
#include <mie/misc.h>
#include <mie/status.h>
struct b_queue_entry;
struct fx_queue_entry;
struct mie_attribute_map {
b_btree m_entries;
fx_bst m_entries;
};
enum mie_attribute_map_flags {
@@ -18,8 +18,8 @@ enum mie_attribute_map_flags {
struct mie_attribute_map_iterator {
const char *it_name;
const struct mie_attribute *it_value;
b_btree_node *_n;
struct b_queue_entry *_e;
fx_bst_node *_n;
struct fx_queue_entry *_e;
};
MIE_API void mie_attribute_map_init(struct mie_attribute_map *map);
@@ -27,7 +27,7 @@ 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);
return fx_bst_empty(&map->m_entries);
}
MIE_API const struct mie_attribute *mie_attribute_map_get(

View File

@@ -1,10 +1,17 @@
#ifndef MIE_ATTRIBUTE_ATTRIBUTE_H_
#define MIE_ATTRIBUTE_ATTRIBUTE_H_
#include <mie/misc.h>
#include <stdbool.h>
struct mie_attribute_definition;
struct mie_attribute {
const struct mie_attribute_definition *a_def;
};
MIE_API bool mie_attribute_check_name(
const struct mie_attribute *attrib, const char *dialect_name,
const char *attrib_name);
#endif

View File

@@ -1,23 +1,28 @@
#ifndef MIE_CTX_H_
#define MIE_CTX_H_
#include <blue/core/btree.h>
#include <blue/ds/hashmap.h>
#include <fx/core/bst.h>
#include <fx/ds/hashmap.h>
#include <mie/id.h>
struct mie_op;
struct mie_pass;
struct mie_diag;
struct mie_file_cell;
struct mie_int_cache;
struct mie_line_source;
struct mie_index_cache;
struct mie_string_cache;
;
struct mie_attribute_map;
struct mie_pass_definition;
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_hashmap *ctx_sel_cache;
b_hashmap *ctx_string_cache;
fx_hashmap *ctx_sel_cache;
fx_hashmap *ctx_string_cache;
#endif
/* map of struct mie_dialect */
struct mie_id_map ctx_dialects;
@@ -27,17 +32,24 @@ struct mie_ctx {
struct mie_id_map ctx_traits;
/* map of struct mie_attribute */
struct mie_id_map ctx_attributes;
/* map of struct mie_pass_definition */
struct mie_id_map ctx_passes;
/* queue of struct mie_diag */
fx_queue ctx_diag;
};
MIE_API struct mie_ctx *mie_ctx_create(void);
MIE_API void mie_ctx_destroy(struct mie_ctx *ctx);
MIE_API bool mie_ctx_resolve_op(const struct mie_ctx *ctx, struct mie_op *op);
MIE_API struct mie_op *mie_ctx_create_op(
const struct mie_ctx *ctx, const char *dialect, const char *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_op_definition *mie_ctx_get_op_definition(
const struct mie_ctx *ctx, const char *dialect_name, const char *op_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);
@@ -59,4 +71,17 @@ MIE_API struct mie_type *mie_ctx_get_function_type(
MIE_API struct mie_value *mie_ctx_get_null(struct mie_ctx *ctx);
MIE_API enum mie_status mie_ctx_register_pass(
struct mie_ctx *ctx, struct mie_pass_definition *pass);
MIE_API enum mie_status mie_ctx_get_pass(
struct mie_ctx *ctx, const char *name,
const struct mie_attribute_map *args, struct mie_pass **out);
MIE_API struct mie_diag *mie_ctx_push_diag(
struct mie_ctx *ctx, struct mie_line_source *src,
const struct mie_file_cell *loc, const char *dialect,
unsigned long diag_class);
MIE_API struct mie_diag *mie_ctx_pop_diag(struct mie_ctx *ctx);
#endif

View File

@@ -0,0 +1,36 @@
#ifndef MIE_DIAG_AMENDMENT_H_
#define MIE_DIAG_AMENDMENT_H_
#include <mie/parse/file-span.h>
enum mie_diag_amendment_type {
MIE_DIAG_AMENDMENT_NONE = 0,
MIE_DIAG_AMENDMENT_ADD,
MIE_DIAG_AMENDMENT_REMOVE,
MIE_DIAG_AMENDMENT_REPLACE,
};
struct mie_diag_amendment {
enum mie_diag_amendment_type a_type;
unsigned long __x;
union {
struct {
struct mie_file_cell a_loc;
char *a_str;
} a_add;
struct {
struct mie_file_cell a_loc;
unsigned long a_length;
} a_remove;
struct {
struct mie_file_cell a_loc;
unsigned long a_length;
char *a_str;
} a_replace;
};
};
#endif

View File

@@ -0,0 +1,18 @@
#ifndef MIE_DIAG_CLASS_H_
#define MIE_DIAG_CLASS_H_
enum mie_diag_class_type {
MIE_DIAG_CLASS_NONE = 0,
MIE_DIAG_CLASS_HINT,
MIE_DIAG_CLASS_WARNING,
MIE_DIAG_CLASS_ERROR,
};
struct mie_diag_class {
unsigned int c_id;
const char *c_id_str_short, *c_id_str_long;
enum mie_diag_class_type c_type;
const char *c_title;
};
#endif

View File

@@ -0,0 +1,34 @@
#ifndef MIE_DIAG_COMPONENT_H_
#define MIE_DIAG_COMPONENT_H_
#include <fx/core/queue.h>
#include <stddef.h>
enum mie_diag_component_type {
MIE_DIAG_COMPONENT_NONE = 0,
MIE_DIAG_COMPONENT_MSG,
MIE_DIAG_COMPONENT_SNIPPET,
};
struct mie_diag_component {
enum mie_diag_component_type c_type;
fx_queue_entry c_entry;
};
struct mie_diag_c_snippet {
struct mie_diag_component s_base;
unsigned long s_first_line, s_last_line;
struct mie_diag_amendment *s_amendments;
size_t s_nr_amendments;
struct mie_diag_highlight *s_highlights;
size_t s_nr_highlights;
};
struct mie_diag_c_msg {
struct mie_diag_component msg_base;
char *msg_content;
};
#endif

View File

@@ -0,0 +1,73 @@
#ifndef MIE_DIAG_DIAG_H_
#define MIE_DIAG_DIAG_H_
#include <fx/core/queue.h>
#include <mie/parse/file-span.h>
#define MIE_DIAG_HL(type, span) \
{ \
.hl_type = MIE_DIAG_HIGHLIGHT_##type, \
.hl_span = (span), \
}
#define MIE_DIAG_ADD(str, loc) \
{ \
.a_type = MIE_DIAG_AMENDMENT_ADD, .__x = strlen(str), \
.a_add = { \
.a_loc = (loc), \
.a_str = (str), \
}, \
}
#define MIE_DIAG_REMOVE(len, llc) \
{ \
.a_type = MIE_DIAG_AMENDMENT_REMOVE, \
.a_remove = { \
.a_loc = (loc), \
.a_length = (len), \
}, \
}
#define MIE_DIAG_REPLACE(len, str, loc) \
{ \
.a_type = MIE_DIAG_AMENDMENT_REPLACE, .__x = strlen(str), \
.a_replace = { \
.a_loc = (loc), \
.a_length = (len), \
.a_str = (str), \
}, \
}
struct mie_ctx;
struct mie_diag_class;
struct mie_diag_amendment;
struct mie_diag_highlight;
enum mie_diag_type {
MIE_DIAG_NONE = 0,
MIE_DIAG_HINT,
MIE_DIAG_WARNING,
MIE_DIAG_ERROR,
};
struct mie_diag {
struct mie_dialect *diag_parent;
const struct mie_diag_class *diag_class;
struct mie_line_source *diag_src;
struct mie_file_cell diag_loc;
fx_queue_entry diag_entry;
fx_queue diag_components;
};
MIE_API void mie_diag_set_location(
struct mie_diag *diag, unsigned long row, unsigned long col);
MIE_API void mie_diag_push_msg(
struct mie_diag *diag, struct mie_ctx *ctx, const char *dialect,
unsigned long msg, ...);
MIE_API void mie_diag_push_string(struct mie_diag *diag, const char *str);
MIE_API void mie_diag_push_snippet(
struct mie_diag *diag, unsigned long first_line, unsigned long last_line,
const struct mie_diag_amendment *amendmends, size_t nr_amendments,
const struct mie_diag_highlight *highlights, size_t nr_highlights);
#endif

View File

@@ -0,0 +1,18 @@
#ifndef MIE_DIAG_HIGHLIGHT_H_
#define MIE_DIAG_HIGHLIGHT_H_
#include <mie/parse/file-span.h>
enum mie_diag_highlight_type {
MIE_DIAG_HIGHLIGHT_NONE = 0,
MIE_DIAG_HIGHLIGHT_HINT,
MIE_DIAG_HIGHLIGHT_WARNING,
MIE_DIAG_HIGHLIGHT_ERROR,
};
struct mie_diag_highlight {
enum mie_diag_highlight_type hl_type;
struct mie_file_span hl_span;
};
#endif

View File

@@ -0,0 +1,10 @@
#ifndef MIE_DIAG_MSG_H_
#define MIE_DIAG_MSG_H_
struct mie_diag_msg {
unsigned int msg_id;
const char *msg_id_str_short, *msg_id_str_long;
const char *msg_content;
};
#endif

View File

View File

@@ -8,7 +8,48 @@
struct mie_ctx;
struct mie_dialect;
struct mie_emitter;
enum mie_arith_diag {
MIE_ARITH_E_INVALID_INTEGER_TYPE,
MIE_ARITH_E_INVALID_FLOAT_TYPE,
MIE_ARITH_E_INVALID_COMPARISON_PREDICATE,
};
enum mie_arith_msg {
MIE_ARITH_MSG_EXPECTED_INTEGER_TYPE,
MIE_ARITH_MSG_EXPECTED_FLOAT_TYPE,
MIE_ARITH_MSG_INVALID_COMPARISON_PREDICATE,
MIE_ARITH_MSG_VALID_COMPARISON_PREDICATES,
};
enum mie_arith_cmpi_predicate {
MIE_ARITH_CMPI_EQ = 0,
MIE_ARITH_CMPI_NE = 1,
MIE_ARITH_CMPI_SLT = 2,
MIE_ARITH_CMPI_SLE = 3,
MIE_ARITH_CMPI_SGT = 4,
MIE_ARITH_CMPI_SGE = 5,
MIE_ARITH_CMPI_ULT = 6,
MIE_ARITH_CMPI_ULE = 7,
MIE_ARITH_CMPI_UGT = 8,
MIE_ARITH_CMPI_UGE = 9,
};
MIE_API struct mie_dialect *mie_arith_dialect_create(struct mie_ctx *ctx);
MIE_API struct mie_register *mie_arith_constant_i_put(
struct mie_emitter *e, long long value, const char *name);
MIE_API struct mie_register *mie_arith_constant_f_put(
struct mie_emitter *e, long long value, const char *name);
MIE_API struct mie_register *mie_arith_addi_put(
struct mie_emitter *e, struct mie_register *left,
struct mie_register *right, const char *name);
MIE_API struct mie_register *mie_arith_cmpi_put(
struct mie_emitter *e, enum mie_arith_cmpi_predicate pred,
struct mie_register *left, struct mie_register *right, const char *name);
MIE_API struct mie_register *mie_arith_addf_put(
struct mie_emitter *e, struct mie_register *left,
struct mie_register *right, const char *name);
#endif

View File

@@ -1,11 +1,13 @@
#ifndef MIE_DIALECT_BUILTIN_H_
#define MIE_DIALECT_BUILTIN_H_
#include <blue/ds/string.h>
#include <fx/ds/string.h>
#include <mie/attribute/attribute.h>
#include <mie/interface/interface.h>
#include <mie/misc.h>
#include <mie/parse/file-span.h>
#include <mie/trait/trait.h>
#include <mie/vector.h>
struct mie_dialect;
@@ -14,11 +16,66 @@ struct mie_op;
struct mie_int_type;
struct mie_float_type;
enum mie_builtin_diag {
MIE_BUILTIN_E_UNRECOGNISED_TOKEN,
MIE_BUILTIN_E_UNEXPECTED_TOKEN,
MIE_BUILTIN_E_UNRESOLVED_TYPE,
MIE_BUILTIN_E_UNRESOLVED_VALUE,
MIE_BUILTIN_E_UNRESOLVED_SUCCESSOR,
MIE_BUILTIN_E_UNKNOWN_OP,
MIE_BUILTIN_E_OP_REQUIRES_PARENT_SCOPE,
MIE_BUILTIN_E_INCORRECT_NUMBER_OF_ARGUMENTS,
MIE_BUILTIN_E_INCORRECT_NUMBER_OF_RESULTS,
MIE_BUILTIN_E_INCORRECT_NUMBER_OF_TYPES,
MIE_BUILTIN_E_INCORRECT_TYPE,
MIE_BUILTIN_E_INVALID_TYPE,
MIE_BUILTIN_E_NAME_ALREADY_IN_USE,
MIE_BUILTIN_E_INTERNAL_ERROR,
};
enum mie_builtin_msg {
MIE_BUILTIN_MSG_UNRECOGNISED_TOKEN,
MIE_BUILTIN_MSG_UNEXPECTED_TOKEN,
MIE_BUILTIN_MSG_UNRESOLVED_VALUE,
MIE_BUILTIN_MSG_UNRESOLVED_BUILTIN_TYPE,
MIE_BUILTIN_MSG_UNRESOLVED_DIALECT_TYPE,
MIE_BUILTIN_MSG_CANNOT_FIND_BLOCK,
MIE_BUILTIN_MSG_VALUE_DEFINED_IN_NON_DOMINANT_BLOCK,
MIE_BUILTIN_MSG_VALUE_DEFINED_AFTER_USE,
MIE_BUILTIN_MSG_VALUE_DEFINED_OUTSIDE_ISOLATED_REGION,
MIE_BUILTIN_MSG_VALUE_DEFINED_IN_BLOCK,
MIE_BUILTIN_MSG_UNKNOWN_OP,
MIE_BUILTIN_MSG_OP_REQUIRES_PARENT_SCOPE,
MIE_BUILTIN_MSG_OP_PARENT_SCOPE_EXAMPLE,
MIE_BUILTIN_MSG_USE_GENERIC_OP_SYNTAX,
MIE_BUILTIN_MSG_OP_HAS_NO_PARSER,
MIE_BUILTIN_MSG_DIALECT_INTERNAL_ERROR,
MIE_BUILTIN_MSG_COMPILER_INTERNAL_ERROR,
MIE_BUILTIN_MSG_OP_INCORRECT_NUMBER_OF_ARGS,
MIE_BUILTIN_MSG_OP_INCORRECT_NUMBER_OF_RESULTS,
MIE_BUILTIN_MSG_OP_NR_TYPES_DOESNT_MATCH_NR_ARGS,
MIE_BUILTIN_MSG_OP_NR_TYPES_DOESNT_MATCH_NR_RESULTS,
MIE_BUILTIN_MSG_OP_EXPECTS_X_RESULTS,
MIE_BUILTIN_MSG_NR_RESULT_NAME_OUTPUT_MISMATCH,
MIE_BUILTIN_MSG_NAME_ALREADY_IN_USE,
MIE_BUILTIN_MSG_NAME_ALREADY_USED_HERE,
MIE_BUILTIN_MSG_CANNOT_USE_FUNCTION_TYPE_HERE,
MIE_BUILTIN_MSG_CANNOT_USE_STORAGE_TYPE_HERE,
MIE_BUILTIN_MSG_MUST_USE_FUNCTION_TYPE_HERE,
MIE_BUILTIN_MSG_MUST_USE_STORAGE_TYPE_HERE,
};
enum mie_float_width {
MIE_FLOAT_32 = 32,
MIE_FLOAT_64 = 64,
};
enum mie_memref_rank_type {
MIE_MEMREF_RANK_UNKNOWN = 0,
MIE_MEMREF_RANK_STATIC,
MIE_MEMREF_RANK_TYPE,
};
struct mie_string {
struct mie_attribute str_base;
char *str_val;
@@ -54,6 +111,16 @@ struct mie_index {
size_t i_value;
};
struct mie_array {
struct mie_attribute a_base;
MIE_VECTOR_DECLARE(const struct mie_attribute *, a_items);
};
struct mie_type_attr {
struct mie_attribute ty_base;
const struct mie_type *ty_value;
};
struct mie_symbol {
struct mie_interface sym_base;
const char *(*sym_get_name)(const struct mie_op *);
@@ -63,6 +130,15 @@ struct mie_symbol_table {
struct mie_trait tab_base;
};
struct mie_memref_rank {
enum mie_memref_rank_type r_ranktype;
struct mie_file_span r_span;
union {
size_t r_static;
const struct mie_type *r_type;
};
};
struct mie_int_cache;
struct mie_float_cache;
struct mie_string_cache;
@@ -100,11 +176,26 @@ 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 const char *mie_string_get_cstr(const struct mie_attribute *attrib);
MIE_API const struct mie_type *mie_type_attr_get_type(
const struct mie_attribute *attrib);
MIE_API bool mie_int_get_value(const struct mie_attribute *attrib, long long *out);
MIE_API bool mie_float_get_value(const struct mie_attribute *attrib, double *out);
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 struct mie_type *mie_ctx_get_memref_type(
struct mie_ctx *ctx, const struct mie_memref_rank *ranks, size_t nr_ranks);
MIE_API struct mie_attribute *mie_type_attr_create(
struct mie_ctx *ctx, const struct mie_type *ty);
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);
MIE_API size_t mie_memref_type_get_nr_ranks(const struct mie_type *type);
MIE_API const struct mie_memref_rank *mie_memref_type_get_rank(
const struct mie_type *type, size_t i);
#endif

View File

@@ -2,10 +2,23 @@
#define MIE_DIALECT_CF_H_
#include <mie/misc.h>
#include <stddef.h>
struct mie_ctx;
struct mie_block;
struct mie_dialect;
struct mie_emitter;
struct mie_register;
MIE_API struct mie_dialect *mie_cf_dialect_create(struct mie_ctx *ctx);
MIE_API struct mie_op *mie_cf_br_put(
struct mie_emitter *e, struct mie_block *dest,
struct mie_register **dest_args, size_t nr_dest_args);
MIE_API struct mie_op *mie_cf_br_cond_put(
struct mie_emitter *e, struct mie_register *cond,
struct mie_block *true_block, struct mie_register **true_args,
size_t nr_true_args, struct mie_block *false_block,
struct mie_register **false_args, size_t nr_false_args);
#endif

View File

@@ -1,8 +1,8 @@
#ifndef MIE_DIALECT_DIALECT_H_
#define MIE_DIALECT_DIALECT_H_
#include <blue/core/btree.h>
#include <blue/core/queue.h>
#include <fx/core/bst.h>
#include <fx/core/queue.h>
#include <mie/id.h>
#include <mie/misc.h>
#include <mie/vector.h>
@@ -13,6 +13,9 @@ struct mie_op_definition;
struct mie_type_definition;
struct mie_trait_definition;
struct mie_diag_class;
struct mie_diag_msg;
struct mie_dialect {
mie_id d_id;
char *d_name;
@@ -27,6 +30,12 @@ struct mie_dialect {
struct mie_id_map d_attributes;
/* map of struct mie_interface_definition */
struct mie_id_map d_interfaces;
/* array of mie_diag_class */
struct mie_diag_class *d_diag_classes;
size_t d_nr_diag_classes;
/* array of mie_diag_msg */
struct mie_diag_msg *d_diag_msgs;
size_t d_nr_diag_msgs;
enum mie_status (*d_cleanup)(struct mie_dialect *);
};

View File

@@ -2,10 +2,24 @@
#define MIE_DIALECT_FUNC_H_
#include <mie/misc.h>
#include <stddef.h>
struct mie_ctx;
struct mie_type;
struct mie_dialect;
struct mie_emitter;
struct mie_register;
struct mie_func_parameter {
const char *param_name;
const struct mie_type *param_type;
struct mie_register *param_reg;
};
MIE_API struct mie_dialect *mie_func_dialect_create(struct mie_ctx *ctx);
MIE_API struct mie_op *mie_func_func_put(
struct mie_emitter *e, const char *name, struct mie_func_parameter *params,
size_t nr_params, const struct mie_type **ret_types, size_t nr_ret_types);
#endif

View File

@@ -8,6 +8,13 @@
struct mie_ctx;
struct mie_dialect;
enum mie_memref_msg {
MIE_MEMREF_MSG_OP_EXPECTS_MEMREF_ARGUMENT,
MIE_MEMREF_MSG_LAST_MEMREF_RANK_MUST_BE_TYPE,
MIE_MEMREF_MSG_MEMREF_MUST_HAVE_AT_LEAST_ONE_RANK,
MIE_MEMREF_MSG_OP_RESULT_DETERMINED_BY_LAST_MEMREF_RANK,
};
MIE_API struct mie_dialect *mie_memref_dialect_create(struct mie_ctx *ctx);
#endif

View File

@@ -4,8 +4,19 @@
#include <mie/misc.h>
struct mie_ctx;
struct mie_type;
struct mie_region;
struct mie_dialect;
struct mie_emitter;
struct mie_register;
MIE_API struct mie_dialect *mie_scf_dialect_create(struct mie_ctx *ctx);
MIE_API struct mie_op *mie_scf_if_put(
struct mie_emitter *e, struct mie_register *cond,
const struct mie_type *result_type, struct mie_region **out_true,
struct mie_region **out_false, const char *name);
MIE_API struct mie_op *mie_scf_yield_put(
struct mie_emitter *e, struct mie_register *value);
#endif

View File

@@ -1,9 +1,9 @@
#ifndef MIE_ID_H_
#define MIE_ID_H_
#include <blue/core/btree.h>
#include <blue/core/queue.h>
#include <blue/core/rope.h>
#include <fx/core/bst.h>
#include <fx/core/queue.h>
#include <fx/core/rope.h>
#include <mie/misc.h>
#include <mie/status.h>
#include <stddef.h>
@@ -42,30 +42,30 @@ typedef struct mie_id {
};
union {
b_btree_node e_node;
b_queue_entry e_entry;
fx_bst_node e_node;
fx_queue_entry e_entry;
};
} mie_id;
struct mie_id_builder {
b_hash_ctx b_hash;
fx_hash_ctx b_hash;
};
struct mie_id_map {
mie_id map_ns_id;
b_btree map_entries;
fx_bst map_entries;
};
struct mie_id_map_iterator {
mie_id *it_id;
b_btree_node *_n;
fx_bst_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);
MIE_API void mie_id_init_ns(mie_id *out, const mie_id *ns, const fx_rope *name);
static inline int mie_id_compare(const mie_id *a, const mie_id *b)
{
@@ -86,8 +86,20 @@ static inline void mie_id_builder_add_cstr(
{
mie_id_builder_add(builder, s, strlen(s));
}
static inline void mie_id_builder_add_id(
struct mie_id_builder *builder, const mie_id *id)
{
mie_id_builder_add(builder, id->id_bytes, sizeof id->id_bytes);
}
static inline void mie_id_builder_add_int(
struct mie_id_builder *builder, long long v)
{
char s[32];
size_t len = snprintf(s, sizeof s, "%lld", v);
mie_id_builder_add(builder, s, len);
}
MIE_API void mie_id_builder_add_rope(
struct mie_id_builder *builder, const b_rope *rope);
struct mie_id_builder *builder, const fx_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);
@@ -95,12 +107,12 @@ 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);
return fx_bst_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);
struct mie_id_map *map, mie_id *node, const fx_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);

View File

@@ -1,21 +1,74 @@
#ifndef MIE_IR_BLOCK_H_
#define MIE_IR_BLOCK_H_
#include <blue/core/queue.h>
#include <fx/core/queue.h>
#include <mie/misc.h>
#include <mie/name.h>
#include <mie/vector.h>
#define MIE_BLOCK_ID_INVALID ((size_t)0)
struct mie_op;
struct mie_register;
struct mie_block {
struct mie_name b_name;
MIE_VECTOR_DECLARE(struct mie_register *, b_params);
MIE_VECTOR_DECLARE(struct mie_op, b_ops);
struct mie_block_predecessor {
struct mie_block *p_block;
};
struct mie_block {
struct mie_name b_name;
struct mie_region *b_parent;
/* immediate predecessor blocks */
MIE_VECTOR_DECLARE(struct mie_block_predecessor, b_ipred);
/* used by struct mie_region */
unsigned int b_id;
struct mie_block *b_idom;
// struct mie_block *b_sdom, *b_dfs_parent;
fx_queue_entry b_entry;
MIE_VECTOR_DECLARE(struct mie_register, b_params);
/* queue of struct mie_op */
fx_queue b_ops;
};
extern struct mie_vector_ops mie_block_vector_ops;
MIE_API struct mie_op *mie_block_get_first_op(const struct mie_block *block);
MIE_API struct mie_op *mie_block_get_prev_op(
const struct mie_block *block, const struct mie_op *before);
MIE_API struct mie_op *mie_block_get_next_op(
const struct mie_block *block, const struct mie_op *after);
MIE_API struct mie_op *mie_block_get_last_op(const struct mie_block *block);
MIE_API struct mie_op *mie_block_get_terminator(const struct mie_block *block);
MIE_API struct mie_op_successor *mie_block_get_first_successor(
const struct mie_block *block);
MIE_API struct mie_op_successor *mie_block_get_prev_successor(
const struct mie_block *block, const struct mie_op_successor *before);
MIE_API struct mie_op_successor *mie_block_get_next_successor(
const struct mie_block *block, const struct mie_op_successor *after);
MIE_API struct mie_op_successor *mie_block_get_last_successor(
const struct mie_block *block);
MIE_API struct mie_block_predecessor *mie_block_get_first_predecessor(
const struct mie_block *block);
MIE_API struct mie_block_predecessor *mie_block_get_prev_predecessor(
const struct mie_block *block, const struct mie_block_predecessor *before);
MIE_API struct mie_block_predecessor *mie_block_get_next_predecessor(
const struct mie_block *block, const struct mie_block_predecessor *after);
MIE_API struct mie_block_predecessor *mie_block_get_last_predecessor(
const struct mie_block *block);
MIE_API struct mie_op *mie_block_add_op(struct mie_block *block);
MIE_API struct mie_op *mie_block_add_op_after(
struct mie_block *block, struct mie_op *after);
MIE_API struct mie_register *mie_block_add_param(struct mie_block *block);
MIE_API struct mie_register *mie_block_find_register(
const struct mie_block *block, const char *name,
const struct mie_op *start_point);
#endif

View File

@@ -0,0 +1,39 @@
#ifndef MIE_IR_BUILDER_H_
#define MIE_IR_BUILDER_H_
#include <mie/ir/emit.h>
#include <mie/misc.h>
#include <stddef.h>
struct mie_op;
struct mie_ctx;
struct mie_type;
struct mie_name;
struct mie_block;
struct mie_region;
struct mie_register;
struct mie_builder;
MIE_API struct mie_builder *mie_builder_create(
struct mie_ctx *ctx, struct mie_op *root);
MIE_API void mie_builder_destroy(struct mie_builder *builder);
MIE_API struct mie_ctx *mie_builder_get_ctx(struct mie_builder *builder);
MIE_API struct mie_block *mie_builder_get_current_block(struct mie_builder *builder);
MIE_API void mie_builder_step_into_op(
struct mie_builder *builder, struct mie_op *op);
MIE_API void mie_builder_step_into_region(
struct mie_builder *builder, struct mie_region *region);
MIE_API void mie_builder_step_into_block(
struct mie_builder *builder, struct mie_block *block);
MIE_API void mie_builder_step_out(struct mie_builder *builder);
MIE_API struct mie_op *mie_builder_put_op(
struct mie_builder *builder, const char *dialect, const char *op,
struct mie_register **args, size_t nr_args);
MIE_API enum mie_status mie_builder_put_name(
struct mie_builder *builder, struct mie_name *name, const char *hint);
#endif

42
mie/include/mie/ir/emit.h Normal file
View File

@@ -0,0 +1,42 @@
#ifndef MIE_IR_EMIT_H_
#define MIE_IR_EMIT_H_
#include <mie/misc.h>
#include <mie/status.h>
#include <stddef.h>
#define MIE_EMITTER(p) ((struct mie_emitter *)(p))
struct mie_op;
struct mie_name;
struct mie_block;
struct mie_register;
struct mie_emitter;
typedef struct mie_ctx *(*mie_emit_get_ctx)(const struct mie_emitter *);
typedef enum mie_status (*mie_emit_put_name)(
struct mie_emitter *, struct mie_name *, const char *);
typedef struct mie_op *(*mie_emit_put_op)(
struct mie_emitter *, const char *, const char *,
struct mie_register **, size_t);
typedef struct mie_block *(*mie_emit_put_block)(
struct mie_emitter *, struct mie_block *);
struct mie_emitter {
mie_emit_get_ctx e_get_ctx;
mie_emit_put_name e_put_name;
mie_emit_put_op e_put_op;
mie_emit_put_block e_put_block;
};
MIE_API struct mie_ctx *mie_emitter_get_ctx(struct mie_emitter *emitter);
MIE_API enum mie_status mie_emitter_put_name(
struct mie_emitter *emitter, struct mie_name *name, const char *hint);
MIE_API struct mie_op *mie_emitter_put_op(
struct mie_emitter *emitter, const char *dialect_name,
const char *op_name, struct mie_register **args, size_t nr_args);
MIE_API struct mie_block *mie_emitter_put_block(
struct mie_emitter *emitter, struct mie_block *insert_point);
#endif

View File

@@ -1,22 +0,0 @@
#ifndef MIE_IR_MODULE_H_
#define MIE_IR_MODULE_H_
#include <blue/core/stream.h>
#include <mie/misc.h>
#include <mie/name.h>
#include <mie/vector.h>
#include <stddef.h>
struct mie_op;
struct mie_module {
struct mie_name_map *m_names;
MIE_VECTOR_DECLARE(struct mie_op, m_ops);
};
MIE_API struct mie_module *mie_module_create(void);
MIE_API void mie_module_destroy(struct mie_module *mod);
MIE_API struct mie_op *mie_module_add_op(struct mie_module *mod);
#endif

View File

@@ -1,8 +1,8 @@
#ifndef MIE_IR_OP_DEFINITION_H_
#define MIE_IR_OP_DEFINITION_H_
#include <blue/core/btree.h>
#include <blue/core/stream.h>
#include <fx/core/bst.h>
#include <fx/core/stream.h>
#include <mie/id.h>
#include <mie/interface/interface-map.h>
#include <mie/status.h>
@@ -12,8 +12,10 @@
#define MIE_OP_MAX_RESULTS 8
struct mie_op;
struct mie_printer;
struct mie_parser;
struct mie_dialect;
struct mie_parser_scope;
#if 0
enum mie_op_trait {
@@ -101,8 +103,9 @@ struct mie_op_definition {
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 *);
enum mie_status (*op_print)(struct mie_printer *, const struct mie_op *);
enum mie_status (*op_parse)(
struct mie_parser *, struct mie_parser_scope *, struct mie_op *);
};
MIE_API struct mie_op_definition *mie_op_definition_create(

View File

@@ -9,8 +9,8 @@
#include <mie/name.h>
#include <mie/parse/file-span.h>
struct mie_ctx;
struct mie_type;
struct mie_value;
struct mie_block;
struct mie_region;
@@ -29,7 +29,7 @@ struct mie_op_arg {
struct mie_file_span arg_span;
union {
/* only valid if F_ARG_RESOLVED is set in arg_flags */
struct mie_register *arg_value;
struct mie_register_use arg_value;
/* only valid if F_ARG_RESOLVED is NOT set in arg_flags */
struct mie_register_ref arg_unresolved;
};
@@ -37,6 +37,7 @@ struct mie_op_arg {
struct mie_op_successor {
enum mie_op_flags s_flags;
struct mie_file_span s_name_span;
union {
/* only valid if F_SUCCESSOR_RESOLVED is set in s_flags; */
@@ -50,25 +51,69 @@ struct mie_op_successor {
struct mie_op {
enum mie_op_flags op_flags;
/* used by struct mie_block */
fx_queue_entry op_entry;
/* these pointers are only valid if the F_OP_RESOLVED flag is set */
const struct mie_dialect *op_dialect;
struct mie_line_source *op_src;
/* this pointer is only valid if the F_OP_RESOLVED flag is set */
const struct mie_op_definition *op_info;
struct mie_block *op_container;
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);
fx_queue 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_VECTOR_DECLARE(struct mie_register, op_result);
};
MIE_API struct mie_op *mie_op_create(void);
MIE_API void mie_op_destroy(struct mie_op *op);
MIE_API void mie_op_init(struct mie_op *op);
MIE_API void mie_op_cleanup(struct mie_op *op);
MIE_API size_t mie_op_get_name(const struct mie_op *op, char *out, size_t max);
MIE_API struct mie_op_arg *mie_op_add_arg(struct mie_op *op);
MIE_API struct mie_register *mie_op_add_result(
struct mie_op *op, const struct mie_type *ty);
MIE_API struct mie_op_successor *mie_op_add_successor(
struct mie_op *op, struct mie_block *block, struct mie_register **args,
size_t nr_args);
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);
MIE_API bool mie_op_is(
const struct mie_op *op, const char *dialect_name, const char *op_name);
MIE_API bool mie_op_has_trait(
const struct mie_op *op, const char *dialect_name, const char *trait_name);
MIE_API bool mie_op_has_interface(
const struct mie_op *op, const char *dialect_name, const char *iface_name);
MIE_API struct mie_op *mie_op_get_parent(const struct mie_op *op);
MIE_API struct mie_region *mie_op_get_first_region(const struct mie_op *op);
MIE_API struct mie_region *mie_op_get_prev_region(
const struct mie_op *op, const struct mie_region *before);
MIE_API struct mie_region *mie_op_get_next_region(
const struct mie_op *op, const struct mie_region *after);
MIE_API struct mie_region *mie_op_get_last_region(const struct mie_op *op);
MIE_API struct mie_register *mie_op_get_arg(const struct mie_op *op, size_t index);
MIE_API struct mie_register *mie_op_get_result_with_name(
const struct mie_op *op, const char *name);
MIE_API void mie_op_get_args_span(
const struct mie_op *op, struct mie_file_span *result);
MIE_API void mie_op_get_results_span(
const struct mie_op *op, struct mie_file_span *result);
MIE_API struct mie_op *mie_op_get_first_child_op(const struct mie_op *op);
MIE_API struct mie_op *mie_op_get_last_child_op(const struct mie_op *op);
MIE_API const struct mie_type *mie_op_arg_get_type(const struct mie_op_arg *arg);
#endif

View File

@@ -1,17 +1,57 @@
#ifndef MIE_IR_REGION_H_
#define MIE_IR_REGION_H_
#include <fx/core/bst.h>
#include <fx/core/queue.h>
#include <mie/misc.h>
#include <mie/vector.h>
#include <stddef.h>
struct mie_op;
struct mie_ctx;
struct mie_block;
struct mie_region {
struct mie_name_map *r_names;
MIE_VECTOR_DECLARE(struct mie_block *, r_blocks);
struct mie_op *r_parent;
/* used by struct mie_op */
fx_queue_entry r_entry;
/* queue of struct mie_block */
fx_queue r_blocks;
/* bst of struct mie_block, as numbered by a depth-first search.
* this ordering is recalculated by mie_region_refresh_dominance */
fx_bst r_blocks_s;
};
MIE_API struct mie_block *mie_region_get_first_block(
const struct mie_region *region);
MIE_API struct mie_block *mie_region_get_prev_block(
const struct mie_region *region, const struct mie_block *before);
MIE_API struct mie_block *mie_region_get_next_block(
const struct mie_region *region, const struct mie_block *after);
MIE_API struct mie_block *mie_region_get_last_block(const struct mie_region *region);
MIE_API struct mie_block *mie_region_add_block(struct mie_region *region);
MIE_API struct mie_block *mie_region_add_block_before(
struct mie_region *region, struct mie_block *before);
MIE_API struct mie_block *mie_region_add_block_after(
struct mie_region *region, struct mie_block *after);
MIE_API struct mie_block *mie_region_find_block(
const struct mie_region *region, const char *name);
MIE_API struct mie_register *mie_region_find_register(
const struct mie_region *region, const char *name);
/* calculate the dominance-tree of all blocks in a region.
* this function populates the following attributes of every block in the
* region:
* b_id
* fx_node
* fx_parent
* as well as the following attributes of the region itself:
* r_blocks_s
* only top-level blocks and ops are considered by this function. if an op
* within the region itself contains one/more child regions, these are ignored.
*/
MIE_API void mie_region_refresh_dominance(struct mie_region *region);
#endif

View File

@@ -2,7 +2,10 @@
#define MIE_IR_REGISTER_H_
#include <mie/name.h>
#include <mie/vector.h>
struct mie_op;
struct mie_register;
struct mie_target_register;
enum mie_register_flags {
@@ -25,8 +28,16 @@ struct mie_register_ref {
const struct mie_type *reg_type;
};
/* represents a use of/resolved reference to a mie_register */
struct mie_register_use {
fx_queue_entry u_entry;
struct mie_op *u_user;
struct mie_register *u_reg;
};
struct mie_register {
enum mie_register_flags reg_flags;
struct mie_file_span reg_span;
union {
/* only valid if F_VIRTUAL is set. */
struct mie_name reg_name;
@@ -46,6 +57,19 @@ struct mie_register {
* for which this register is a parameter
* if this is a BLOCK_PARAM register, this pointer is NULL */
struct mie_op *reg_op;
/* list of struct mie_register_use, representing all the places
* where this register is used. */
fx_queue reg_use;
};
extern struct mie_vector_ops mie_register_vector_ops;
extern struct mie_vector_ops mie_register_use_vector_ops;
MIE_API void mie_register_move(struct mie_register *dest, struct mie_register *src);
MIE_API void mie_register_cleanup(struct mie_register *reg);
MIE_API void mie_register_use_move(
struct mie_register_use *dest, struct mie_register_use *src);
MIE_API void mie_register_use_cleanup(struct mie_register_use *reg);
#endif

View File

@@ -0,0 +1,14 @@
#ifndef MIE_IR_RESOLVE_H_
#define MIE_IR_RESOLVE_H_
#include <mie/misc.h>
#include <stdbool.h>
struct mie_op;
struct mie_ctx;
MIE_API bool mie_resolve_op_self(struct mie_op *op, struct mie_ctx *ctx);
MIE_API bool mie_resolve_op_args(struct mie_op *op, struct mie_ctx *ctx);
MIE_API bool mie_resolve_op_successors(struct mie_op *op, struct mie_ctx *ctx);
#endif

70
mie/include/mie/ir/walk.h Normal file
View File

@@ -0,0 +1,70 @@
#ifndef MIE_IR_WALK_H_
#define MIE_IR_WALK_H_
#include <fx/core/queue.h>
#include <mie/misc.h>
#include <mie/status.h>
#include <stddef.h>
struct mie_op;
enum mie_walker_flags {
MIE_WALKER_F_NONE = 0x00u,
/* 0: default behaviour */
MIE_WALKER_F_PREORDER = 0x00u,
MIE_WALKER_F_POSTORDER = 0x01u,
/* 0: default behaviour */
MIE_WALKER_F_FORWARD = 0x00u,
MIE_WALKER_F_BACKWARD = 0x02u,
MIE_WALKER_F_RECURSIVE = 0x04u,
MIE_WALKER_F_INCLUDE_OPS = 0x08u,
MIE_WALKER_F_INCLUDE_REGIONS = 0x10u,
MIE_WALKER_F_INCLUDE_BLOCKS = 0x20u,
};
enum mie_walk_item_type {
MIE_WALK_ITEM_NONE = 0,
MIE_WALK_ITEM_OP,
MIE_WALK_ITEM_BLOCK,
MIE_WALK_ITEM_REGION,
};
struct mie_walk_item {
int _f;
fx_queue_entry _e;
enum mie_walk_item_type i_type;
// size_t i_index;
size_t i_depth;
union {
struct mie_op *i_op;
struct mie_block *i_block;
struct mie_region *i_region;
};
};
struct mie_walker {
enum mie_walker_flags w_flags;
union {
/* used for recursive walks */
fx_queue w_stack;
/* used for non-recursive walks */
struct {
struct mie_walk_item w_region, w_block, w_op;
};
};
};
MIE_API void mie_walker_begin(
struct mie_walker *walker, const struct mie_op *op,
enum mie_walker_flags flags);
MIE_API void mie_walker_end(struct mie_walker *walker);
MIE_API enum mie_status mie_walker_step(struct mie_walker *walker);
MIE_API struct mie_walk_item *mie_walker_get(struct mie_walker *walker);
#endif

View File

@@ -1,187 +1,334 @@
#ifndef MIE_MACROS_H_
#define MIE_MACROS_H_
#define __MIE_DIALECT_BEGIN(func_prefix, c_struct, dialect_name) \
struct mie_dialect *func_prefix##_dialect_create(struct mie_ctx *ctx) \
{ \
struct mie_dialect *self = mie_dialect_create( \
ctx, dialect_name, sizeof(c_struct)); \
if (!self) { \
return NULL; \
} \
struct mie_op_definition *op = NULL; \
struct mie_type_definition *type = NULL; \
struct mie_trait_definition *trait = NULL; \
struct mie_attribute_definition *attribute = NULL; \
struct mie_interface_definition *interface = NULL;
/******************************************************************************/
/* DIALECT DEFINITION MACROS */
/******************************************************************************/
#define __MIE_DIALECT_END() \
return self; \
}
#define MIE_DIALECT_BEGIN(func_prefix, c_struct, dialect_name) \
struct mie_dialect* func_prefix##_dialect_create(struct mie_ctx* ctx) \
{ \
struct mie_dialect* self = mie_dialect_create( \
ctx, dialect_name, sizeof(c_struct)); \
if (!self) { \
return NULL; \
} \
struct mie_op_definition* op = NULL; \
struct mie_type_definition* type = NULL; \
struct mie_trait_definition* trait = NULL; \
struct mie_attribute_definition* attribute = NULL; \
struct mie_interface_definition* interface = NULL;
#define __MIE_OP_DEFINITION_BEGIN(func_prefix, op_name) \
struct mie_op_definition *func_prefix##_op_create( \
struct mie_dialect *d, struct mie_ctx *ctx) \
{ \
struct mie_op_definition *op \
= mie_op_definition_create(d, op_name); \
if (!op) { \
return NULL; \
} \
const struct mie_trait *trait = NULL; \
struct mie_interface *i = NULL; \
const struct mie_interface_definition *id = NULL;
#define MIE_DIALECT_END() \
return self; \
}
#define __MIE_OP_DEFINITION_END() \
return op; \
}
#define MIE_DIALECT_INIT(func) func(self)
#define MIE_DIALECT_CLEANUP(func) self->d_cleanup = (func)
#define MIE_DIALECT_DIAG_CLASS_LIST(list) \
self->d_diag_classes = (list); \
self->d_nr_diag_classes = (list##_count)
#define MIE_DIALECT_DIAG_MSG_LIST(list) \
self->d_diag_msgs = (list); \
self->d_nr_diag_msgs = (list##_count)
#define MIE_DIALECT_ADD_OP(op_id) \
extern struct mie_op_definition* op_id##_op_create( \
struct mie_dialect*, struct mie_ctx*); \
op = op_id##_op_create(self, ctx)
#define MIE_DIALECT_ADD_TYPE(type_id) \
extern struct mie_type_definition* type_id##_type_create( \
struct mie_dialect*, struct mie_ctx*); \
type = type_id##_type_create(self, ctx)
#define MIE_DIALECT_ADD_TRAIT(trait_id) \
extern struct mie_trait_definition* trait_id##_trait_create( \
struct mie_dialect*, struct mie_ctx*); \
trait = trait_id##_trait_create(self, ctx)
#define MIE_DIALECT_ADD_ATTRIBUTE(attr_id) \
extern struct mie_attribute_definition* attr_id##_attribute_create( \
struct mie_dialect*, struct mie_ctx*); \
attribute = attr_id##_attribute_create(self, ctx)
#define MIE_DIALECT_ADD_INTERFACE(iface_id) \
extern struct mie_interface_definition* iface_id##_interface_create( \
struct mie_dialect*, struct mie_ctx*); \
interface = iface_id##_interface_create(self, ctx)
#define __MIE_TYPE_DEFINITION_BEGIN(func_prefix, type_name) \
struct mie_type_definition *func_prefix##_type_create( \
struct mie_dialect *d, struct mie_ctx *ctx) \
{ \
struct mie_type_definition *type \
= mie_type_definition_create(d, type_name); \
if (!type) { \
return NULL; \
} \
const struct mie_trait *trait = NULL;
/******************************************************************************/
/* OP DEFINITION MACROS */
/******************************************************************************/
#define __MIE_TYPE_DEFINITION_END() \
return type; \
}
#define MIE_OP_DEFINITION_BEGIN(func_prefix, op_name) \
struct mie_op_definition* func_prefix##_op_create( \
struct mie_dialect* d, struct mie_ctx* ctx) \
{ \
struct mie_op_definition* op \
= mie_op_definition_create(d, op_name); \
if (!op) { \
return NULL; \
} \
const struct mie_trait* trait = NULL; \
struct mie_interface* i = NULL; \
const struct mie_interface_definition* id = NULL;
#define __MIE_TRAIT_DEFINITION_BEGIN(func_prefix, trait_name) \
struct mie_trait_definition *func_prefix##_trait_create( \
struct mie_dialect *d, struct mie_ctx *ctx) \
{ \
struct mie_trait_definition *trait \
= mie_trait_definition_create(d, trait_name); \
if (!trait) { \
return NULL; \
}
#define MIE_OP_DEFINITION_END() \
return op; \
}
#define __MIE_TRAIT_DEFINITION_END() \
return trait; \
}
#define __MIE_ATTRIBUTE_DEFINITION_BEGIN(func_prefix, attribute_name) \
struct mie_attribute_definition *func_prefix##_attribute_create( \
struct mie_dialect *d, struct mie_ctx *ctx) \
{ \
struct mie_attribute_definition *attribute \
= mie_attribute_definition_create(d, attribute_name); \
if (!attribute) { \
return NULL; \
}
#define __MIE_ATTRIBUTE_DEFINITION_END() \
return attribute; \
}
#define __MIE_INTERFACE_DEFINITION_BEGIN(func_prefix, iface_name) \
struct mie_interface_definition *func_prefix##_interface_create( \
struct mie_dialect *d, struct mie_ctx *ctx) \
{ \
struct mie_interface_definition *i \
= mie_interface_definition_create(d, iface_name); \
if (!i) { \
return NULL; \
}
#define __MIE_INTERFACE_DEFINITION_END() \
return i; \
}
#define __MIE_DIALECT_INIT(func) func(self)
#define __MIE_DIALECT_CLEANUP(func) self->d_cleanup = (func)
#define __MIE_DIALECT_ADD_OP(op_id) \
extern struct mie_op_definition *op_id##_op_create( \
struct mie_dialect *, struct mie_ctx *); \
op = op_id##_op_create(self, ctx)
#define __MIE_DIALECT_ADD_TYPE(type_id) \
extern struct mie_type_definition *type_id##_type_create( \
struct mie_dialect *, struct mie_ctx *); \
type = type_id##_type_create(self, ctx)
#define __MIE_DIALECT_ADD_TRAIT(trait_id) \
extern struct mie_trait_definition *trait_id##_trait_create( \
struct mie_dialect *, struct mie_ctx *); \
trait = trait_id##_trait_create(self, ctx)
#define __MIE_DIALECT_ADD_ATTRIBUTE(attribute_id) \
extern struct mie_attribute_definition *attribute_id##_attribute_create( \
struct mie_dialect *, struct mie_ctx *); \
attribute = attribute_id##_attribute_create(self, ctx)
#define __MIE_DIALECT_ADD_INTERFACE(interface_id) \
extern struct mie_interface_definition *interface_id##_interface_create( \
struct mie_dialect *, struct mie_ctx *); \
interface = interface_id##_interface_create(self, ctx)
#define MIE_DIALECT_BEGIN(c_sym, c_struct, name) \
__MIE_DIALECT_BEGIN(c_sym, c_struct, name)
#define MIE_DIALECT_END() __MIE_DIALECT_END()
#define MIE_DIALECT_INIT(func) __MIE_DIALECT_INIT(func)
#define MIE_DIALECT_CLEANUP(func) __MIE_DIALECT_CLEANUP(func)
#define MIE_DIALECT_ADD_OP(c_sym) __MIE_DIALECT_ADD_OP(c_sym)
#define MIE_DIALECT_ADD_TYPE(c_sym) __MIE_DIALECT_ADD_TYPE(c_sym)
#define MIE_DIALECT_ADD_TRAIT(c_sym) __MIE_DIALECT_ADD_TRAIT(c_sym)
#define MIE_DIALECT_ADD_ATTRIBUTE(c_sym) __MIE_DIALECT_ADD_ATTRIBUTE(c_sym)
#define MIE_DIALECT_ADD_INTERFACE(c_sym) __MIE_DIALECT_ADD_INTERFACE(c_sym)
#define MIE_OP_DEFINITION_BEGIN(c_sym, op) __MIE_OP_DEFINITION_BEGIN(c_sym, op)
#define MIE_OP_DEFINITION_END() __MIE_OP_DEFINITION_END()
#define MIE_OP_DEFINITION_PRINT(func) op->op_print = (func)
#define MIE_OP_DEFINITION_PARSE(func) op->op_parse = (func)
#define MIE_OP_DEFINITION_TRAIT(trait_dialect, trait_name) \
trait = mie_ctx_get_trait(ctx, trait_dialect, trait_name); \
mie_op_definition_add_trait(op, trait);
#define MIE_OP_INTERFACE_BEGIN(dialect_name, if_name, c_struct) \
id = mie_ctx_get_interface_definition(ctx, dialect_name, if_name); \
if (id) { \
c_struct *iface = (c_struct *)mie_interface_create(id);
#define MIE_OP_DEFINITION_PRINT(func) op->op_print = (func)
#define MIE_OP_DEFINITION_PARSE(func) op->op_parse = (func)
#define MIE_OP_DEFINITION_TRAIT(trait_dialect, trait_name) \
trait = mie_ctx_get_trait(ctx, trait_dialect, trait_name); \
mie_op_definition_add_trait(op, trait);
#define MIE_OP_INTERFACE_BEGIN(dialect_name, if_name, c_struct) \
id = mie_ctx_get_interface_definition(ctx, dialect_name, if_name); \
if (id) { \
c_struct* iface = (c_struct*)mie_interface_create(id);
#define MIE_OP_INTERFACE_FUNC(func_name) iface->func_name
#define MIE_OP_INTERFACE_END() \
mie_op_definition_add_interface(op, (struct mie_interface*)iface); \
}
#define MIE_OP_INTERFACE_END() \
mie_op_definition_add_interface(op, (struct mie_interface *)iface); \
}
/******************************************************************************/
/* TYPE DEFINITION MACROS */
/******************************************************************************/
#define MIE_TYPE_DEFINITION_BEGIN(c_sym, type) \
__MIE_TYPE_DEFINITION_BEGIN(c_sym, type)
#define MIE_TYPE_DEFINITION_END() __MIE_TYPE_DEFINITION_END()
#define MIE_TYPE_DEFINITION_FLAGS(flags) type->ty_flags = flags
#define MIE_TYPE_DEFINITION_STRUCT(name) type->ty_data_size = sizeof(name)
#define MIE_TYPE_DEFINITION_INIT(func) type->ty_init = (func)
#define MIE_TYPE_DEFINITION_PRINT(func) type->ty_print = (func)
#define MIE_TYPE_DEFINITION_PARSE(func) type->ty_parse = (func)
#define MIE_TYPE_DEFINITION_BEGIN(func_prefix, type_name) \
struct mie_type_definition* func_prefix##_type_create( \
struct mie_dialect* d, struct mie_ctx* ctx) \
{ \
struct mie_type_definition* type \
= mie_type_definition_create(d, type_name); \
if (!type) { \
return NULL; \
} \
const struct mie_trait* trait = NULL;
#define MIE_TYPE_DEFINITION_END() \
return type; \
}
#define MIE_TYPE_DEFINITION_FLAGS(flags) type->ty_flags = flags
#define MIE_TYPE_DEFINITION_STRUCT(name) type->ty_data_size = sizeof(name)
#define MIE_TYPE_DEFINITION_INIT(func) type->ty_init = (func)
#define MIE_TYPE_DEFINITION_PRINT(func) type->ty_print = (func)
#define MIE_TYPE_DEFINITION_PARSE(func) type->ty_parse = (func)
#define MIE_TYPE_DEFINITION_BUILD_ID(func) type->ty_build_id = (func)
#define MIE_TYPE_DEFINITION_INIT(func) type->ty_init = (func)
#define MIE_TYPE_DEFINITION_CLEANUP(func) type->ty_cleanup = (func)
#define MIE_TYPE_DEFINITION_TRAIT(trait_dialect, trait_name) \
trait = mie_ctx_get_trait(ctx, trait_dialect, trait_name); \
mie_type_definition_add_trait(type, trait);
#define MIE_TYPE_DEFINITION_INIT(func) type->ty_init = (func)
#define MIE_TYPE_DEFINITION_CLEANUP(func) type->ty_cleanup = (func)
#define MIE_TYPE_DEFINITION_TRAIT(trait_dialect, trait_name) \
trait = mie_ctx_get_trait(ctx, trait_dialect, trait_name); \
mie_type_definition_add_trait(type, trait);
/******************************************************************************/
/* TRAIT DEFINITION MACROS */
/******************************************************************************/
#define MIE_TRAIT_DEFINITION_BEGIN(func_prefix, trait_name) \
struct mie_trait_definition* func_prefix##_trait_create( \
struct mie_dialect* d, struct mie_ctx* ctx) \
{ \
struct mie_trait_definition* trait \
= mie_trait_definition_create(d, trait_name); \
if (!trait) { \
return NULL; \
}
#define MIE_TRAIT_DEFINITION_END() \
return trait; \
}
#define MIE_TRAIT_DEFINITION_BEGIN(c_sym, trait) \
__MIE_TRAIT_DEFINITION_BEGIN(c_sym, trait)
#define MIE_TRAIT_DEFINITION_END() __MIE_TRAIT_DEFINITION_END()
#define MIE_TRAIT_DEFINITION_TARGETS(targets) trait->tr_target = (targets)
#define MIE_TRAIT_DEFINITION_STRUCT(name) trait->tr_data_size = sizeof(name)
#define MIE_TRAIT_DEFINITION_PRINT(func) trait->tr_print = (func)
#define MIE_TRAIT_DEFINITION_BUILD_ID(func) trait->tr_build_id = (func)
#define MIE_TRAIT_DEFINITION_CLEANUP(func) trait->tr_cleanup = (func)
#define MIE_TRAIT_DEFINITION_VALIDATE(func) trait->tr_validate = (func)
#define MIE_TRAIT_DEFINITION_STRUCT(name) trait->tr_data_size = sizeof(name)
#define MIE_TRAIT_DEFINITION_PRINT(func) trait->tr_print = (func)
#define MIE_TRAIT_DEFINITION_BUILD_ID(func) trait->tr_build_id = (func)
#define MIE_TRAIT_DEFINITION_CLEANUP(func) trait->tr_cleanup = (func)
#define MIE_TRAIT_DEFINITION_VALIDATE(func) trait->tr_validate = (func)
#define MIE_ATTRIBUTE_DEFINITION_BEGIN(c_sym, attribute) \
__MIE_ATTRIBUTE_DEFINITION_BEGIN(c_sym, attribute)
#define MIE_ATTRIBUTE_DEFINITION_END() __MIE_ATTRIBUTE_DEFINITION_END()
#define MIE_ATTRIBUTE_DEFINITION_STRUCT(name) \
attribute->a_data_size = sizeof(name)
#define MIE_ATTRIBUTE_DEFINITION_INIT(func) attribute->a_init = (func)
/******************************************************************************/
/* ATTRIBUTE DEFINITION MACROS */
/******************************************************************************/
#define MIE_ATTRIBUTE_DEFINITION_BEGIN(func_prefix, attribute_name) \
struct mie_attribute_definition* func_prefix##_attribute_create( \
struct mie_dialect* d, struct mie_ctx* ctx) \
{ \
struct mie_attribute_definition* attribute \
= mie_attribute_definition_create(d, attribute_name); \
if (!attribute) { \
return NULL; \
}
#define MIE_ATTRIBUTE_DEFINITION_END() \
return attribute; \
}
#define MIE_ATTRIBUTE_DEFINITION_STRUCT(name) \
attribute->a_data_size = sizeof(name)
#define MIE_ATTRIBUTE_DEFINITION_INIT(func) attribute->a_init = (func)
#define MIE_ATTRIBUTE_DEFINITION_CLEANUP(func) attribute->a_cleanup = (func)
#define MIE_ATTRIBUTE_DEFINITION_PRINT(func) attribute->a_print = (func)
#define MIE_ATTRIBUTE_DEFINITION_PARSE(func) attribute->a_parse = (func)
#define MIE_ATTRIBUTE_DEFINITION_PRINT(func) attribute->a_print = (func)
#define MIE_ATTRIBUTE_DEFINITION_PARSE(func) attribute->a_parse = (func)
/******************************************************************************/
/* INTERFACE DEFINITION MACROS */
/******************************************************************************/
#define MIE_INTERFACE_DEFINITION_BEGIN(func_prefix, iface_name) \
struct mie_interface_definition* func_prefix##_interface_create( \
struct mie_dialect* d, struct mie_ctx* ctx) \
{ \
struct mie_interface_definition* i \
= mie_interface_definition_create(d, iface_name); \
if (!i) { \
return NULL; \
}
#define MIE_INTERFACE_DEFINITION_END() \
return i; \
}
#define MIE_INTERFACE_DEFINITION_BEGIN(c_sym, iface) \
__MIE_INTERFACE_DEFINITION_BEGIN(c_sym, iface)
#define MIE_INTERFACE_DEFINITION_END() __MIE_INTERFACE_DEFINITION_END()
#define MIE_INTERFACE_DEFINITION_STRUCT(name) i->if_size = sizeof(name)
/******************************************************************************/
/* PASS DEFINITION MACROS */
/******************************************************************************/
#define MIE_PASS_DEFINITION_BEGIN(prefix) \
struct mie_pass_definition* prefix##_pass_create(struct mie_ctx* ctx) \
{ \
struct mie_pass_definition* p = mie_pass_definition_create(); \
if (!p) { \
return NULL; \
}
#define MIE_PASS_DEFINITION_END() \
if (mie_ctx_register_pass(ctx, p) != MIE_SUCCESS) { \
return NULL; \
} \
return p; \
}
#define MIE_PASS_NAME(name) p->p_name = (name)
#define MIE_PASS_DESCRIPTION(desc) p->p_description = (desc)
#define MIE_PASS_STRUCT(c_struct) p->p_data_size = sizeof(c_struct)
#define MIE_PASS_TYPE(type) p->p_type = (type)
#define MIE_PASS_INIT(func) p->p_init = (func)
#define MIE_PASS_TRANSFORM(func) \
p->p_transform = (func); \
p->p_type = MIE_PASS_TRANSFORM
#define MIE_PASS_ANALYSE(func) \
p->p_analyse = (func); \
p->p_type = MIE_PASS_ANALYSE
#define MIE_PASS_FILTER_OP(dialect, op) \
p->p_filter.f_op = mie_ctx_get_op_definition(ctx, dialect, op)
#define MIE_PASS_FILTER_TRAIT(dialect, tr) \
p->p_filter.f_trait = mie_ctx_get_trait_definition(ctx, dialect, tr)
#define MIE_PASS_FILTER_INTERFACE(dialect, ifn) \
p->p_filter.f_iface = mie_ctx_get_iface_definition(ctx, dialect, ifn)
/******************************************************************************/
/* PASS GROUP MACROS */
/******************************************************************************/
#define MIE_PASS_GROUP_BEGIN(prefix) \
enum mie_status prefix##_passes_register(struct mie_ctx* ctx) \
{ \
struct mie_pass_definition* pass = NULL;
#define MIE_PASS_GROUP_END() \
return MIE_SUCCESS; \
}
#define MIE_PASS_GROUP_DECLARATION(prefix) \
enum mie_status prefix##_passes_register(struct mie_ctx*);
#define MIE_PASS_GROUP_ADD_PASS(id) \
do { \
extern struct mie_pass_definition* id##_pass_create( \
struct mie_ctx*); \
pass = id##_pass_create(ctx); \
if (!pass) { \
return MIE_ERR_INTERNAL_FAILURE; \
} \
} while (0)
#endif
/******************************************************************************/
/* REWRITE PATTERN MACROS */
/******************************************************************************/
#define MIE_REWRITE_PATTERN_BEGIN(name) \
struct mie_pattern* name##_create(struct mie_pattern_set* set) \
{ \
struct mie_pattern* self = mie_pattern_set_add(set); \
if (!self) { \
return NULL; \
}
#define MIE_REWRITE_PATTERN_END() \
return self; \
}
#define MIE_REWRITE_PATTERN_ROOT(dialect_name, op_name) \
self->p_root.t_dialect_name = (dialect_name); \
self->p_root.t_op_name = (op_name)
#define MIE_REWRITE_PATTERN_MATCH(func) self->p_match = (func)
#define MIE_REWRITE_PATTERN_REWRITE(func) self->p_rewrite = (func)
/******************************************************************************/
/* DIAG CLASS MACROS */
/******************************************************************************/
#define __MIE_CNAME2(x, y) x##_##y
#define __MIE_CNAME1(x, y) __MIE_CNAME2(x, y)
#define __MIE_CNAME(fun) __MIE_CNAME1(MIE_DIAG_CLASS_PREFIX, fun)
#define __MIE_CSNAME2(x, y) #x #y
#define __MIE_CSNAME1(x, y) __MIE_CSNAME2(x, y)
#define __MIE_CSNAME(fun) __MIE_CSNAME1(MIE_DIAG_CLASS_PREFIX, fun)
#define MIE_DIAG_CLASS_LIST_EXTERN(list_name) \
extern struct mie_diag_class list_name[]; \
extern const size_t list_name##_count
#define MIE_DIAG_CLASS_LIST_BEGIN(list_name) \
struct mie_diag_class list_name[] = {
#define MIE_DIAG_CLASS_LIST_END(list_name) \
} \
; \
const size_t list_name##_count = sizeof(list_name) / sizeof(list_name[0]);
#define MIE_DIAG_CLASS(id, type, title) \
[__MIE_CNAME(id)] = { \
.c_id = __MIE_CNAME(id), \
.c_type = MIE_DIAG_CLASS_##type, \
.c_title = (title), \
.c_id_str_short = #id, \
.c_id_str_long = __MIE_CSNAME(id), \
},
/******************************************************************************/
/* DIAG MSG MACROS */
/******************************************************************************/
#define __MIE_MNAME2(x, y) x##_##y
#define __MIE_MNAME1(x, y) __MIE_CNAME2(x, y)
#define __MIE_MNAME(fun) __MIE_CNAME1(MIE_DIAG_MSG_PREFIX, fun)
#define __MIE_MSNAME2(x, y) #x #y
#define __MIE_MSNAME1(x, y) __MIE_CSNAME2(x, y)
#define __MIE_MSNAME(fun) __MIE_CSNAME1(MIE_DIAG_MSG_PREFIX, fun)
#define MIE_DIAG_MSG_LIST_EXTERN(list_name) \
extern struct mie_diag_msg list_name[]; \
extern const size_t list_name##_count
#define MIE_DIAG_MSG_LIST_BEGIN(list_name) \
struct mie_diag_msg list_name[] = {
#define MIE_DIAG_MSG_LIST_END(list_name) \
} \
; \
const size_t list_name##_count = sizeof(list_name) / sizeof(list_name[0]);
#define MIE_DIAG_MSG(id, content) \
[__MIE_MNAME(id)] = { \
.msg_id = __MIE_MNAME(id), \
.msg_content = (content), \
.msg_id_str_short = #id, \
.msg_id_str_long = __MIE_MSNAME(id), \
},

View File

@@ -1,8 +1,8 @@
#ifndef MIE_NAME_H_
#define MIE_NAME_H_
#include <blue/core/btree.h>
#include <blue/core/queue.h>
#include <fx/core/bst.h>
#include <fx/core/queue.h>
#include <mie/misc.h>
#include <mie/parse/file-span.h>
@@ -30,36 +30,41 @@ struct mie_name_map_entry {
enum mie_name_map_entry_type e_type;
uint64_t e_hash;
union {
b_queue_entry e_entry;
b_btree_node e_node;
fx_queue_entry e_entry;
fx_bst_node e_node;
};
};
struct mie_name_bucket {
struct mie_name_map_entry b_base;
fx_queue b_names;
};
/* stores a unique name, and forms a binary tree of similar entries.
* this struct is designed to be embedded directly within a larger struct
* (rather than just as a pointer), allowing the larger struct to be part
* of a name map. Because of this, mie_name CANNOT be used in any memory that
* may be re-allocated. If a mie_name is moved after it is added to a
* mie_name_map, the internal bst pointers that make up the map will be
* invalidated, causing some very obscure memory-related errors. */
* invalidated, causing some very obscure memory-related errors.
*
* if mie_name IS stored in movable memory, care must be taken to use
* mie_name_move rather than memcpy/memmove to move the mie_name from
* one location to another. */
struct mie_name {
struct mie_name_map_entry n_base;
struct mie_name_map *n_parent;
struct mie_name_bucket *n_bucket;
char *n_str;
/* if this name was read from a file, these structs can be used to
* record the location within the file where the name is found. */
struct mie_file_span n_start, n_end;
};
struct mie_name_bucket {
struct mie_name_map_entry b_base;
b_queue b_names;
struct mie_file_span n_span;
};
struct mie_name_map {
const struct mie_name_map *m_parent;
b_btree m_entries;
fx_bst m_entries;
size_t m_next_id;
};
@@ -73,6 +78,7 @@ extern struct mie_name *mie_name_map_put(
struct mie_name_map *map, struct mie_name *entry, const char *hint,
enum mie_name_map_flags flags);
extern void mie_name_move(struct mie_name *dst, struct mie_name *src);
extern void mie_name_destroy(struct mie_name *name);
#endif

View File

@@ -1,17 +1,23 @@
#ifndef MIE_PARSE_LEX_H_
#define MIE_PARSE_LEX_H_
#include <blue/core/stream.h>
#include <fx/core/queue.h>
#include <fx/core/stream.h>
#include <mie/misc.h>
#include <mie/status.h>
struct mie_lex;
struct mie_ctx;
struct mie_token;
struct mie_line_source;
MIE_API struct mie_lex *mie_lex_create(b_stream *src);
MIE_API struct mie_lex *mie_lex_create(
struct mie_line_source *src, struct mie_ctx *ctx);
MIE_API void mie_lex_destroy(struct mie_lex *lex);
MIE_API enum mie_status mie_lex_get_status(const struct mie_lex *lex);
MIE_API struct mie_line_source *mie_lex_get_line_source(const struct mie_lex *lex);
MIE_API const struct mie_file_cell *mie_lex_get_cursor(const struct mie_lex *lex);
MIE_API struct mie_token *mie_lex_peek(struct mie_lex *lex);
MIE_API void mie_lex_advance(struct mie_lex *lex);

View File

@@ -0,0 +1,35 @@
#ifndef MIE_PARSE_LINE_SOURCE_H_
#define MIE_PARSE_LINE_SOURCE_H_
#include <fx/core/stream.h>
#include <fx/ds/array.h>
#include <fx/ds/string.h>
#include <mie/misc.h>
#include <mie/parse/file-span.h>
#include <mie/status.h>
struct mie_line_source {
fx_stream *s_stream;
const char *s_path;
fx_string *s_linebuf;
fx_iterator *s_linebuf_ptr;
fx_array *s_lines;
struct mie_file_cell s_cursor;
};
MIE_API enum mie_status mie_line_source_init(
struct mie_line_source *src, const char *path, fx_stream *stream);
MIE_API void mie_line_source_cleanup(struct mie_line_source *src);
MIE_API const char *mie_line_source_get_path(const struct mie_line_source *src);
MIE_API const struct mie_file_cell *mie_line_source_get_cursor(
const struct mie_line_source *src);
MIE_API fx_wchar mie_line_source_peekc(struct mie_line_source *src);
MIE_API fx_wchar mie_line_source_getc(struct mie_line_source *src);
MIE_API enum mie_status mie_line_source_get_row(
struct mie_line_source *src, size_t row, const fx_string **out);
MIE_API bool mie_line_source_input_available(struct mie_line_source *src);
#endif

View File

@@ -1,7 +1,7 @@
#ifndef MIE_PARSE_PARSER_H_
#define MIE_PARSE_PARSER_H_
#include <blue/ds/string.h>
#include <fx/ds/string.h>
#include <mie/ir/register.h>
#include <mie/misc.h>
#include <mie/parse/token.h>
@@ -25,6 +25,30 @@ struct mie_register;
struct mie_attribute_map;
struct mie_attribute;
#define MIE_PARSE_ITEM_NONE {.i_type = MIE_PARSER_ITEM_NONE}
#define MIE_PARSE_ITEM_TOKEN(tok) \
{.i_type = MIE_PARSER_ITEM_TOK, .i_tok = (tok)}
#define MIE_PARSE_ITEM_CSTR(s) {.i_type = MIE_PARSER_ITEM_CSTR, .i_cstr = (s)}
struct mie_parser_scope {
struct mie_region *s_region;
struct mie_name_map *s_names;
};
enum mie_parser_item_type {
MIE_PARSER_ITEM_NONE = 0,
MIE_PARSER_ITEM_TOK,
MIE_PARSER_ITEM_CSTR,
};
struct mie_parser_item {
enum mie_parser_item_type i_type;
union {
unsigned int i_tok;
const char *i_cstr;
};
};
MIE_API struct mie_parser *mie_parser_create(
struct mie_ctx *ctx, struct mie_lex *lex);
MIE_API void mie_parser_destroy(struct mie_parser *ctx);
@@ -33,7 +57,7 @@ MIE_API struct mie_ctx *mie_parser_get_mie_ctx(struct mie_parser *ctx);
MIE_API struct mie_lex *mie_parser_get_lexer(struct mie_parser *ctx);
MIE_API enum mie_status mie_parser_get_status(const struct mie_parser *ctx);
MIE_API void mie_parser_set_status(struct mie_parser *ctx, enum mie_status status);
MIE_API b_string *mie_parser_get_tempstr(struct mie_parser *ctx);
MIE_API fx_string *mie_parser_get_tempstr(struct mie_parser *ctx);
MIE_API struct mie_token *mie_parser_peek(struct mie_parser *ctx);
MIE_API enum mie_token_type mie_parser_peek_type(struct mie_parser *ctx);
@@ -50,38 +74,45 @@ MIE_API bool mie_parser_parse_int(
MIE_API bool mie_parser_parse_float(
struct mie_parser *ctx, double *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_word(
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
struct mie_parser *ctx, fx_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_name(
struct mie_parser *ctx, fx_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_instname(
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
struct mie_parser *ctx, fx_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_graphname(
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
struct mie_parser *ctx, fx_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_opname(
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
struct mie_parser *ctx, fx_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_vregname(
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
struct mie_parser *ctx, fx_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_mregname(
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
struct mie_parser *ctx, fx_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_blockname(
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
struct mie_parser *ctx, fx_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_attribname(
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
struct mie_parser *ctx, fx_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_typename(
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
struct mie_parser *ctx, fx_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_symname(
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
struct mie_parser *ctx, fx_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_string(
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_keyword(struct mie_parser *ctx, const char *kw);
struct mie_parser *ctx, fx_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_keyword(
struct mie_parser *ctx, const char *kw, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_symbol(
struct mie_parser *ctx, enum mie_token_symbol sym);
MIE_API bool mie_parser_parse_linefeed(struct mie_parser *ctx);
MIE_API bool mie_parser_parse_type(
struct mie_parser *ctx, const struct mie_type **out);
struct mie_parser *ctx, const char *context,
const struct mie_type **out, struct mie_file_span *out_span);
MIE_API bool mie_parser_parse_type_list(
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(const struct mie_type *, out));
struct mie_parser *ctx, const char *context,
MIE_VECTOR_REF_PARAM(const struct mie_type *, out),
struct mie_file_span *out_span);
MIE_API bool mie_parser_parse_function_type(
struct mie_parser *ctx, struct mie_type **out);
struct mie_parser *ctx, const char *context, struct mie_type **out,
struct mie_file_span *out_span);
MIE_API bool mie_parser_parse_operand(
struct mie_parser *ctx, struct mie_op_arg *out);
@@ -89,30 +120,33 @@ MIE_API bool mie_parser_parse_operand_list(
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_arg, out));
MIE_API bool mie_parser_parse_parameter(
struct mie_parser *ctx, struct mie_op_arg *out);
struct mie_parser *ctx, bool include_type, struct mie_op_arg *out,
const char *context);
MIE_API bool mie_parser_parse_parameter_list(
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_arg, out));
struct mie_parser *ctx, bool include_type,
MIE_VECTOR_REF_PARAM(struct mie_op_arg, out), const char *context);
MIE_API bool mie_parser_parse_unknown_keyword(struct mie_parser *ctx, b_string *out);
MIE_API bool mie_parser_parse_unknown_keyword(struct mie_parser *ctx, fx_string *out);
MIE_API bool mie_parser_parse_unknown_symbol(
struct mie_parser *ctx, enum mie_token_symbol sym);
MIE_API bool mie_parser_parse_register(
struct mie_parser *ctx, struct mie_name_map *names,
struct mie_register *out);
struct mie_parser *ctx, struct mie_parser_scope *scope,
const char *context, struct mie_register *out);
MIE_API bool mie_parser_parse_register_list(
struct mie_parser *ctx, struct mie_name_map *names,
MIE_VECTOR_REF_PARAM(struct mie_register *, out));
struct mie_parser *ctx, struct mie_parser_scope *scope,
const char *context, MIE_VECTOR_REF_PARAM(struct mie_register, out));
MIE_API bool mie_parser_parse_region(
struct mie_parser *ctx, struct mie_region *region);
struct mie_parser *ctx, struct mie_op *parent,
struct mie_region *region, struct mie_block *first_block);
MIE_API bool mie_parser_parse_region_list(
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_region, out));
struct mie_parser *ctx, struct mie_op *parent);
MIE_API bool mie_parser_parse_anonymous_block(
struct mie_parser *ctx, struct mie_name_map *names,
struct mie_parser *ctx, struct mie_parser_scope *scope,
struct mie_block *block);
MIE_API bool mie_parser_parse_block(
struct mie_parser *ctx, struct mie_name_map *names,
struct mie_parser *ctx, struct mie_parser_scope *scope,
struct mie_block *block);
MIE_API bool mie_parser_parse_successor(
@@ -122,11 +156,34 @@ MIE_API bool mie_parser_parse_successor_list(
MIE_API bool mie_parser_parse_module(struct mie_parser *ctx, struct mie_module *mod);
MIE_API bool mie_parser_parse_op(
struct mie_parser *ctx, struct mie_name_map *names, struct mie_op *dest);
struct mie_parser *ctx, struct mie_parser_scope *scope,
struct mie_op *dest);
MIE_API bool mie_parser_parse_attribute(
struct mie_parser *ctx, const struct mie_attribute **dest);
MIE_API bool mie_parser_parse_attribute_map(
struct mie_parser *ctx, struct mie_attribute_map *out);
MIE_API struct mie_diag *mie_parser_report_error_simple(
struct mie_parser *parser, const char *dialect, unsigned int diag_class,
unsigned int msg, const struct mie_file_span *loc);
MIE_API void mie_parser_report_unexpected_token_v(
struct mie_parser *parser,
const struct mie_parser_item expected_tokens[], const char *context);
MIE_API void mie_parser_report_unexpected_token_s(
struct mie_parser *parser, const char *expected_token, const char *context);
static inline void mie_parser_report_unexpected_token(
struct mie_parser *parser, unsigned int expected_token, const char *context)
{
struct mie_parser_item t[]
= {MIE_PARSE_ITEM_TOKEN(expected_token), MIE_PARSE_ITEM_NONE};
mie_parser_report_unexpected_token_v(parser, t, context);
}
MIE_API struct mie_name *mie_parser_scope_put_name(
struct mie_parser_scope *scope, struct mie_name *entry,
const char *hint, enum mie_name_map_flags flags);
MIE_API struct mie_register *mie_parser_scope_find_value(
struct mie_parser_scope *scope, const char *name);
#endif

View File

@@ -1,7 +1,7 @@
#ifndef MIE_PARSE_TOKEN_H_
#define MIE_PARSE_TOKEN_H_
#include <blue/core/queue.h>
#include <fx/core/queue.h>
#include <mie/misc.h>
#include <mie/parse/file-span.h>
@@ -39,6 +39,7 @@ enum mie_token_type {
MIE_TOK_TYPENAME = 0x4000u,
/* word or name, prefixed with a # hash */
MIE_TOK_ATTRIBNAME = 0x8000u,
__MIE_TOK_UBOUND = 0x9000u,
};
enum mie_token_value_type {
@@ -51,7 +52,7 @@ enum mie_token_value_type {
enum mie_token_symbol {
MIE_SYM_NONE = 0,
MIE_SYM_COLON,
MIE_SYM_COLON = __MIE_TOK_UBOUND,
MIE_SYM_EQUAL,
MIE_SYM_COMMA,
MIE_SYM_HYPHEN,
@@ -64,6 +65,7 @@ enum mie_token_symbol {
MIE_SYM_TILDE,
MIE_SYM_BANG,
MIE_SYM_ATSIGN,
MIE_SYM_QUESTION,
MIE_SYM_LEFT_BRACE,
MIE_SYM_RIGHT_BRACE,
MIE_SYM_LEFT_BRACKET,
@@ -80,7 +82,7 @@ struct mie_token {
struct mie_file_span tok_location;
enum mie_token_type tok_type;
enum mie_token_value_type tok_value_type;
b_queue_entry tok_entry;
fx_queue_entry tok_entry;
union {
char *tok_str;

View File

@@ -0,0 +1,10 @@
#ifndef MIE_PASS_BUILTIN_H_
#define MIE_PASS_BUILTIN_H_
#include <mie/misc.h>
struct mie_ctx;
MIE_API enum mie_status mie_builtin_passes_register(struct mie_ctx *);
#endif

View File

@@ -0,0 +1,69 @@
#ifndef MIE_PASS_PASS_DEFINITION_H_
#define MIE_PASS_PASS_DEFINITION_H_
#include <mie/id.h>
#include <stddef.h>
#define MIE_PASS_CONTINUE \
((struct mie_pass_result) {.r_type = MIE_PASS_RESULT_CONTINUE, \
.r_status = MIE_SUCCESS})
#define MIE_PASS_INTERRUPT(status) \
((struct mie_pass_result) {.r_type = MIE_PASS_RESULT_INTERRUPT, \
.r_status = (status)})
struct mie_op;
struct mie_ctx;
struct mie_pass;
struct mie_dialect;
struct mie_op_definition;
struct mie_trait_definition;
struct mie_interface_definition;
struct mie_attribute_map;
enum mie_pass_type {
MIE_PASS_NONE = 0,
MIE_PASS_TRANSFORM,
MIE_PASS_ANALYSE,
};
enum mie_pass_result_type {
MIE_PASS_RESULT_CONTINUE = 0,
MIE_PASS_RESULT_INTERRUPT,
};
struct mie_pass_result {
enum mie_pass_result_type r_type;
enum mie_status r_status;
};
struct mie_pass_args {
struct mie_ctx *p_ctx;
};
struct mie_pass_filter {
const struct mie_dialect *f_dialect;
const struct mie_op_definition *f_op;
const struct mie_trait_definition *f_trait;
const struct mie_interface_definition *f_iface;
};
struct mie_pass_definition {
mie_id p_id;
const char *p_name;
const char *p_description;
size_t p_data_size;
enum mie_pass_type p_type;
enum mie_status (*p_init)(
struct mie_pass *, const struct mie_attribute_map *);
struct mie_pass_result (*p_transform)(
struct mie_pass *, struct mie_op *, struct mie_pass_args *);
struct mie_pass_result (*p_analyse)(
struct mie_pass *, const struct mie_op *, struct mie_pass_args *);
struct mie_pass_filter p_filter;
};
MIE_API struct mie_pass_definition *mie_pass_definition_create(void);
#endif

View File

@@ -0,0 +1,46 @@
#ifndef MIE_PASS_PASS_MANAGER_H_
#define MIE_PASS_PASS_MANAGER_H_
#include <mie/pass/pass-definition.h>
#include <mie/status.h>
#include <mie/vector.h>
struct mie_pass;
struct mie_op;
struct mie_op_pass;
enum mie_pass_manager_flags {
MIE_PASSMGR_F_NONE = 0x00u,
};
struct mie_pass_manager {
enum mie_pass_manager_flags pm_flags;
struct mie_ctx *pm_ctx;
size_t pm_depth;
MIE_VECTOR_DECLARE(struct mie_pass *, pm_passes);
MIE_VECTOR_DECLARE(struct mie_pass_manager *, pm_nested);
struct mie_pass_filter pm_filter;
};
MIE_API struct mie_pass_manager *mie_pass_manager_create(struct mie_ctx *ctx);
MIE_API void mie_pass_manager_destroy(struct mie_pass_manager *pm);
MIE_API struct mie_pass_manager *mie_pass_manager_nest(struct mie_pass_manager *pm);
MIE_API enum mie_status mie_pass_manager_filter_op(
struct mie_pass_manager *pm, const char *dialect_name, const char *op_name);
MIE_API enum mie_status mie_pass_manager_filter_trait(
struct mie_pass_manager *pm, const char *dialect_name,
const char *trait_name);
MIE_API enum mie_status mie_pass_manager_filter_interface(
struct mie_pass_manager *pm, const char *dialect_name,
const char *iface_name);
MIE_API void mie_pass_manager_add_pass(
struct mie_pass_manager *pm, struct mie_pass *pass);
MIE_API struct mie_pass_result mie_pass_manager_run(
struct mie_pass_manager *pm, struct mie_op *target);
#endif

View File

@@ -0,0 +1,14 @@
#ifndef MIE_PASS_PASS_H_
#define MIE_PASS_PASS_H_
#include <mie/pass/pass-definition.h>
struct mie_pass {
const struct mie_pass_definition *p_def;
};
MIE_API const char *mie_pass_get_name(const struct mie_pass *pass);
MIE_API struct mie_pass_result mie_pass_execute(
struct mie_pass *pass, struct mie_op *op, struct mie_pass_args *args);
#endif

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