Compare commits
65 Commits
58bd336eb8
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 73b4b77816 | |||
| a29779aa83 | |||
| 778835032d | |||
| 540c8e6d8b | |||
| 1c44c3e5c8 | |||
| 28b72cbf1e | |||
| 8c9cab7408 | |||
| 4d315d6abe | |||
| a99610ac02 | |||
| 6bebcbfdf6 | |||
| ab7ccfcfef | |||
| a27375ac2e | |||
| ef4349b732 | |||
| 639652b083 | |||
| fc610a6605 | |||
| f88d537043 | |||
| fe1e7d81c4 | |||
| 000a9c2671 | |||
| 8a50445dd8 | |||
| 81fde5d43b | |||
| 06101b6316 | |||
| 7b729c49fa | |||
| 51c8d2744c | |||
| 2858323eca | |||
| fed4cad7e8 | |||
| a107964e2b | |||
| 6abdf8f993 | |||
| 870b2bfbac | |||
| 5344c02b48 | |||
| 4a4f0c483a | |||
| f37ee90b0e | |||
| 3f901ed83a | |||
| b28efa2d08 | |||
| 5835d25679 | |||
| d4fbd75a59 | |||
| 0b1d4697a2 | |||
| cd49417972 | |||
| bd5ba9e9fd | |||
| b5fa40d4d8 | |||
| a67e4b6688 | |||
| 5873326138 | |||
| 00152cac56 | |||
| 287983fa95 | |||
| 8cdbf5389c | |||
| 00c7c3d5ea | |||
| 9e546ee32f | |||
| 00ba3a3d87 | |||
| d44bc8c5c0 | |||
| a22e95d88d | |||
| 0a791fdfb2 | |||
| fe511011ec | |||
| e8534f8d70 | |||
| bf8c966c03 | |||
| 7d30e8f3ff | |||
| e9d2c0fbc7 | |||
| a710ef0b24 | |||
| 0277931ca1 | |||
| ac7860b6bd | |||
| 29984307aa | |||
| ac96248d7e | |||
| 593eda2797 | |||
| d0ac8a9fed | |||
| 89ebbcc462 | |||
| 554a1e7342 | |||
| 6d1e308ff1 |
@@ -1,22 +1,22 @@
|
|||||||
select.graph {
|
select.graph {
|
||||||
%entry = +select.entry -> #select.chain
|
%entry = +select.entry -> !select.chain
|
||||||
|
|
||||||
%0 = +select.register @0 : i32 -> #select.register
|
%0 = +select.register @0 : i32 -> !select.register
|
||||||
%1 = +select.register @1 : i32 -> #select.register
|
%1 = +select.register @1 : i32 -> !select.register
|
||||||
|
|
||||||
%v.0, %c.0 = +select.register.read %entry, %0 \
|
%v.0, %c.0 = +select.register.read %entry, %0 \
|
||||||
: (#select.chain, #select.register) \
|
: (!select.chain, !select.register) \
|
||||||
-> (i32, #select.chain)
|
-> (i32, !select.chain)
|
||||||
|
|
||||||
%v.1, %c.1 = +select.register.read %entry, %1 \
|
%v.1, %c.1 = +select.register.read %entry, %1 \
|
||||||
: (#select.chain, #select.register) \
|
: (!select.chain, !select.register) \
|
||||||
-> (i32, #select.chain)
|
-> (i32, !select.chain)
|
||||||
|
|
||||||
%2 = +select.register @2 : i32
|
%2 = +select.register @2 : i32
|
||||||
|
|
||||||
%v.2, %c.2 = +select.register.read %entry, %2 \
|
%v.2, %c.2 = +select.register.read %entry, %2 \
|
||||||
: (#select.chain, #select.register) \
|
: (!select.chain, !select.register) \
|
||||||
-> (#select.register, #select.chain)
|
-> (!select.register, !select.chain)
|
||||||
|
|
||||||
%v.3 = arith.build-pair %v.0, %v.1 : (i32, i32) -> i64
|
%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
|
%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 \
|
%c.3, %g.0 = +select.register.write %entry, %x0, %v.5 \
|
||||||
: (#select.chain, #select.register, i32) \
|
: (!select.chain, !select.register, i32) \
|
||||||
-> (#select.chain, #select.glue)
|
-> (!select.chain, !select.glue)
|
||||||
|
|
||||||
%c.4 = *risc-v.RET %c.3, %x0, %g.0 \
|
%c.4 = *risc-v.RET %c.3, %x0, %g.0 \
|
||||||
: (#select.chain, #select.register, #select.glue) \
|
: (!select.chain, !select.register, !select.glue) \
|
||||||
-> #select.chain
|
-> !select.chain
|
||||||
|
|
||||||
+select.graph-root %c.4 : #select.chain
|
+select.graph-root %c.4 : !select.chain
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,31 +1,31 @@
|
|||||||
select.graph {
|
select.graph {
|
||||||
%entry = +select.entry -> #select.chain
|
%entry = +select.entry -> !select.chain
|
||||||
|
|
||||||
%N1 = ptr.alloca i32 -> ptr
|
%N1 = ptr.alloca i32 -> ptr
|
||||||
|
|
||||||
%N2 = i32.constant 3 -> i32
|
%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
|
%N4 = ptr.alloca i32 -> ptr
|
||||||
|
|
||||||
%N5 = i32.constant 0 -> i32
|
%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
|
%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
|
%N14.c = cf.br %N12.c, %N13
|
||||||
|
|
||||||
|
|||||||
30
doc/sample/ir/dominance-test.mie
Normal file
30
doc/sample/ir/dominance-test.mie
Normal 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 = () -> () } : () -> ()
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
; Comment
|
; Comment
|
||||||
func.func @reduce(%buffer: memref<1024*f32>, %lb: index, %ub: index, %step: index) -> f32 {
|
module {
|
||||||
|
func.func @reduce(%buffer: memref<1024*f32>, %lb: index, %ub: index, %step: index) -> f32 {
|
||||||
; Initial sum set to 0.
|
; Initial sum set to 0.
|
||||||
%sum.0 = f32.constant 0.0
|
%sum.0 = arith.constant 0.0 : f32
|
||||||
; iter_args binds initial values to the loop's region arguments.
|
; iter_args binds initial values to the loop's region arguments.
|
||||||
%sum = scf.for %iv = %lb to %ub step %step iter-args(%sum.iter = %sum.0) -> (f32) {
|
%sum = scf.for %iv = %lb to %ub step %step iter-args(%sum.iter = %sum.0) -> f32 {
|
||||||
%t = memref.load %buffer[%iv] : memref<1024*f32>
|
%t = memref.load %buffer[%iv] : memref<1024*f32>
|
||||||
%sum.next = arith.addf %sum.iter, %t : f32
|
%sum.next = arith.addf %sum.iter, %t : f32
|
||||||
; Yield current iteration sum to next iteration %sum.iter or to %sum
|
; Yield current iteration sum to next iteration %sum.iter or to %sum
|
||||||
@@ -12,4 +13,5 @@ func.func @reduce(%buffer: memref<1024*f32>, %lb: index, %ub: index, %step: inde
|
|||||||
}
|
}
|
||||||
|
|
||||||
func.return %sum : f32
|
func.return %sum : f32
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,25 +1,16 @@
|
|||||||
~func.func() ({
|
module {
|
||||||
^entry(%buffer: memref<1024*f32>, %lb: index, %ub: index, %step: index):
|
func.func @_reduce(%buffer: memref<1024*f32>, %lb: index, %ub: index, %step: index) -> f32 {
|
||||||
; Initial sum set to 0.
|
%sum.0 = arith.constant 0 : f32
|
||||||
%sum.0 = ~f32.constant() {value = 0.0 : f32} : () -> f32
|
cf.br ^for.entry(%lb: index, %sum.0: f32)
|
||||||
; iter_args binds initial values to the loop's region arguments.
|
^for.entry(%iv: index, %sum.iter: f32):
|
||||||
;%sum = "scf.for"(%lb, %ub, %step) -> (f32) {
|
%t = memref.load %buffer[%iv] : memref<1024*f32>
|
||||||
~cf.br [ ^for.entry(%lb: index, %sum.0: f32) ] : () -> ()
|
%sum.next = arith.addf %sum.iter, %t : f32
|
||||||
|
cf.br ^for.cond(%iv: index, %sum.next: f32)
|
||||||
^for.entry(%iv: index, %sum.iter: f32):
|
^for.cond(%iv.0: index, %sum.iter.0: index):
|
||||||
%t = ~memref.load(%buffer, %iv) : (memref<1024*f32>, index) -> f32
|
%iv.next = arith.addi %iv.0, %step : index
|
||||||
%sum.next = ~arith.addf(%sum.iter, %t) : (f32, f32) -> f32
|
%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)
|
||||||
~cf.br [ ^for.cond:(%iv: index, %sum.next: f32) ] : () -> ()
|
^for.end(%sum: f32):
|
||||||
|
func.return %sum : 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
|
|
||||||
|
|
||||||
|
|||||||
26
doc/sample/ir/parse-test-2.mie
Normal file
26
doc/sample/ir/parse-test-2.mie
Normal 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 } : () -> ()
|
||||||
|
}) : () -> ()
|
||||||
@@ -1,26 +1,25 @@
|
|||||||
~builtin.module() ({
|
module {
|
||||||
~func.func() ({
|
func.func @reduce(%buffer: memref<?*f32>, %lb: index, %ub: index, %step: index) -> f32 {
|
||||||
^entry(%buffer: i32, %lb: index, %ub: index, %step: index):
|
|
||||||
; Initial sum set to 0.
|
; Initial sum set to 0.
|
||||||
%sum.0 = ~arith.constant() {value = 0.0 : f32} : () -> f32
|
%sum.0 = arith.constant 0.0 : f32
|
||||||
; iter_args binds initial values to the loop's region arguments.
|
; iter_args binds initial values to the loop's region arguments.
|
||||||
;%sum = "scf.for"(%lb, %ub, %step) -> (f32) {
|
;%sum = "scf.for"(%lb, %ub, %step) -> (f32) {
|
||||||
~cf.br() [ ^for.entry:(%lb: index, %sum.0: f32) ] : () -> ()
|
cf.br ^for.entry(%lb: index, %sum.0: f32)
|
||||||
|
|
||||||
^for.entry(%iv: index, %sum.iter: f32):
|
^for.entry(%iv: index, %sum.iter: f32):
|
||||||
%t, %x, %z = ~memref.load(%buffer, %iv) : (i32, index) -> (f32, i1, i1)
|
%t = memref.load %buffer[%iv] : memref<?*f32>
|
||||||
%sum.next = ~arith.addf(%sum.iter, %t) : (f32, f32) -> f32
|
%sum.next = arith.addf %sum.iter, %t : f32
|
||||||
|
|
||||||
~cf.br() [ ^for.cond:(%iv: index, %sum.next: f32) ] : () -> ()
|
cf.br ^for.cond(%iv: index, %sum.next: f32)
|
||||||
|
|
||||||
^for.cond(%iv2: index, %sum.next2: f32):
|
^for.cond(%iv2: index, %sum.next2: f32):
|
||||||
; Yield current iteration sum to next iteration %sum.iter or to %sum
|
; Yield current iteration sum to next iteration %sum.iter or to %sum
|
||||||
; if final iteration.
|
; if final iteration.
|
||||||
%iv.next = ~arith.addi(%iv, %step) : (index, index) -> index
|
%iv.next = arith.addi %iv, %step : index
|
||||||
%stop = ~arith.cmpi(%iv.next, %ub) { predicate = 9 } : (index, index) -> i1
|
%stop = arith.cmpi uge %iv.next, %ub : index
|
||||||
~cf.br-cond(%stop) [ ^for.end, ^for.entry:(%iv.next: index, %sum.next: f32) ] : (i1) -> ()
|
cf.br-cond %stop, ^for.end, ^for.entry(%iv.next: index, %sum.next: f32)
|
||||||
|
|
||||||
^for.end(%sum: f32):
|
^for.end(%sum: f32):
|
||||||
~func.return(%sum) : (f32) -> ()
|
func.return %sum : f32
|
||||||
}) {sym_name = "reduce", function_type = (i32, index, index, index) -> f32 } : () -> ()
|
}
|
||||||
}) : () -> ()
|
}
|
||||||
|
|||||||
45
mie/ctx.c
45
mie/ctx.c
@@ -4,6 +4,8 @@
|
|||||||
#include <blue/ds/string.h>
|
#include <blue/ds/string.h>
|
||||||
#include <mie/attribute/attribute-definition.h>
|
#include <mie/attribute/attribute-definition.h>
|
||||||
#include <mie/ctx.h>
|
#include <mie/ctx.h>
|
||||||
|
#include <mie/diag/class.h>
|
||||||
|
#include <mie/diag/diag.h>
|
||||||
#include <mie/dialect/arith.h>
|
#include <mie/dialect/arith.h>
|
||||||
#include <mie/dialect/builtin.h>
|
#include <mie/dialect/builtin.h>
|
||||||
#include <mie/dialect/dialect.h>
|
#include <mie/dialect/dialect.h>
|
||||||
@@ -86,7 +88,6 @@ struct mie_op *mie_ctx_create_op(
|
|||||||
|
|
||||||
out->op_flags |= MIE_OP_F_OP_RESOLVED;
|
out->op_flags |= MIE_OP_F_OP_RESOLVED;
|
||||||
out->op_info = def;
|
out->op_info = def;
|
||||||
out->op_dialect = def->op_parent;
|
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
@@ -127,7 +128,6 @@ bool mie_ctx_resolve_op(const struct mie_ctx *ctx, struct mie_op *op)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
op->op_dialect = dialect;
|
|
||||||
op->op_info = op_info;
|
op->op_info = op_info;
|
||||||
|
|
||||||
free(op->op_name);
|
free(op->op_name);
|
||||||
@@ -484,3 +484,44 @@ enum mie_status mie_ctx_get_pass(
|
|||||||
*out = pass;
|
*out = pass;
|
||||||
return status;
|
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];
|
||||||
|
|
||||||
|
b_queue_push_back(&ctx->ctx_diag, &diag->diag_entry);
|
||||||
|
|
||||||
|
return diag;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_diag *mie_ctx_pop_diag(struct mie_ctx *ctx)
|
||||||
|
{
|
||||||
|
b_queue_entry *entry = b_queue_pop_front(&ctx->ctx_diag);
|
||||||
|
if (!entry) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return b_unbox(struct mie_diag, entry, diag_entry);
|
||||||
|
}
|
||||||
|
|||||||
124
mie/diag/diag.c
Normal file
124
mie/diag/diag.c
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
#include <blue/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 = b_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
b_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 = b_strdup(str);
|
||||||
|
|
||||||
|
b_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
b_queue_push_back(&diag->diag_components, &c_snippet->s_base.c_entry);
|
||||||
|
}
|
||||||
6
mie/diag/diag.h
Normal file
6
mie/diag/diag.h
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _DIAG_DIAG_H_
|
||||||
|
#define _DIAG_DIAG_H_
|
||||||
|
|
||||||
|
#include <blue/core/queue.h>
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,9 +1,16 @@
|
|||||||
#include <mie/ctx.h>
|
#include <mie/ctx.h>
|
||||||
|
#include <mie/diag/class.h>
|
||||||
|
#include <mie/diag/msg.h>
|
||||||
#include <mie/dialect/arith.h>
|
#include <mie/dialect/arith.h>
|
||||||
#include <mie/dialect/dialect.h>
|
#include <mie/dialect/dialect.h>
|
||||||
#include <mie/macros.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_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_addi);
|
||||||
MIE_DIALECT_ADD_OP(mie_arith_cmpi);
|
MIE_DIALECT_ADD_OP(mie_arith_cmpi);
|
||||||
MIE_DIALECT_ADD_OP(mie_arith_addf);
|
MIE_DIALECT_ADD_OP(mie_arith_addf);
|
||||||
|
|||||||
29
mie/dialect/arith/diag.c
Normal file
29
mie/dialect/arith/diag.c
Normal 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)
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
|
#include <mie/dialect/arith.h>
|
||||||
|
#include <mie/dialect/builtin.h>
|
||||||
#include <mie/dialect/dialect.h>
|
#include <mie/dialect/dialect.h>
|
||||||
#include <mie/ir/op-definition.h>
|
#include <mie/ir/op-definition.h>
|
||||||
#include <mie/ir/op.h>
|
#include <mie/ir/op.h>
|
||||||
#include <mie/macros.h>
|
#include <mie/macros.h>
|
||||||
|
#include <mie/parse/parser.h>
|
||||||
#include <mie/print/printer.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)
|
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
|
||||||
{
|
{
|
||||||
@@ -23,8 +27,60 @@ static enum mie_status print(struct mie_printer *printer, const struct mie_op *o
|
|||||||
return MIE_SUCCESS;
|
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;
|
return MIE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
#include <mie/ctx.h>
|
#include <mie/ctx.h>
|
||||||
|
#include <mie/dialect/arith.h>
|
||||||
#include <mie/dialect/builtin.h>
|
#include <mie/dialect/builtin.h>
|
||||||
#include <mie/dialect/dialect.h>
|
#include <mie/dialect/dialect.h>
|
||||||
#include <mie/ir/builder.h>
|
#include <mie/ir/emit.h>
|
||||||
#include <mie/ir/op-definition.h>
|
#include <mie/ir/op-definition.h>
|
||||||
#include <mie/ir/op.h>
|
#include <mie/ir/op.h>
|
||||||
#include <mie/macros.h>
|
#include <mie/macros.h>
|
||||||
|
#include <mie/parse/parser.h>
|
||||||
#include <mie/print/printer.h>
|
#include <mie/print/printer.h>
|
||||||
#include <mie/type/type.h>
|
#include <mie/type/type.h>
|
||||||
|
|
||||||
@@ -27,25 +29,78 @@ static enum mie_status print(struct mie_printer *printer, const struct mie_op *o
|
|||||||
return MIE_SUCCESS;
|
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;
|
return MIE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mie_register *mie_arith_put_addi(
|
struct mie_register *mie_arith_addi_put(
|
||||||
struct mie_builder *builder, struct mie_register *left,
|
struct mie_emitter *e, struct mie_register *left,
|
||||||
struct mie_register *right, const char *name)
|
struct mie_register *right, const char *name)
|
||||||
{
|
{
|
||||||
struct mie_register *args[] = {left, right};
|
struct mie_register *args[] = {left, right};
|
||||||
const size_t nr_args = sizeof args / sizeof args[0];
|
const size_t nr_args = sizeof args / sizeof args[0];
|
||||||
|
|
||||||
struct mie_op *op
|
struct mie_op *op = mie_emitter_put_op(e, "arith", "addi", args, nr_args);
|
||||||
= mie_builder_put_op(builder, "arith", "addi", args, nr_args);
|
|
||||||
const struct mie_type *ty = left->reg_type;
|
const struct mie_type *ty = left->reg_type;
|
||||||
|
|
||||||
struct mie_register *result = mie_op_add_result(op, ty);
|
struct mie_register *result = mie_op_add_result(op, ty);
|
||||||
result->reg_block = mie_builder_get_current_block(builder);
|
mie_emitter_put_name(e, &result->reg_name, name);
|
||||||
mie_builder_put_name(builder, &result->reg_name, name);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,34 @@
|
|||||||
|
#include <mie/diag/diag.h>
|
||||||
|
#include <mie/dialect/arith.h>
|
||||||
#include <mie/dialect/builtin.h>
|
#include <mie/dialect/builtin.h>
|
||||||
#include <mie/dialect/dialect.h>
|
#include <mie/dialect/dialect.h>
|
||||||
|
#include <mie/ir/emit.h>
|
||||||
#include <mie/ir/op-definition.h>
|
#include <mie/ir/op-definition.h>
|
||||||
#include <mie/ir/op.h>
|
#include <mie/ir/op.h>
|
||||||
#include <mie/macros.h>
|
#include <mie/macros.h>
|
||||||
|
#include <mie/parse/parser.h>
|
||||||
#include <mie/print/printer.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)
|
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
|
||||||
{
|
{
|
||||||
@@ -24,41 +49,12 @@ static enum mie_status print(struct mie_printer *printer, const struct mie_op *o
|
|||||||
|
|
||||||
b_stream_write_char(printer->p_stream, ' ');
|
b_stream_write_char(printer->p_stream, ' ');
|
||||||
|
|
||||||
switch (pred) {
|
if (pred < 0 || pred >= nr_predicates) {
|
||||||
case 0:
|
return MIE_ERR_BAD_STATE;
|
||||||
b_stream_write_string(printer->p_stream, "eq", NULL);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
b_stream_write_string(printer->p_stream, "ne", NULL);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
b_stream_write_string(printer->p_stream, "slt", NULL);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
b_stream_write_string(printer->p_stream, "sle", NULL);
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
b_stream_write_string(printer->p_stream, "sgt", NULL);
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
b_stream_write_string(printer->p_stream, "sge", NULL);
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
b_stream_write_string(printer->p_stream, "ult", NULL);
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
b_stream_write_string(printer->p_stream, "ule", NULL);
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
b_stream_write_string(printer->p_stream, "ugt", NULL);
|
|
||||||
break;
|
|
||||||
case 9:
|
|
||||||
b_stream_write_string(printer->p_stream, "uge", NULL);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return MIE_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
b_stream_write_string(printer->p_stream, predicates[pred], NULL);
|
||||||
|
|
||||||
b_stream_write_char(printer->p_stream, ' ');
|
b_stream_write_char(printer->p_stream, ' ');
|
||||||
mie_printer_print_op_arg(printer, left, false);
|
mie_printer_print_op_arg(printer, left, false);
|
||||||
b_stream_write_string(printer->p_stream, ", ", NULL);
|
b_stream_write_string(printer->p_stream, ", ", NULL);
|
||||||
@@ -69,11 +65,111 @@ static enum mie_status print(struct mie_printer *printer, const struct mie_op *o
|
|||||||
return MIE_SUCCESS;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
b_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(b_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;
|
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_BEGIN(mie_arith_cmpi, "cmpi")
|
||||||
MIE_OP_DEFINITION_PRINT(print);
|
MIE_OP_DEFINITION_PRINT(print);
|
||||||
MIE_OP_DEFINITION_PARSE(parse);
|
MIE_OP_DEFINITION_PARSE(parse);
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
#include <mie/attribute/attribute.h>
|
#include <mie/attribute/attribute.h>
|
||||||
|
#include <mie/dialect/arith.h>
|
||||||
#include <mie/dialect/builtin.h>
|
#include <mie/dialect/builtin.h>
|
||||||
#include <mie/dialect/dialect.h>
|
#include <mie/dialect/dialect.h>
|
||||||
#include <mie/ir/builder.h>
|
#include <mie/ir/emit.h>
|
||||||
#include <mie/ir/op-definition.h>
|
#include <mie/ir/op-definition.h>
|
||||||
#include <mie/ir/op.h>
|
#include <mie/ir/op.h>
|
||||||
#include <mie/macros.h>
|
#include <mie/macros.h>
|
||||||
|
#include <mie/parse/parser.h>
|
||||||
#include <mie/print/printer.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)
|
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
|
||||||
{
|
{
|
||||||
@@ -36,44 +39,155 @@ static enum mie_status print(struct mie_printer *printer, const struct mie_op *o
|
|||||||
return MIE_SUCCESS;
|
return MIE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
|
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;
|
return MIE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mie_register *mie_arith_put_constant_i(
|
static enum mie_status parse_float(
|
||||||
struct mie_builder *builder, long long value, const char *name)
|
struct mie_parser *parser, double d, struct mie_file_span *loc,
|
||||||
|
struct mie_op *out)
|
||||||
{
|
{
|
||||||
struct mie_op *op
|
if (!mie_parser_parse_symbol(parser, MIE_SYM_COLON)) {
|
||||||
= mie_builder_put_op(builder, "arith", "constant", NULL, 0);
|
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
|
const struct mie_type *ty
|
||||||
= mie_ctx_get_int_type(mie_builder_get_ctx(builder), 32);
|
= mie_ctx_get_int_type(mie_emitter_get_ctx(e), 32);
|
||||||
struct mie_register *result = mie_op_add_result(op, ty);
|
struct mie_register *result = mie_op_add_result(op, ty);
|
||||||
|
|
||||||
result->reg_block = mie_builder_get_current_block(builder);
|
mie_emitter_put_name(e, &result->reg_name, name);
|
||||||
mie_builder_put_name(builder, &result->reg_name, name);
|
|
||||||
|
|
||||||
struct mie_attribute *val
|
struct mie_attribute *val
|
||||||
= mie_ctx_get_int(mie_builder_get_ctx(builder), value, 32);
|
= mie_ctx_get_int(mie_emitter_get_ctx(e), value, 32);
|
||||||
mie_attribute_map_put(&op->op_attrib, "value", val, MIE_ATTRMAP_F_REPLACE);
|
mie_attribute_map_put(&op->op_attrib, "value", val, MIE_ATTRMAP_F_REPLACE);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mie_register *mie_arith_put_constant_f(
|
struct mie_register *mie_arith_constant_f_put(
|
||||||
struct mie_builder *builder, long long value, const char *name)
|
struct mie_emitter *e, long long value, const char *name)
|
||||||
{
|
{
|
||||||
struct mie_op *op
|
struct mie_op *op = mie_emitter_put_op(e, "arith", "constant", NULL, 0);
|
||||||
= mie_builder_put_op(builder, "arith", "constant", NULL, 0);
|
|
||||||
const struct mie_type *ty
|
const struct mie_type *ty
|
||||||
= mie_ctx_get_int_type(mie_builder_get_ctx(builder), 32);
|
= mie_ctx_get_int_type(mie_emitter_get_ctx(e), 32);
|
||||||
struct mie_register *result = mie_op_add_result(op, ty);
|
struct mie_register *result = mie_op_add_result(op, ty);
|
||||||
|
|
||||||
result->reg_block = mie_builder_get_current_block(builder);
|
mie_emitter_put_name(e, &result->reg_name, name);
|
||||||
mie_builder_put_name(builder, &result->reg_name, name);
|
|
||||||
|
|
||||||
struct mie_attribute *val
|
struct mie_attribute *val
|
||||||
= mie_ctx_get_float(mie_builder_get_ctx(builder), value, 32);
|
= mie_ctx_get_float(mie_emitter_get_ctx(e), value, 32);
|
||||||
mie_attribute_map_put(&op->op_attrib, "value", val, MIE_ATTRMAP_F_REPLACE);
|
mie_attribute_map_put(&op->op_attrib, "value", val, MIE_ATTRMAP_F_REPLACE);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ static enum mie_status parse(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const struct mie_type *type = NULL;
|
const struct mie_type *type = NULL;
|
||||||
if (!mie_parser_parse_type(ctx, &type)) {
|
if (!mie_parser_parse_type(ctx, NULL, &type, NULL)) {
|
||||||
return MIE_ERR_BAD_SYNTAX;
|
return MIE_ERR_BAD_SYNTAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ static enum mie_status parse(
|
|||||||
|
|
||||||
if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)) {
|
if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)) {
|
||||||
width = 64;
|
width = 64;
|
||||||
} else if (!mie_parser_parse_type(ctx, &type)) {
|
} else if (!mie_parser_parse_type(ctx, NULL, &type, NULL)) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
width = mie_int_type_get_width(type);
|
width = mie_int_type_get_width(type);
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ static enum mie_status parse(
|
|||||||
|
|
||||||
const struct mie_type *type = NULL;
|
const struct mie_type *type = NULL;
|
||||||
|
|
||||||
if (!mie_parser_parse_type(ctx, &type)) {
|
if (!mie_parser_parse_type(ctx, NULL, &type, NULL)) {
|
||||||
free(ty);
|
free(ty);
|
||||||
return MIE_ERR_BAD_FORMAT;
|
return MIE_ERR_BAD_FORMAT;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
#include <mie/ctx.h>
|
#include <mie/ctx.h>
|
||||||
|
#include <mie/diag/class.h>
|
||||||
|
#include <mie/diag/msg.h>
|
||||||
#include <mie/dialect/builtin.h>
|
#include <mie/dialect/builtin.h>
|
||||||
#include <mie/dialect/dialect.h>
|
#include <mie/dialect/dialect.h>
|
||||||
#include <mie/macros.h>
|
#include <mie/macros.h>
|
||||||
@@ -81,20 +83,26 @@ struct mie_attribute *mie_ctx_get_index(struct mie_ctx *ctx, size_t val)
|
|||||||
dialect->ctx_indices, ctx, 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_BEGIN(mie_builtin, struct builtin_dialect, "builtin")
|
||||||
MIE_DIALECT_INIT(init);
|
MIE_DIALECT_INIT(init);
|
||||||
MIE_DIALECT_CLEANUP(cleanup);
|
MIE_DIALECT_CLEANUP(cleanup);
|
||||||
MIE_DIALECT_ADD_OP(mie_builtin_module);
|
MIE_DIALECT_DIAG_CLASS_LIST(mie_builtin_diag);
|
||||||
MIE_DIALECT_ADD_TYPE(mie_builtin_string);
|
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_int);
|
||||||
MIE_DIALECT_ADD_TYPE(mie_builtin_float);
|
MIE_DIALECT_ADD_TYPE(mie_builtin_float);
|
||||||
MIE_DIALECT_ADD_TYPE(mie_builtin_index);
|
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_int);
|
||||||
MIE_DIALECT_ADD_ATTRIBUTE(mie_builtin_float);
|
MIE_DIALECT_ADD_ATTRIBUTE(mie_builtin_float);
|
||||||
MIE_DIALECT_ADD_ATTRIBUTE(mie_builtin_array);
|
|
||||||
MIE_DIALECT_ADD_ATTRIBUTE(mie_builtin_type);
|
MIE_DIALECT_ADD_ATTRIBUTE(mie_builtin_type);
|
||||||
MIE_DIALECT_ADD_TRAIT(mie_builtin_isolated_from_above);
|
MIE_DIALECT_ADD_ATTRIBUTE(mie_builtin_string);
|
||||||
MIE_DIALECT_ADD_TRAIT(mie_builtin_symbol_table);
|
|
||||||
MIE_DIALECT_ADD_INTERFACE(mie_builtin_symbol);
|
MIE_DIALECT_ADD_INTERFACE(mie_builtin_symbol);
|
||||||
|
MIE_DIALECT_ADD_ATTRIBUTE(mie_builtin_array);
|
||||||
|
MIE_DIALECT_ADD_OP(mie_builtin_module);
|
||||||
MIE_DIALECT_END()
|
MIE_DIALECT_END()
|
||||||
|
|||||||
98
mie/dialect/builtin/diag.c
Normal file
98
mie/dialect/builtin/diag.c
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
#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(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)
|
||||||
@@ -1,29 +1,44 @@
|
|||||||
|
#include <mie/ctx.h>
|
||||||
#include <mie/dialect/dialect.h>
|
#include <mie/dialect/dialect.h>
|
||||||
#include <mie/ir/op-definition.h>
|
#include <mie/ir/op-definition.h>
|
||||||
#include <mie/ir/op.h>
|
#include <mie/ir/op.h>
|
||||||
#include <mie/ir/region.h>
|
#include <mie/ir/region.h>
|
||||||
#include <mie/macros.h>
|
#include <mie/macros.h>
|
||||||
|
#include <mie/parse/parser.h>
|
||||||
#include <mie/print/printer.h>
|
#include <mie/print/printer.h>
|
||||||
|
|
||||||
static enum mie_status print(struct mie_printer *out, const struct mie_op *op)
|
static enum mie_status print(struct mie_printer *out, const struct mie_op *op)
|
||||||
{
|
{
|
||||||
b_stream_write_char(out->p_stream, ' ');
|
b_stream_write_char(out->p_stream, ' ');
|
||||||
if (MIE_VECTOR_COUNT(op->op_regions) == 0) {
|
|
||||||
return MIE_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct mie_region *region = &op->op_regions.items[0];
|
struct mie_region *region = mie_op_get_first_region(op);
|
||||||
|
if (region) {
|
||||||
mie_printer_print_region(out, region, 0);
|
mie_printer_print_region(out, region, 0);
|
||||||
|
}
|
||||||
|
|
||||||
return MIE_SUCCESS;
|
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_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;
|
return MIE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
MIE_OP_DEFINITION_BEGIN(mie_builtin_module, "module")
|
MIE_OP_DEFINITION_BEGIN(mie_builtin_module, "module")
|
||||||
MIE_OP_DEFINITION_PRINT(print);
|
MIE_OP_DEFINITION_PRINT(print);
|
||||||
MIE_OP_DEFINITION_PARSE(parse);
|
MIE_OP_DEFINITION_PARSE(parse);
|
||||||
|
MIE_OP_DEFINITION_TRAIT("builtin", "isolated-from-above");
|
||||||
MIE_OP_DEFINITION_END()
|
MIE_OP_DEFINITION_END()
|
||||||
|
|||||||
290
mie/dialect/builtin/type/memref.c
Normal file
290
mie/dialect/builtin/type/memref.c
Normal file
@@ -0,0 +1,290 @@
|
|||||||
|
#include <blue/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 b_unbox(struct mie_type, target, ty_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct memref_type *type
|
||||||
|
= (struct memref_type *)mie_type_create(type_info);
|
||||||
|
if (!type) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
b_bstr type_name;
|
||||||
|
b_bstr_begin_dynamic(&type_name);
|
||||||
|
b_bstr_write_cstr(&type_name, "builtin.memref<", NULL);
|
||||||
|
|
||||||
|
struct mie_printer printer;
|
||||||
|
mie_printer_init(
|
||||||
|
&printer, ctx, (b_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) {
|
||||||
|
b_bstr_write_char(&type_name, '*');
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (ranks[i].r_ranktype) {
|
||||||
|
case MIE_MEMREF_RANK_UNKNOWN:
|
||||||
|
b_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:
|
||||||
|
b_bstr_write_fmt(&type_name, NULL, "%zu", ranks[i].r_static);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
b_bstr_write_char(&type_name, '>');
|
||||||
|
type->m_base.ty_name = b_bstr_end(&type_name);
|
||||||
|
type->m_base.ty_instance_size = 0;
|
||||||
|
b_rope name_rope = B_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;
|
||||||
|
b_stream_write_string(
|
||||||
|
out->p_stream,
|
||||||
|
(out->p_flags & MIE_PRINT_F_ABBREVIATED) ? "memref"
|
||||||
|
: "builtin.memref",
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
b_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) {
|
||||||
|
b_stream_write_char(out->p_stream, '*');
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (rank->r_ranktype) {
|
||||||
|
case MIE_MEMREF_RANK_UNKNOWN:
|
||||||
|
b_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:
|
||||||
|
b_stream_write_fmt(
|
||||||
|
out->p_stream, NULL, "%zu", rank->r_static);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b_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()
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
|
#include <mie/dialect/builtin.h>
|
||||||
#include <mie/dialect/dialect.h>
|
#include <mie/dialect/dialect.h>
|
||||||
|
#include <mie/ir/emit.h>
|
||||||
#include <mie/ir/op-definition.h>
|
#include <mie/ir/op-definition.h>
|
||||||
#include <mie/ir/op.h>
|
#include <mie/ir/op.h>
|
||||||
#include <mie/macros.h>
|
#include <mie/macros.h>
|
||||||
|
#include <mie/parse/parser.h>
|
||||||
#include <mie/print/printer.h>
|
#include <mie/print/printer.h>
|
||||||
|
|
||||||
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
|
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
|
||||||
@@ -28,11 +31,124 @@ static enum mie_status print(struct mie_printer *printer, const struct mie_op *o
|
|||||||
return MIE_SUCCESS;
|
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);
|
||||||
|
b_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 = b_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;
|
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_BEGIN(mie_cf_br_cond, "br-cond")
|
||||||
MIE_OP_DEFINITION_PRINT(print);
|
MIE_OP_DEFINITION_PRINT(print);
|
||||||
MIE_OP_DEFINITION_PARSE(parse);
|
MIE_OP_DEFINITION_PARSE(parse);
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
#include <mie/dialect/dialect.h>
|
#include <mie/dialect/dialect.h>
|
||||||
#include <mie/ir/block.h>
|
#include <mie/ir/block.h>
|
||||||
|
#include <mie/ir/emit.h>
|
||||||
#include <mie/ir/op-definition.h>
|
#include <mie/ir/op-definition.h>
|
||||||
#include <mie/ir/op.h>
|
#include <mie/ir/op.h>
|
||||||
#include <mie/macros.h>
|
#include <mie/macros.h>
|
||||||
|
#include <mie/parse/parser.h>
|
||||||
#include <mie/print/printer.h>
|
#include <mie/print/printer.h>
|
||||||
|
|
||||||
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
|
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
|
||||||
@@ -15,11 +17,96 @@ static enum mie_status print(struct mie_printer *printer, const struct mie_op *o
|
|||||||
return MIE_SUCCESS;
|
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);
|
||||||
|
b_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 = b_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;
|
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_BEGIN(mie_cf_br, "br")
|
||||||
MIE_OP_DEFINITION_PRINT(print);
|
MIE_OP_DEFINITION_PRINT(print);
|
||||||
MIE_OP_DEFINITION_PARSE(parse);
|
MIE_OP_DEFINITION_PARSE(parse);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <mie/macros.h>
|
#include <mie/macros.h>
|
||||||
|
|
||||||
MIE_DIALECT_BEGIN(mie_func, struct mie_dialect, "func")
|
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_func);
|
||||||
MIE_DIALECT_ADD_OP(mie_func_return);
|
MIE_DIALECT_ADD_OP(mie_func_return);
|
||||||
MIE_DIALECT_END()
|
MIE_DIALECT_END()
|
||||||
|
|||||||
@@ -1,16 +1,18 @@
|
|||||||
#include <mie/attribute/attribute-map.h>
|
#include <mie/attribute/attribute-map.h>
|
||||||
#include <mie/ctx.h>
|
#include <mie/ctx.h>
|
||||||
|
#include <mie/diag/diag.h>
|
||||||
#include <mie/dialect/builtin.h>
|
#include <mie/dialect/builtin.h>
|
||||||
#include <mie/dialect/dialect.h>
|
#include <mie/dialect/dialect.h>
|
||||||
#include <mie/dialect/func.h>
|
#include <mie/dialect/func.h>
|
||||||
#include <mie/interface/interface-definition.h>
|
#include <mie/interface/interface-definition.h>
|
||||||
#include <mie/interface/interface.h>
|
#include <mie/interface/interface.h>
|
||||||
#include <mie/ir/block.h>
|
#include <mie/ir/block.h>
|
||||||
#include <mie/ir/builder.h>
|
#include <mie/ir/emit.h>
|
||||||
#include <mie/ir/op-definition.h>
|
#include <mie/ir/op-definition.h>
|
||||||
#include <mie/ir/op.h>
|
#include <mie/ir/op.h>
|
||||||
#include <mie/ir/region.h>
|
#include <mie/ir/region.h>
|
||||||
#include <mie/macros.h>
|
#include <mie/macros.h>
|
||||||
|
#include <mie/parse/parser.h>
|
||||||
#include <mie/print/printer.h>
|
#include <mie/print/printer.h>
|
||||||
#include <mie/type/function.h>
|
#include <mie/type/function.h>
|
||||||
|
|
||||||
@@ -28,8 +30,8 @@ static enum mie_status print(struct mie_printer *printer, const struct mie_op *o
|
|||||||
|
|
||||||
b_stream_write_fmt(printer->p_stream, NULL, " @%s(", sym_name_cstr);
|
b_stream_write_fmt(printer->p_stream, NULL, " @%s(", sym_name_cstr);
|
||||||
|
|
||||||
const struct mie_region *code = &op->op_regions.items[0];
|
const struct mie_region *code = mie_op_get_first_region(op);
|
||||||
const struct mie_block *entry = &code->r_blocks.items[0];
|
const struct mie_block *entry = mie_region_get_first_block(code);
|
||||||
|
|
||||||
for (size_t i = 0; i < MIE_VECTOR_COUNT(entry->b_params); i++) {
|
for (size_t i = 0; i < MIE_VECTOR_COUNT(entry->b_params); i++) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
@@ -69,15 +71,132 @@ static enum mie_status print(struct mie_printer *printer, const struct mie_op *o
|
|||||||
return MIE_SUCCESS;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
b_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), b_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, ¶m_reg->reg_name,
|
||||||
|
block_params.items[i].arg_unresolved.reg_name,
|
||||||
|
MIE_NAME_MAP_F_STRICT)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mie_vector_push_back(in_types, ¶m_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;
|
return MIE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mie_op *mie_func_put_func(
|
struct mie_op *mie_func_func_put(
|
||||||
struct mie_builder *builder, const char *name,
|
struct mie_emitter *e, const char *name, struct mie_func_parameter *params,
|
||||||
struct mie_func_parameter *params, size_t nr_params,
|
size_t nr_params, const struct mie_type **ret_types, size_t nr_ret_types)
|
||||||
const struct mie_type **ret_types, size_t nr_ret_types)
|
|
||||||
{
|
{
|
||||||
const struct mie_type **param_types
|
const struct mie_type **param_types
|
||||||
= calloc(nr_params, sizeof *param_types);
|
= calloc(nr_params, sizeof *param_types);
|
||||||
@@ -90,7 +209,7 @@ struct mie_op *mie_func_put_func(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const struct mie_type *func_type = mie_ctx_get_function_type(
|
const struct mie_type *func_type = mie_ctx_get_function_type(
|
||||||
mie_builder_get_ctx(builder), param_types, nr_params, ret_types,
|
mie_emitter_get_ctx(e), param_types, nr_params, ret_types,
|
||||||
nr_ret_types);
|
nr_ret_types);
|
||||||
free(param_types);
|
free(param_types);
|
||||||
|
|
||||||
@@ -98,7 +217,7 @@ struct mie_op *mie_func_put_func(
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mie_op *op = mie_builder_put_op(builder, "func", "func", NULL, 0);
|
struct mie_op *op = mie_emitter_put_op(e, "func", "func", NULL, 0);
|
||||||
|
|
||||||
struct mie_region *region = mie_op_add_region(op);
|
struct mie_region *region = mie_op_add_region(op);
|
||||||
struct mie_block *entry = mie_region_add_block(region);
|
struct mie_block *entry = mie_region_add_block(region);
|
||||||
@@ -114,9 +233,9 @@ struct mie_op *mie_func_put_func(
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct mie_attribute *sym_name
|
struct mie_attribute *sym_name
|
||||||
= mie_ctx_get_string(mie_builder_get_ctx(builder), name);
|
= mie_ctx_get_string(mie_emitter_get_ctx(e), name);
|
||||||
struct mie_attribute *function_type
|
struct mie_attribute *function_type
|
||||||
= mie_type_attr_create(mie_builder_get_ctx(builder), func_type);
|
= mie_type_attr_create(mie_emitter_get_ctx(e), func_type);
|
||||||
|
|
||||||
mie_attribute_map_put(
|
mie_attribute_map_put(
|
||||||
&op->op_attrib, "sym_name", sym_name, MIE_ATTRMAP_F_REPLACE);
|
&op->op_attrib, "sym_name", sym_name, MIE_ATTRMAP_F_REPLACE);
|
||||||
@@ -130,6 +249,8 @@ struct mie_op *mie_func_put_func(
|
|||||||
MIE_OP_DEFINITION_BEGIN(mie_func_func, "func")
|
MIE_OP_DEFINITION_BEGIN(mie_func_func, "func")
|
||||||
MIE_OP_DEFINITION_PRINT(print);
|
MIE_OP_DEFINITION_PRINT(print);
|
||||||
MIE_OP_DEFINITION_PARSE(parse);
|
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_BEGIN("builtin", "symbol", struct mie_symbol)
|
||||||
MIE_OP_INTERFACE_FUNC(sym_get_name) = NULL;
|
MIE_OP_INTERFACE_FUNC(sym_get_name) = NULL;
|
||||||
MIE_OP_INTERFACE_END()
|
MIE_OP_INTERFACE_END()
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <mie/ir/op.h>
|
#include <mie/ir/op.h>
|
||||||
#include <mie/ir/region.h>
|
#include <mie/ir/region.h>
|
||||||
#include <mie/macros.h>
|
#include <mie/macros.h>
|
||||||
|
#include <mie/parse/parser.h>
|
||||||
#include <mie/print/printer.h>
|
#include <mie/print/printer.h>
|
||||||
#include <mie/type/function.h>
|
#include <mie/type/function.h>
|
||||||
|
|
||||||
@@ -38,8 +39,81 @@ static enum mie_status print(struct mie_printer *printer, const struct mie_op *o
|
|||||||
return MIE_SUCCESS;
|
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),
|
||||||
|
"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;
|
return MIE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
23
mie/dialect/func/trait/function-like.c
Normal file
23
mie/dialect/func/trait/function-like.c
Normal 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
27
mie/dialect/memref/diag.c
Normal 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)
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#include <mie/diag/class.h>
|
||||||
|
#include <mie/diag/msg.h>
|
||||||
#include <mie/dialect/dialect.h>
|
#include <mie/dialect/dialect.h>
|
||||||
#include <mie/dialect/memref.h>
|
#include <mie/dialect/memref.h>
|
||||||
#include <mie/macros.h>
|
#include <mie/macros.h>
|
||||||
@@ -5,6 +7,11 @@
|
|||||||
#include <mie/type/type-definition.h>
|
#include <mie/type/type-definition.h>
|
||||||
#include <mie/type/type.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_BEGIN(mie_memref, struct mie_dialect, "memref")
|
||||||
MIE_DIALECT_ADD_TYPE(mie_memref_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()
|
MIE_DIALECT_END()
|
||||||
|
|||||||
214
mie/dialect/memref/op/load.c
Normal file
214
mie/dialect/memref/op/load.c
Normal 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)
|
||||||
|
{
|
||||||
|
b_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]);
|
||||||
|
}
|
||||||
|
|
||||||
|
b_stream_write_char(printer->p_stream, '[');
|
||||||
|
|
||||||
|
for (size_t i = 1; i < MIE_VECTOR_COUNT(op->op_args); i++) {
|
||||||
|
if (i > 1) {
|
||||||
|
b_stream_write_string(printer->p_stream, ", ", NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
mie_printer_print_op_arg(printer, &op->op_args.items[i], false);
|
||||||
|
}
|
||||||
|
b_stream_write_char(printer->p_stream, ']');
|
||||||
|
|
||||||
|
if (memref_type) {
|
||||||
|
b_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);
|
||||||
|
b_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 = b_string_steal(str);
|
||||||
|
out->arg_unresolved.reg_flags = MIE_REGISTER_F_VIRTUAL;
|
||||||
|
} else if (mie_parser_parse_mregname(ctx, str, &loc)) {
|
||||||
|
out->arg_unresolved.reg_name = b_string_steal(str);
|
||||||
|
out->arg_unresolved.reg_flags = MIE_REGISTER_F_MACHINE;
|
||||||
|
} else {
|
||||||
|
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()
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
#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>
|
|
||||||
|
|
||||||
enum memref_rank_type {
|
|
||||||
MEMREF_RANK_UNKNOWN = 0,
|
|
||||||
MEMREF_RANK_STATIC,
|
|
||||||
MEMREF_RANK_TYPE,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct memref_rank {
|
|
||||||
enum memref_rank_type r_ranktype;
|
|
||||||
union {
|
|
||||||
size_t r_static;
|
|
||||||
const struct mie_type *r_type;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct memref_type {
|
|
||||||
struct mie_type m_base;
|
|
||||||
MIE_VECTOR_DECLARE(struct memref_rank, m_rank);
|
|
||||||
};
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
b_stream_write_string(
|
|
||||||
out->p_stream,
|
|
||||||
(out->p_flags & MIE_PRINT_F_ABBREVIATED) ? "memref" : "memref.memref",
|
|
||||||
NULL);
|
|
||||||
return MIE_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static enum mie_status parse(struct mie_parser *parser, const struct mie_type **out)
|
|
||||||
{
|
|
||||||
printf("Parse memref!\n");
|
|
||||||
|
|
||||||
return MIE_ERR_BAD_FORMAT;
|
|
||||||
}
|
|
||||||
|
|
||||||
MIE_TYPE_DEFINITION_BEGIN(mie_memref_memref, "memref")
|
|
||||||
MIE_TYPE_DEFINITION_INIT(type_init);
|
|
||||||
MIE_TYPE_DEFINITION_PRINT(print);
|
|
||||||
MIE_TYPE_DEFINITION_PARSE(parse);
|
|
||||||
MIE_TYPE_DEFINITION_END()
|
|
||||||
@@ -7,7 +7,9 @@ static enum mie_status print(struct mie_printer *printer, const struct mie_op *o
|
|||||||
return MIE_SUCCESS;
|
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;
|
return MIE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ static enum mie_status print(struct mie_printer *printer, const struct mie_op *o
|
|||||||
return MIE_SUCCESS;
|
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;
|
return MIE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ static enum mie_status print(struct mie_printer *printer, const struct mie_op *o
|
|||||||
return MIE_SUCCESS;
|
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;
|
return MIE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,281 @@
|
|||||||
|
#include <mie/ctx.h>
|
||||||
|
#include <mie/dialect/builtin.h>
|
||||||
#include <mie/dialect/dialect.h>
|
#include <mie/dialect/dialect.h>
|
||||||
|
#include <mie/ir/block.h>
|
||||||
#include <mie/ir/op-definition.h>
|
#include <mie/ir/op-definition.h>
|
||||||
|
#include <mie/ir/op.h>
|
||||||
|
#include <mie/ir/region.h>
|
||||||
#include <mie/macros.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(struct mie_printer *printer, const struct mie_op *op)
|
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];
|
||||||
|
|
||||||
|
b_stream_write_char(printer->p_stream, ' ');
|
||||||
|
mie_printer_print_register(printer, iv, 0);
|
||||||
|
b_stream_write_string(printer->p_stream, " = ", NULL);
|
||||||
|
mie_printer_print_op_arg(printer, lb, 0);
|
||||||
|
b_stream_write_string(printer->p_stream, " to ", NULL);
|
||||||
|
mie_printer_print_op_arg(printer, ub, 0);
|
||||||
|
b_stream_write_string(printer->p_stream, " step ", NULL);
|
||||||
|
mie_printer_print_op_arg(printer, step, 0);
|
||||||
|
|
||||||
|
if (MIE_VECTOR_COUNT(entry->b_params) > 1) {
|
||||||
|
b_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) {
|
||||||
|
b_stream_write_string(printer->p_stream, ", ", NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
mie_printer_print_register(
|
||||||
|
printer, &entry->b_params.items[i], 0);
|
||||||
|
b_stream_write_string(printer->p_stream, " = ", NULL);
|
||||||
|
mie_printer_print_op_arg(
|
||||||
|
printer, &op->op_args.items[i + 2], false);
|
||||||
|
}
|
||||||
|
b_stream_write_char(printer->p_stream, ')');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MIE_VECTOR_COUNT(op->op_result) > 0) {
|
||||||
|
b_stream_write_string(printer->p_stream, " -> ", NULL);
|
||||||
|
if (MIE_VECTOR_COUNT(op->op_result) > 1) {
|
||||||
|
b_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) {
|
||||||
|
b_stream_write_char(printer->p_stream, ')');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
b_stream_write_char(printer->p_stream, ' ');
|
||||||
|
mie_printer_print_region(
|
||||||
|
printer, body, MIE_PRINT_F_EXCLUDE_FIRST_BLOCK_HEADER);
|
||||||
|
|
||||||
return MIE_SUCCESS;
|
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;
|
return MIE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,85 @@
|
|||||||
#include <mie/dialect/dialect.h>
|
#include <mie/dialect/dialect.h>
|
||||||
|
#include <mie/ir/emit.h>
|
||||||
#include <mie/ir/op-definition.h>
|
#include <mie/ir/op-definition.h>
|
||||||
|
#include <mie/ir/op.h>
|
||||||
|
#include <mie/ir/region.h>
|
||||||
#include <mie/macros.h>
|
#include <mie/macros.h>
|
||||||
|
#include <mie/print/printer.h>
|
||||||
|
|
||||||
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
|
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
|
||||||
|
{
|
||||||
|
b_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) {
|
||||||
|
b_stream_write_string(printer->p_stream, " -> ", NULL);
|
||||||
|
|
||||||
|
if (MIE_VECTOR_COUNT(op->op_result) > 1) {
|
||||||
|
b_stream_write_char(printer->p_stream, '(');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_result); i++) {
|
||||||
|
if (i > 0) {
|
||||||
|
b_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) {
|
||||||
|
b_stream_write_char(printer->p_stream, '(');
|
||||||
|
}
|
||||||
|
|
||||||
|
b_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) {
|
||||||
|
b_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;
|
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")
|
MIE_OP_DEFINITION_BEGIN(mie_scf_if, "if")
|
||||||
|
|||||||
@@ -1,17 +1,120 @@
|
|||||||
|
#include <mie/dialect/builtin.h>
|
||||||
#include <mie/dialect/dialect.h>
|
#include <mie/dialect/dialect.h>
|
||||||
|
#include <mie/ir/emit.h>
|
||||||
#include <mie/ir/op-definition.h>
|
#include <mie/ir/op-definition.h>
|
||||||
|
#include <mie/ir/op.h>
|
||||||
#include <mie/macros.h>
|
#include <mie/macros.h>
|
||||||
|
#include <mie/parse/parser.h>
|
||||||
|
#include <mie/print/printer.h>
|
||||||
|
|
||||||
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
|
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
|
||||||
{
|
{
|
||||||
|
b_stream_write_char(printer->p_stream, ' ');
|
||||||
|
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_args); i++) {
|
||||||
|
if (i > 0) {
|
||||||
|
b_stream_write_string(printer->p_stream, ", ", NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
mie_printer_print_op_arg(printer, &op->op_args.items[i], false);
|
||||||
|
}
|
||||||
|
|
||||||
|
b_stream_write_string(printer->p_stream, " : ", NULL);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_args); i++) {
|
||||||
|
if (i > 0) {
|
||||||
|
b_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;
|
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;
|
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_BEGIN(mie_scf_yield, "yield")
|
||||||
MIE_OP_DEFINITION_PRINT(print);
|
MIE_OP_DEFINITION_PRINT(print);
|
||||||
MIE_OP_DEFINITION_PARSE(parse);
|
MIE_OP_DEFINITION_PARSE(parse);
|
||||||
|
|||||||
@@ -9,7 +9,9 @@ static enum mie_status print(struct mie_printer *printer, const struct mie_op *o
|
|||||||
return MIE_SUCCESS;
|
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;
|
return MIE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,10 @@
|
|||||||
|
|
||||||
struct mie_op;
|
struct mie_op;
|
||||||
struct mie_pass;
|
struct mie_pass;
|
||||||
|
struct mie_diag;
|
||||||
|
struct mie_file_cell;
|
||||||
struct mie_int_cache;
|
struct mie_int_cache;
|
||||||
|
struct mie_line_source;
|
||||||
struct mie_index_cache;
|
struct mie_index_cache;
|
||||||
struct mie_string_cache;
|
struct mie_string_cache;
|
||||||
struct mie_attribute_map;
|
struct mie_attribute_map;
|
||||||
@@ -31,6 +34,8 @@ struct mie_ctx {
|
|||||||
struct mie_id_map ctx_attributes;
|
struct mie_id_map ctx_attributes;
|
||||||
/* map of struct mie_pass_definition */
|
/* map of struct mie_pass_definition */
|
||||||
struct mie_id_map ctx_passes;
|
struct mie_id_map ctx_passes;
|
||||||
|
/* queue of struct mie_diag */
|
||||||
|
b_queue ctx_diag;
|
||||||
};
|
};
|
||||||
|
|
||||||
MIE_API struct mie_ctx *mie_ctx_create(void);
|
MIE_API struct mie_ctx *mie_ctx_create(void);
|
||||||
@@ -38,7 +43,6 @@ MIE_API void mie_ctx_destroy(struct mie_ctx *ctx);
|
|||||||
|
|
||||||
MIE_API struct mie_op *mie_ctx_create_op(
|
MIE_API struct mie_op *mie_ctx_create_op(
|
||||||
const struct mie_ctx *ctx, const char *dialect, const char *op);
|
const struct mie_ctx *ctx, const char *dialect, const char *op);
|
||||||
MIE_API bool mie_ctx_resolve_op(const struct mie_ctx *ctx, struct mie_op *op);
|
|
||||||
|
|
||||||
MIE_API struct mie_dialect *mie_ctx_get_dialect(
|
MIE_API struct mie_dialect *mie_ctx_get_dialect(
|
||||||
const struct mie_ctx *ctx, const char *name);
|
const struct mie_ctx *ctx, const char *name);
|
||||||
@@ -73,4 +77,11 @@ MIE_API enum mie_status mie_ctx_get_pass(
|
|||||||
struct mie_ctx *ctx, const char *name,
|
struct mie_ctx *ctx, const char *name,
|
||||||
const struct mie_attribute_map *args, struct mie_pass **out);
|
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
|
#endif
|
||||||
|
|||||||
36
mie/include/mie/diag/amendment.h
Normal file
36
mie/include/mie/diag/amendment.h
Normal 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
|
||||||
18
mie/include/mie/diag/class.h
Normal file
18
mie/include/mie/diag/class.h
Normal 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
|
||||||
34
mie/include/mie/diag/component.h
Normal file
34
mie/include/mie/diag/component.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#ifndef MIE_DIAG_COMPONENT_H_
|
||||||
|
#define MIE_DIAG_COMPONENT_H_
|
||||||
|
|
||||||
|
#include <blue/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;
|
||||||
|
b_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
|
||||||
73
mie/include/mie/diag/diag.h
Normal file
73
mie/include/mie/diag/diag.h
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
#ifndef MIE_DIAG_DIAG_H_
|
||||||
|
#define MIE_DIAG_DIAG_H_
|
||||||
|
|
||||||
|
#include <blue/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;
|
||||||
|
b_queue_entry diag_entry;
|
||||||
|
b_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
|
||||||
18
mie/include/mie/diag/highlight.h
Normal file
18
mie/include/mie/diag/highlight.h
Normal 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
|
||||||
10
mie/include/mie/diag/msg.h
Normal file
10
mie/include/mie/diag/msg.h
Normal 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
|
||||||
@@ -8,19 +8,48 @@
|
|||||||
|
|
||||||
struct mie_ctx;
|
struct mie_ctx;
|
||||||
struct mie_dialect;
|
struct mie_dialect;
|
||||||
struct mie_builder;
|
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_dialect *mie_arith_dialect_create(struct mie_ctx *ctx);
|
||||||
|
|
||||||
MIE_API struct mie_register *mie_arith_put_constant_i(
|
MIE_API struct mie_register *mie_arith_constant_i_put(
|
||||||
struct mie_builder *builder, long long value, const char *name);
|
struct mie_emitter *e, long long value, const char *name);
|
||||||
MIE_API struct mie_register *mie_arith_put_constant_f(
|
MIE_API struct mie_register *mie_arith_constant_f_put(
|
||||||
struct mie_builder *builder, long long value, const char *name);
|
struct mie_emitter *e, long long value, const char *name);
|
||||||
MIE_API struct mie_register *mie_arith_put_addi(
|
MIE_API struct mie_register *mie_arith_addi_put(
|
||||||
struct mie_builder *builder, struct mie_register *left,
|
struct mie_emitter *e, struct mie_register *left,
|
||||||
struct mie_register *right, const char *name);
|
struct mie_register *right, const char *name);
|
||||||
MIE_API struct mie_register *mie_arith_put_addf(
|
MIE_API struct mie_register *mie_arith_cmpi_put(
|
||||||
struct mie_builder *builder, struct mie_register *left,
|
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);
|
struct mie_register *right, const char *name);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <mie/attribute/attribute.h>
|
#include <mie/attribute/attribute.h>
|
||||||
#include <mie/interface/interface.h>
|
#include <mie/interface/interface.h>
|
||||||
#include <mie/misc.h>
|
#include <mie/misc.h>
|
||||||
|
#include <mie/parse/file-span.h>
|
||||||
#include <mie/trait/trait.h>
|
#include <mie/trait/trait.h>
|
||||||
#include <mie/vector.h>
|
#include <mie/vector.h>
|
||||||
|
|
||||||
@@ -15,11 +16,66 @@ struct mie_op;
|
|||||||
struct mie_int_type;
|
struct mie_int_type;
|
||||||
struct mie_float_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 {
|
enum mie_float_width {
|
||||||
MIE_FLOAT_32 = 32,
|
MIE_FLOAT_32 = 32,
|
||||||
MIE_FLOAT_64 = 64,
|
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_string {
|
||||||
struct mie_attribute str_base;
|
struct mie_attribute str_base;
|
||||||
char *str_val;
|
char *str_val;
|
||||||
@@ -74,6 +130,15 @@ struct mie_symbol_table {
|
|||||||
struct mie_trait tab_base;
|
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_int_cache;
|
||||||
struct mie_float_cache;
|
struct mie_float_cache;
|
||||||
struct mie_string_cache;
|
struct mie_string_cache;
|
||||||
@@ -120,6 +185,8 @@ 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_int_type(struct mie_ctx *ctx, size_t bit_width);
|
||||||
MIE_API struct mie_type *mie_ctx_get_float_type(
|
MIE_API struct mie_type *mie_ctx_get_float_type(
|
||||||
struct mie_ctx *ctx, size_t bit_width);
|
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(
|
MIE_API struct mie_attribute *mie_type_attr_create(
|
||||||
struct mie_ctx *ctx, const struct mie_type *ty);
|
struct mie_ctx *ctx, const struct mie_type *ty);
|
||||||
@@ -127,4 +194,8 @@ MIE_API struct mie_attribute *mie_type_attr_create(
|
|||||||
MIE_API size_t mie_int_type_get_width(const struct mie_type *type);
|
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_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
|
#endif
|
||||||
|
|||||||
@@ -2,10 +2,23 @@
|
|||||||
#define MIE_DIALECT_CF_H_
|
#define MIE_DIALECT_CF_H_
|
||||||
|
|
||||||
#include <mie/misc.h>
|
#include <mie/misc.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
struct mie_ctx;
|
struct mie_ctx;
|
||||||
|
struct mie_block;
|
||||||
struct mie_dialect;
|
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_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
|
#endif
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ struct mie_op_definition;
|
|||||||
struct mie_type_definition;
|
struct mie_type_definition;
|
||||||
struct mie_trait_definition;
|
struct mie_trait_definition;
|
||||||
|
|
||||||
|
struct mie_diag_class;
|
||||||
|
struct mie_diag_msg;
|
||||||
|
|
||||||
struct mie_dialect {
|
struct mie_dialect {
|
||||||
mie_id d_id;
|
mie_id d_id;
|
||||||
char *d_name;
|
char *d_name;
|
||||||
@@ -27,6 +30,12 @@ struct mie_dialect {
|
|||||||
struct mie_id_map d_attributes;
|
struct mie_id_map d_attributes;
|
||||||
/* map of struct mie_interface_definition */
|
/* map of struct mie_interface_definition */
|
||||||
struct mie_id_map d_interfaces;
|
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 *);
|
enum mie_status (*d_cleanup)(struct mie_dialect *);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
struct mie_ctx;
|
struct mie_ctx;
|
||||||
struct mie_type;
|
struct mie_type;
|
||||||
struct mie_dialect;
|
struct mie_dialect;
|
||||||
|
struct mie_emitter;
|
||||||
struct mie_register;
|
struct mie_register;
|
||||||
struct mie_builder;
|
|
||||||
|
|
||||||
struct mie_func_parameter {
|
struct mie_func_parameter {
|
||||||
const char *param_name;
|
const char *param_name;
|
||||||
@@ -18,9 +18,8 @@ struct mie_func_parameter {
|
|||||||
|
|
||||||
MIE_API struct mie_dialect *mie_func_dialect_create(struct mie_ctx *ctx);
|
MIE_API struct mie_dialect *mie_func_dialect_create(struct mie_ctx *ctx);
|
||||||
|
|
||||||
MIE_API struct mie_op *mie_func_put_func(
|
MIE_API struct mie_op *mie_func_func_put(
|
||||||
struct mie_builder *builder, const char *name,
|
struct mie_emitter *e, const char *name, struct mie_func_parameter *params,
|
||||||
struct mie_func_parameter *params, size_t nr_params,
|
size_t nr_params, const struct mie_type **ret_types, size_t nr_ret_types);
|
||||||
const struct mie_type **ret_types, size_t nr_ret_types);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -8,6 +8,13 @@
|
|||||||
struct mie_ctx;
|
struct mie_ctx;
|
||||||
struct mie_dialect;
|
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);
|
MIE_API struct mie_dialect *mie_memref_dialect_create(struct mie_ctx *ctx);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -4,8 +4,19 @@
|
|||||||
#include <mie/misc.h>
|
#include <mie/misc.h>
|
||||||
|
|
||||||
struct mie_ctx;
|
struct mie_ctx;
|
||||||
|
struct mie_type;
|
||||||
|
struct mie_region;
|
||||||
struct mie_dialect;
|
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_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
|
#endif
|
||||||
|
|||||||
@@ -86,6 +86,18 @@ static inline void mie_id_builder_add_cstr(
|
|||||||
{
|
{
|
||||||
mie_id_builder_add(builder, s, strlen(s));
|
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(
|
MIE_API void mie_id_builder_add_rope(
|
||||||
struct mie_id_builder *builder, const b_rope *rope);
|
struct mie_id_builder *builder, const b_rope *rope);
|
||||||
MIE_API void mie_id_builder_add_marker(
|
MIE_API void mie_id_builder_add_marker(
|
||||||
|
|||||||
@@ -6,20 +6,69 @@
|
|||||||
#include <mie/name.h>
|
#include <mie/name.h>
|
||||||
#include <mie/vector.h>
|
#include <mie/vector.h>
|
||||||
|
|
||||||
|
#define MIE_BLOCK_ID_INVALID ((size_t)0)
|
||||||
|
|
||||||
struct mie_op;
|
struct mie_op;
|
||||||
struct mie_register;
|
struct mie_register;
|
||||||
|
|
||||||
|
struct mie_block_predecessor {
|
||||||
|
struct mie_block *p_block;
|
||||||
|
};
|
||||||
|
|
||||||
struct mie_block {
|
struct mie_block {
|
||||||
struct mie_name b_name;
|
struct mie_name b_name;
|
||||||
struct mie_region *b_parent;
|
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;
|
||||||
|
b_queue_entry b_entry;
|
||||||
|
|
||||||
MIE_VECTOR_DECLARE(struct mie_register, b_params);
|
MIE_VECTOR_DECLARE(struct mie_register, b_params);
|
||||||
MIE_VECTOR_DECLARE(struct mie_op, b_ops);
|
/* queue of struct mie_op */
|
||||||
|
b_queue b_ops;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct mie_vector_ops mie_block_vector_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(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_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
|
#endif
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#ifndef MIE_IR_BUILDER_H_
|
#ifndef MIE_IR_BUILDER_H_
|
||||||
#define MIE_IR_BUILDER_H_
|
#define MIE_IR_BUILDER_H_
|
||||||
|
|
||||||
|
#include <mie/ir/emit.h>
|
||||||
#include <mie/misc.h>
|
#include <mie/misc.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
@@ -30,9 +31,9 @@ MIE_API void mie_builder_step_into_block(
|
|||||||
MIE_API void mie_builder_step_out(struct mie_builder *builder);
|
MIE_API void mie_builder_step_out(struct mie_builder *builder);
|
||||||
|
|
||||||
MIE_API struct mie_op *mie_builder_put_op(
|
MIE_API struct mie_op *mie_builder_put_op(
|
||||||
struct mie_builder *, const char *dialect, const char *op,
|
struct mie_builder *builder, const char *dialect, const char *op,
|
||||||
struct mie_register **args, size_t nr_args);
|
struct mie_register **args, size_t nr_args);
|
||||||
MIE_API enum mie_status mie_builder_put_name(
|
MIE_API enum mie_status mie_builder_put_name(
|
||||||
struct mie_builder *, struct mie_name *name, const char *hint);
|
struct mie_builder *builder, struct mie_name *name, const char *hint);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
42
mie/include/mie/ir/emit.h
Normal file
42
mie/include/mie/ir/emit.h
Normal 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
|
||||||
@@ -15,6 +15,7 @@ struct mie_op;
|
|||||||
struct mie_printer;
|
struct mie_printer;
|
||||||
struct mie_parser;
|
struct mie_parser;
|
||||||
struct mie_dialect;
|
struct mie_dialect;
|
||||||
|
struct mie_parser_scope;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
enum mie_op_trait {
|
enum mie_op_trait {
|
||||||
@@ -103,7 +104,8 @@ struct mie_op_definition {
|
|||||||
const struct mie_op_result op_results[MIE_OP_MAX_RESULTS];
|
const struct mie_op_result op_results[MIE_OP_MAX_RESULTS];
|
||||||
|
|
||||||
enum mie_status (*op_print)(struct mie_printer *, const 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_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(
|
MIE_API struct mie_op_definition *mie_op_definition_create(
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
#include <mie/name.h>
|
#include <mie/name.h>
|
||||||
#include <mie/parse/file-span.h>
|
#include <mie/parse/file-span.h>
|
||||||
|
|
||||||
|
struct mie_ctx;
|
||||||
struct mie_type;
|
struct mie_type;
|
||||||
|
|
||||||
struct mie_value;
|
struct mie_value;
|
||||||
struct mie_block;
|
struct mie_block;
|
||||||
struct mie_region;
|
struct mie_region;
|
||||||
@@ -37,6 +37,7 @@ struct mie_op_arg {
|
|||||||
|
|
||||||
struct mie_op_successor {
|
struct mie_op_successor {
|
||||||
enum mie_op_flags s_flags;
|
enum mie_op_flags s_flags;
|
||||||
|
struct mie_file_span s_name_span;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
/* only valid if F_SUCCESSOR_RESOLVED is set in s_flags; */
|
/* only valid if F_SUCCESSOR_RESOLVED is set in s_flags; */
|
||||||
@@ -50,16 +51,20 @@ struct mie_op_successor {
|
|||||||
|
|
||||||
struct mie_op {
|
struct mie_op {
|
||||||
enum mie_op_flags op_flags;
|
enum mie_op_flags op_flags;
|
||||||
|
/* used by struct mie_block */
|
||||||
|
b_queue_entry op_entry;
|
||||||
|
|
||||||
/* these pointers are only valid if the F_OP_RESOLVED flag is set */
|
struct mie_line_source *op_src;
|
||||||
const struct mie_dialect *op_dialect;
|
/* this pointer is only valid if the F_OP_RESOLVED flag is set */
|
||||||
const struct mie_op_definition *op_info;
|
const struct mie_op_definition *op_info;
|
||||||
|
|
||||||
|
struct mie_block *op_container;
|
||||||
struct mie_file_span op_name_span;
|
struct mie_file_span op_name_span;
|
||||||
/* only valid if the F_RESOLVED flag is NOT set */
|
/* only valid if the F_RESOLVED flag is NOT set */
|
||||||
char *op_name;
|
char *op_name;
|
||||||
|
|
||||||
MIE_VECTOR_DECLARE(struct mie_region, op_regions);
|
b_queue op_regions;
|
||||||
|
|
||||||
MIE_VECTOR_DECLARE(struct mie_op_successor, op_successors);
|
MIE_VECTOR_DECLARE(struct mie_op_successor, op_successors);
|
||||||
struct mie_attribute_map op_attrib;
|
struct mie_attribute_map op_attrib;
|
||||||
MIE_VECTOR_DECLARE(struct mie_op_arg, op_args);
|
MIE_VECTOR_DECLARE(struct mie_op_arg, op_args);
|
||||||
@@ -72,16 +77,43 @@ 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_init(struct mie_op *op);
|
||||||
MIE_API void mie_op_cleanup(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_op_arg *mie_op_add_arg(struct mie_op *op);
|
||||||
MIE_API struct mie_register *mie_op_add_result(
|
MIE_API struct mie_register *mie_op_add_result(
|
||||||
struct mie_op *op, const struct mie_type *ty);
|
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_region *mie_op_add_region(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(
|
MIE_API bool mie_op_has_trait(
|
||||||
const struct mie_op *op, const char *dialect_name, const char *trait_name);
|
const struct mie_op *op, const char *dialect_name, const char *trait_name);
|
||||||
MIE_API bool mie_op_has_interface(
|
MIE_API bool mie_op_has_interface(
|
||||||
const struct mie_op *op, const char *dialect_name, const char *iface_name);
|
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);
|
MIE_API const struct mie_type *mie_op_arg_get_type(const struct mie_op_arg *arg);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,19 +1,57 @@
|
|||||||
#ifndef MIE_IR_REGION_H_
|
#ifndef MIE_IR_REGION_H_
|
||||||
#define MIE_IR_REGION_H_
|
#define MIE_IR_REGION_H_
|
||||||
|
|
||||||
|
#include <blue/core/btree.h>
|
||||||
|
#include <blue/core/queue.h>
|
||||||
#include <mie/misc.h>
|
#include <mie/misc.h>
|
||||||
#include <mie/vector.h>
|
#include <mie/vector.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
struct mie_op;
|
struct mie_op;
|
||||||
|
struct mie_ctx;
|
||||||
struct mie_block;
|
struct mie_block;
|
||||||
|
|
||||||
struct mie_region {
|
struct mie_region {
|
||||||
struct mie_name_map *r_names;
|
struct mie_name_map *r_names;
|
||||||
struct mie_op *r_parent;
|
struct mie_op *r_parent;
|
||||||
MIE_VECTOR_DECLARE(struct mie_block, r_blocks);
|
/* used by struct mie_op */
|
||||||
|
b_queue_entry r_entry;
|
||||||
|
/* queue of struct mie_block */
|
||||||
|
b_queue r_blocks;
|
||||||
|
/* bst of struct mie_block, as numbered by a depth-first search.
|
||||||
|
* this ordering is recalculated by mie_region_refresh_dominance */
|
||||||
|
b_btree 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(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
|
||||||
|
* b_node
|
||||||
|
* b_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
|
#endif
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ struct mie_register_use {
|
|||||||
|
|
||||||
struct mie_register {
|
struct mie_register {
|
||||||
enum mie_register_flags reg_flags;
|
enum mie_register_flags reg_flags;
|
||||||
|
struct mie_file_span reg_span;
|
||||||
union {
|
union {
|
||||||
/* only valid if F_VIRTUAL is set. */
|
/* only valid if F_VIRTUAL is set. */
|
||||||
struct mie_name reg_name;
|
struct mie_name reg_name;
|
||||||
|
|||||||
14
mie/include/mie/ir/resolve.h
Normal file
14
mie/include/mie/ir/resolve.h
Normal 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
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
#ifndef MIE_IR_REWRITE_H_
|
|
||||||
#define MIE_IR_REWRITE_H_
|
|
||||||
|
|
||||||
struct mie_rewriter;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
#ifndef MIE_IR_WALK_H_
|
#ifndef MIE_IR_WALK_H_
|
||||||
#define MIE_IR_WALK_H_
|
#define MIE_IR_WALK_H_
|
||||||
|
|
||||||
|
#include <blue/core/queue.h>
|
||||||
#include <mie/misc.h>
|
#include <mie/misc.h>
|
||||||
#include <mie/status.h>
|
#include <mie/status.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
struct mie_op;
|
struct mie_op;
|
||||||
struct mie_walker;
|
|
||||||
|
|
||||||
enum mie_walker_flags {
|
enum mie_walker_flags {
|
||||||
MIE_WALKER_F_NONE = 0x00u,
|
MIE_WALKER_F_NONE = 0x00u,
|
||||||
@@ -26,19 +26,45 @@ enum mie_walker_flags {
|
|||||||
MIE_WALKER_F_INCLUDE_BLOCKS = 0x20u,
|
MIE_WALKER_F_INCLUDE_BLOCKS = 0x20u,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mie_walker_item {
|
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;
|
||||||
|
b_queue_entry _e;
|
||||||
|
enum mie_walk_item_type i_type;
|
||||||
|
// size_t i_index;
|
||||||
size_t i_depth;
|
size_t i_depth;
|
||||||
|
union {
|
||||||
struct mie_op *i_op;
|
struct mie_op *i_op;
|
||||||
struct mie_block *i_block;
|
struct mie_block *i_block;
|
||||||
struct mie_region *i_region;
|
struct mie_region *i_region;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
MIE_API struct mie_walker *mie_walker_begin(
|
struct mie_walker {
|
||||||
struct mie_op *op, enum mie_walker_flags flags);
|
enum mie_walker_flags w_flags;
|
||||||
|
union {
|
||||||
|
/* used for recursive walks */
|
||||||
|
b_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 void mie_walker_end(struct mie_walker *walker);
|
||||||
|
|
||||||
MIE_API enum mie_status mie_walker_step(struct mie_walker *walker);
|
MIE_API enum mie_status mie_walker_step(struct mie_walker *walker);
|
||||||
|
|
||||||
MIE_API struct mie_walker_item *mie_walker_get(struct mie_walker *walker);
|
MIE_API struct mie_walk_item *mie_walker_get(struct mie_walker *walker);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -6,18 +6,18 @@
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
#define MIE_DIALECT_BEGIN(func_prefix, c_struct, dialect_name) \
|
#define MIE_DIALECT_BEGIN(func_prefix, c_struct, dialect_name) \
|
||||||
struct mie_dialect *func_prefix##_dialect_create(struct mie_ctx *ctx) \
|
struct mie_dialect* func_prefix##_dialect_create(struct mie_ctx* ctx) \
|
||||||
{ \
|
{ \
|
||||||
struct mie_dialect *self = mie_dialect_create( \
|
struct mie_dialect* self = mie_dialect_create( \
|
||||||
ctx, dialect_name, sizeof(c_struct)); \
|
ctx, dialect_name, sizeof(c_struct)); \
|
||||||
if (!self) { \
|
if (!self) { \
|
||||||
return NULL; \
|
return NULL; \
|
||||||
} \
|
} \
|
||||||
struct mie_op_definition *op = NULL; \
|
struct mie_op_definition* op = NULL; \
|
||||||
struct mie_type_definition *type = NULL; \
|
struct mie_type_definition* type = NULL; \
|
||||||
struct mie_trait_definition *trait = NULL; \
|
struct mie_trait_definition* trait = NULL; \
|
||||||
struct mie_attribute_definition *attribute = NULL; \
|
struct mie_attribute_definition* attribute = NULL; \
|
||||||
struct mie_interface_definition *interface = NULL;
|
struct mie_interface_definition* interface = NULL;
|
||||||
|
|
||||||
#define MIE_DIALECT_END() \
|
#define MIE_DIALECT_END() \
|
||||||
return self; \
|
return self; \
|
||||||
@@ -25,25 +25,31 @@
|
|||||||
|
|
||||||
#define MIE_DIALECT_INIT(func) func(self)
|
#define MIE_DIALECT_INIT(func) func(self)
|
||||||
#define MIE_DIALECT_CLEANUP(func) self->d_cleanup = (func)
|
#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) \
|
#define MIE_DIALECT_ADD_OP(op_id) \
|
||||||
extern struct mie_op_definition *op_id##_op_create( \
|
extern struct mie_op_definition* op_id##_op_create( \
|
||||||
struct mie_dialect *, struct mie_ctx *); \
|
struct mie_dialect*, struct mie_ctx*); \
|
||||||
op = op_id##_op_create(self, ctx)
|
op = op_id##_op_create(self, ctx)
|
||||||
#define MIE_DIALECT_ADD_TYPE(type_id) \
|
#define MIE_DIALECT_ADD_TYPE(type_id) \
|
||||||
extern struct mie_type_definition *type_id##_type_create( \
|
extern struct mie_type_definition* type_id##_type_create( \
|
||||||
struct mie_dialect *, struct mie_ctx *); \
|
struct mie_dialect*, struct mie_ctx*); \
|
||||||
type = type_id##_type_create(self, ctx)
|
type = type_id##_type_create(self, ctx)
|
||||||
#define MIE_DIALECT_ADD_TRAIT(trait_id) \
|
#define MIE_DIALECT_ADD_TRAIT(trait_id) \
|
||||||
extern struct mie_trait_definition *trait_id##_trait_create( \
|
extern struct mie_trait_definition* trait_id##_trait_create( \
|
||||||
struct mie_dialect *, struct mie_ctx *); \
|
struct mie_dialect*, struct mie_ctx*); \
|
||||||
trait = trait_id##_trait_create(self, ctx)
|
trait = trait_id##_trait_create(self, ctx)
|
||||||
#define MIE_DIALECT_ADD_ATTRIBUTE(attr_id) \
|
#define MIE_DIALECT_ADD_ATTRIBUTE(attr_id) \
|
||||||
extern struct mie_attribute_definition *attr_id##_attribute_create( \
|
extern struct mie_attribute_definition* attr_id##_attribute_create( \
|
||||||
struct mie_dialect *, struct mie_ctx *); \
|
struct mie_dialect*, struct mie_ctx*); \
|
||||||
attribute = attr_id##_attribute_create(self, ctx)
|
attribute = attr_id##_attribute_create(self, ctx)
|
||||||
#define MIE_DIALECT_ADD_INTERFACE(iface_id) \
|
#define MIE_DIALECT_ADD_INTERFACE(iface_id) \
|
||||||
extern struct mie_interface_definition *iface_id##_interface_create( \
|
extern struct mie_interface_definition* iface_id##_interface_create( \
|
||||||
struct mie_dialect *, struct mie_ctx *); \
|
struct mie_dialect*, struct mie_ctx*); \
|
||||||
interface = iface_id##_interface_create(self, ctx)
|
interface = iface_id##_interface_create(self, ctx)
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@@ -51,17 +57,17 @@
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
#define MIE_OP_DEFINITION_BEGIN(func_prefix, op_name) \
|
#define MIE_OP_DEFINITION_BEGIN(func_prefix, op_name) \
|
||||||
struct mie_op_definition *func_prefix##_op_create( \
|
struct mie_op_definition* func_prefix##_op_create( \
|
||||||
struct mie_dialect *d, struct mie_ctx *ctx) \
|
struct mie_dialect* d, struct mie_ctx* ctx) \
|
||||||
{ \
|
{ \
|
||||||
struct mie_op_definition *op \
|
struct mie_op_definition* op \
|
||||||
= mie_op_definition_create(d, op_name); \
|
= mie_op_definition_create(d, op_name); \
|
||||||
if (!op) { \
|
if (!op) { \
|
||||||
return NULL; \
|
return NULL; \
|
||||||
} \
|
} \
|
||||||
const struct mie_trait *trait = NULL; \
|
const struct mie_trait* trait = NULL; \
|
||||||
struct mie_interface *i = NULL; \
|
struct mie_interface* i = NULL; \
|
||||||
const struct mie_interface_definition *id = NULL;
|
const struct mie_interface_definition* id = NULL;
|
||||||
|
|
||||||
#define MIE_OP_DEFINITION_END() \
|
#define MIE_OP_DEFINITION_END() \
|
||||||
return op; \
|
return op; \
|
||||||
@@ -75,10 +81,10 @@
|
|||||||
#define MIE_OP_INTERFACE_BEGIN(dialect_name, if_name, c_struct) \
|
#define MIE_OP_INTERFACE_BEGIN(dialect_name, if_name, c_struct) \
|
||||||
id = mie_ctx_get_interface_definition(ctx, dialect_name, if_name); \
|
id = mie_ctx_get_interface_definition(ctx, dialect_name, if_name); \
|
||||||
if (id) { \
|
if (id) { \
|
||||||
c_struct *iface = (c_struct *)mie_interface_create(id);
|
c_struct* iface = (c_struct*)mie_interface_create(id);
|
||||||
#define MIE_OP_INTERFACE_FUNC(func_name) iface->func_name
|
#define MIE_OP_INTERFACE_FUNC(func_name) iface->func_name
|
||||||
#define MIE_OP_INTERFACE_END() \
|
#define MIE_OP_INTERFACE_END() \
|
||||||
mie_op_definition_add_interface(op, (struct mie_interface *)iface); \
|
mie_op_definition_add_interface(op, (struct mie_interface*)iface); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@@ -86,15 +92,15 @@
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
#define MIE_TYPE_DEFINITION_BEGIN(func_prefix, type_name) \
|
#define MIE_TYPE_DEFINITION_BEGIN(func_prefix, type_name) \
|
||||||
struct mie_type_definition *func_prefix##_type_create( \
|
struct mie_type_definition* func_prefix##_type_create( \
|
||||||
struct mie_dialect *d, struct mie_ctx *ctx) \
|
struct mie_dialect* d, struct mie_ctx* ctx) \
|
||||||
{ \
|
{ \
|
||||||
struct mie_type_definition *type \
|
struct mie_type_definition* type \
|
||||||
= mie_type_definition_create(d, type_name); \
|
= mie_type_definition_create(d, type_name); \
|
||||||
if (!type) { \
|
if (!type) { \
|
||||||
return NULL; \
|
return NULL; \
|
||||||
} \
|
} \
|
||||||
const struct mie_trait *trait = NULL;
|
const struct mie_trait* trait = NULL;
|
||||||
|
|
||||||
#define MIE_TYPE_DEFINITION_END() \
|
#define MIE_TYPE_DEFINITION_END() \
|
||||||
return type; \
|
return type; \
|
||||||
@@ -117,10 +123,10 @@
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
#define MIE_TRAIT_DEFINITION_BEGIN(func_prefix, trait_name) \
|
#define MIE_TRAIT_DEFINITION_BEGIN(func_prefix, trait_name) \
|
||||||
struct mie_trait_definition *func_prefix##_trait_create( \
|
struct mie_trait_definition* func_prefix##_trait_create( \
|
||||||
struct mie_dialect *d, struct mie_ctx *ctx) \
|
struct mie_dialect* d, struct mie_ctx* ctx) \
|
||||||
{ \
|
{ \
|
||||||
struct mie_trait_definition *trait \
|
struct mie_trait_definition* trait \
|
||||||
= mie_trait_definition_create(d, trait_name); \
|
= mie_trait_definition_create(d, trait_name); \
|
||||||
if (!trait) { \
|
if (!trait) { \
|
||||||
return NULL; \
|
return NULL; \
|
||||||
@@ -142,10 +148,10 @@
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
#define MIE_ATTRIBUTE_DEFINITION_BEGIN(func_prefix, attribute_name) \
|
#define MIE_ATTRIBUTE_DEFINITION_BEGIN(func_prefix, attribute_name) \
|
||||||
struct mie_attribute_definition *func_prefix##_attribute_create( \
|
struct mie_attribute_definition* func_prefix##_attribute_create( \
|
||||||
struct mie_dialect *d, struct mie_ctx *ctx) \
|
struct mie_dialect* d, struct mie_ctx* ctx) \
|
||||||
{ \
|
{ \
|
||||||
struct mie_attribute_definition *attribute \
|
struct mie_attribute_definition* attribute \
|
||||||
= mie_attribute_definition_create(d, attribute_name); \
|
= mie_attribute_definition_create(d, attribute_name); \
|
||||||
if (!attribute) { \
|
if (!attribute) { \
|
||||||
return NULL; \
|
return NULL; \
|
||||||
@@ -167,10 +173,10 @@
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
#define MIE_INTERFACE_DEFINITION_BEGIN(func_prefix, iface_name) \
|
#define MIE_INTERFACE_DEFINITION_BEGIN(func_prefix, iface_name) \
|
||||||
struct mie_interface_definition *func_prefix##_interface_create( \
|
struct mie_interface_definition* func_prefix##_interface_create( \
|
||||||
struct mie_dialect *d, struct mie_ctx *ctx) \
|
struct mie_dialect* d, struct mie_ctx* ctx) \
|
||||||
{ \
|
{ \
|
||||||
struct mie_interface_definition *i \
|
struct mie_interface_definition* i \
|
||||||
= mie_interface_definition_create(d, iface_name); \
|
= mie_interface_definition_create(d, iface_name); \
|
||||||
if (!i) { \
|
if (!i) { \
|
||||||
return NULL; \
|
return NULL; \
|
||||||
@@ -187,9 +193,9 @@
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
#define MIE_PASS_DEFINITION_BEGIN(prefix) \
|
#define MIE_PASS_DEFINITION_BEGIN(prefix) \
|
||||||
struct mie_pass_definition *prefix##_pass_create(struct mie_ctx *ctx) \
|
struct mie_pass_definition* prefix##_pass_create(struct mie_ctx* ctx) \
|
||||||
{ \
|
{ \
|
||||||
struct mie_pass_definition *p = mie_pass_definition_create(); \
|
struct mie_pass_definition* p = mie_pass_definition_create(); \
|
||||||
if (!p) { \
|
if (!p) { \
|
||||||
return NULL; \
|
return NULL; \
|
||||||
}
|
}
|
||||||
@@ -224,21 +230,21 @@
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
#define MIE_PASS_GROUP_BEGIN(prefix) \
|
#define MIE_PASS_GROUP_BEGIN(prefix) \
|
||||||
enum mie_status prefix##_passes_register(struct mie_ctx *ctx) \
|
enum mie_status prefix##_passes_register(struct mie_ctx* ctx) \
|
||||||
{ \
|
{ \
|
||||||
struct mie_pass_definition *pass = NULL;
|
struct mie_pass_definition* pass = NULL;
|
||||||
|
|
||||||
#define MIE_PASS_GROUP_END() \
|
#define MIE_PASS_GROUP_END() \
|
||||||
return MIE_SUCCESS; \
|
return MIE_SUCCESS; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MIE_PASS_GROUP_DECLARATION(prefix) \
|
#define MIE_PASS_GROUP_DECLARATION(prefix) \
|
||||||
enum mie_status prefix##_passes_register(struct mie_ctx *);
|
enum mie_status prefix##_passes_register(struct mie_ctx*);
|
||||||
|
|
||||||
#define MIE_PASS_GROUP_ADD_PASS(id) \
|
#define MIE_PASS_GROUP_ADD_PASS(id) \
|
||||||
do { \
|
do { \
|
||||||
extern struct mie_pass_definition *id##_pass_create( \
|
extern struct mie_pass_definition* id##_pass_create( \
|
||||||
struct mie_ctx *); \
|
struct mie_ctx*); \
|
||||||
pass = id##_pass_create(ctx); \
|
pass = id##_pass_create(ctx); \
|
||||||
if (!pass) { \
|
if (!pass) { \
|
||||||
return MIE_ERR_INTERNAL_FAILURE; \
|
return MIE_ERR_INTERNAL_FAILURE; \
|
||||||
@@ -246,3 +252,83 @@
|
|||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#endif
|
#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), \
|
||||||
|
},
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ struct mie_name {
|
|||||||
|
|
||||||
/* if this name was read from a file, these structs can be used to
|
/* 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. */
|
* record the location within the file where the name is found. */
|
||||||
struct mie_file_span n_start, n_end;
|
struct mie_file_span n_span;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mie_name_map {
|
struct mie_name_map {
|
||||||
|
|||||||
@@ -1,17 +1,23 @@
|
|||||||
#ifndef MIE_PARSE_LEX_H_
|
#ifndef MIE_PARSE_LEX_H_
|
||||||
#define MIE_PARSE_LEX_H_
|
#define MIE_PARSE_LEX_H_
|
||||||
|
|
||||||
|
#include <blue/core/queue.h>
|
||||||
#include <blue/core/stream.h>
|
#include <blue/core/stream.h>
|
||||||
#include <mie/misc.h>
|
#include <mie/misc.h>
|
||||||
#include <mie/status.h>
|
#include <mie/status.h>
|
||||||
|
|
||||||
struct mie_lex;
|
struct mie_lex;
|
||||||
|
struct mie_ctx;
|
||||||
struct mie_token;
|
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 void mie_lex_destroy(struct mie_lex *lex);
|
||||||
|
|
||||||
MIE_API enum mie_status mie_lex_get_status(const 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 struct mie_token *mie_lex_peek(struct mie_lex *lex);
|
||||||
MIE_API void mie_lex_advance(struct mie_lex *lex);
|
MIE_API void mie_lex_advance(struct mie_lex *lex);
|
||||||
|
|
||||||
|
|||||||
35
mie/include/mie/parse/line-source.h
Normal file
35
mie/include/mie/parse/line-source.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#ifndef MIE_PARSE_LINE_SOURCE_H_
|
||||||
|
#define MIE_PARSE_LINE_SOURCE_H_
|
||||||
|
|
||||||
|
#include <blue/core/stream.h>
|
||||||
|
#include <blue/ds/array.h>
|
||||||
|
#include <blue/ds/string.h>
|
||||||
|
#include <mie/misc.h>
|
||||||
|
#include <mie/parse/file-span.h>
|
||||||
|
#include <mie/status.h>
|
||||||
|
|
||||||
|
struct mie_line_source {
|
||||||
|
b_stream *s_stream;
|
||||||
|
const char *s_path;
|
||||||
|
b_string *s_linebuf;
|
||||||
|
b_iterator *s_linebuf_ptr;
|
||||||
|
b_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, b_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 b_wchar mie_line_source_peekc(struct mie_line_source *src);
|
||||||
|
MIE_API b_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 b_string **out);
|
||||||
|
|
||||||
|
MIE_API bool mie_line_source_input_available(struct mie_line_source *src);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -25,6 +25,30 @@ struct mie_register;
|
|||||||
struct mie_attribute_map;
|
struct mie_attribute_map;
|
||||||
struct mie_attribute;
|
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(
|
MIE_API struct mie_parser *mie_parser_create(
|
||||||
struct mie_ctx *ctx, struct mie_lex *lex);
|
struct mie_ctx *ctx, struct mie_lex *lex);
|
||||||
MIE_API void mie_parser_destroy(struct mie_parser *ctx);
|
MIE_API void mie_parser_destroy(struct mie_parser *ctx);
|
||||||
@@ -51,6 +75,8 @@ MIE_API bool mie_parser_parse_float(
|
|||||||
struct mie_parser *ctx, double *out, struct mie_file_span *loc);
|
struct mie_parser *ctx, double *out, struct mie_file_span *loc);
|
||||||
MIE_API bool mie_parser_parse_word(
|
MIE_API bool mie_parser_parse_word(
|
||||||
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
|
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
|
||||||
|
MIE_API bool mie_parser_parse_name(
|
||||||
|
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
|
||||||
MIE_API bool mie_parser_parse_instname(
|
MIE_API bool mie_parser_parse_instname(
|
||||||
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
|
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
|
||||||
MIE_API bool mie_parser_parse_graphname(
|
MIE_API bool mie_parser_parse_graphname(
|
||||||
@@ -71,17 +97,22 @@ MIE_API bool mie_parser_parse_symname(
|
|||||||
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
|
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
|
||||||
MIE_API bool mie_parser_parse_string(
|
MIE_API bool mie_parser_parse_string(
|
||||||
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
|
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
|
||||||
MIE_API bool mie_parser_parse_keyword(struct mie_parser *ctx, const char *kw);
|
MIE_API bool mie_parser_parse_keyword(
|
||||||
|
struct mie_parser *ctx, const char *kw, struct mie_file_span *loc);
|
||||||
MIE_API bool mie_parser_parse_symbol(
|
MIE_API bool mie_parser_parse_symbol(
|
||||||
struct mie_parser *ctx, enum mie_token_symbol sym);
|
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_linefeed(struct mie_parser *ctx);
|
||||||
|
|
||||||
MIE_API bool mie_parser_parse_type(
|
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(
|
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(
|
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(
|
MIE_API bool mie_parser_parse_operand(
|
||||||
struct mie_parser *ctx, struct mie_op_arg *out);
|
struct mie_parser *ctx, struct mie_op_arg *out);
|
||||||
@@ -89,31 +120,33 @@ MIE_API bool mie_parser_parse_operand_list(
|
|||||||
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_arg, out));
|
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_arg, out));
|
||||||
|
|
||||||
MIE_API bool mie_parser_parse_parameter(
|
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(
|
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, b_string *out);
|
||||||
MIE_API bool mie_parser_parse_unknown_symbol(
|
MIE_API bool mie_parser_parse_unknown_symbol(
|
||||||
struct mie_parser *ctx, enum mie_token_symbol sym);
|
struct mie_parser *ctx, enum mie_token_symbol sym);
|
||||||
|
|
||||||
MIE_API bool mie_parser_parse_register(
|
MIE_API bool mie_parser_parse_register(
|
||||||
struct mie_parser *ctx, struct mie_name_map *names,
|
struct mie_parser *ctx, struct mie_parser_scope *scope,
|
||||||
struct mie_register *out);
|
const char *context, struct mie_register *out);
|
||||||
MIE_API bool mie_parser_parse_register_list(
|
MIE_API bool mie_parser_parse_register_list(
|
||||||
struct mie_parser *ctx, struct mie_name_map *names,
|
struct mie_parser *ctx, struct mie_parser_scope *scope,
|
||||||
MIE_VECTOR_REF_PARAM(struct mie_register, out));
|
const char *context, MIE_VECTOR_REF_PARAM(struct mie_register, out));
|
||||||
|
|
||||||
MIE_API bool mie_parser_parse_region(
|
MIE_API bool mie_parser_parse_region(
|
||||||
struct mie_parser *ctx, struct mie_op *parent, struct mie_region *region);
|
|
||||||
MIE_API bool mie_parser_parse_region_list(
|
|
||||||
struct mie_parser *ctx, struct mie_op *parent,
|
struct mie_parser *ctx, struct mie_op *parent,
|
||||||
MIE_VECTOR_REF_PARAM(struct mie_region, out));
|
struct mie_region *region, struct mie_block *first_block);
|
||||||
|
MIE_API bool mie_parser_parse_region_list(
|
||||||
|
struct mie_parser *ctx, struct mie_op *parent);
|
||||||
MIE_API bool mie_parser_parse_anonymous_block(
|
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);
|
struct mie_block *block);
|
||||||
MIE_API bool mie_parser_parse_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);
|
struct mie_block *block);
|
||||||
|
|
||||||
MIE_API bool mie_parser_parse_successor(
|
MIE_API bool mie_parser_parse_successor(
|
||||||
@@ -123,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_module(struct mie_parser *ctx, struct mie_module *mod);
|
||||||
MIE_API bool mie_parser_parse_op(
|
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(
|
MIE_API bool mie_parser_parse_attribute(
|
||||||
struct mie_parser *ctx, const struct mie_attribute **dest);
|
struct mie_parser *ctx, const struct mie_attribute **dest);
|
||||||
MIE_API bool mie_parser_parse_attribute_map(
|
MIE_API bool mie_parser_parse_attribute_map(
|
||||||
struct mie_parser *ctx, struct mie_attribute_map *out);
|
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
|
#endif
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ enum mie_token_type {
|
|||||||
MIE_TOK_TYPENAME = 0x4000u,
|
MIE_TOK_TYPENAME = 0x4000u,
|
||||||
/* word or name, prefixed with a # hash */
|
/* word or name, prefixed with a # hash */
|
||||||
MIE_TOK_ATTRIBNAME = 0x8000u,
|
MIE_TOK_ATTRIBNAME = 0x8000u,
|
||||||
|
__MIE_TOK_UBOUND = 0x9000u,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum mie_token_value_type {
|
enum mie_token_value_type {
|
||||||
@@ -51,7 +52,7 @@ enum mie_token_value_type {
|
|||||||
|
|
||||||
enum mie_token_symbol {
|
enum mie_token_symbol {
|
||||||
MIE_SYM_NONE = 0,
|
MIE_SYM_NONE = 0,
|
||||||
MIE_SYM_COLON,
|
MIE_SYM_COLON = __MIE_TOK_UBOUND,
|
||||||
MIE_SYM_EQUAL,
|
MIE_SYM_EQUAL,
|
||||||
MIE_SYM_COMMA,
|
MIE_SYM_COMMA,
|
||||||
MIE_SYM_HYPHEN,
|
MIE_SYM_HYPHEN,
|
||||||
@@ -64,6 +65,7 @@ enum mie_token_symbol {
|
|||||||
MIE_SYM_TILDE,
|
MIE_SYM_TILDE,
|
||||||
MIE_SYM_BANG,
|
MIE_SYM_BANG,
|
||||||
MIE_SYM_ATSIGN,
|
MIE_SYM_ATSIGN,
|
||||||
|
MIE_SYM_QUESTION,
|
||||||
MIE_SYM_LEFT_BRACE,
|
MIE_SYM_LEFT_BRACE,
|
||||||
MIE_SYM_RIGHT_BRACE,
|
MIE_SYM_RIGHT_BRACE,
|
||||||
MIE_SYM_LEFT_BRACKET,
|
MIE_SYM_LEFT_BRACKET,
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
struct mie_op;
|
struct mie_op;
|
||||||
struct mie_ctx;
|
struct mie_ctx;
|
||||||
struct mie_pass;
|
struct mie_pass;
|
||||||
|
struct mie_dialect;
|
||||||
struct mie_op_definition;
|
struct mie_op_definition;
|
||||||
struct mie_trait_definition;
|
struct mie_trait_definition;
|
||||||
struct mie_interface_definition;
|
struct mie_interface_definition;
|
||||||
@@ -40,6 +41,7 @@ struct mie_pass_args {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct mie_pass_filter {
|
struct mie_pass_filter {
|
||||||
|
const struct mie_dialect *f_dialect;
|
||||||
const struct mie_op_definition *f_op;
|
const struct mie_op_definition *f_op;
|
||||||
const struct mie_trait_definition *f_trait;
|
const struct mie_trait_definition *f_trait;
|
||||||
const struct mie_interface_definition *f_iface;
|
const struct mie_interface_definition *f_iface;
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ enum mie_print_flags {
|
|||||||
MIE_PRINT_F_INCLUDE_TYPE = 0x04u,
|
MIE_PRINT_F_INCLUDE_TYPE = 0x04u,
|
||||||
MIE_PRINT_F_EXCLUDE_BLOCK_HEADER = 0x08u,
|
MIE_PRINT_F_EXCLUDE_BLOCK_HEADER = 0x08u,
|
||||||
MIE_PRINT_F_EXCLUDE_FIRST_BLOCK_HEADER = 0x10u,
|
MIE_PRINT_F_EXCLUDE_FIRST_BLOCK_HEADER = 0x10u,
|
||||||
|
|
||||||
|
MIE_PRINT_F_MARK_UNRESOLVED_ELEMENTS = 0x20u,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mie_printer {
|
struct mie_printer {
|
||||||
|
|||||||
20
mie/include/mie/rewrite/convert.h
Normal file
20
mie/include/mie/rewrite/convert.h
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#ifndef MIE_REWRITE_CONVERT_H_
|
||||||
|
#define MIE_REWRITE_CONVERT_H_
|
||||||
|
|
||||||
|
#include <mie/ctx.h>
|
||||||
|
|
||||||
|
struct mie_pattern_set;
|
||||||
|
struct mie_convert_config;
|
||||||
|
|
||||||
|
MIE_API struct mie_convert_config *mie_convert_config_create(struct mie_ctx *ctx);
|
||||||
|
MIE_API void mie_convert_config_destroy(struct mie_convert_config *cfg);
|
||||||
|
|
||||||
|
MIE_API enum mie_status mie_convert_config_add_illegal_op(
|
||||||
|
struct mie_convert_config *cfg, const char *dialect_name,
|
||||||
|
const char *op_name);
|
||||||
|
|
||||||
|
MIE_API enum mie_status mie_convert_apply(
|
||||||
|
struct mie_op *op, struct mie_convert_config *cfg,
|
||||||
|
struct mie_pattern_set *patterns);
|
||||||
|
|
||||||
|
#endif
|
||||||
16
mie/include/mie/rewrite/greedy.h
Normal file
16
mie/include/mie/rewrite/greedy.h
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#ifndef MIE_REWRITE_GREEDY_H_
|
||||||
|
#define MIE_REWRITE_GREEDY_H_
|
||||||
|
|
||||||
|
#include <mie/ctx.h>
|
||||||
|
|
||||||
|
struct mie_pattern_set;
|
||||||
|
struct mie_greedy_config;
|
||||||
|
|
||||||
|
MIE_API struct mie_greedy_config *mie_greedy_config_create(struct mie_ctx *ctx);
|
||||||
|
MIE_API void mie_greedy_config_destroy(struct mie_greedy_config *cfg);
|
||||||
|
|
||||||
|
MIE_API enum mie_status mie_greedy_apply(
|
||||||
|
struct mie_op *op, struct mie_greedy_config *cfg,
|
||||||
|
struct mie_pattern_set *patterns);
|
||||||
|
|
||||||
|
#endif
|
||||||
54
mie/include/mie/rewrite/pattern.h
Normal file
54
mie/include/mie/rewrite/pattern.h
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
#ifndef MIE_REWRITE_PATTERN_H_
|
||||||
|
#define MIE_REWRITE_PATTERN_H_
|
||||||
|
|
||||||
|
#include <mie/vector.h>
|
||||||
|
|
||||||
|
#define MIE_REWRITE_RESULT(result, status) \
|
||||||
|
((struct mie_rewrite_result) {.r_result = (result), .r_status = (status)})
|
||||||
|
|
||||||
|
struct mie_op;
|
||||||
|
struct mie_rewriter;
|
||||||
|
|
||||||
|
enum mie_match_result {
|
||||||
|
MIE_NO_MATCH_FOUND = 0,
|
||||||
|
MIE_MATCH_FOUND,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mie_rewrite_result {
|
||||||
|
enum {
|
||||||
|
MIE_REWRITE_SUCCESS = 0,
|
||||||
|
MIE_REWRITE_IGNORE,
|
||||||
|
MIE_REWRITE_FAILURE,
|
||||||
|
} r_result;
|
||||||
|
enum mie_status r_status;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mie_pattern {
|
||||||
|
struct {
|
||||||
|
const char *t_dialect_name, *t_op_name;
|
||||||
|
const struct mie_op_definition *t_op;
|
||||||
|
} p_root;
|
||||||
|
|
||||||
|
enum mie_match_result (*p_match)(const struct mie_op *);
|
||||||
|
struct mie_rewrite_result (*p_rewrite)(
|
||||||
|
struct mie_op *, struct mie_rewriter *);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mie_pattern_set {
|
||||||
|
MIE_VECTOR_DECLARE(struct mie_pattern, s_patterns);
|
||||||
|
};
|
||||||
|
|
||||||
|
MIE_API void mie_pattern_set_init(struct mie_pattern_set *set);
|
||||||
|
MIE_API void mie_pattern_set_cleanup(struct mie_pattern_set *set);
|
||||||
|
|
||||||
|
MIE_API struct mie_pattern *mie_pattern_set_add(struct mie_pattern_set *set);
|
||||||
|
MIE_API struct mie_pattern *mie_pattern_set_match(
|
||||||
|
struct mie_pattern_set *set, const struct mie_op *op);
|
||||||
|
|
||||||
|
MIE_API enum mie_match_result mie_pattern_match(
|
||||||
|
const struct mie_pattern *pattern, const struct mie_op *op);
|
||||||
|
MIE_API struct mie_rewrite_result mie_pattern_rewrite(
|
||||||
|
const struct mie_pattern *pattern, struct mie_op *op,
|
||||||
|
struct mie_rewriter *rewriter);
|
||||||
|
|
||||||
|
#endif
|
||||||
117
mie/include/mie/rewrite/rewriter.h
Normal file
117
mie/include/mie/rewrite/rewriter.h
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
#ifndef MIE_IR_REWRITE_H_
|
||||||
|
#define MIE_IR_REWRITE_H_
|
||||||
|
|
||||||
|
#include <mie/ir/emit.h>
|
||||||
|
#include <mie/misc.h>
|
||||||
|
#include <mie/status.h>
|
||||||
|
#include <mie/vector.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
struct mie_op;
|
||||||
|
struct mie_ctx;
|
||||||
|
struct mie_type;
|
||||||
|
struct mie_region;
|
||||||
|
struct mie_register;
|
||||||
|
struct mie_op_successor;
|
||||||
|
|
||||||
|
struct mie_rewriter {
|
||||||
|
struct mie_emitter r_base;
|
||||||
|
struct mie_ctx *r_ctx;
|
||||||
|
/* anything ops added to the IR are inserted in this block. */
|
||||||
|
struct mie_block *r_insert_block;
|
||||||
|
/* anything ops added to the IR are inserted after this op.
|
||||||
|
* if this is null, the insertion point is the end of r_insert_block. */
|
||||||
|
struct mie_op *r_insert_point;
|
||||||
|
};
|
||||||
|
|
||||||
|
MIE_API void mie_rewriter_init(struct mie_rewriter *rw, struct mie_ctx *ctx);
|
||||||
|
MIE_API void mie_rewriter_cleanup(struct mie_rewriter *rw);
|
||||||
|
|
||||||
|
MIE_API struct mie_ctx *mie_rewriter_get_ctx(const struct mie_rewriter *rw);
|
||||||
|
|
||||||
|
MIE_API struct mie_block *mie_rewriter_get_insertion_block(struct mie_rewriter *rw);
|
||||||
|
MIE_API struct mie_op *mie_rewriter_get_insertion_point(struct mie_rewriter *rw);
|
||||||
|
|
||||||
|
MIE_API struct mie_block *mie_rewriter_set_insertion_block(
|
||||||
|
struct mie_rewriter *rw, struct mie_block *block);
|
||||||
|
MIE_API struct mie_op *mie_rewriter_set_insertion_point(
|
||||||
|
struct mie_rewriter *rw, struct mie_op *insert_point);
|
||||||
|
|
||||||
|
MIE_API struct mie_block *mie_rewriter_split_block(
|
||||||
|
struct mie_rewriter *rw, struct mie_block *block, struct mie_op *before,
|
||||||
|
const char *name);
|
||||||
|
MIE_API struct mie_block *mie_rewriter_create_block(
|
||||||
|
struct mie_rewriter *rw, struct mie_block *insert_before, const char *name);
|
||||||
|
MIE_API struct mie_register *mie_rewriter_add_block_parameter(
|
||||||
|
struct mie_rewriter *rw, struct mie_block *block, const char *name,
|
||||||
|
const struct mie_type *type);
|
||||||
|
|
||||||
|
MIE_API enum mie_status mie_rewriter_move_block_to_start(
|
||||||
|
struct mie_rewriter *rw, struct mie_block *block,
|
||||||
|
struct mie_region *from, struct mie_region *to);
|
||||||
|
MIE_API enum mie_status mie_rewriter_move_block_to_end(
|
||||||
|
struct mie_rewriter *rw, struct mie_block *block,
|
||||||
|
struct mie_region *from, struct mie_region *to);
|
||||||
|
MIE_API enum mie_status mie_rewriter_move_block_before(
|
||||||
|
struct mie_rewriter *rw, struct mie_block *block,
|
||||||
|
struct mie_region *from, struct mie_region *to, struct mie_block *before);
|
||||||
|
MIE_API enum mie_status mie_rewriter_move_block_after(
|
||||||
|
struct mie_rewriter *rw, struct mie_block *block,
|
||||||
|
struct mie_region *from, struct mie_region *to, struct mie_block *after);
|
||||||
|
|
||||||
|
MIE_API enum mie_status mie_rewriter_rename_block(
|
||||||
|
struct mie_rewriter *rw, struct mie_block *block, const char *name);
|
||||||
|
|
||||||
|
MIE_API enum mie_status mie_rewriter_move_blocks_to_start(
|
||||||
|
struct mie_rewriter *rw, struct mie_region *from, struct mie_region *to);
|
||||||
|
MIE_API enum mie_status mie_rewriter_move_blocks_to_end(
|
||||||
|
struct mie_rewriter *rw, struct mie_region *from, struct mie_region *to);
|
||||||
|
MIE_API enum mie_status mie_rewriter_move_blocks_before(
|
||||||
|
struct mie_rewriter *rw, struct mie_region *from, struct mie_region *to,
|
||||||
|
struct mie_block *before);
|
||||||
|
MIE_API enum mie_status mie_rewriter_move_blocks_after(
|
||||||
|
struct mie_rewriter *rw, struct mie_region *from, struct mie_region *to,
|
||||||
|
struct mie_block *after);
|
||||||
|
|
||||||
|
MIE_API enum mie_status mie_rewriter_move_region_to_start(
|
||||||
|
struct mie_rewriter *rw, struct mie_region *region, struct mie_op *from,
|
||||||
|
struct mie_op *to);
|
||||||
|
MIE_API enum mie_status mie_rewriter_move_region_to_end(
|
||||||
|
struct mie_rewriter *rw, struct mie_region *region, struct mie_op *from,
|
||||||
|
struct mie_op *to);
|
||||||
|
MIE_API enum mie_status mie_rewriter_move_region_before(
|
||||||
|
struct mie_rewriter *rw, struct mie_region *region, struct mie_op *from,
|
||||||
|
struct mie_op *to, struct mie_region *before);
|
||||||
|
MIE_API enum mie_status mie_rewriter_move_region_after(
|
||||||
|
struct mie_rewriter *rw, struct mie_region *region, struct mie_op *from,
|
||||||
|
struct mie_op *to, struct mie_region *after);
|
||||||
|
|
||||||
|
MIE_API struct mie_op *mie_rewriter_put_op(
|
||||||
|
struct mie_rewriter *rw, const char *dialect, const char *op,
|
||||||
|
struct mie_register **args, size_t nr_args);
|
||||||
|
MIE_API struct mie_op *mie_rewriter_replace_op(
|
||||||
|
struct mie_rewriter *rw, struct mie_op *op, const char *dialect_name,
|
||||||
|
const char *op_name);
|
||||||
|
MIE_API struct mie_op_successor *mie_rewriter_add_op_successor(
|
||||||
|
struct mie_rewriter *rw, struct mie_op *op, struct mie_block *dest,
|
||||||
|
struct mie_register **args, size_t nr_args);
|
||||||
|
MIE_API struct mie_op_arg *mie_rewriter_add_op_successor_arg(
|
||||||
|
struct mie_rewriter *rw, struct mie_op *op, struct mie_op_successor *s,
|
||||||
|
struct mie_register *reg);
|
||||||
|
MIE_API struct mie_op_arg *mie_rewriter_add_op_arg(
|
||||||
|
struct mie_rewriter *rw, struct mie_op *op, struct mie_register *reg);
|
||||||
|
MIE_API enum mie_status mie_rewriter_erase_op(
|
||||||
|
struct mie_rewriter *rw, struct mie_op *op);
|
||||||
|
MIE_API enum mie_status mie_rewriter_move_op_args_to_successor(
|
||||||
|
struct mie_rewriter *rw, struct mie_op *op, struct mie_op_successor *s);
|
||||||
|
|
||||||
|
MIE_API enum mie_status mie_rewriter_replace_register(
|
||||||
|
struct mie_rewriter *rw, struct mie_register *old,
|
||||||
|
struct mie_register *new);
|
||||||
|
MIE_API enum mie_status mie_rewriter_rename_register(
|
||||||
|
struct mie_rewriter *rw, struct mie_register *reg, const char *name);
|
||||||
|
|
||||||
|
MIE_API enum mie_status mie_rewriter_put_name(
|
||||||
|
struct mie_rewriter *rw, struct mie_name *name, const char *hint);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -23,4 +23,6 @@ MIE_API void mie_function_type_build_id(
|
|||||||
size_t nr_in_types, const struct mie_type **out_types,
|
size_t nr_in_types, const struct mie_type **out_types,
|
||||||
size_t nr_out_types);
|
size_t nr_out_types);
|
||||||
|
|
||||||
|
MIE_API bool mie_type_is_function(const struct mie_type *ty);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -14,9 +14,12 @@ struct mie_storage_type {
|
|||||||
MIE_API struct mie_storage_type *mie_storage_type_create(void);
|
MIE_API struct mie_storage_type *mie_storage_type_create(void);
|
||||||
MIE_API void mie_storage_type_add_part(
|
MIE_API void mie_storage_type_add_part(
|
||||||
struct mie_storage_type *ty, const struct mie_type *part);
|
struct mie_storage_type *ty, const struct mie_type *part);
|
||||||
|
MIE_API size_t mie_storage_type_get_nr_parts(const struct mie_storage_type *ty);
|
||||||
|
|
||||||
MIE_API void mie_storage_type_build_id(
|
MIE_API void mie_storage_type_build_id(
|
||||||
struct mie_id_builder *builder, const struct mie_type **parts,
|
struct mie_id_builder *builder, const struct mie_type **parts,
|
||||||
size_t nr_parts);
|
size_t nr_parts);
|
||||||
|
|
||||||
|
MIE_API bool mie_type_is_storage(const struct mie_type *ty);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -47,4 +47,7 @@ MIE_API void mie_type_build_id(
|
|||||||
MIE_API void mie_type_generate_id(
|
MIE_API void mie_type_generate_id(
|
||||||
const struct mie_type *type, const mie_id *ns, mie_id *out);
|
const struct mie_type *type, const mie_id *ns, mie_id *out);
|
||||||
|
|
||||||
|
MIE_API bool mie_type_is(
|
||||||
|
const struct mie_type *ty, const char *dialect_name, const char *type_name);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ struct mie_vector_ops {
|
|||||||
/* use this macro to forward your reference to a vector (which you got via
|
/* use this macro to forward your reference to a vector (which you got via
|
||||||
* MIE_VECTOR_REF_PARAM in your function prototype), to another function whose
|
* MIE_VECTOR_REF_PARAM in your function prototype), to another function whose
|
||||||
* prototype also uses MIE_VECTOR_REF_PARAM */
|
* prototype also uses MIE_VECTOR_REF_PARAM */
|
||||||
#define MIE_VECTOR_REF2(name) &(name.items), &(name.count), &(name.max)
|
#define MIE_VECTOR_REF2(name) name, name##_count, name##_max
|
||||||
|
|
||||||
/* use these functions if you're accessing a vector directly. */
|
/* use these functions if you're accessing a vector directly. */
|
||||||
#define mie_vector_push_back(vector, ptr, ops) \
|
#define mie_vector_push_back(vector, ptr, ops) \
|
||||||
@@ -49,8 +49,8 @@ struct mie_vector_ops {
|
|||||||
&(vector.max), ops)
|
&(vector.max), ops)
|
||||||
#define mie_vector_pop_back(vector, ops) \
|
#define mie_vector_pop_back(vector, ops) \
|
||||||
__mie_vector_pop_back( \
|
__mie_vector_pop_back( \
|
||||||
(void **)&(vector), sizeof *vector, &(vector.count), \
|
(void **)&(vector.items), sizeof *vector.items, \
|
||||||
&(vector.max), ops)
|
&(vector.count), &(vector.max), ops)
|
||||||
#define mie_vector_emplace_back(vector, ops) \
|
#define mie_vector_emplace_back(vector, ops) \
|
||||||
__mie_vector_emplace_back( \
|
__mie_vector_emplace_back( \
|
||||||
(void **)&(vector.items), sizeof *vector.items, \
|
(void **)&(vector.items), sizeof *vector.items, \
|
||||||
@@ -86,6 +86,10 @@ struct mie_vector_ops {
|
|||||||
__mie_vector_destroy( \
|
__mie_vector_destroy( \
|
||||||
(void **)(vector), sizeof **vector, (vector##_count), \
|
(void **)(vector), sizeof **vector, (vector##_count), \
|
||||||
(vector##_max), ops)
|
(vector##_max), ops)
|
||||||
|
#define mie_vector_ref_get_item(vector, index) (*vector)[index]
|
||||||
|
#define mie_vector_ref_get_item_ptr(vector, index) (&(*vector)[index])
|
||||||
|
#define mie_vector_ref_get_count(vector) *(vector##_count)
|
||||||
|
#define mie_vector_ref_get_max(vector) *(vector##_count)
|
||||||
|
|
||||||
/* don't use these functions */
|
/* don't use these functions */
|
||||||
MIE_API int __mie_vector_push_back(
|
MIE_API int __mie_vector_push_back(
|
||||||
|
|||||||
251
mie/ir/block.c
251
mie/ir/block.c
@@ -2,9 +2,230 @@
|
|||||||
#include <mie/ir/op.h>
|
#include <mie/ir/op.h>
|
||||||
#include <mie/ir/register.h>
|
#include <mie/ir/register.h>
|
||||||
|
|
||||||
|
struct mie_op *mie_block_get_first_op(const struct mie_block *block)
|
||||||
|
{
|
||||||
|
b_queue_entry *entry = b_queue_first(&block->b_ops);
|
||||||
|
if (!entry) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return b_unbox(struct mie_op, entry, op_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_op *mie_block_get_prev_op(
|
||||||
|
const struct mie_block *block, const struct mie_op *before)
|
||||||
|
{
|
||||||
|
if (!before || before->op_container != block) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
b_queue_entry *entry = b_queue_prev(&before->op_entry);
|
||||||
|
if (!entry) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return b_unbox(struct mie_op, entry, op_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_op *mie_block_get_next_op(
|
||||||
|
const struct mie_block *block, const struct mie_op *after)
|
||||||
|
{
|
||||||
|
if (!after || after->op_container != block) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
b_queue_entry *entry = b_queue_next(&after->op_entry);
|
||||||
|
if (!entry) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return b_unbox(struct mie_op, entry, op_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_op *mie_block_get_last_op(const struct mie_block *block)
|
||||||
|
{
|
||||||
|
b_queue_entry *entry = b_queue_last(&block->b_ops);
|
||||||
|
if (!entry) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return b_unbox(struct mie_op, entry, op_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_op *mie_block_get_terminator(const struct mie_block *block)
|
||||||
|
{
|
||||||
|
b_queue_entry *op_entry = b_queue_last(&block->b_ops);
|
||||||
|
return b_unbox(struct mie_op, op_entry, op_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_op_successor *mie_block_get_first_successor(const struct mie_block *block)
|
||||||
|
{
|
||||||
|
struct mie_op *op = mie_block_get_terminator(block);
|
||||||
|
if (!op) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MIE_VECTOR_COUNT(op->op_successors) == 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &op->op_successors.items[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_op_successor *mie_block_get_prev_successor(
|
||||||
|
const struct mie_block *block, const struct mie_op_successor *before)
|
||||||
|
{
|
||||||
|
struct mie_op *op = mie_block_get_terminator(block);
|
||||||
|
if (!op) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MIE_VECTOR_COUNT(op->op_successors) == 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t i = before - &op->op_successors.items[0];
|
||||||
|
if (i == 0 || i >= MIE_VECTOR_COUNT(op->op_successors)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &op->op_successors.items[i - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_op_successor *mie_block_get_next_successor(
|
||||||
|
const struct mie_block *block, const struct mie_op_successor *after)
|
||||||
|
{
|
||||||
|
struct mie_op *op = mie_block_get_terminator(block);
|
||||||
|
if (!op) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MIE_VECTOR_COUNT(op->op_successors) == 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t i = after - &op->op_successors.items[0];
|
||||||
|
if (i >= MIE_VECTOR_COUNT(op->op_successors)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i + 1 >= MIE_VECTOR_COUNT(op->op_successors)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &op->op_successors.items[i + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_op_successor *mie_block_get_last_successor(const struct mie_block *block)
|
||||||
|
{
|
||||||
|
struct mie_op *op = mie_block_get_terminator(block);
|
||||||
|
if (!op) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t nr_successors = MIE_VECTOR_COUNT(op->op_successors);
|
||||||
|
|
||||||
|
if (nr_successors == 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &op->op_successors.items[nr_successors - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_block_predecessor *mie_block_get_first_predecessor(
|
||||||
|
const struct mie_block *block)
|
||||||
|
{
|
||||||
|
size_t nr_predecessors = MIE_VECTOR_COUNT(block->b_ipred);
|
||||||
|
|
||||||
|
if (nr_predecessors == 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &block->b_ipred.items[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_block_predecessor *mie_block_get_prev_predecessor(
|
||||||
|
const struct mie_block *block, const struct mie_block_predecessor *before)
|
||||||
|
{
|
||||||
|
if (MIE_VECTOR_COUNT(block->b_ipred) == 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t i = before - &block->b_ipred.items[0];
|
||||||
|
if (i == 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &block->b_ipred.items[i - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_block_predecessor *mie_block_get_next_predecessor(
|
||||||
|
const struct mie_block *block, const struct mie_block_predecessor *after)
|
||||||
|
{
|
||||||
|
if (MIE_VECTOR_COUNT(block->b_ipred) == 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t i = after - &block->b_ipred.items[0];
|
||||||
|
if (i >= MIE_VECTOR_COUNT(block->b_ipred)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i + 1 >= MIE_VECTOR_COUNT(block->b_ipred)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &block->b_ipred.items[i + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_block_predecessor *mie_block_get_last_predecessor(
|
||||||
|
const struct mie_block *block)
|
||||||
|
{
|
||||||
|
size_t nr_predecessors = MIE_VECTOR_COUNT(block->b_ipred);
|
||||||
|
|
||||||
|
if (nr_predecessors == 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &block->b_ipred.items[nr_predecessors - 1];
|
||||||
|
}
|
||||||
|
|
||||||
struct mie_op *mie_block_add_op(struct mie_block *block)
|
struct mie_op *mie_block_add_op(struct mie_block *block)
|
||||||
{
|
{
|
||||||
return mie_vector_emplace_back(block->b_ops, NULL);
|
struct mie_op *op = malloc(sizeof *op);
|
||||||
|
if (!op) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mie_op_init(op);
|
||||||
|
op->op_container = block;
|
||||||
|
|
||||||
|
b_queue_push_back(&block->b_ops, &op->op_entry);
|
||||||
|
|
||||||
|
return op;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_op *mie_block_add_op_after(struct mie_block *block, struct mie_op *after)
|
||||||
|
{
|
||||||
|
if (after && after->op_container != block) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_op *op = malloc(sizeof *op);
|
||||||
|
if (!op) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mie_op_init(op);
|
||||||
|
op->op_container = block;
|
||||||
|
|
||||||
|
if (after) {
|
||||||
|
b_queue_insert_after(&block->b_ops, &op->op_entry, &after->op_entry);
|
||||||
|
} else {
|
||||||
|
b_queue_push_back(&block->b_ops, &op->op_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
return op;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mie_register *mie_block_add_param(struct mie_block *block)
|
struct mie_register *mie_block_add_param(struct mie_block *block)
|
||||||
@@ -17,3 +238,31 @@ struct mie_register *mie_block_add_param(struct mie_block *block)
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct mie_register *mie_block_find_register(
|
||||||
|
const struct mie_block *block, const char *name,
|
||||||
|
const struct mie_op *start_point)
|
||||||
|
{
|
||||||
|
const b_queue_entry *entry = b_queue_last(&block->b_ops);
|
||||||
|
if (start_point) {
|
||||||
|
entry = &start_point->op_entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < MIE_VECTOR_COUNT(block->b_params); i++) {
|
||||||
|
if (!strcmp(block->b_params.items[i].reg_name.n_str, name)) {
|
||||||
|
return &block->b_params.items[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (entry) {
|
||||||
|
struct mie_op *op = b_unbox(struct mie_op, entry, op_entry);
|
||||||
|
struct mie_register *reg = mie_op_get_result_with_name(op, name);
|
||||||
|
if (reg) {
|
||||||
|
return reg;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry = b_queue_prev(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include <mie/ctx.h>
|
#include <mie/ctx.h>
|
||||||
#include <mie/ir/block.h>
|
#include <mie/ir/block.h>
|
||||||
#include <mie/ir/builder.h>
|
#include <mie/ir/builder.h>
|
||||||
|
#include <mie/ir/emit.h>
|
||||||
#include <mie/ir/op-definition.h>
|
#include <mie/ir/op-definition.h>
|
||||||
#include <mie/ir/op.h>
|
#include <mie/ir/op.h>
|
||||||
#include <mie/ir/region.h>
|
#include <mie/ir/region.h>
|
||||||
@@ -13,6 +14,7 @@ struct builder_scope {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct mie_builder {
|
struct mie_builder {
|
||||||
|
struct mie_emitter b_base;
|
||||||
struct mie_ctx *b_ctx;
|
struct mie_ctx *b_ctx;
|
||||||
b_queue b_scope_stack;
|
b_queue b_scope_stack;
|
||||||
struct mie_op *b_root;
|
struct mie_op *b_root;
|
||||||
@@ -28,6 +30,11 @@ struct mie_builder *mie_builder_create(struct mie_ctx *ctx, struct mie_op *root)
|
|||||||
|
|
||||||
memset(out, 0x0, sizeof *out);
|
memset(out, 0x0, sizeof *out);
|
||||||
|
|
||||||
|
out->b_base.e_get_ctx = (mie_emit_get_ctx)mie_builder_get_ctx;
|
||||||
|
out->b_base.e_put_op = (mie_emit_put_op)mie_builder_put_op;
|
||||||
|
out->b_base.e_put_name = (mie_emit_put_name)mie_builder_put_name;
|
||||||
|
out->b_base.e_put_block = NULL;
|
||||||
|
|
||||||
out->b_ctx = ctx;
|
out->b_ctx = ctx;
|
||||||
out->b_root = root;
|
out->b_root = root;
|
||||||
|
|
||||||
@@ -41,6 +48,23 @@ struct mie_ctx *mie_builder_get_ctx(struct mie_builder *builder)
|
|||||||
return builder->b_ctx;
|
return builder->b_ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct mie_name_map *get_current_name_map(struct mie_builder *builder)
|
||||||
|
{
|
||||||
|
b_queue_entry *cur = b_queue_last(&builder->b_scope_stack);
|
||||||
|
while (cur) {
|
||||||
|
struct builder_scope *scope
|
||||||
|
= b_unbox(struct builder_scope, cur, s_entry);
|
||||||
|
|
||||||
|
if (scope->s_region && scope->s_region->r_names) {
|
||||||
|
return scope->s_region->r_names;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur = b_queue_prev(cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
struct mie_block *mie_builder_get_current_block(struct mie_builder *builder)
|
struct mie_block *mie_builder_get_current_block(struct mie_builder *builder)
|
||||||
{
|
{
|
||||||
b_queue_entry *entry = b_queue_last(&builder->b_scope_stack);
|
b_queue_entry *entry = b_queue_last(&builder->b_scope_stack);
|
||||||
@@ -56,12 +80,10 @@ struct mie_block *mie_builder_get_current_block(struct mie_builder *builder)
|
|||||||
|
|
||||||
void mie_builder_step_into_op(struct mie_builder *builder, struct mie_op *op)
|
void mie_builder_step_into_op(struct mie_builder *builder, struct mie_op *op)
|
||||||
{
|
{
|
||||||
struct mie_region *region = NULL;
|
struct mie_region *region = mie_op_get_last_region(op);
|
||||||
|
|
||||||
if (MIE_VECTOR_COUNT(op->op_regions) == 0) {
|
if (!region) {
|
||||||
region = mie_op_add_region(op);
|
region = mie_op_add_region(op);
|
||||||
} else {
|
|
||||||
region = &op->op_regions.items[MIE_VECTOR_COUNT(op->op_regions) - 1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mie_builder_step_into_region(builder, region);
|
mie_builder_step_into_region(builder, region);
|
||||||
@@ -70,12 +92,10 @@ void mie_builder_step_into_op(struct mie_builder *builder, struct mie_op *op)
|
|||||||
void mie_builder_step_into_region(
|
void mie_builder_step_into_region(
|
||||||
struct mie_builder *builder, struct mie_region *region)
|
struct mie_builder *builder, struct mie_region *region)
|
||||||
{
|
{
|
||||||
struct mie_block *block = NULL;
|
struct mie_block *block = mie_region_get_last_block(region);
|
||||||
|
|
||||||
if (MIE_VECTOR_COUNT(region->r_blocks) == 0) {
|
if (!block) {
|
||||||
block = mie_region_add_block(region);
|
block = mie_region_add_block(region);
|
||||||
} else {
|
|
||||||
block = ®ion->r_blocks.items[MIE_VECTOR_COUNT(region->r_blocks) - 1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mie_builder_step_into_block(builder, block);
|
mie_builder_step_into_block(builder, block);
|
||||||
@@ -110,28 +130,6 @@ void mie_builder_step_out(struct mie_builder *builder)
|
|||||||
free(scope);
|
free(scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct mie_block *create_current_block(struct mie_builder *builder)
|
|
||||||
{
|
|
||||||
struct mie_region *region = NULL;
|
|
||||||
|
|
||||||
if (MIE_VECTOR_COUNT(builder->b_root->op_regions) == 0) {
|
|
||||||
region = mie_op_add_region(builder->b_root);
|
|
||||||
} else {
|
|
||||||
region = &builder->b_root->op_regions
|
|
||||||
.items[MIE_VECTOR_COUNT(builder->b_root->op_result) - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
struct mie_block *block = NULL;
|
|
||||||
|
|
||||||
if (MIE_VECTOR_COUNT(region->r_blocks) == 0) {
|
|
||||||
block = mie_region_add_block(region);
|
|
||||||
} else {
|
|
||||||
block = ®ion->r_blocks.items[MIE_VECTOR_COUNT(region->r_blocks)];
|
|
||||||
}
|
|
||||||
|
|
||||||
return block;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct mie_op *mie_builder_put_op(
|
struct mie_op *mie_builder_put_op(
|
||||||
struct mie_builder *builder, const char *dialect, const char *op_name,
|
struct mie_builder *builder, const char *dialect, const char *op_name,
|
||||||
struct mie_register **args, size_t nr_args)
|
struct mie_register **args, size_t nr_args)
|
||||||
@@ -147,7 +145,6 @@ struct mie_op *mie_builder_put_op(
|
|||||||
struct mie_op *op = mie_block_add_op(block);
|
struct mie_op *op = mie_block_add_op(block);
|
||||||
op->op_flags = MIE_OP_F_OP_RESOLVED;
|
op->op_flags = MIE_OP_F_OP_RESOLVED;
|
||||||
op->op_info = op_def;
|
op->op_info = op_def;
|
||||||
op->op_dialect = op_def->op_parent;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < nr_args; i++) {
|
for (size_t i = 0; i < nr_args; i++) {
|
||||||
struct mie_op_arg *arg = mie_op_add_arg(op);
|
struct mie_op_arg *arg = mie_op_add_arg(op);
|
||||||
@@ -163,9 +160,12 @@ struct mie_op *mie_builder_put_op(
|
|||||||
enum mie_status mie_builder_put_name(
|
enum mie_status mie_builder_put_name(
|
||||||
struct mie_builder *builder, struct mie_name *name, const char *hint)
|
struct mie_builder *builder, struct mie_name *name, const char *hint)
|
||||||
{
|
{
|
||||||
struct mie_block *block = mie_builder_get_current_block(builder);
|
struct mie_name_map *map = get_current_name_map(builder);
|
||||||
struct mie_region *scope = block->b_parent;
|
if (!map) {
|
||||||
return mie_name_map_put(scope->r_names, name, hint, 0)
|
return MIE_ERR_BAD_STATE;
|
||||||
? MIE_SUCCESS
|
}
|
||||||
: MIE_ERR_NAME_EXISTS;
|
|
||||||
|
struct mie_name *result = mie_name_map_put(map, name, hint, 0);
|
||||||
|
|
||||||
|
return result ? MIE_SUCCESS : MIE_ERR_NAME_EXISTS;
|
||||||
}
|
}
|
||||||
|
|||||||
42
mie/ir/emit.c
Normal file
42
mie/ir/emit.c
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
#include <mie/ir/emit.h>
|
||||||
|
|
||||||
|
struct mie_ctx *mie_emitter_get_ctx(struct mie_emitter *emitter)
|
||||||
|
{
|
||||||
|
if (emitter->e_get_ctx) {
|
||||||
|
return emitter->e_get_ctx(emitter);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum mie_status mie_emitter_put_name(
|
||||||
|
struct mie_emitter *emitter, struct mie_name *name, const char *hint)
|
||||||
|
{
|
||||||
|
if (emitter->e_put_name) {
|
||||||
|
return emitter->e_put_name(emitter, name, hint);
|
||||||
|
}
|
||||||
|
|
||||||
|
return MIE_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
if (emitter->e_put_op) {
|
||||||
|
return emitter->e_put_op(
|
||||||
|
emitter, dialect_name, op_name, args, nr_args);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_block *mie_emitter_put_block(
|
||||||
|
struct mie_emitter *emitter, struct mie_block *insert_point)
|
||||||
|
{
|
||||||
|
if (emitter->e_put_block) {
|
||||||
|
return emitter->e_put_block(emitter, insert_point);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
222
mie/ir/op.c
222
mie/ir/op.c
@@ -1,4 +1,10 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <mie/ctx.h>
|
||||||
|
#include <mie/diag/diag.h>
|
||||||
|
#include <mie/diag/highlight.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-definition.h>
|
||||||
#include <mie/ir/op.h>
|
#include <mie/ir/op.h>
|
||||||
#include <mie/ir/region.h>
|
#include <mie/ir/region.h>
|
||||||
@@ -64,6 +70,17 @@ void mie_op_cleanup(struct mie_op *op)
|
|||||||
/* TODO */
|
/* TODO */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t mie_op_get_name(const struct mie_op *op, char *out, size_t max)
|
||||||
|
{
|
||||||
|
if (!(op->op_flags & MIE_OP_F_OP_RESOLVED)) {
|
||||||
|
return snprintf(out, max, "%s", op->op_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return snprintf(
|
||||||
|
out, max, "%s.%s", op->op_info->op_parent->d_name,
|
||||||
|
op->op_info->op_name);
|
||||||
|
}
|
||||||
|
|
||||||
struct mie_op_arg *mie_op_add_arg(struct mie_op *op)
|
struct mie_op_arg *mie_op_add_arg(struct mie_op *op)
|
||||||
{
|
{
|
||||||
return mie_vector_emplace_back(op->op_args, &op_arg_vector_ops);
|
return mie_vector_emplace_back(op->op_args, &op_arg_vector_ops);
|
||||||
@@ -76,19 +93,82 @@ struct mie_register *mie_op_add_result(struct mie_op *op, const struct mie_type
|
|||||||
result->reg_flags = MIE_REGISTER_F_VIRTUAL | MIE_REGISTER_F_OP_RESULT;
|
result->reg_flags = MIE_REGISTER_F_VIRTUAL | MIE_REGISTER_F_OP_RESULT;
|
||||||
result->reg_type = ty;
|
result->reg_type = ty;
|
||||||
result->reg_op = op;
|
result->reg_op = op;
|
||||||
|
result->reg_block = op->op_container;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct mie_op_successor *mie_op_add_successor(
|
||||||
|
struct mie_op *op, struct mie_block *block, struct mie_register **args,
|
||||||
|
size_t nr_args)
|
||||||
|
{
|
||||||
|
struct mie_op_successor *s
|
||||||
|
= mie_vector_emplace_back(op->op_successors, NULL);
|
||||||
|
|
||||||
|
s->s_flags = MIE_OP_F_SUCCESSOR_RESOLVED;
|
||||||
|
s->s_block = block;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < nr_args; i++) {
|
||||||
|
struct mie_op_arg *arg
|
||||||
|
= mie_vector_emplace_back(s->s_args, &op_arg_vector_ops);
|
||||||
|
|
||||||
|
arg->arg_flags = MIE_OP_F_ARG_RESOLVED;
|
||||||
|
arg->arg_value.u_reg = args[i];
|
||||||
|
arg->arg_value.u_user = op;
|
||||||
|
b_queue_push_back(&args[i]->reg_use, &arg->arg_value.u_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_isolated(const struct mie_op *op)
|
||||||
|
{
|
||||||
|
if (!(op->op_flags & MIE_OP_F_OP_RESOLVED)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct mie_trait *isolated = mie_trait_table_get_unique(
|
||||||
|
&op->op_info->op_traits, "builtin", "isolated-from-above");
|
||||||
|
return isolated != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
struct mie_region *mie_op_add_region(struct mie_op *op)
|
struct mie_region *mie_op_add_region(struct mie_op *op)
|
||||||
{
|
{
|
||||||
struct mie_region *region = mie_vector_emplace_back(op->op_regions, NULL);
|
bool isolated = is_isolated(op);
|
||||||
region->r_names = mie_name_map_create(NULL);
|
|
||||||
|
struct mie_region *region = malloc(sizeof *region);
|
||||||
|
if (!region) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
region->r_parent = op;
|
region->r_parent = op;
|
||||||
|
|
||||||
|
if (isolated) {
|
||||||
|
region->r_names = mie_name_map_create(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
b_queue_push_back(&op->op_regions, ®ion->r_entry);
|
||||||
|
|
||||||
return region;
|
return region;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool mie_op_is(const struct mie_op *op, const char *dialect_name, const char *op_name)
|
||||||
|
{
|
||||||
|
if (!op->op_info || !op->op_info->op_parent) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(op->op_info->op_parent->d_name, dialect_name) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(op->op_info->op_name, op_name) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool mie_op_has_trait(
|
bool mie_op_has_trait(
|
||||||
const struct mie_op *op, const char *dialect_name, const char *trait_name)
|
const struct mie_op *op, const char *dialect_name, const char *trait_name)
|
||||||
{
|
{
|
||||||
@@ -119,3 +199,141 @@ bool mie_op_has_interface(
|
|||||||
&op->op_info->op_iface, dialect_name, iface_name);
|
&op->op_info->op_iface, dialect_name, iface_name);
|
||||||
return p != NULL;
|
return p != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct mie_region *mie_op_get_first_region(const struct mie_op *op)
|
||||||
|
{
|
||||||
|
b_queue_entry *entry = b_queue_first(&op->op_regions);
|
||||||
|
if (!entry) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return b_unbox(struct mie_region, entry, r_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_region *mie_op_get_prev_region(
|
||||||
|
const struct mie_op *op, const struct mie_region *before)
|
||||||
|
{
|
||||||
|
if (!before || before->r_parent != op) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
b_queue_entry *entry = b_queue_prev(&before->r_entry);
|
||||||
|
if (!entry) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return b_unbox(struct mie_region, entry, r_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_region *mie_op_get_next_region(
|
||||||
|
const struct mie_op *op, const struct mie_region *after)
|
||||||
|
{
|
||||||
|
if (!after || after->r_parent != op) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
b_queue_entry *entry = b_queue_next(&after->r_entry);
|
||||||
|
if (!entry) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return b_unbox(struct mie_region, entry, r_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_region *mie_op_get_last_region(const struct mie_op *op)
|
||||||
|
{
|
||||||
|
b_queue_entry *entry = b_queue_last(&op->op_regions);
|
||||||
|
if (!entry) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return b_unbox(struct mie_region, entry, r_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_register *mie_op_get_arg(const struct mie_op *op, size_t index)
|
||||||
|
{
|
||||||
|
if (MIE_VECTOR_COUNT(op->op_args) <= index) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct mie_op_arg *arg = &op->op_args.items[index];
|
||||||
|
if (!(arg->arg_flags & MIE_OP_F_ARG_RESOLVED)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return arg->arg_value.u_reg;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_register *mie_op_get_result_with_name(
|
||||||
|
const struct mie_op *op, const char *name)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_result); i++) {
|
||||||
|
if (!strcmp(op->op_result.items[i].reg_name.n_str, name)) {
|
||||||
|
return &op->op_result.items[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mie_op_get_args_span(const struct mie_op *op, struct mie_file_span *result)
|
||||||
|
{
|
||||||
|
memset(result, 0x0, sizeof *result);
|
||||||
|
|
||||||
|
size_t nr = MIE_VECTOR_COUNT(op->op_args);
|
||||||
|
if (!nr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct mie_op_arg *first = &op->op_args.items[0];
|
||||||
|
const struct mie_op_arg *last = &op->op_args.items[nr - 1];
|
||||||
|
|
||||||
|
result->s_start = first->arg_span.s_start;
|
||||||
|
result->s_end = last->arg_span.s_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mie_op_get_results_span(const struct mie_op *op, struct mie_file_span *result)
|
||||||
|
{
|
||||||
|
memset(result, 0x0, sizeof *result);
|
||||||
|
|
||||||
|
size_t nr = MIE_VECTOR_COUNT(op->op_result);
|
||||||
|
if (!nr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct mie_register *first = &op->op_result.items[0];
|
||||||
|
const struct mie_register *last = &op->op_result.items[nr - 1];
|
||||||
|
|
||||||
|
result->s_start = first->reg_span.s_start;
|
||||||
|
result->s_end = last->reg_span.s_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_op *mie_op_get_first_child_op(const struct mie_op *op)
|
||||||
|
{
|
||||||
|
struct mie_region *first_region = mie_op_get_first_region(op);
|
||||||
|
if (!first_region) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_block *first_block = mie_region_get_first_block(first_region);
|
||||||
|
if (!first_block) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mie_block_get_first_op(first_block);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_op *mie_op_get_last_child_op(const struct mie_op *op)
|
||||||
|
{
|
||||||
|
struct mie_region *last_region = mie_op_get_last_region(op);
|
||||||
|
if (!last_region) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_block *last_block = mie_region_get_last_block(last_region);
|
||||||
|
if (!last_block) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mie_block_get_last_op(last_block);
|
||||||
|
}
|
||||||
|
|||||||
140
mie/ir/region.c
140
mie/ir/region.c
@@ -1,18 +1,154 @@
|
|||||||
|
#include <limits.h>
|
||||||
|
#include <mie/ctx.h>
|
||||||
|
#include <mie/diag/diag.h>
|
||||||
|
#include <mie/dialect/builtin.h>
|
||||||
#include <mie/ir/block.h>
|
#include <mie/ir/block.h>
|
||||||
|
#include <mie/ir/op.h>
|
||||||
#include <mie/ir/region.h>
|
#include <mie/ir/region.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
struct mie_block *mie_region_get_first_block(const struct mie_region *region)
|
||||||
|
{
|
||||||
|
b_queue_entry *entry = b_queue_first(®ion->r_blocks);
|
||||||
|
if (!entry) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return b_unbox(struct mie_block, entry, b_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_block *mie_region_get_prev_block(
|
||||||
|
const struct mie_region *region, const struct mie_block *before)
|
||||||
|
{
|
||||||
|
if (!before || before->b_parent != region) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
b_queue_entry *entry = b_queue_prev(&before->b_entry);
|
||||||
|
if (!entry) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return b_unbox(struct mie_block, entry, b_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_block *mie_region_get_next_block(
|
||||||
|
const struct mie_region *region, const struct mie_block *after)
|
||||||
|
{
|
||||||
|
if (!after || after->b_parent != region) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
b_queue_entry *entry = b_queue_next(&after->b_entry);
|
||||||
|
if (!entry) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return b_unbox(struct mie_block, entry, b_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_block *mie_region_get_last_block(const struct mie_region *region)
|
||||||
|
{
|
||||||
|
b_queue_entry *entry = b_queue_last(®ion->r_blocks);
|
||||||
|
if (!entry) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return b_unbox(struct mie_block, entry, b_entry);
|
||||||
|
}
|
||||||
|
|
||||||
struct mie_block *mie_region_add_block(struct mie_region *region)
|
struct mie_block *mie_region_add_block(struct mie_region *region)
|
||||||
{
|
{
|
||||||
struct mie_block *block = mie_vector_emplace_back(
|
struct mie_block *block = malloc(sizeof *block);
|
||||||
region->r_blocks, &mie_block_vector_ops);
|
|
||||||
|
|
||||||
if (!block) {
|
if (!block) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memset(block, 0x0, sizeof *block);
|
||||||
block->b_parent = region;
|
block->b_parent = region;
|
||||||
|
block->b_id = MIE_BLOCK_ID_INVALID;
|
||||||
|
|
||||||
|
b_queue_push_back(®ion->r_blocks, &block->b_entry);
|
||||||
|
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct mie_block *mie_region_add_block_before(
|
||||||
|
struct mie_region *region, struct mie_block *before)
|
||||||
|
{
|
||||||
|
if (before->b_parent != region) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_block *block = malloc(sizeof *block);
|
||||||
|
|
||||||
|
if (!block) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(block, 0x0, sizeof *block);
|
||||||
|
block->b_parent = region;
|
||||||
|
|
||||||
|
b_queue_insert_before(®ion->r_blocks, &block->b_entry, &before->b_entry);
|
||||||
|
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_block *mie_region_add_block_after(
|
||||||
|
struct mie_region *region, struct mie_block *after)
|
||||||
|
{
|
||||||
|
if (after->b_parent != region) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_block *block = malloc(sizeof *block);
|
||||||
|
|
||||||
|
if (!block) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(block, 0x0, sizeof *block);
|
||||||
|
block->b_parent = region;
|
||||||
|
|
||||||
|
b_queue_insert_after(®ion->r_blocks, &block->b_entry, &after->b_entry);
|
||||||
|
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_block *mie_region_find_block(
|
||||||
|
const struct mie_region *region, const char *name)
|
||||||
|
{
|
||||||
|
b_queue_entry *cur = b_queue_first(®ion->r_blocks);
|
||||||
|
while (cur) {
|
||||||
|
struct mie_block *block = b_unbox(struct mie_block, cur, b_entry);
|
||||||
|
const char *block_name = block->b_name.n_str;
|
||||||
|
if (block_name && !strcmp(block_name, name)) {
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur = b_queue_next(cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_register *mie_region_find_register(
|
||||||
|
const struct mie_region *region, const char *name)
|
||||||
|
{
|
||||||
|
b_queue_entry *cur = b_queue_first(®ion->r_blocks);
|
||||||
|
|
||||||
|
while (cur) {
|
||||||
|
struct mie_block *block = b_unbox(struct mie_block, cur, b_entry);
|
||||||
|
struct mie_register *reg
|
||||||
|
= mie_block_find_register(block, name, NULL);
|
||||||
|
if (reg) {
|
||||||
|
return reg;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur = b_queue_next(cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|||||||
277
mie/ir/resolve.c
Normal file
277
mie/ir/resolve.c
Normal file
@@ -0,0 +1,277 @@
|
|||||||
|
#include <mie/ctx.h>
|
||||||
|
#include <mie/diag/diag.h>
|
||||||
|
#include <mie/diag/highlight.h>
|
||||||
|
#include <mie/dialect/builtin.h>
|
||||||
|
#include <mie/dialect/dialect.h>
|
||||||
|
#include <mie/ir/block.h>
|
||||||
|
#include <mie/ir/op.h>
|
||||||
|
#include <mie/ir/region.h>
|
||||||
|
#include <mie/ir/register.h>
|
||||||
|
|
||||||
|
enum register_find_result {
|
||||||
|
REG_FIND_NONE = 0,
|
||||||
|
REG_FIND_USE_BEFORE_DEFINE,
|
||||||
|
REG_FIND_UNDOMINATED,
|
||||||
|
REG_FIND_ISOLATED,
|
||||||
|
};
|
||||||
|
|
||||||
|
bool mie_resolve_op_self(struct mie_op *op, struct mie_ctx *ctx)
|
||||||
|
{
|
||||||
|
if (op->op_flags & MIE_OP_F_OP_RESOLVED) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *dialect_name = NULL, *op_name = NULL;
|
||||||
|
|
||||||
|
char *dot = strchr(op->op_name, '.');
|
||||||
|
if (dot) {
|
||||||
|
*dot = 0;
|
||||||
|
dialect_name = op->op_name;
|
||||||
|
op_name = dot + 1;
|
||||||
|
} else {
|
||||||
|
dialect_name = NULL;
|
||||||
|
op_name = op->op_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct mie_dialect *dialect = mie_ctx_get_dialect(ctx, dialect_name);
|
||||||
|
if (dot) {
|
||||||
|
*dot = '.';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* dialect_name is no longer valid after this point */
|
||||||
|
dialect_name = NULL;
|
||||||
|
|
||||||
|
if (!dialect) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct mie_op_definition *op_info
|
||||||
|
= mie_dialect_get_op(dialect, op_name);
|
||||||
|
if (!op_info) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
op->op_info = op_info;
|
||||||
|
|
||||||
|
free(op->op_name);
|
||||||
|
op->op_name = NULL;
|
||||||
|
|
||||||
|
op->op_flags |= MIE_OP_F_OP_RESOLVED;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum register_find_result find_register_wide(
|
||||||
|
struct mie_op *op, const char *name, struct mie_register **out)
|
||||||
|
{
|
||||||
|
struct mie_region *region = op->op_container->b_parent;
|
||||||
|
enum register_find_result result = REG_FIND_UNDOMINATED;
|
||||||
|
struct mie_register *reg = NULL;
|
||||||
|
|
||||||
|
while (region) {
|
||||||
|
reg = mie_region_find_register(region, name);
|
||||||
|
if (reg) {
|
||||||
|
*out = reg;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_op *op = region->r_parent;
|
||||||
|
if (mie_op_has_trait(op, "builtin", "isolated-from-above")) {
|
||||||
|
result = REG_FIND_ISOLATED;
|
||||||
|
}
|
||||||
|
|
||||||
|
region = op->op_container ? op->op_container->b_parent : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!reg) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reg->reg_block == op->op_container) {
|
||||||
|
return REG_FIND_USE_BEFORE_DEFINE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool resolve_arg(
|
||||||
|
struct mie_op *op, struct mie_op_arg *arg, struct mie_ctx *ctx)
|
||||||
|
{
|
||||||
|
const char *arg_name = arg->arg_unresolved.reg_name;
|
||||||
|
struct mie_block *block = op->op_container;
|
||||||
|
struct mie_op *search_start = op;
|
||||||
|
struct mie_register *reg = NULL;
|
||||||
|
bool cfg = (block->b_idom != NULL);
|
||||||
|
|
||||||
|
while (block) {
|
||||||
|
reg = mie_block_find_register(block, arg_name, search_start);
|
||||||
|
if (reg) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
search_start = NULL;
|
||||||
|
block = block->b_idom;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reg) {
|
||||||
|
free(arg->arg_unresolved.reg_name);
|
||||||
|
arg->arg_flags |= MIE_OP_F_ARG_RESOLVED;
|
||||||
|
|
||||||
|
memset(&arg->arg_value, 0x0, sizeof arg->arg_value);
|
||||||
|
arg->arg_value.u_reg = reg;
|
||||||
|
arg->arg_value.u_user = op;
|
||||||
|
b_queue_push_back(®->reg_use, &arg->arg_value.u_entry);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum register_find_result find_result
|
||||||
|
= find_register_wide(op, arg_name, ®);
|
||||||
|
|
||||||
|
if (!cfg && REG_FIND_UNDOMINATED) {
|
||||||
|
/* this isn't a cfg (yet), so ignore dominance-relaced resolution issues */
|
||||||
|
free(arg->arg_unresolved.reg_name);
|
||||||
|
arg->arg_flags |= MIE_OP_F_ARG_RESOLVED;
|
||||||
|
|
||||||
|
memset(&arg->arg_value, 0x0, sizeof arg->arg_value);
|
||||||
|
arg->arg_value.u_reg = reg;
|
||||||
|
arg->arg_value.u_user = op;
|
||||||
|
b_queue_push_back(®->reg_use, &arg->arg_value.u_entry);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_diag *diag = mie_ctx_push_diag(
|
||||||
|
ctx, op->op_src, &arg->arg_span.s_start, "builtin",
|
||||||
|
MIE_BUILTIN_E_UNRESOLVED_VALUE);
|
||||||
|
mie_diag_push_msg(diag, ctx, "builtin", MIE_BUILTIN_MSG_UNRESOLVED_VALUE);
|
||||||
|
|
||||||
|
struct mie_diag_highlight hl[] = {
|
||||||
|
{
|
||||||
|
.hl_type = MIE_DIAG_HIGHLIGHT_ERROR,
|
||||||
|
.hl_span = arg->arg_span,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
mie_diag_push_snippet(
|
||||||
|
diag, arg->arg_span.s_start.c_row, arg->arg_span.s_end.c_row,
|
||||||
|
NULL, 0, hl, 1);
|
||||||
|
|
||||||
|
if (!reg) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_block *reg_container = reg->reg_block;
|
||||||
|
|
||||||
|
switch (find_result) {
|
||||||
|
case REG_FIND_ISOLATED:
|
||||||
|
mie_diag_push_msg(
|
||||||
|
diag, ctx, "builtin",
|
||||||
|
MIE_BUILTIN_MSG_VALUE_DEFINED_OUTSIDE_ISOLATED_REGION);
|
||||||
|
break;
|
||||||
|
case REG_FIND_UNDOMINATED:
|
||||||
|
mie_diag_push_msg(
|
||||||
|
diag, ctx, "builtin",
|
||||||
|
MIE_BUILTIN_MSG_VALUE_DEFINED_IN_NON_DOMINANT_BLOCK);
|
||||||
|
break;
|
||||||
|
case REG_FIND_USE_BEFORE_DEFINE:
|
||||||
|
mie_diag_push_msg(
|
||||||
|
diag, ctx, "builtin",
|
||||||
|
MIE_BUILTIN_MSG_VALUE_DEFINED_AFTER_USE);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
hl[0].hl_type = MIE_DIAG_HIGHLIGHT_HINT;
|
||||||
|
hl[0].hl_span = reg->reg_span;
|
||||||
|
|
||||||
|
mie_diag_push_snippet(
|
||||||
|
diag, reg->reg_span.s_start.c_row, reg->reg_span.s_end.c_row,
|
||||||
|
NULL, 0, hl, 1);
|
||||||
|
|
||||||
|
if (!reg_container) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
hl[0].hl_span = reg_container->b_name.n_span;
|
||||||
|
|
||||||
|
mie_diag_push_snippet(
|
||||||
|
diag, reg_container->b_name.n_span.s_start.c_row,
|
||||||
|
reg_container->b_name.n_span.s_end.c_row, NULL, 0, hl, 1);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool resolve_successor(
|
||||||
|
struct mie_op *op, struct mie_op_successor *s, struct mie_ctx *ctx)
|
||||||
|
{
|
||||||
|
if (s->s_flags & MIE_OP_F_SUCCESSOR_RESOLVED) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_block *container = op->op_container;
|
||||||
|
struct mie_region *region = container ? container->b_parent : NULL;
|
||||||
|
if (!region) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_diag *diag = NULL;
|
||||||
|
struct mie_block *dest = mie_region_find_block(region, s->s_block_name);
|
||||||
|
if (!dest) {
|
||||||
|
diag = mie_ctx_push_diag(
|
||||||
|
ctx, op->op_src, &s->s_name_span.s_start, "builtin",
|
||||||
|
MIE_BUILTIN_E_UNRESOLVED_SUCCESSOR);
|
||||||
|
mie_diag_push_msg(
|
||||||
|
diag, ctx, "builtin", MIE_BUILTIN_MSG_CANNOT_FIND_BLOCK);
|
||||||
|
const struct mie_diag_highlight hl[] = {
|
||||||
|
{
|
||||||
|
.hl_type = MIE_DIAG_HIGHLIGHT_ERROR,
|
||||||
|
.hl_span = s->s_name_span,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
mie_diag_push_snippet(
|
||||||
|
diag, s->s_name_span.s_start.c_row,
|
||||||
|
s->s_name_span.s_end.c_row, NULL, 0, hl, 1);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(s->s_block_name);
|
||||||
|
s->s_block = dest;
|
||||||
|
s->s_flags |= MIE_OP_F_SUCCESSOR_RESOLVED;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mie_resolve_op_args(struct mie_op *op, struct mie_ctx *ctx)
|
||||||
|
{
|
||||||
|
bool ok = true;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_args); i++) {
|
||||||
|
if (!resolve_arg(op, &op->op_args.items[i], ctx)) {
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_successors); i++) {
|
||||||
|
struct mie_op_successor *s = &op->op_successors.items[i];
|
||||||
|
for (size_t k = 0; k < MIE_VECTOR_COUNT(s->s_args); k++) {
|
||||||
|
if (!resolve_arg(op, &s->s_args.items[k], ctx)) {
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mie_resolve_op_successors(struct mie_op *op, struct mie_ctx *ctx)
|
||||||
|
{
|
||||||
|
bool ok = true;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_successors); i++) {
|
||||||
|
if (!resolve_successor(op, &op->op_successors.items[i], ctx)) {
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
1036
mie/ir/walk.c
1036
mie/ir/walk.c
File diff suppressed because it is too large
Load Diff
254
mie/lt-idom.c
Normal file
254
mie/lt-idom.c
Normal file
@@ -0,0 +1,254 @@
|
|||||||
|
#include <mie/ir/block.h>
|
||||||
|
#include <mie/ir/op.h>
|
||||||
|
#include <mie/ir/region.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
struct set {
|
||||||
|
MIE_VECTOR_DECLARE(unsigned int, v);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dfs_stack_item {
|
||||||
|
struct mie_block *i_parent, *i_node;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct lt_ctx {
|
||||||
|
size_t nr_nodes;
|
||||||
|
struct mie_block **vertex;
|
||||||
|
struct set *bucket;
|
||||||
|
unsigned int *semi;
|
||||||
|
unsigned int *idom;
|
||||||
|
unsigned int *samedom;
|
||||||
|
unsigned int *parent;
|
||||||
|
unsigned int *ancestor;
|
||||||
|
unsigned int *label;
|
||||||
|
|
||||||
|
MIE_VECTOR_DECLARE(struct dfs_stack_item, dfstack);
|
||||||
|
};
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
static B_BTREE_DEFINE_SIMPLE_INSERT(struct mie_block, b_node, b_id, put_block_by_id);
|
||||||
|
static B_BTREE_DEFINE_SIMPLE_GET(
|
||||||
|
struct mie_block, size_t, b_node, b_id, get_block_by_id);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void set_add(struct set *set, unsigned int val)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < MIE_VECTOR_COUNT(set->v); i++) {
|
||||||
|
if (set->v.items[i] == val) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mie_vector_push_back(set->v, &val, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct mie_block *pop_block_successor(
|
||||||
|
MIE_VECTOR_REF_PARAM(struct mie_block *, successors))
|
||||||
|
{
|
||||||
|
size_t count = mie_vector_ref_get_count(successors);
|
||||||
|
if (count == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_block *out = mie_vector_ref_get_item(successors, count - 1);
|
||||||
|
mie_vector_ref_pop_back(successors, NULL);
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void enqueue_block_successors(
|
||||||
|
struct mie_block *block,
|
||||||
|
MIE_VECTOR_REF_PARAM(struct mie_block *, successors))
|
||||||
|
{
|
||||||
|
struct mie_op_successor *s = mie_block_get_first_successor(block);
|
||||||
|
struct mie_block_predecessor pred = {.p_block = block};
|
||||||
|
|
||||||
|
while (s) {
|
||||||
|
if (s->s_flags & MIE_OP_F_SUCCESSOR_RESOLVED) {
|
||||||
|
mie_vector_ref_push_back(successors, &s->s_block, NULL);
|
||||||
|
mie_vector_push_back(s->s_block->b_ipred, &pred, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
s = mie_block_get_next_successor(block, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dfs_stack_pop(
|
||||||
|
struct lt_ctx *ctx, struct mie_block **parent, struct mie_block **node)
|
||||||
|
{
|
||||||
|
size_t nr = MIE_VECTOR_COUNT(ctx->dfstack);
|
||||||
|
if (!nr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct dfs_stack_item *item = &ctx->dfstack.items[nr - 1];
|
||||||
|
*parent = item->i_parent;
|
||||||
|
*node = item->i_node;
|
||||||
|
mie_vector_pop_back(ctx->dfstack, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dfs_stack_push(
|
||||||
|
struct lt_ctx *ctx, struct mie_block *parent, struct mie_block *node)
|
||||||
|
{
|
||||||
|
struct dfs_stack_item item = {.i_node = node, .i_parent = parent};
|
||||||
|
mie_vector_push_back(ctx->dfstack, &item, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dfs(struct lt_ctx *ctx, struct mie_block *root)
|
||||||
|
{
|
||||||
|
dfs_stack_push(ctx, NULL, root);
|
||||||
|
unsigned int id = 1;
|
||||||
|
|
||||||
|
while (MIE_VECTOR_COUNT(ctx->dfstack) > 0) {
|
||||||
|
struct mie_block *p, *n;
|
||||||
|
dfs_stack_pop(ctx, &p, &n);
|
||||||
|
|
||||||
|
if (n->b_id != MIE_BLOCK_ID_INVALID) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
printf("dfs(p=%s, n=%s)\n", p ? p->b_name.n_str : "NA",
|
||||||
|
n->b_name.n_str);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
n->b_id = id++;
|
||||||
|
ctx->vertex[n->b_id] = n;
|
||||||
|
ctx->semi[n->b_id] = n->b_id;
|
||||||
|
ctx->parent[n->b_id] = p ? p->b_id : MIE_BLOCK_ID_INVALID;
|
||||||
|
|
||||||
|
struct mie_op_successor *s = mie_block_get_first_successor(n);
|
||||||
|
while (s) {
|
||||||
|
dfs_stack_push(ctx, n, s->s_block);
|
||||||
|
mie_vector_push_back(s->s_block->b_ipred, &n, NULL);
|
||||||
|
s = mie_block_get_next_successor(n, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void link(struct lt_ctx *ctx, unsigned int parent, unsigned int node)
|
||||||
|
{
|
||||||
|
ctx->ancestor[node] = parent;
|
||||||
|
ctx->label[node] = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int eval(struct lt_ctx *ctx, unsigned int v)
|
||||||
|
{
|
||||||
|
unsigned int a = ctx->ancestor[v];
|
||||||
|
if (ctx->ancestor[a] > MIE_BLOCK_ID_INVALID) {
|
||||||
|
unsigned int b = eval(ctx, a);
|
||||||
|
ctx->ancestor[v] = ctx->ancestor[a];
|
||||||
|
if (ctx->semi[b] < ctx->semi[ctx->label[v]]) {
|
||||||
|
ctx->label[v] = b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctx->label[v];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void reset_block_relationship_metadata(struct mie_region *region)
|
||||||
|
{
|
||||||
|
b_queue_entry *cur = b_queue_first(®ion->r_blocks);
|
||||||
|
while (cur) {
|
||||||
|
struct mie_block *block = b_unbox(struct mie_block, cur, b_entry);
|
||||||
|
|
||||||
|
block->b_id = MIE_BLOCK_ID_INVALID;
|
||||||
|
block->b_idom = NULL;
|
||||||
|
// block->b_sdom = block->b_dfs_parent = NULL;
|
||||||
|
mie_vector_destroy(block->b_ipred, NULL);
|
||||||
|
|
||||||
|
cur = b_queue_next(cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(®ion->r_blocks_s, 0x0, sizeof region->r_blocks_s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lt_ctx_init(struct lt_ctx *ctx, size_t nr_nodes)
|
||||||
|
{
|
||||||
|
memset(ctx, 0x0, sizeof *ctx);
|
||||||
|
ctx->idom = calloc(nr_nodes + 1, sizeof(unsigned int));
|
||||||
|
ctx->samedom = calloc(nr_nodes + 1, sizeof(unsigned int));
|
||||||
|
ctx->vertex = calloc(nr_nodes + 1, sizeof(struct mie_block *));
|
||||||
|
ctx->bucket = calloc(nr_nodes + 1, sizeof(struct set));
|
||||||
|
ctx->semi = calloc(nr_nodes + 1, sizeof(unsigned int));
|
||||||
|
ctx->parent = calloc(nr_nodes + 1, sizeof(unsigned int));
|
||||||
|
ctx->ancestor = calloc(nr_nodes + 1, sizeof(unsigned int));
|
||||||
|
ctx->label = calloc(nr_nodes + 1, sizeof(unsigned int));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lt_ctx_cleanup(struct lt_ctx *ctx)
|
||||||
|
{
|
||||||
|
free(ctx->idom);
|
||||||
|
free(ctx->samedom);
|
||||||
|
free(ctx->vertex);
|
||||||
|
free(ctx->bucket);
|
||||||
|
free(ctx->semi);
|
||||||
|
free(ctx->parent);
|
||||||
|
free(ctx->ancestor);
|
||||||
|
free(ctx->label);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mie_region_refresh_dominance(struct mie_region *region)
|
||||||
|
{
|
||||||
|
struct lt_ctx ctx;
|
||||||
|
size_t nr_nodes = b_queue_length(®ion->r_blocks);
|
||||||
|
lt_ctx_init(&ctx, nr_nodes);
|
||||||
|
|
||||||
|
struct mie_block *root = mie_region_get_first_block(region);
|
||||||
|
|
||||||
|
reset_block_relationship_metadata(region);
|
||||||
|
dfs(&ctx, root);
|
||||||
|
|
||||||
|
for (size_t i = nr_nodes; i > 0; i--) {
|
||||||
|
struct mie_block *n = ctx.vertex[i];
|
||||||
|
unsigned int p = ctx.parent[i];
|
||||||
|
unsigned int s = p;
|
||||||
|
|
||||||
|
struct mie_block_predecessor *pred
|
||||||
|
= mie_block_get_first_predecessor(n);
|
||||||
|
while (pred) {
|
||||||
|
struct mie_block *v = pred->p_block;
|
||||||
|
unsigned int s_prime = MIE_BLOCK_ID_INVALID;
|
||||||
|
|
||||||
|
if (v->b_id <= n->b_id) {
|
||||||
|
s_prime = v->b_id;
|
||||||
|
} else {
|
||||||
|
s_prime = eval(&ctx, v->b_id);
|
||||||
|
s_prime = ctx.semi[s_prime];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s_prime < s) {
|
||||||
|
s = s_prime;
|
||||||
|
}
|
||||||
|
|
||||||
|
pred = mie_block_get_next_predecessor(n, pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.semi[n->b_id] = s;
|
||||||
|
set_add(&ctx.bucket[s], n->b_id);
|
||||||
|
link(&ctx, p, n->b_id);
|
||||||
|
|
||||||
|
for (size_t k = 0; k < MIE_VECTOR_COUNT(ctx.bucket[p].v); k++) {
|
||||||
|
unsigned int v = ctx.bucket[p].v.items[k];
|
||||||
|
unsigned int y = eval(&ctx, v);
|
||||||
|
if (ctx.semi[y] == ctx.semi[p]) {
|
||||||
|
ctx.idom[v] = p;
|
||||||
|
} else {
|
||||||
|
ctx.samedom[v] = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 1; i <= nr_nodes; i++) {
|
||||||
|
struct mie_block *n = ctx.vertex[i];
|
||||||
|
if (ctx.samedom[i] > 0) {
|
||||||
|
ctx.idom[i] = ctx.idom[ctx.samedom[i]];
|
||||||
|
}
|
||||||
|
|
||||||
|
n->b_idom = ctx.vertex[ctx.idom[i]];
|
||||||
|
// n->b_sdom = ctx.vertex[ctx.semi[i]];
|
||||||
|
// n->b_dfs_parent = ctx.vertex[ctx.parent[i]];
|
||||||
|
}
|
||||||
|
|
||||||
|
lt_ctx_cleanup(&ctx);
|
||||||
|
}
|
||||||
@@ -305,6 +305,10 @@ void mie_name_move(struct mie_name *dst, struct mie_name *src)
|
|||||||
void mie_name_destroy(struct mie_name *name)
|
void mie_name_destroy(struct mie_name *name)
|
||||||
{
|
{
|
||||||
struct mie_name_map *parent = name->n_parent;
|
struct mie_name_map *parent = name->n_parent;
|
||||||
|
if (!parent) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
struct mie_name_map_entry *entry
|
struct mie_name_map_entry *entry
|
||||||
= get_entry(&parent->m_entries, name->n_base.e_hash);
|
= get_entry(&parent->m_entries, name->n_base.e_hash);
|
||||||
struct mie_name_bucket *bucket = NULL;
|
struct mie_name_bucket *bucket = NULL;
|
||||||
|
|||||||
211
mie/parse/lex.c
211
mie/parse/lex.c
@@ -7,6 +7,10 @@
|
|||||||
#include <blue/ds/number.h>
|
#include <blue/ds/number.h>
|
||||||
#include <blue/ds/string.h>
|
#include <blue/ds/string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <mie/ctx.h>
|
||||||
|
#include <mie/diag/diag.h>
|
||||||
|
#include <mie/diag/highlight.h>
|
||||||
|
#include <mie/dialect/builtin.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -36,6 +40,7 @@ static struct lex_token_def symbols[] = {
|
|||||||
LEX_TOKEN_DEF(MIE_SYM_HASH, "#"),
|
LEX_TOKEN_DEF(MIE_SYM_HASH, "#"),
|
||||||
LEX_TOKEN_DEF(MIE_SYM_ATSIGN, "@"),
|
LEX_TOKEN_DEF(MIE_SYM_ATSIGN, "@"),
|
||||||
LEX_TOKEN_DEF(MIE_SYM_BANG, "!"),
|
LEX_TOKEN_DEF(MIE_SYM_BANG, "!"),
|
||||||
|
LEX_TOKEN_DEF(MIE_SYM_QUESTION, "?"),
|
||||||
LEX_TOKEN_DEF(MIE_SYM_TILDE, "~"),
|
LEX_TOKEN_DEF(MIE_SYM_TILDE, "~"),
|
||||||
LEX_TOKEN_DEF(MIE_SYM_LEFT_BRACE, "{"),
|
LEX_TOKEN_DEF(MIE_SYM_LEFT_BRACE, "{"),
|
||||||
LEX_TOKEN_DEF(MIE_SYM_RIGHT_BRACE, "}"),
|
LEX_TOKEN_DEF(MIE_SYM_RIGHT_BRACE, "}"),
|
||||||
@@ -66,6 +71,14 @@ static struct mie_lex_symbol_node *get_symbol_node(
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct mie_diag *push_diag(struct mie_lex *lex, unsigned long diag_class)
|
||||||
|
{
|
||||||
|
return mie_ctx_push_diag(
|
||||||
|
lex->lex_ctx, lex->lex_source,
|
||||||
|
mie_line_source_get_cursor(lex->lex_source), "builtin",
|
||||||
|
diag_class);
|
||||||
|
}
|
||||||
|
|
||||||
static b_string *get_temp_string(struct mie_lex *lex)
|
static b_string *get_temp_string(struct mie_lex *lex)
|
||||||
{
|
{
|
||||||
if (!lex->lex_temp) {
|
if (!lex->lex_temp) {
|
||||||
@@ -145,7 +158,7 @@ static struct mie_lex_symbol_node *build_symbol_tree(void)
|
|||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mie_lex *mie_lex_create(b_stream *src)
|
struct mie_lex *mie_lex_create(struct mie_line_source *src, struct mie_ctx *ctx)
|
||||||
{
|
{
|
||||||
struct mie_lex *lex = malloc(sizeof *lex);
|
struct mie_lex *lex = malloc(sizeof *lex);
|
||||||
if (!lex) {
|
if (!lex) {
|
||||||
@@ -154,11 +167,10 @@ struct mie_lex *mie_lex_create(b_stream *src)
|
|||||||
|
|
||||||
memset(lex, 0x0, sizeof *lex);
|
memset(lex, 0x0, sizeof *lex);
|
||||||
|
|
||||||
lex->lex_cursor_row = lex->lex_cursor_col = 1;
|
lex->lex_ctx = ctx;
|
||||||
|
|
||||||
lex->lex_status = MIE_SUCCESS;
|
lex->lex_status = MIE_SUCCESS;
|
||||||
lex->lex_source = src;
|
lex->lex_source = src;
|
||||||
lex->lex_linebuf = b_string_create();
|
|
||||||
|
|
||||||
lex->lex_sym_tree = build_symbol_tree();
|
lex->lex_sym_tree = build_symbol_tree();
|
||||||
if (!lex->lex_sym_tree) {
|
if (!lex->lex_sym_tree) {
|
||||||
@@ -184,10 +196,6 @@ void mie_lex_destroy(struct mie_lex *lex)
|
|||||||
entry = next;
|
entry = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lex->lex_linebuf) {
|
|
||||||
free(lex->lex_linebuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lex->lex_sym_tree) {
|
if (lex->lex_sym_tree) {
|
||||||
destroy_symbol_tree(lex->lex_sym_tree);
|
destroy_symbol_tree(lex->lex_sym_tree);
|
||||||
}
|
}
|
||||||
@@ -204,87 +212,14 @@ enum mie_status mie_lex_get_status(const struct mie_lex *lex)
|
|||||||
return lex->lex_status;
|
return lex->lex_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum mie_status refill_linebuf(struct mie_lex *lex)
|
struct mie_line_source *mie_lex_get_line_source(const struct mie_lex *lex)
|
||||||
{
|
{
|
||||||
if (!lex->lex_source) {
|
return lex->lex_source;
|
||||||
return MIE_ERR_EOF;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lex->lex_linebuf_ptr) {
|
|
||||||
b_iterator_unref(lex->lex_linebuf_ptr);
|
|
||||||
lex->lex_linebuf_ptr = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
b_stringstream *s = b_stringstream_create();
|
|
||||||
|
|
||||||
b_status status = b_stream_read_line_s(lex->lex_source, s);
|
|
||||||
|
|
||||||
if (status == B_ERR_NO_DATA) {
|
|
||||||
return MIE_ERR_EOF;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!B_OK(status)) {
|
|
||||||
return MIE_ERR_INTERNAL_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
b_string_replace_all_with_stringstream(lex->lex_linebuf, s);
|
|
||||||
b_stringstream_unref(s);
|
|
||||||
|
|
||||||
lex->lex_linebuf_ptr = b_iterator_begin(lex->lex_linebuf);
|
|
||||||
|
|
||||||
return MIE_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int peek(struct mie_lex *lex)
|
const struct mie_file_cell *mie_lex_get_cursor(const struct mie_lex *lex)
|
||||||
{
|
{
|
||||||
enum mie_status status = MIE_SUCCESS;
|
return &lex->lex_source->s_cursor;
|
||||||
|
|
||||||
if (!lex->lex_linebuf_ptr || !b_iterator_is_valid(lex->lex_linebuf_ptr)) {
|
|
||||||
status = refill_linebuf(lex);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status != MIE_SUCCESS) {
|
|
||||||
return -status;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (b_string_get_size(lex->lex_linebuf, B_STRLEN_NORMAL) == 0) {
|
|
||||||
return -MIE_ERR_EOF;
|
|
||||||
}
|
|
||||||
|
|
||||||
b_wchar c = b_iterator_get_value(lex->lex_linebuf_ptr).v_int;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int advance(struct mie_lex *lex)
|
|
||||||
{
|
|
||||||
enum mie_status status = MIE_SUCCESS;
|
|
||||||
|
|
||||||
if (!b_iterator_is_valid(lex->lex_linebuf_ptr)) {
|
|
||||||
status = refill_linebuf(lex);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status != MIE_SUCCESS) {
|
|
||||||
return -status;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (b_string_get_size(lex->lex_linebuf, B_STRLEN_NORMAL) == 0) {
|
|
||||||
return -MIE_ERR_EOF;
|
|
||||||
}
|
|
||||||
|
|
||||||
b_wchar c = b_iterator_get_value(lex->lex_linebuf_ptr).v_int;
|
|
||||||
b_iterator_move_next(lex->lex_linebuf_ptr);
|
|
||||||
|
|
||||||
lex->lex_cursor_col++;
|
|
||||||
if (c == '\n') {
|
|
||||||
lex->lex_cursor_col = 1;
|
|
||||||
lex->lex_cursor_row++;
|
|
||||||
}
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool input_available(struct mie_lex *lex)
|
|
||||||
{
|
|
||||||
return lex->lex_linebuf_ptr && b_iterator_is_valid(lex->lex_linebuf_ptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool char_can_begin_symbol(char c)
|
static bool char_can_begin_symbol(char c)
|
||||||
@@ -313,22 +248,18 @@ static struct mie_token *create_token(enum mie_token_type type)
|
|||||||
|
|
||||||
static void set_token_start(struct mie_lex *lex)
|
static void set_token_start(struct mie_lex *lex)
|
||||||
{
|
{
|
||||||
lex->lex_token_start_row = lex->lex_cursor_row;
|
lex->lex_token_start = *mie_line_source_get_cursor(lex->lex_source);
|
||||||
lex->lex_token_start_col = lex->lex_cursor_col;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_token_end(struct mie_lex *lex)
|
static void set_token_end(struct mie_lex *lex)
|
||||||
{
|
{
|
||||||
lex->lex_token_end_row = lex->lex_cursor_row;
|
lex->lex_token_end = *mie_line_source_get_cursor(lex->lex_source);
|
||||||
lex->lex_token_end_col = lex->lex_cursor_col;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum mie_status push_token(struct mie_lex *lex, struct mie_token *tok)
|
static enum mie_status push_token(struct mie_lex *lex, struct mie_token *tok)
|
||||||
{
|
{
|
||||||
tok->tok_location.s_start.c_row = lex->lex_token_start_row;
|
tok->tok_location.s_start = lex->lex_token_start;
|
||||||
tok->tok_location.s_start.c_col = lex->lex_token_start_col;
|
tok->tok_location.s_end = lex->lex_token_end;
|
||||||
tok->tok_location.s_end.c_row = lex->lex_token_end_row;
|
|
||||||
tok->tok_location.s_end.c_col = lex->lex_token_end_col;
|
|
||||||
|
|
||||||
b_queue_push_back(&lex->lex_queue, &tok->tok_entry);
|
b_queue_push_back(&lex->lex_queue, &tok->tok_entry);
|
||||||
return MIE_SUCCESS;
|
return MIE_SUCCESS;
|
||||||
@@ -423,7 +354,7 @@ static enum mie_status push_float(struct mie_lex *lex, double v)
|
|||||||
static enum mie_status read_line_comment(struct mie_lex *lex)
|
static enum mie_status read_line_comment(struct mie_lex *lex)
|
||||||
{
|
{
|
||||||
while (true) {
|
while (true) {
|
||||||
b_wchar c = advance(lex);
|
b_wchar c = mie_line_source_getc(lex->lex_source);
|
||||||
|
|
||||||
if (c == -MIE_ERR_EOF || c == '\n') {
|
if (c == -MIE_ERR_EOF || c == '\n') {
|
||||||
break;
|
break;
|
||||||
@@ -449,7 +380,7 @@ static enum mie_status read_number(struct mie_lex *lex, bool negate)
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
b_wchar c = peek(lex);
|
b_wchar c = mie_line_source_peekc(lex->lex_source);
|
||||||
if (c == -MIE_ERR_EOF) {
|
if (c == -MIE_ERR_EOF) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -461,7 +392,7 @@ static enum mie_status read_number(struct mie_lex *lex, bool negate)
|
|||||||
if (c == '_') {
|
if (c == '_') {
|
||||||
token_len++;
|
token_len++;
|
||||||
set_token_end(lex);
|
set_token_end(lex);
|
||||||
advance(lex);
|
mie_line_source_getc(lex->lex_source);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -479,7 +410,7 @@ static enum mie_status read_number(struct mie_lex *lex, bool negate)
|
|||||||
char s[] = {c, 0};
|
char s[] = {c, 0};
|
||||||
b_string_append_cstr(str, s);
|
b_string_append_cstr(str, s);
|
||||||
set_token_end(lex);
|
set_token_end(lex);
|
||||||
advance(lex);
|
mie_line_source_getc(lex->lex_source);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -491,7 +422,7 @@ static enum mie_status read_number(struct mie_lex *lex, bool negate)
|
|||||||
base = 16;
|
base = 16;
|
||||||
token_len++;
|
token_len++;
|
||||||
set_token_end(lex);
|
set_token_end(lex);
|
||||||
advance(lex);
|
mie_line_source_getc(lex->lex_source);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -499,7 +430,7 @@ static enum mie_status read_number(struct mie_lex *lex, bool negate)
|
|||||||
base = 2;
|
base = 2;
|
||||||
token_len++;
|
token_len++;
|
||||||
set_token_end(lex);
|
set_token_end(lex);
|
||||||
advance(lex);
|
mie_line_source_getc(lex->lex_source);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -517,7 +448,7 @@ static enum mie_status read_number(struct mie_lex *lex, bool negate)
|
|||||||
|
|
||||||
b_string_append_wc(str, c);
|
b_string_append_wc(str, c);
|
||||||
set_token_end(lex);
|
set_token_end(lex);
|
||||||
advance(lex);
|
mie_line_source_getc(lex->lex_source);
|
||||||
token_len++;
|
token_len++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -569,7 +500,7 @@ static enum mie_status read_ident(struct mie_lex *lex, enum mie_token_type type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
b_wchar c = peek(lex);
|
b_wchar c = mie_line_source_peekc(lex->lex_source);
|
||||||
|
|
||||||
if ((c == '.' || c == '-') && prev == c) {
|
if ((c == '.' || c == '-') && prev == c) {
|
||||||
return MIE_ERR_BAD_SYNTAX;
|
return MIE_ERR_BAD_SYNTAX;
|
||||||
@@ -586,7 +517,7 @@ static enum mie_status read_ident(struct mie_lex *lex, enum mie_token_type type)
|
|||||||
prev = c;
|
prev = c;
|
||||||
b_string_append_wc(str, c);
|
b_string_append_wc(str, c);
|
||||||
set_token_end(lex);
|
set_token_end(lex);
|
||||||
advance(lex);
|
mie_line_source_getc(lex->lex_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == MIE_TOK_NONE) {
|
if (type == MIE_TOK_NONE) {
|
||||||
@@ -601,6 +532,7 @@ static enum mie_status read_ident(struct mie_lex *lex, enum mie_token_type type)
|
|||||||
return push_string_token(lex, type, s);
|
return push_string_token(lex, type, s);
|
||||||
} else {
|
} else {
|
||||||
push_symbol(lex, MIE_SYM_ASTERISK);
|
push_symbol(lex, MIE_SYM_ASTERISK);
|
||||||
|
lex->lex_token_start.c_col++;
|
||||||
return push_string_token(lex, MIE_TOK_WORD, s);
|
return push_string_token(lex, MIE_TOK_WORD, s);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -613,17 +545,17 @@ static enum mie_status read_string(struct mie_lex *lex)
|
|||||||
{
|
{
|
||||||
b_string *str = get_temp_string(lex);
|
b_string *str = get_temp_string(lex);
|
||||||
|
|
||||||
b_wchar c = peek(lex);
|
b_wchar c = mie_line_source_peekc(lex->lex_source);
|
||||||
bool esc = false;
|
bool esc = false;
|
||||||
|
|
||||||
if (c != '"') {
|
if (c != '"') {
|
||||||
return MIE_ERR_BAD_SYNTAX;
|
return MIE_ERR_BAD_SYNTAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
advance(lex);
|
mie_line_source_getc(lex->lex_source);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
b_wchar c = peek(lex);
|
b_wchar c = mie_line_source_peekc(lex->lex_source);
|
||||||
|
|
||||||
if (esc) {
|
if (esc) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
@@ -636,23 +568,23 @@ static enum mie_status read_string(struct mie_lex *lex)
|
|||||||
}
|
}
|
||||||
|
|
||||||
esc = false;
|
esc = false;
|
||||||
advance(lex);
|
mie_line_source_getc(lex->lex_source);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c == '\\') {
|
if (c == '\\') {
|
||||||
esc = true;
|
esc = true;
|
||||||
advance(lex);
|
mie_line_source_getc(lex->lex_source);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c == '"') {
|
if (c == '"') {
|
||||||
advance(lex);
|
mie_line_source_getc(lex->lex_source);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
b_string_append_wc(str, c);
|
b_string_append_wc(str, c);
|
||||||
advance(lex);
|
mie_line_source_getc(lex->lex_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *s = b_string_steal(str);
|
char *s = b_string_steal(str);
|
||||||
@@ -666,7 +598,7 @@ static enum mie_status read_symbol(struct mie_lex *lex)
|
|||||||
b_wchar prev = 0;
|
b_wchar prev = 0;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
b_wchar c = peek(lex);
|
b_wchar c = mie_line_source_peekc(lex->lex_source);
|
||||||
if (c < 0) {
|
if (c < 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -679,11 +611,12 @@ static enum mie_status read_symbol(struct mie_lex *lex)
|
|||||||
|
|
||||||
node = next;
|
node = next;
|
||||||
set_token_end(lex);
|
set_token_end(lex);
|
||||||
advance(lex);
|
mie_line_source_getc(lex->lex_source);
|
||||||
prev = c;
|
prev = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!node || node->s_def == NULL) {
|
if (!node || node->s_def == NULL) {
|
||||||
|
push_diag(lex, MIE_BUILTIN_E_UNRECOGNISED_TOKEN);
|
||||||
return MIE_ERR_BAD_SYNTAX;
|
return MIE_ERR_BAD_SYNTAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -734,11 +667,11 @@ static enum mie_status read_symbol(struct mie_lex *lex)
|
|||||||
|
|
||||||
static void skip_whitespace(struct mie_lex *lex)
|
static void skip_whitespace(struct mie_lex *lex)
|
||||||
{
|
{
|
||||||
b_wchar c = peek(lex);
|
b_wchar c = mie_line_source_peekc(lex->lex_source);
|
||||||
|
|
||||||
while (b_wchar_is_space(c)) {
|
while (b_wchar_is_space(c)) {
|
||||||
advance(lex);
|
mie_line_source_getc(lex->lex_source);
|
||||||
c = peek(lex);
|
c = mie_line_source_peekc(lex->lex_source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -755,34 +688,34 @@ static bool should_skip(b_wchar c, bool skip_linefeeds)
|
|||||||
|
|
||||||
static void skip_ignored_chars(struct mie_lex *lex, bool include_linefeeds)
|
static void skip_ignored_chars(struct mie_lex *lex, bool include_linefeeds)
|
||||||
{
|
{
|
||||||
b_wchar c = peek(lex);
|
b_wchar c = mie_line_source_peekc(lex->lex_source);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
while (should_skip(c, include_linefeeds)) {
|
while (should_skip(c, include_linefeeds)) {
|
||||||
advance(lex);
|
mie_line_source_getc(lex->lex_source);
|
||||||
c = peek(lex);
|
c = mie_line_source_peekc(lex->lex_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c != ';') {
|
if (c != ';') {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
advance(lex);
|
mie_line_source_getc(lex->lex_source);
|
||||||
c = peek(lex);
|
c = mie_line_source_peekc(lex->lex_source);
|
||||||
|
|
||||||
while (c != '\n') {
|
while (c != '\n') {
|
||||||
advance(lex);
|
mie_line_source_getc(lex->lex_source);
|
||||||
c = peek(lex);
|
c = mie_line_source_peekc(lex->lex_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
advance(lex);
|
mie_line_source_getc(lex->lex_source);
|
||||||
c = peek(lex);
|
c = mie_line_source_peekc(lex->lex_source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum mie_status pump_tokens(struct mie_lex *lex)
|
static enum mie_status pump_tokens(struct mie_lex *lex)
|
||||||
{
|
{
|
||||||
b_wchar c = peek(lex);
|
b_wchar c = mie_line_source_peekc(lex->lex_source);
|
||||||
|
|
||||||
if (c < 0) {
|
if (c < 0) {
|
||||||
return -c;
|
return -c;
|
||||||
@@ -795,13 +728,13 @@ static enum mie_status pump_tokens(struct mie_lex *lex)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
c = peek(lex);
|
c = mie_line_source_peekc(lex->lex_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c == '\\') {
|
if (c == '\\') {
|
||||||
advance(lex);
|
mie_line_source_getc(lex->lex_source);
|
||||||
skip_ignored_chars(lex, true);
|
skip_ignored_chars(lex, true);
|
||||||
c = peek(lex);
|
c = mie_line_source_peekc(lex->lex_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c == '\n') {
|
if (c == '\n') {
|
||||||
@@ -809,13 +742,13 @@ static enum mie_status pump_tokens(struct mie_lex *lex)
|
|||||||
set_token_end(lex);
|
set_token_end(lex);
|
||||||
|
|
||||||
while (c == '\n') {
|
while (c == '\n') {
|
||||||
advance(lex);
|
mie_line_source_getc(lex->lex_source);
|
||||||
|
|
||||||
if (!input_available(lex)) {
|
if (!mie_line_source_input_available(lex->lex_source)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
c = peek(lex);
|
c = mie_line_source_peekc(lex->lex_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c < 0) {
|
if (c < 0) {
|
||||||
@@ -826,8 +759,8 @@ static enum mie_status pump_tokens(struct mie_lex *lex)
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (b_wchar_is_space(c) && c != '\n') {
|
while (b_wchar_is_space(c) && c != '\n') {
|
||||||
advance(lex);
|
mie_line_source_getc(lex->lex_source);
|
||||||
c = peek(lex);
|
c = mie_line_source_peekc(lex->lex_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_VALID_IDENT_START_CHAR(c)) {
|
if (IS_VALID_IDENT_START_CHAR(c)) {
|
||||||
@@ -846,6 +779,20 @@ static enum mie_status pump_tokens(struct mie_lex *lex)
|
|||||||
return read_number(lex, false);
|
return read_number(lex, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct mie_diag *diag = push_diag(lex, MIE_BUILTIN_E_UNRECOGNISED_TOKEN);
|
||||||
|
mie_diag_push_msg(
|
||||||
|
diag, lex->lex_ctx, "builtin", MIE_BUILTIN_MSG_UNRECOGNISED_TOKEN);
|
||||||
|
const struct mie_file_cell *cursor
|
||||||
|
= mie_line_source_get_cursor(lex->lex_source);
|
||||||
|
unsigned long line = cursor->c_row;
|
||||||
|
const struct mie_diag_highlight hl[] = {
|
||||||
|
{
|
||||||
|
.hl_type = MIE_DIAG_HIGHLIGHT_ERROR,
|
||||||
|
.hl_span = {.s_start = *cursor, .s_end = *cursor},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const size_t nr_hl = sizeof hl / sizeof hl[0];
|
||||||
|
mie_diag_push_snippet(diag, line, line, NULL, 0, hl, nr_hl);
|
||||||
return MIE_ERR_BAD_SYNTAX;
|
return MIE_ERR_BAD_SYNTAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -893,7 +840,7 @@ bool mie_lex_tokens_available(struct mie_lex *lex)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input_available(lex)) {
|
if (mie_line_source_input_available(lex->lex_source)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,27 +5,24 @@
|
|||||||
#include <blue/ds/dict.h>
|
#include <blue/ds/dict.h>
|
||||||
#include <blue/ds/string.h>
|
#include <blue/ds/string.h>
|
||||||
#include <mie/parse/lex.h>
|
#include <mie/parse/lex.h>
|
||||||
|
#include <mie/parse/line-source.h>
|
||||||
#include <mie/parse/token.h>
|
#include <mie/parse/token.h>
|
||||||
#include <mie/status.h>
|
#include <mie/status.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
struct mie_lex {
|
struct mie_lex {
|
||||||
struct mie_lex_symbol_node *lex_sym_tree;
|
struct mie_lex_symbol_node *lex_sym_tree;
|
||||||
b_stream *lex_source;
|
struct mie_line_source *lex_source;
|
||||||
enum mie_status lex_status;
|
enum mie_status lex_status;
|
||||||
|
|
||||||
|
struct mie_ctx *lex_ctx;
|
||||||
b_queue lex_queue;
|
b_queue lex_queue;
|
||||||
|
|
||||||
b_string *lex_temp;
|
b_string *lex_temp;
|
||||||
b_queue lex_state;
|
b_queue lex_state;
|
||||||
unsigned int lex_brace_depth;
|
unsigned int lex_brace_depth;
|
||||||
|
|
||||||
unsigned long lex_token_start_row, lex_token_start_col;
|
struct mie_file_cell lex_token_start, lex_token_end;
|
||||||
unsigned long lex_token_end_row, lex_token_end_col;
|
|
||||||
unsigned long lex_cursor_row, lex_cursor_col;
|
|
||||||
|
|
||||||
b_string *lex_linebuf;
|
|
||||||
b_iterator *lex_linebuf_ptr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mie_lex_symbol_node {
|
struct mie_lex_symbol_node {
|
||||||
|
|||||||
161
mie/parse/line-source.c
Normal file
161
mie/parse/line-source.c
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
#include <mie/parse/line-source.h>
|
||||||
|
|
||||||
|
enum mie_status mie_line_source_init(
|
||||||
|
struct mie_line_source *src, const char *path, b_stream *stream)
|
||||||
|
{
|
||||||
|
memset(src, 0x0, sizeof *src);
|
||||||
|
|
||||||
|
src->s_lines = b_array_create();
|
||||||
|
|
||||||
|
if (!src->s_lines) {
|
||||||
|
return MIE_ERR_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
src->s_stream = stream;
|
||||||
|
src->s_path = path;
|
||||||
|
src->s_cursor.c_col = 1;
|
||||||
|
src->s_cursor.c_row = 1;
|
||||||
|
|
||||||
|
return MIE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mie_line_source_cleanup(struct mie_line_source *src)
|
||||||
|
{
|
||||||
|
if (src->s_linebuf_ptr) {
|
||||||
|
b_iterator_unref(src->s_linebuf_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src->s_lines) {
|
||||||
|
b_array_unref(src->s_lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(src, 0x0, sizeof *src);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *mie_line_source_get_path(const struct mie_line_source *src)
|
||||||
|
{
|
||||||
|
return src->s_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct mie_file_cell *mie_line_source_get_cursor(
|
||||||
|
const struct mie_line_source *src)
|
||||||
|
{
|
||||||
|
return &src->s_cursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum mie_status refill_linebuf(struct mie_line_source *src)
|
||||||
|
{
|
||||||
|
if (!src->s_stream) {
|
||||||
|
return MIE_ERR_EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src->s_linebuf_ptr) {
|
||||||
|
b_iterator_unref(src->s_linebuf_ptr);
|
||||||
|
src->s_linebuf_ptr = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
b_stringstream *s = b_stringstream_create();
|
||||||
|
|
||||||
|
b_status status = b_stream_read_line_s(src->s_stream, s);
|
||||||
|
|
||||||
|
if (status == B_ERR_NO_DATA) {
|
||||||
|
return MIE_ERR_EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!B_OK(status)) {
|
||||||
|
return MIE_ERR_INTERNAL_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
b_string *line = b_string_create();
|
||||||
|
b_string_replace_all_with_stringstream(line, s);
|
||||||
|
b_stringstream_unref(s);
|
||||||
|
|
||||||
|
b_array_append(src->s_lines, line);
|
||||||
|
b_string_unref(line);
|
||||||
|
|
||||||
|
src->s_linebuf = line;
|
||||||
|
src->s_linebuf_ptr = b_iterator_begin(src->s_linebuf);
|
||||||
|
|
||||||
|
return MIE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int peek(struct mie_line_source *src)
|
||||||
|
{
|
||||||
|
enum mie_status status = MIE_SUCCESS;
|
||||||
|
|
||||||
|
if (!src->s_linebuf_ptr || !b_iterator_is_valid(src->s_linebuf_ptr)) {
|
||||||
|
status = refill_linebuf(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status != MIE_SUCCESS) {
|
||||||
|
return -status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b_string_get_size(src->s_linebuf, B_STRLEN_NORMAL) == 0) {
|
||||||
|
return -MIE_ERR_EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
b_wchar c = b_iterator_get_value(src->s_linebuf_ptr).v_int;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int advance(struct mie_line_source *src)
|
||||||
|
{
|
||||||
|
enum mie_status status = MIE_SUCCESS;
|
||||||
|
|
||||||
|
if (!b_iterator_is_valid(src->s_linebuf_ptr)) {
|
||||||
|
status = refill_linebuf(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status != MIE_SUCCESS) {
|
||||||
|
return -status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b_string_get_size(src->s_linebuf, B_STRLEN_NORMAL) == 0) {
|
||||||
|
return -MIE_ERR_EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
b_wchar c = b_iterator_get_value(src->s_linebuf_ptr).v_int;
|
||||||
|
b_iterator_move_next(src->s_linebuf_ptr);
|
||||||
|
|
||||||
|
src->s_cursor.c_col++;
|
||||||
|
if (c == '\n') {
|
||||||
|
src->s_cursor.c_col = 1;
|
||||||
|
src->s_cursor.c_row++;
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
b_wchar mie_line_source_peekc(struct mie_line_source *src)
|
||||||
|
{
|
||||||
|
return peek(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
b_wchar mie_line_source_getc(struct mie_line_source *src)
|
||||||
|
{
|
||||||
|
return advance(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum mie_status mie_line_source_get_row(
|
||||||
|
struct mie_line_source *src, size_t row, const b_string **out)
|
||||||
|
{
|
||||||
|
if (row == 0) {
|
||||||
|
return MIE_ERR_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
row--;
|
||||||
|
|
||||||
|
if (row >= b_array_size(src->s_lines)) {
|
||||||
|
return MIE_ERR_EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
b_string *line = b_array_at(src->s_lines, row);
|
||||||
|
*out = line;
|
||||||
|
|
||||||
|
return MIE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mie_line_source_input_available(struct mie_line_source *src)
|
||||||
|
{
|
||||||
|
return src->s_linebuf_ptr && b_iterator_is_valid(src->s_linebuf_ptr);
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -4,4 +4,5 @@
|
|||||||
|
|
||||||
MIE_PASS_GROUP_BEGIN(mie_builtin)
|
MIE_PASS_GROUP_BEGIN(mie_builtin)
|
||||||
MIE_PASS_GROUP_ADD_PASS(prefix_func_with_underscore);
|
MIE_PASS_GROUP_ADD_PASS(prefix_func_with_underscore);
|
||||||
|
MIE_PASS_GROUP_ADD_PASS(convert_scf_to_cf);
|
||||||
MIE_PASS_GROUP_END()
|
MIE_PASS_GROUP_END()
|
||||||
|
|||||||
271
mie/pass/builtin/convert-scf-to-cf.c
Normal file
271
mie/pass/builtin/convert-scf-to-cf.c
Normal file
@@ -0,0 +1,271 @@
|
|||||||
|
#include <mie/ctx.h>
|
||||||
|
#include <mie/dialect/arith.h>
|
||||||
|
#include <mie/dialect/builtin.h>
|
||||||
|
#include <mie/dialect/cf.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/ir/walk.h>
|
||||||
|
#include <mie/macros.h>
|
||||||
|
#include <mie/pass/pass-definition.h>
|
||||||
|
#include <mie/pass/pass.h>
|
||||||
|
#include <mie/rewrite/convert.h>
|
||||||
|
#include <mie/rewrite/pattern.h>
|
||||||
|
#include <mie/rewrite/rewriter.h>
|
||||||
|
|
||||||
|
static bool op_is_flat(const struct mie_op *op)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum mie_match_result if_match(const struct mie_op *op)
|
||||||
|
{
|
||||||
|
if (!mie_op_is(op, "scf", "if")) {
|
||||||
|
return MIE_NO_MATCH_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MIE_MATCH_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct mie_rewrite_result if_rewrite(
|
||||||
|
struct mie_op *op, struct mie_rewriter *rewriter)
|
||||||
|
{
|
||||||
|
printf("if: rewriting %p %s.%s\n", op, op->op_info->op_parent->d_name,
|
||||||
|
op->op_info->op_name);
|
||||||
|
|
||||||
|
struct mie_register *cond = mie_op_get_arg(op, 0);
|
||||||
|
struct mie_region *parent_region = op->op_container->b_parent;
|
||||||
|
|
||||||
|
struct mie_region *if_region = mie_op_get_first_region(op);
|
||||||
|
struct mie_block *if_start = mie_region_get_first_block(if_region);
|
||||||
|
struct mie_block *if_end = mie_region_get_last_block(if_region);
|
||||||
|
struct mie_region *else_region = mie_op_get_next_region(op, if_region);
|
||||||
|
struct mie_block *else_start = mie_region_get_first_block(else_region);
|
||||||
|
|
||||||
|
struct mie_block *pre_block = op->op_container;
|
||||||
|
struct mie_block *end_block
|
||||||
|
= mie_rewriter_split_block(rewriter, pre_block, op, "if.end");
|
||||||
|
|
||||||
|
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_result); i++) {
|
||||||
|
struct mie_register *old_reg = &op->op_result.items[i];
|
||||||
|
struct mie_register *new_reg = mie_block_add_param(end_block);
|
||||||
|
new_reg->reg_type = old_reg->reg_type;
|
||||||
|
char *name = b_strdup(old_reg->reg_name.n_str);
|
||||||
|
|
||||||
|
mie_name_destroy(&old_reg->reg_name);
|
||||||
|
mie_rewriter_rename_register(rewriter, new_reg, name);
|
||||||
|
mie_rewriter_replace_register(rewriter, old_reg, new_reg);
|
||||||
|
free(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_walker walker;
|
||||||
|
mie_walker_begin(&walker, op, MIE_WALKER_F_INCLUDE_OPS);
|
||||||
|
|
||||||
|
do {
|
||||||
|
const struct mie_walk_item *item = mie_walker_get(&walker);
|
||||||
|
if (!mie_op_is(item->i_op, "scf", "yield")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("if: found scf.yield %p\n", item->i_op);
|
||||||
|
|
||||||
|
struct mie_op *br = mie_rewriter_replace_op(
|
||||||
|
rewriter, item->i_op, "cf", "br");
|
||||||
|
struct mie_op_successor *s = mie_rewriter_add_op_successor(
|
||||||
|
rewriter, br, end_block, NULL, 0);
|
||||||
|
mie_rewriter_move_op_args_to_successor(rewriter, br, s);
|
||||||
|
|
||||||
|
} while (mie_walker_step(&walker) == MIE_SUCCESS);
|
||||||
|
|
||||||
|
mie_walker_end(&walker);
|
||||||
|
|
||||||
|
mie_rewriter_move_blocks_after(
|
||||||
|
rewriter, if_region, parent_region, pre_block);
|
||||||
|
mie_rewriter_rename_block(rewriter, if_start, "if.then");
|
||||||
|
|
||||||
|
if (else_region) {
|
||||||
|
mie_rewriter_move_blocks_after(
|
||||||
|
rewriter, else_region, parent_region, if_end);
|
||||||
|
mie_rewriter_rename_block(rewriter, else_start, "if.else");
|
||||||
|
}
|
||||||
|
|
||||||
|
mie_rewriter_erase_op(rewriter, op);
|
||||||
|
|
||||||
|
mie_rewriter_set_insertion_block(rewriter, pre_block);
|
||||||
|
mie_rewriter_set_insertion_point(rewriter, NULL);
|
||||||
|
mie_cf_br_cond_put(
|
||||||
|
MIE_EMITTER(rewriter), cond, if_start, NULL, 0, else_start,
|
||||||
|
NULL, 0);
|
||||||
|
|
||||||
|
return MIE_REWRITE_RESULT(MIE_REWRITE_SUCCESS, MIE_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum mie_match_result for_match(const struct mie_op *op)
|
||||||
|
{
|
||||||
|
if (!mie_op_is(op, "scf", "for")) {
|
||||||
|
return MIE_NO_MATCH_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MIE_MATCH_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct mie_rewrite_result for_rewrite(
|
||||||
|
struct mie_op *op, struct mie_rewriter *rewriter)
|
||||||
|
{
|
||||||
|
printf("for: rewriting %p %s.%s\n", op, op->op_info->op_parent->d_name,
|
||||||
|
op->op_info->op_name);
|
||||||
|
|
||||||
|
struct mie_region *parent_region = op->op_container->b_parent;
|
||||||
|
struct mie_region *for_body = mie_op_get_first_region(op);
|
||||||
|
struct mie_block *for_entry = mie_region_get_first_block(for_body);
|
||||||
|
struct mie_block *pre_block = op->op_container;
|
||||||
|
struct mie_block *end_block
|
||||||
|
= mie_rewriter_split_block(rewriter, pre_block, op, "for.end");
|
||||||
|
|
||||||
|
struct mie_register *entry_iv = &for_entry->b_params.items[0];
|
||||||
|
struct mie_register *lb = op->op_args.items[0].arg_value.u_reg;
|
||||||
|
struct mie_register *ub = op->op_args.items[1].arg_value.u_reg;
|
||||||
|
struct mie_register *step = op->op_args.items[2].arg_value.u_reg;
|
||||||
|
|
||||||
|
MIE_VECTOR_DEFINE(struct mie_register *, initial_args);
|
||||||
|
mie_vector_push_back(initial_args, &lb, NULL);
|
||||||
|
for (size_t i = 3; i < MIE_VECTOR_COUNT(op->op_args); i++) {
|
||||||
|
struct mie_register *arg = op->op_args.items[i].arg_value.u_reg;
|
||||||
|
mie_vector_push_back(initial_args, &arg, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
mie_rewriter_set_insertion_block(rewriter, pre_block);
|
||||||
|
mie_cf_br_put(
|
||||||
|
MIE_EMITTER(rewriter), for_entry, initial_args.items,
|
||||||
|
initial_args.count);
|
||||||
|
|
||||||
|
char iv_next_name[64];
|
||||||
|
snprintf(
|
||||||
|
iv_next_name, sizeof iv_next_name, "%s.next",
|
||||||
|
entry_iv->reg_name.n_str);
|
||||||
|
|
||||||
|
mie_rewriter_set_insertion_block(rewriter, for_entry);
|
||||||
|
struct mie_block *for_cond
|
||||||
|
= mie_rewriter_create_block(rewriter, end_block, "for.cond");
|
||||||
|
|
||||||
|
for (size_t i = 0; i < MIE_VECTOR_COUNT(for_entry->b_params); i++) {
|
||||||
|
const char *var_name = for_entry->b_params.items[i].reg_name.n_str;
|
||||||
|
const struct mie_type *var_type
|
||||||
|
= for_entry->b_params.items[i].reg_type;
|
||||||
|
|
||||||
|
mie_rewriter_add_block_parameter(
|
||||||
|
rewriter, for_cond, var_name, entry_iv->reg_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_result); i++) {
|
||||||
|
struct mie_register *old_reg = &op->op_result.items[i];
|
||||||
|
struct mie_register *new_reg = mie_block_add_param(end_block);
|
||||||
|
new_reg->reg_type = old_reg->reg_type;
|
||||||
|
char *name = b_strdup(old_reg->reg_name.n_str);
|
||||||
|
|
||||||
|
mie_name_destroy(&old_reg->reg_name);
|
||||||
|
mie_rewriter_rename_register(rewriter, new_reg, name);
|
||||||
|
mie_rewriter_replace_register(rewriter, old_reg, new_reg);
|
||||||
|
free(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_walker walker;
|
||||||
|
mie_walker_begin(&walker, op, MIE_WALKER_F_INCLUDE_OPS);
|
||||||
|
|
||||||
|
do {
|
||||||
|
const struct mie_walk_item *item = mie_walker_get(&walker);
|
||||||
|
if (!mie_op_is(item->i_op, "scf", "yield")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("for: found scf.yield %p\n", item->i_op);
|
||||||
|
|
||||||
|
struct mie_op *br = mie_rewriter_replace_op(
|
||||||
|
rewriter, item->i_op, "cf", "br");
|
||||||
|
struct mie_op_successor *s = mie_rewriter_add_op_successor(
|
||||||
|
rewriter, br, for_cond, NULL, 0);
|
||||||
|
struct mie_op_arg *iv_arg = mie_rewriter_add_op_successor_arg(
|
||||||
|
rewriter, br, s, entry_iv);
|
||||||
|
mie_rewriter_move_op_args_to_successor(rewriter, br, s);
|
||||||
|
|
||||||
|
} while (mie_walker_step(&walker) == MIE_SUCCESS);
|
||||||
|
|
||||||
|
mie_walker_end(&walker);
|
||||||
|
|
||||||
|
mie_rewriter_move_blocks_after(rewriter, for_body, parent_region, pre_block);
|
||||||
|
|
||||||
|
mie_rewriter_set_insertion_block(rewriter, for_cond);
|
||||||
|
|
||||||
|
struct mie_register *cond_iv = &for_cond->b_params.items[0];
|
||||||
|
|
||||||
|
struct mie_register *iv_next = mie_arith_addi_put(
|
||||||
|
MIE_EMITTER(rewriter), cond_iv, step, iv_next_name);
|
||||||
|
struct mie_register *iv_cmp = mie_arith_cmpi_put(
|
||||||
|
MIE_EMITTER(rewriter), MIE_ARITH_CMPI_UGE, iv_next, ub, "stop");
|
||||||
|
|
||||||
|
MIE_VECTOR_DEFINE(struct mie_register *, true_args);
|
||||||
|
MIE_VECTOR_DEFINE(struct mie_register *, false_args);
|
||||||
|
|
||||||
|
mie_vector_push_back(false_args, &iv_next, NULL);
|
||||||
|
|
||||||
|
for (size_t i = 1; i < MIE_VECTOR_COUNT(for_cond->b_params); i++) {
|
||||||
|
struct mie_register *param = &for_cond->b_params.items[i];
|
||||||
|
mie_vector_push_back(true_args, ¶m, NULL);
|
||||||
|
mie_vector_push_back(false_args, ¶m, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
mie_cf_br_cond_put(
|
||||||
|
MIE_EMITTER(rewriter), iv_cmp, end_block, true_args.items,
|
||||||
|
true_args.count, for_entry, false_args.items, false_args.count);
|
||||||
|
|
||||||
|
mie_vector_destroy(true_args, NULL);
|
||||||
|
mie_vector_destroy(false_args, NULL);
|
||||||
|
|
||||||
|
mie_rewriter_erase_op(rewriter, op);
|
||||||
|
|
||||||
|
return MIE_REWRITE_RESULT(MIE_REWRITE_SUCCESS, MIE_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
MIE_REWRITE_PATTERN_BEGIN(if_pattern)
|
||||||
|
MIE_REWRITE_PATTERN_ROOT("scf", "if");
|
||||||
|
MIE_REWRITE_PATTERN_MATCH(if_match);
|
||||||
|
MIE_REWRITE_PATTERN_REWRITE(if_rewrite);
|
||||||
|
MIE_REWRITE_PATTERN_END()
|
||||||
|
|
||||||
|
MIE_REWRITE_PATTERN_BEGIN(for_pattern)
|
||||||
|
MIE_REWRITE_PATTERN_ROOT("scf", "for");
|
||||||
|
MIE_REWRITE_PATTERN_MATCH(for_match);
|
||||||
|
MIE_REWRITE_PATTERN_REWRITE(for_rewrite);
|
||||||
|
MIE_REWRITE_PATTERN_END()
|
||||||
|
|
||||||
|
static struct mie_pass_result transform(
|
||||||
|
struct mie_pass *pass, struct mie_op *op, struct mie_pass_args *args)
|
||||||
|
{
|
||||||
|
printf("%s: taking a look at %p %s.%s\n", mie_pass_get_name(pass), op,
|
||||||
|
op->op_info->op_parent->d_name, op->op_info->op_name);
|
||||||
|
|
||||||
|
struct mie_convert_config *cfg = mie_convert_config_create(args->p_ctx);
|
||||||
|
mie_convert_config_add_illegal_op(cfg, "scf", "if");
|
||||||
|
mie_convert_config_add_illegal_op(cfg, "scf", "for");
|
||||||
|
|
||||||
|
struct mie_pattern_set patterns = {};
|
||||||
|
if_pattern_create(&patterns);
|
||||||
|
for_pattern_create(&patterns);
|
||||||
|
mie_convert_apply(op, cfg, &patterns);
|
||||||
|
|
||||||
|
mie_pattern_set_cleanup(&patterns);
|
||||||
|
mie_convert_config_destroy(cfg);
|
||||||
|
|
||||||
|
return MIE_PASS_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
MIE_PASS_DEFINITION_BEGIN(convert_scf_to_cf)
|
||||||
|
MIE_PASS_NAME("convert-scf-to-cf");
|
||||||
|
MIE_PASS_DESCRIPTION(
|
||||||
|
"Convert high-level SCF constructs to low-level CF operations "
|
||||||
|
"and blocks.");
|
||||||
|
MIE_PASS_TRANSFORM(transform);
|
||||||
|
MIE_PASS_FILTER_OP("func", "func");
|
||||||
|
MIE_PASS_DEFINITION_END()
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <mie/dialect/dialect.h>
|
#include <mie/dialect/dialect.h>
|
||||||
#include <mie/interface/interface-definition.h>
|
#include <mie/interface/interface-definition.h>
|
||||||
#include <mie/ir/block.h>
|
#include <mie/ir/block.h>
|
||||||
|
#include <mie/ir/op-definition.h>
|
||||||
#include <mie/ir/op.h>
|
#include <mie/ir/op.h>
|
||||||
#include <mie/ir/region.h>
|
#include <mie/ir/region.h>
|
||||||
#include <mie/ir/walk.h>
|
#include <mie/ir/walk.h>
|
||||||
@@ -87,18 +88,19 @@ enum mie_status mie_pass_manager_filter_op(
|
|||||||
return MIE_SUCCESS;
|
return MIE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dialect_name || !op_name) {
|
if (!dialect_name) {
|
||||||
return MIE_ERR_INVALID_ARGUMENT;
|
return MIE_ERR_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct mie_op_definition *op
|
if (!op_name) {
|
||||||
= mie_ctx_get_op_definition(pm->pm_ctx, dialect_name, op_name);
|
pm->pm_filter.f_dialect
|
||||||
if (!op) {
|
= mie_ctx_get_dialect(pm->pm_ctx, dialect_name);
|
||||||
return MIE_ERR_NO_ENTRY;
|
return pm->pm_filter.f_dialect ? MIE_SUCCESS : MIE_ERR_NO_ENTRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
pm->pm_filter.f_op = op;
|
pm->pm_filter.f_op
|
||||||
return MIE_SUCCESS;
|
= mie_ctx_get_op_definition(pm->pm_ctx, dialect_name, op_name);
|
||||||
|
return pm->pm_filter.f_op ? MIE_SUCCESS : MIE_ERR_NO_ENTRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum mie_status mie_pass_manager_filter_trait(
|
enum mie_status mie_pass_manager_filter_trait(
|
||||||
@@ -152,6 +154,10 @@ static bool filter_check_op(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (filter->f_dialect && op->op_info->op_parent != filter->f_dialect) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (filter->f_trait
|
if (filter->f_trait
|
||||||
&& !mie_op_has_trait(
|
&& !mie_op_has_trait(
|
||||||
op, filter->f_trait->tr_parent->d_name,
|
op, filter->f_trait->tr_parent->d_name,
|
||||||
@@ -199,16 +205,20 @@ static void schedule_passes(
|
|||||||
b_queue_push_back(schedule, &sched->s_entry);
|
b_queue_push_back(schedule, &sched->s_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mie_walker *walker = mie_walker_begin(op, MIE_WALKER_F_INCLUDE_OPS);
|
struct mie_walker walker;
|
||||||
while (mie_walker_step(walker) == MIE_SUCCESS) {
|
mie_walker_begin(&walker, op, MIE_WALKER_F_INCLUDE_OPS);
|
||||||
|
do {
|
||||||
for (size_t i = 0; i < MIE_VECTOR_COUNT(pm->pm_nested); i++) {
|
for (size_t i = 0; i < MIE_VECTOR_COUNT(pm->pm_nested); i++) {
|
||||||
struct mie_pass_manager *nested = pm->pm_nested.items[i];
|
struct mie_pass_manager *nested = pm->pm_nested.items[i];
|
||||||
struct mie_walker_item *item = mie_walker_get(walker);
|
struct mie_walk_item *item = mie_walker_get(&walker);
|
||||||
schedule_passes(nested, schedule, item->i_op, depth + 1);
|
if (item) {
|
||||||
|
schedule_passes(
|
||||||
|
nested, schedule, item->i_op, depth + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} while (mie_walker_step(&walker) == MIE_SUCCESS);
|
||||||
|
|
||||||
mie_walker_end(walker);
|
mie_walker_end(&walker);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sched_item_execute(
|
static void sched_item_execute(
|
||||||
|
|||||||
@@ -51,7 +51,8 @@ static void print_block_header_params(
|
|||||||
static void print_block_header(
|
static void print_block_header(
|
||||||
struct mie_printer *printer, const struct mie_block *block)
|
struct mie_printer *printer, const struct mie_block *block)
|
||||||
{
|
{
|
||||||
if (!block->b_name.n_str && !MIE_VECTOR_COUNT(block->b_params)) {
|
bool first_block = b_queue_prev(&block->b_entry) == NULL;
|
||||||
|
if (first_block && !block->b_name.n_str) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,6 +60,8 @@ static void print_block_header(
|
|||||||
|
|
||||||
if (block->b_name.n_str) {
|
if (block->b_name.n_str) {
|
||||||
b_stream_write_string(printer->p_stream, block->b_name.n_str, NULL);
|
b_stream_write_string(printer->p_stream, block->b_name.n_str, NULL);
|
||||||
|
} else {
|
||||||
|
b_stream_write_string(printer->p_stream, "<UNNAMED>", NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
print_block_header_params(printer, block);
|
print_block_header_params(printer, block);
|
||||||
@@ -76,10 +79,11 @@ void mie_printer_print_block(
|
|||||||
|
|
||||||
b_stream_push_indent(printer->p_stream, 4);
|
b_stream_push_indent(printer->p_stream, 4);
|
||||||
|
|
||||||
for (size_t i = 0; i < MIE_VECTOR_COUNT(block->b_ops); i++) {
|
struct mie_op *op = mie_block_get_first_op(block);
|
||||||
const struct mie_op *op = &block->b_ops.items[i];
|
while (op) {
|
||||||
mie_printer_print_op(printer, op);
|
mie_printer_print_op(printer, op);
|
||||||
b_stream_write_char(printer->p_stream, '\n');
|
b_stream_write_char(printer->p_stream, '\n');
|
||||||
|
op = mie_block_get_next_op(block, op);
|
||||||
}
|
}
|
||||||
|
|
||||||
b_stream_pop_indent(printer->p_stream);
|
b_stream_pop_indent(printer->p_stream);
|
||||||
|
|||||||
@@ -11,11 +11,21 @@ void mie_printer_print_op_arg(
|
|||||||
enum mie_register_flags arg_flags = 0;
|
enum mie_register_flags arg_flags = 0;
|
||||||
const char *arg_name = NULL;
|
const char *arg_name = NULL;
|
||||||
const struct mie_type *arg_type = NULL;
|
const struct mie_type *arg_type = NULL;
|
||||||
|
bool resolved = false;
|
||||||
|
|
||||||
if (MIE_TEST_FLAGS(arg->arg_flags, MIE_OP_F_ARG_RESOLVED)) {
|
if (MIE_TEST_FLAGS(arg->arg_flags, MIE_OP_F_ARG_RESOLVED)) {
|
||||||
|
resolved = true;
|
||||||
|
|
||||||
|
if (!arg->arg_value.u_reg) {
|
||||||
|
/* this should only be caused by an internal parser/rewriter bug */
|
||||||
|
arg_flags = 0;
|
||||||
|
arg_name = "<NULL>";
|
||||||
|
arg_type = NULL;
|
||||||
|
} else {
|
||||||
arg_flags = arg->arg_value.u_reg->reg_flags;
|
arg_flags = arg->arg_value.u_reg->reg_flags;
|
||||||
arg_name = arg->arg_value.u_reg->reg_name.n_str;
|
arg_name = arg->arg_value.u_reg->reg_name.n_str;
|
||||||
arg_type = arg->arg_value.u_reg->reg_type;
|
arg_type = arg->arg_value.u_reg->reg_type;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
arg_flags = arg->arg_unresolved.reg_flags;
|
arg_flags = arg->arg_unresolved.reg_flags;
|
||||||
arg_name = arg->arg_unresolved.reg_name;
|
arg_name = arg->arg_unresolved.reg_name;
|
||||||
@@ -28,9 +38,19 @@ void mie_printer_print_op_arg(
|
|||||||
b_stream_write_char(printer->p_stream, '%');
|
b_stream_write_char(printer->p_stream, '%');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!arg_name) {
|
||||||
|
arg_name = "<NO-NAME>";
|
||||||
|
}
|
||||||
|
|
||||||
b_stream_write_string(printer->p_stream, arg_name, NULL);
|
b_stream_write_string(printer->p_stream, arg_name, NULL);
|
||||||
|
|
||||||
if (!include_type) {
|
if (!resolved
|
||||||
|
&& MIE_TEST_FLAGS(
|
||||||
|
printer->p_flags, MIE_PRINT_F_MARK_UNRESOLVED_ELEMENTS)) {
|
||||||
|
b_stream_write_char(printer->p_stream, '?');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!include_type || !arg_type) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,12 +64,26 @@ void mie_printer_print_op_successor(
|
|||||||
bool compact)
|
bool compact)
|
||||||
{
|
{
|
||||||
b_stream_write_char(printer->p_stream, '^');
|
b_stream_write_char(printer->p_stream, '^');
|
||||||
|
bool resolved = false;
|
||||||
|
|
||||||
|
const char *name = NULL;
|
||||||
if (successor->s_flags & MIE_OP_F_SUCCESSOR_RESOLVED) {
|
if (successor->s_flags & MIE_OP_F_SUCCESSOR_RESOLVED) {
|
||||||
b_stream_write_string(
|
name = successor->s_block->b_name.n_str;
|
||||||
printer->p_stream, successor->s_block->b_name.n_str, NULL);
|
resolved = true;
|
||||||
} else {
|
} else {
|
||||||
b_stream_write_string(
|
name = successor->s_block_name;
|
||||||
printer->p_stream, successor->s_block_name, NULL);
|
}
|
||||||
|
|
||||||
|
if (!name) {
|
||||||
|
name = "<NO-NAME>";
|
||||||
|
}
|
||||||
|
|
||||||
|
b_stream_write_string(printer->p_stream, name, NULL);
|
||||||
|
|
||||||
|
if (!resolved
|
||||||
|
&& MIE_TEST_FLAGS(
|
||||||
|
printer->p_flags, MIE_PRINT_F_MARK_UNRESOLVED_ELEMENTS)) {
|
||||||
|
b_stream_write_char(printer->p_stream, '?');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MIE_VECTOR_COUNT(successor->s_args) == 0) {
|
if (MIE_VECTOR_COUNT(successor->s_args) == 0) {
|
||||||
@@ -96,18 +130,24 @@ static void print_successor_list(
|
|||||||
|
|
||||||
static void print_region_list(struct mie_printer *printer, const struct mie_op *op)
|
static void print_region_list(struct mie_printer *printer, const struct mie_op *op)
|
||||||
{
|
{
|
||||||
if (!MIE_VECTOR_COUNT(op->op_regions)) {
|
if (b_queue_empty(&op->op_regions)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
b_stream_write_string(printer->p_stream, " (", NULL);
|
b_stream_write_string(printer->p_stream, " (", NULL);
|
||||||
|
|
||||||
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_regions); i++) {
|
struct mie_region *region = mie_op_get_first_region(op);
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
while (region) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
b_stream_write_string(printer->p_stream, ", ", NULL);
|
b_stream_write_string(printer->p_stream, ", ", NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
mie_printer_print_region(printer, &op->op_regions.items[i], 0);
|
mie_printer_print_region(printer, region, 0);
|
||||||
|
|
||||||
|
region = mie_op_get_next_region(op, region);
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
b_stream_write_string(printer->p_stream, ")", NULL);
|
b_stream_write_string(printer->p_stream, ")", NULL);
|
||||||
@@ -195,9 +235,14 @@ static void print_generic_op(struct mie_printer *printer, const struct mie_op *o
|
|||||||
if (op->op_flags & MIE_OP_F_OP_RESOLVED) {
|
if (op->op_flags & MIE_OP_F_OP_RESOLVED) {
|
||||||
b_stream_write_fmt(
|
b_stream_write_fmt(
|
||||||
printer->p_stream, NULL, "%s.%s",
|
printer->p_stream, NULL, "%s.%s",
|
||||||
op->op_dialect->d_name, op->op_info->op_name);
|
op->op_info->op_parent->d_name, op->op_info->op_name);
|
||||||
} else {
|
} else {
|
||||||
b_stream_write_string(printer->p_stream, op->op_name, NULL);
|
b_stream_write_string(printer->p_stream, op->op_name, NULL);
|
||||||
|
|
||||||
|
if (MIE_TEST_FLAGS(
|
||||||
|
printer->p_flags, MIE_PRINT_F_MARK_UNRESOLVED_ELEMENTS)) {
|
||||||
|
b_stream_write_char(printer->p_stream, '?');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
b_stream_write_char(printer->p_stream, '(');
|
b_stream_write_char(printer->p_stream, '(');
|
||||||
@@ -263,7 +308,7 @@ void mie_printer_print_op_name(struct mie_printer *printer, const struct mie_op
|
|||||||
if (printer->p_flags & MIE_PRINT_F_GENERIC) {
|
if (printer->p_flags & MIE_PRINT_F_GENERIC) {
|
||||||
generic = true;
|
generic = true;
|
||||||
b_stream_write_char(printer->p_stream, '~');
|
b_stream_write_char(printer->p_stream, '~');
|
||||||
} else if (!strcmp(op->op_dialect->d_name, "builtin")) {
|
} else if (!strcmp(op->op_info->op_parent->d_name, "builtin")) {
|
||||||
builtin = true;
|
builtin = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,7 +319,8 @@ void mie_printer_print_op_name(struct mie_printer *printer, const struct mie_op
|
|||||||
|
|
||||||
if (generic || !builtin || !abbreviate) {
|
if (generic || !builtin || !abbreviate) {
|
||||||
b_stream_write_fmt(
|
b_stream_write_fmt(
|
||||||
printer->p_stream, NULL, "%s.", op->op_dialect->d_name);
|
printer->p_stream, NULL, "%s.",
|
||||||
|
op->op_info->op_parent->d_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
b_stream_write_string(printer->p_stream, op->op_info->op_name, NULL);
|
b_stream_write_string(printer->p_stream, op->op_info->op_name, NULL);
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user