Compare commits

...

10 Commits

23 changed files with 503 additions and 142 deletions

View File

@@ -1,9 +1,9 @@
pkg2 = {
onEnter => [
on-enter => [
cout put:'start!'
],
onExit => [
on-exit => [
cout put:'end!'
]
}.

View File

@@ -15,32 +15,31 @@ while true do
end
end
shiftWidth = 0
shift-width = 0
while true do
cout print:'Shift size: '
cout flush
shiftStr = ''
cin get:shiftStr
shift-str = cin read-line.
if shiftStr == '' then
if shift-str == '' then
continue
end
try
shiftWidth = Int parse:shiftStr
catch (#err:number_format, err)
shift-width = Int parse:shift-str
catch ($err:number-format, err)
continue
end
break
end
encodedMessage = ''
encoded-message = ''
for c in message do
i = c toOrdinal
i = c to-ordinal
sub = 0
if i >= 65 && i <= 90 then
@@ -50,16 +49,16 @@ for c in message do
else
continue
end
i -= sub
i += shiftWidth
i += shift-width
if i >= 26 then
i -= 26
end
c2 = i toChar
encodedMessage += c2
c2 = i to-char
encoded-message += c2
end
cout put:encodedMessage
cout put:encoded-message

View File

@@ -1,7 +1,7 @@
try
x = 0
--v = Int parse:'342'
catch ($err:number_format, err) in
catch ($err:number-format, err) in
x = 1
--cout put:'Cannot parse integer string ({err})'
catch (_, err) in

View File

@@ -1,12 +1,12 @@
y = 1 + 2 * 3 / 4 * 5 - 6 + 7 multiplyBy:2.
z = w = 2 + 3 multiplyBy:2.
x = (((1 + 2 * 3) multiplyBy:3) add: 5) + 2.
x = ((1 + 2 * 3) multiplyBy:3).
y = 1 + 2 * 3 / 4 * 5 - 6 + 7 multiply-by:2.
z = w = 2 + 3 multiply-by:2.
x = (((1 + 2 * 3) multiply-by:3) add: 5) + 2.
x = ((1 + 2 * 3) multiply-by:3).
p = 5 multiply(by:3, add:(2 + 1)).
q = 10 squared squared.
p1
setAge:2 squared squared + 4 squared multiply(by:2, add:4 + 1 * 3)
set-age:2 squared squared + 4 squared multiply(by:2, add:4 + 1 * 3)
in:"mon" + "ths".
m = xz multiply(by:3 add:2) squared.
@@ -20,7 +20,7 @@ x = OrderedCollection new
yourself.
age = Person new(name:"John Doe", age:34)
setAge:144 inUnit:"months";
set-age:144 in-unit:"months";
ageInMonths.
x = 5.
@@ -76,10 +76,10 @@ pkg = { 1, 2, 3, 4, 5 }.
pkg = { 10, 2 => "Hello", 9, 5 => "World", 14 }.
pkg = { { 0 }, { 1 }, { y for y in huh } }.
pkg = { x multiplyBy:2 for x in wow if x > 2 }.
pkg = { x multiply-by:2 for x in wow if x > 2 }.
pkg->x = 32.
k = (1 multiplyBy:2, 4).
k = (1 multiply-by:2, 4).
for (x, y) in pkg do
cout put:'{x}: {y}'
@@ -97,11 +97,11 @@ v = pkg->x.
v = pkg at:'x'.
pkg2 = {
onEnter => [
on-enter => [
cout put:'start!'
],
onExit => [
on-exit => [
cout put:'end!'
]
}.

View File

@@ -58,13 +58,13 @@ class Person
- age | ^self::age.
- ageInMonths | ^self::age * 12.
- age-in-months | ^self::age * 12.
- setName:name | self::name = name.
- set-name:name | self::name = name.
- setAge:age | self::age = age.
- set-age:age | self::age = age.
- setAge:age inUnit:units
- set-age:age in-unit:units
match units in
$years => self::age = age,
$months => self::age = age / 12,
@@ -72,7 +72,7 @@ class Person
_ => self::age = 0
end!
- getAgeInUnit:units
- get-age-in-units:units
^match units in
$years => self::age,
$months => self::age / 12,
@@ -104,12 +104,12 @@ class Person
is converted to the lambda
[ :x | self::val = x ]
*/
-> exampleProperty | get => self::val, set => self::val = value.
-> example-property | get => self::val, set => self::val = value.
/* Without the lambda synthesis, the property would look like this:
Note that this is the only time it is legal to access private fields
via `self` from a lambda. */
-> exampleProperty |
-> example-property |
get => [ ^self::val ],
set => [ :x | self::val = x ].
@@ -119,7 +119,7 @@ class Person
If either the `set` or `get` elements are not provided, the property
becomes read-only or write-only respectively */
-> exampleProperty2 | get => 42.
-> example-property-2 | get => 42.
/* A property can also be configured to act just like a regular variable,
by setting the getter and setters to default implementations.
@@ -131,15 +131,15 @@ class Person
Similarly, the default setter will set the value of a private member
variable named by prepending two underscores to the property name
(__exampleProperty3 in this case) to the value provided to the setter. */
-> exampleProperty3 (get, set)
-> example-property-3 (get, set)
/* Just like in the earlier examples, either `get` or `set` can be omitted
to create a write-only or read-only property respectively */
-> exampleProperty4 (get)
-> example-property-4 (get)
end
p1 = Person new(name:'John Doe', age:34).
p1 setAge:100 inUnit:$months.
p1 set-age:100 in-unit:$months.
p1 test(param:'Hello', 'World').
@@ -299,7 +299,7 @@ a = (32, 64).
try
v = Int parse:'342'
catch ($err:number_format, err) in
catch ($err:number-format, err) in
cout put:'Cannot parse integer string ({err})'
catch (_, err) in
cout put:'Unknown error occurred ({err})'
@@ -308,7 +308,7 @@ end
/* equivalent 'pure' syntax */
[ v = Int parse:'342' ]
on:$err:number_format do:[ :err :data |
on:$err:number-format do:[ :err :data |
cout put:'Cannot parse integer string ({err})'
];
onError:[ :err :data |
@@ -382,10 +382,10 @@ cout put:'Hello, world!' if x > 10.
**/
p1
setAge:2 squared squared + 4 squared multiply(by:2, add:4 + 1 * 3)
set-age:2 squared squared + 4 squared multiply(by:2, add:4 + 1 * 3)
in:'mon' + 'ths'.
(p1
setAge:(((2 squared) squared) + ((4 squared) multiply(by:2, add:(4 + (1 * 3)))))
set-age:(((2 squared) squared) + ((4 squared) multiply(by:2, add:(4 + (1 * 3)))))
in:('mon' + 'ths')).
/******************************************************************************/
@@ -440,7 +440,7 @@ pkg2 = pkg1 map:[ :x | ^x * 2 ].
**/
age = Person new(name:'John Doe', age:34);
setAge:144 inUnit:$months;
set-age:144 in-unit:$months;
ageInMonths.
-- age now has the value 144
@@ -448,7 +448,7 @@ age = Person new(name:'John Doe', age:34);
age = do
x = Person new(name:'John Doe', age:34).
x setAge:144 inUnit:$months.
x set-age:144 in-unit:$months.
x ageInMonths
end
@@ -471,15 +471,15 @@ end
**/
p1 = Person new(name:'John Doe', age:34);
setAge:100 inUnit:$months;
yourself::
set-age:100 in-unit:$months;
yourself
/* p1 now contains the Person object */
/* again, with do..end */
p1 = do
x = Person new(name:'John Doe', age:34).
x setAge:100 inUnit:$months.
x set-age:100 in-unit:$months.
x
end.

View File

@@ -1,27 +1,27 @@
y = 1 + 2 * 3 / 4 * 5 - 6 + 7 multiplyBy:2.
z = w = 2 + 3 multiplyBy:2.
x = (((1 + 2 * 3) multiplyBy:3) add: 5) + 2.
x = ((1 + 2 * 3) multiplyBy:3).
y = -1 + 2 * 3 / 4 * 5 - 6 + 7 multiply-by:2.
z = w = 2 + 3 multiply-by:2.
x = (((1 + 2 * 3) multiply-by:3) add: 5) + 2.
x = ((1 + 2 * 3) multiply-by:3).
p = 5 multiply(by:3, add:(2 + 1)).
q = 10 squared squared.
p1
setAge:2 squared squared + 4 squared multiply(by:2, add:4 + 1 * 3)
set-age:2 squared squared + 4 squared multiply(by:2, add:4 + 1 * 3)
in:"mon" + "ths".
m = xz multiply(by:3 add:2) squared.
m = xz multiply(by:3 add:2); squared.
x = OrderedCollection new
x = Ordered-Collection new
add: 2;
add: 4;
add: 6;
yourself.
age = Person new(name:"John Doe", age:34)
setAge:144 inUnit:"months";
ageInMonths.
set-age:144 in-unit:"months";
age-in-months.
x = 5.
q = 10 if x > 2 else 20.

View File

@@ -3,4 +3,4 @@ package net.doorstuck.test
s1 = 'hello world'
s2 = s1 map:[ :c | ^c uppercase ]
s3 = s1 map:[ :c | ^((c ordinal) + 1) toChar ]
s3 = s1 map:[ :c | ^((c ordinal) + 1) to-char ]

View File

@@ -9,7 +9,7 @@ while true do
cout flush.
v = 0.
input = cin readLine.
input = cin read-line.
if input == '' then
break

View File

@@ -3,8 +3,8 @@ package net.doorstuck.vehicles
protocol Vehicle
- startup
- shutdown
- nrWheels
- nrDoors
- nr-wheels
- nr-doors
- turn(direction:dir)
- accelerate(direction:dir)
- velocity
@@ -12,33 +12,33 @@ end
class Car <Vehicle>
- startup
self.engineRunning = true
self.engine-running = true
end
- shutdown
self.engineRunning = false
self.engine-running = false
end
- nrWheels
- nr-wheels
^4
end
- nrDoors
- nr-doors
^4
end
- turn(direction:dir)
self.currentDirection = dir
self.current-direction = dir
end
- accelerate(direction:dir)
match dir
#forward => self.currentVelocity += 1,
#backward => self.currentVelocity -= 1,
$forward => self.current-velocity += 1,
$backward => self.current-velocity -= 1,
end
end
- velicity
^self.currentVelocity
- velocity
^self.current-velocity
end
end

View File

@@ -30,10 +30,10 @@ version: 1.0
-is:
-implements:
-respondsTo:
-doesNotUnderstand(selector:args:)
-sendMsg(selector:args:)
-toString
-responds-to:
-does-not-understand(selector:args:)
-send-msg(selector:args:)
-to-string
3.2 Int
@@ -78,8 +78,8 @@ version: 1.0
-size
-exists:
-put:at:
-get:
-at:
-at:put:
-map:
-select:
-select:collect:
@@ -92,7 +92,7 @@ version: 1.0
Messages:
-value
-moveNext
-move-next
-select:
-select:collect:
-iterator
@@ -103,7 +103,7 @@ version: 1.0
Messages:
-argCount
-arg-count
-call
-call:
-call(_:_:)
@@ -130,7 +130,7 @@ version: 1.0
-msg
-data
-withMsg:andData:
-with-msg:and-data:
4 std.io

View File

@@ -4,9 +4,30 @@ endif
let s:save_cpo = &cpoptions
set cpoptions&vim
"setlocal iskeyword+=:
setlocal iskeyword+=-
syn match ivyType /\<[A-Z]\{1,2\}\([a-z0-9]\+[A-Z]\{0,2\}\)*\>/
syn match ivyType /\<[A-Z]\{1,2}[a-z0-9]\+\(-\?[A-Z]\{1,2}[a-z0-9]\+\)*\>/
syn match ivySelectorLabel /\<[a-z][A-Za-z0-9-_]*\:/
"syn match ivySelectorLabel /\<\([a-z]\([A-Za-z0-9_]\+\)\:\(\:\)\@!\)\+/
syn match ivyUnnamedVariable /\<_\>/
syn match ivyAtomName /\$[a-z][a-z0-9_:/-]*\>/
syn match ivyWord /\<[a-z_][a-zA-Z0-9_]*\(-\?[a-zA-Z][a-zA-Z0-9_]*\)*\>\(\:\)\@!/
syn match ivyComplexMessageName /\<\zs[A-Za-z][A-Za-z0-9-_]\+\ze(/
"syn match ivyUnaryMessageName /-\s*[a-zA-z][a-zA-Z0-9_]\+\s*\n/
syn match ivyUnaryMessageName /\(-\s*\)\@<=[a-z][A-Za-z0-9-_]*\(\s*\n\)\@=/
syn match ivyUnaryMessageName /\(-\s*\)\@<=[a-z][A-Za-z0-9-_]*\(\s*|\)\@=/
syn match ivyUnaryMessageName /\(+\s*\)\@<=[a-z][A-Za-z0-9-_]*\(\s*\n\)\@=/
syn match ivyUnaryMessageName /\(+\s*\)\@<=[a-z][A-Za-z0-9-_]*\(\s*|\)\@=/
syn match ivyPropertyName /\(->\s*\)\@<=[a-z][A-Za-z0-9-_]*/
syn match ivyLineContinuation /\\\n/
" Modifiers
syn match ivySelfVar /\<self\([^a-zA-Z0-9-_]\)\@=/
" we have to use syn match for keywords because any keyword can be used as a
" label by adding : to the end, and adding : to iskeyword causes more problems
@@ -18,27 +39,6 @@ syn match ivyException /\(try\|catch\|finally\|throw\)\>\(\:\)\@!/
syn match ivyBuiltinVar /\(error\|cout\|cin\|cerr\)\>\(\:\)\@!/
syn match ivyUnspecifiedStatement /\(var\|end\|package\|use\|as\|then\|in\|do\|get\|set\)\>\(\:\)\@!/
syn match ivySelectorLabel /\<[a-z][A-Za-z0-9_]*\:/
"syn match ivySelectorLabel /\<\([a-z]\([A-Za-z0-9_]\+\)\:\(\:\)\@!\)\+/
syn match ivyUnnamedVariable /\<_\>/
syn match ivyAtomName /\$[a-z][a-z0-9_:/]*\>/
syn match ivyComplexMessageName /\<\zs[A-Za-z][A-Za-z0-9]\+\ze(/
"syn match ivyUnaryMessageName /-\s*[a-zA-z][a-zA-Z0-9_]\+\s*\n/
syn match ivyUnaryMessageName /\(-\s*\)\@<=[a-z][A-Za-z0-9_]*\(\s*\n\)\@=/
syn match ivyUnaryMessageName /\(-\s*\)\@<=[a-z][A-Za-z0-9_]*\(\s*|\)\@=/
syn match ivyUnaryMessageName /\(+\s*\)\@<=[a-z][A-Za-z0-9_]*\(\s*\n\)\@=/
syn match ivyUnaryMessageName /\(+\s*\)\@<=[a-z][A-Za-z0-9_]*\(\s*|\)\@=/
syn match ivyPropertyName /\(->\s*\)\@<=[a-z][A-Za-z0-9_]*/
syn match ivyLineContinuation /\\\n/
" Modifiers
syn match ivySelfVar /\<self\([^a-zA-Z0-9_]\)\@=/
syn match ivyPackageStmtIdentifier /\(package \)\@<=\([A-Za-z_][A-Za-z0-9_]*\)\(.\([A-Za-z_][A-Za-z0-9_]*\)\)*\(\n\)\@=\>/
syn match ivyUseStmtIdentifier /\(use \)\@<=\([A-Za-z_][A-Za-z0-9_]*\)\(.\([A-Za-z_][A-Za-z0-9_]*\)\)*\(\n\)\@=\>/
@@ -46,20 +46,18 @@ syn match ivyUseStmtIdentifier /\(use \)\@<=\([A-Za-z_][A-Za-z0-9_]*\)\(.\([A-Za
syn match ivyBraces "[{}]" display
syn match ivyBrackets "[[\]]" display
syn match ivyParens "[()]" display
syn match ivyOpSymbols "+" display
syn match ivyOpSymbols "-" display
syn match ivyOpSymbols "\*" display
syn match ivyOpSymbols "/" display
syn match ivyOpSymbols "::" display
syn match ivyOpSymbols "=\{1,2}" display
syn match ivyOpSymbols ">\{1,2}" display
syn match ivyOpSymbols "<\{1,2}" display
syn match ivyOpSymbols "[!><+\-*/^]=" display
syn match ivyOpSymbols "[+\-/*%&^!|<>;,]" display
syn match ivyOpSymbols "[+\-/*%&^!|<>]=" display
syn match ivyOtherSymbols "=>" display
syn match ivyLambdaSymbols "|" display
syn match ivyLogicSymbols "&&" display
syn match ivyLogicSymbols "||" display
syn match ivyStatementSeparator "\.\s*" display
syn match ivyMessageTerminator "\!\s*" display
syn match ivyMessageTerminator "\![\s\n]\+" display
syn keyword ivyWordOperator is not understands and or
" PROVIDES: @ivyCommentHook
@@ -94,6 +92,7 @@ syn match ivyCharacter "'[^\\]'" display
syn case ignore
syn match ivyInteger "\<0b[01_]*[01]\%([lu]\|lu\|ul\)\=\>" display
syn match ivyInteger "\<\d\+\%(_\+\d\+\)*\%([lu]\|lu\|ul\)\=\>" display
syn match ivyInteger "\<-\d\+\%(_\+\d\+\)*\%([lu]\|lu\|ul\)\=\>" display
syn match ivyInteger "\<0x[[:xdigit:]_]*\x\%([lu]\|lu\|ul\)\=\>" display
syn match ivyReal "\<\d\+\%(_\+\d\+\)*\.\d\+\%(_\+\d\+\)*\%\(e[-+]\=\d\+\%(_\+\d\+\)*\)\=[fdm]\=" display
syn match ivyReal "\.\d\+\%(_\+\d\+\)*\%(e[-+]\=\d\+\%(_\+\d\+\)*\)\=[fdm]\=\>" display
@@ -197,6 +196,7 @@ hi def link ivyCharacter Character
hi def link ivySpecialChar SpecialChar
hi def link ivyInteger Number
hi def link ivyReal Float
hi def link ivyWord Identifier
hi def link ivyUnicodeNumber SpecialChar
hi def link ivyUnicodeSpecifier SpecialChar
hi def link ivyInterpolationDelimiter Delimiter

View File

@@ -76,6 +76,8 @@ static void to_string(struct ivy_ast_node *node, b_string *str)
b_string_append_cstr(str, tok->t_str);
i++;
entry = b_queue_next(entry);
}
b_string_append_cstr(str, ")");

View File

@@ -49,4 +49,7 @@ MIE_API enum mie_status mie_select_builder_set_mem_access(
struct mie_select_builder *builder, struct mie_value *ir_val,
struct mie_select_value *graph_val);
MIE_API enum mie_status mie_select_builder_collapse_chain_ends(
struct mie_select_builder *builder, struct mie_select_value *out);
#endif

View File

@@ -21,11 +21,16 @@ struct mie_select_use {
b_queue_entry u_entry;
};
struct mie_select_chain_end {
struct mie_select_value c_value;
b_queue_entry c_entry;
};
struct mie_select_graph {
b_queue g_nodes;
struct mie_select_node *g_root;
struct mie_select_value g_entry;
struct mie_select_value g_last_chain;
b_queue g_chain_ends;
size_t g_frame_index;
size_t g_node_id;
};
@@ -43,6 +48,7 @@ MIE_API enum mie_status mie_select_graph_get_node(
struct mie_type **values, size_t nr_values, struct mie_select_node **out);
MIE_API void mie_select_graph_dump_text(struct mie_select_graph *graph);
MIE_API void mie_select_graph_dump_dot(struct mie_select_graph *graph);
MIE_API void mie_select_graph_dump_dot(
struct mie_select_graph *graph, const char *filename);
#endif

View File

@@ -20,6 +20,12 @@ enum mie_select_opcode {
MIE_SELECT_OP_MUL,
MIE_SELECT_OP_DIV,
MIE_SELECT_OP_XOR,
MIE_SELECT_OP_CMP_EQ,
MIE_SELECT_OP_CMP_NEQ,
MIE_SELECT_OP_CMP_LT,
MIE_SELECT_OP_CMP_GT,
MIE_SELECT_OP_CMP_LEQ,
MIE_SELECT_OP_CMP_GEQ,
MIE_SELECT_OP_BR,
MIE_SELECT_OP_BR_COND,
};

View File

@@ -581,7 +581,7 @@ struct mie_value *mie_builder_cmp_eq(
sub->op_left = left;
sub->op_right = right;
sub->op_type = mie_value_get_type(left, builder->b_ctx);
sub->op_type = mie_ctx_get_int_type(builder->b_ctx, 1);
if (!mie_block_add_instr(builder->b_current_block, &sub->op_base)) {
free(sub);
@@ -617,7 +617,7 @@ struct mie_value *mie_builder_cmp_neq(
sub->op_left = left;
sub->op_right = right;
sub->op_type = mie_value_get_type(left, builder->b_ctx);
sub->op_type = mie_ctx_get_int_type(builder->b_ctx, 1);
if (!mie_block_add_instr(builder->b_current_block, &sub->op_base)) {
free(sub);
@@ -653,7 +653,7 @@ struct mie_value *mie_builder_cmp_lt(
sub->op_left = left;
sub->op_right = right;
sub->op_type = mie_value_get_type(left, builder->b_ctx);
sub->op_type = mie_ctx_get_int_type(builder->b_ctx, 1);
if (!mie_block_add_instr(builder->b_current_block, &sub->op_base)) {
free(sub);
@@ -689,7 +689,7 @@ struct mie_value *mie_builder_cmp_gt(
sub->op_left = left;
sub->op_right = right;
sub->op_type = mie_value_get_type(left, builder->b_ctx);
sub->op_type = mie_ctx_get_int_type(builder->b_ctx, 1);
if (!mie_block_add_instr(builder->b_current_block, &sub->op_base)) {
free(sub);
@@ -725,7 +725,7 @@ struct mie_value *mie_builder_cmp_leq(
sub->op_left = left;
sub->op_right = right;
sub->op_type = mie_value_get_type(left, builder->b_ctx);
sub->op_type = mie_ctx_get_int_type(builder->b_ctx, 1);
if (!mie_block_add_instr(builder->b_current_block, &sub->op_base)) {
free(sub);
@@ -761,7 +761,7 @@ struct mie_value *mie_builder_cmp_geq(
sub->op_left = left;
sub->op_right = right;
sub->op_type = mie_value_get_type(left, builder->b_ctx);
sub->op_type = mie_ctx_get_int_type(builder->b_ctx, 1);
if (!mie_block_add_instr(builder->b_current_block, &sub->op_base)) {
free(sub);

View File

@@ -50,8 +50,20 @@ DEFINE_PUSH_FUNCTION(add, MIE_SELECT_OP_ADD);
DEFINE_PUSH_FUNCTION(sub, MIE_SELECT_OP_SUB);
DEFINE_PUSH_FUNCTION(mul, MIE_SELECT_OP_MUL);
DEFINE_PUSH_FUNCTION(div, MIE_SELECT_OP_DIV);
DEFINE_PUSH_FUNCTION(cmp_eq, MIE_SELECT_OP_CMP_EQ);
DEFINE_PUSH_FUNCTION(cmp_neq, MIE_SELECT_OP_CMP_NEQ);
DEFINE_PUSH_FUNCTION(cmp_lt, MIE_SELECT_OP_CMP_LT);
DEFINE_PUSH_FUNCTION(cmp_gt, MIE_SELECT_OP_CMP_GT);
DEFINE_PUSH_FUNCTION(cmp_leq, MIE_SELECT_OP_CMP_LEQ);
DEFINE_PUSH_FUNCTION(cmp_geq, MIE_SELECT_OP_CMP_GEQ);
DEFINE_OP(add);
DEFINE_OP(sub);
DEFINE_OP(mul);
DEFINE_OP(div);
DEFINE_OP(cmp_eq);
DEFINE_OP(cmp_neq);
DEFINE_OP(cmp_lt);
DEFINE_OP(cmp_gt);
DEFINE_OP(cmp_leq);
DEFINE_OP(cmp_geq);

171
mie/select/br.c Normal file
View File

@@ -0,0 +1,171 @@
#include "builder.h"
#include <mie/ctx.h>
#include <mie/ir/branch.h>
#include <mie/select/graph.h>
#include <mie/select/node.h>
static enum mie_status get_block_node(
struct mie_select_builder *builder, struct mie_block *block,
struct mie_select_value *out)
{
struct mie_select_node *block_node = NULL;
struct mie_select_graph *graph = mie_select_builder_get_graph(builder);
struct mie_type *ptr_type = mie_ctx_get_type(
mie_select_builder_get_ctx(builder), MIE_TYPE_PTR);
enum mie_status status = mie_select_graph_get_node(
graph, mie_target_builtin(), MIE_SELECT_OP_BLOCK, NULL, 0,
&ptr_type, 1, &block_node);
if (status != MIE_SUCCESS) {
return status;
}
block_node->n_value.v = MIE_VALUE(block);
block_node->n_flags |= MIE_SELECT_NODE_F_PVALUE;
return mie_select_node_get_value(block_node, ptr_type, 0, out);
}
static enum mie_status create_br_cond(
struct mie_select_builder *builder, struct mie_value *cond,
struct mie_select_value *incoming_chain, struct mie_block *dest_block,
struct mie_select_value *out)
{
struct mie_select_graph *graph = mie_select_builder_get_graph(builder);
if (!incoming_chain || !incoming_chain->v_node) {
incoming_chain = mie_select_builder_get_mem_access(builder, cond);
}
if (!incoming_chain || !incoming_chain->v_node) {
incoming_chain = &graph->g_entry;
}
struct mie_select_value dest;
enum mie_status status = get_block_node(builder, dest_block, &dest);
if (status != MIE_SUCCESS) {
return status;
}
struct mie_select_value *operands[] = {
incoming_chain,
mie_select_builder_get_value(builder, cond),
&dest,
};
size_t nr_operands = sizeof operands / sizeof operands[0];
struct mie_type *chain_type = mie_ctx_get_type(
mie_select_builder_get_ctx(builder), MIE_TYPE_OTHER);
struct mie_select_node *br_node = NULL;
status = mie_select_graph_get_node(
graph, mie_target_builtin(), MIE_SELECT_OP_BR_COND, operands,
nr_operands, &chain_type, 1, &br_node);
if (status != MIE_SUCCESS) {
return status;
}
mie_select_node_get_value(br_node, chain_type, 0, out);
return MIE_SUCCESS;
}
static enum mie_status create_br(
struct mie_select_builder *builder, struct mie_block *dest_block,
struct mie_select_value *incoming_chain, struct mie_select_value *out)
{
struct mie_select_graph *graph = mie_select_builder_get_graph(builder);
if (!incoming_chain || !incoming_chain->v_node) {
incoming_chain = &graph->g_entry;
}
struct mie_select_value dest;
enum mie_status status = get_block_node(builder, dest_block, &dest);
if (status != MIE_SUCCESS) {
return status;
}
struct mie_select_value *operands[] = {
incoming_chain,
&dest,
};
size_t nr_operands = sizeof operands / sizeof operands[0];
struct mie_type *chain_type = mie_ctx_get_type(
mie_select_builder_get_ctx(builder), MIE_TYPE_OTHER);
struct mie_select_node *br_node = NULL;
status = mie_select_graph_get_node(
graph, mie_target_builtin(), MIE_SELECT_OP_BR, operands,
nr_operands, &chain_type, 1, &br_node);
if (status != MIE_SUCCESS) {
return status;
}
mie_select_node_get_value(br_node, chain_type, 0, out);
return MIE_SUCCESS;
}
static enum mie_status push_br(
struct mie_select_builder *builder, struct mie_instr *instr)
{
struct mie_branch *br = (struct mie_branch *)instr;
struct mie_select_value incoming_chain = {};
enum mie_status status = mie_select_builder_collapse_chain_ends(
builder, &incoming_chain);
if (status != MIE_SUCCESS) {
return status;
}
struct mie_select_value br_result;
status = create_br(builder, br->b_dest, &incoming_chain, &br_result);
if (status != MIE_SUCCESS) {
return status;
}
return mie_select_builder_set_value(builder, MIE_VALUE(instr), &br_result);
}
static enum mie_status push_br_if(
struct mie_select_builder *builder, struct mie_instr *instr)
{
struct mie_branch_if *br = (struct mie_branch_if *)instr;
struct mie_select_value incoming_chain = {};
enum mie_status status = mie_select_builder_collapse_chain_ends(
builder, &incoming_chain);
if (status != MIE_SUCCESS) {
return status;
}
struct mie_select_value br_true_result, br_false_result;
status = create_br_cond(
builder, br->b_cond, &incoming_chain, br->b_true_block,
&br_true_result);
if (status != MIE_SUCCESS) {
return status;
}
status = create_br(
builder, br->b_false_block, &br_true_result, &br_false_result);
if (status != MIE_SUCCESS) {
return status;
}
return mie_select_builder_set_value(
builder, MIE_VALUE(instr), &br_false_result);
}
struct select_instr_type select_br = {
.i_push = push_br,
};
struct select_instr_type select_br_if = {
.i_push = push_br_if,
};

View File

@@ -94,18 +94,6 @@ const struct mie_target *mie_select_builder_get_target(
return builder->b_target;
}
static void clear_node_map(struct mie_select_builder *builder)
{
b_iterator *it = b_iterator_begin(builder->b_nodes);
while (b_iterator_is_valid(it)) {
b_hashmap_item *item = b_iterator_get_value(it).v_ptr;
free(item->value.value_data);
b_iterator_erase(it);
}
b_iterator_unref(it);
}
struct mie_select_graph *mie_select_builder_finish(struct mie_select_builder *builder)
{
enum mie_status status = MIE_SUCCESS;
@@ -116,8 +104,14 @@ struct mie_select_graph *mie_select_builder_finish(struct mie_select_builder *bu
};
size_t nr_root_operands = 0;
if (graph->g_last_chain.v_node) {
root_operands[0] = &graph->g_last_chain;
struct mie_select_value incoming_chain = {};
status = mie_select_builder_collapse_chain_ends(builder, &incoming_chain);
if (status != MIE_SUCCESS) {
return NULL;
}
if (incoming_chain.v_node) {
root_operands[0] = &incoming_chain;
nr_root_operands++;
}
@@ -129,9 +123,13 @@ struct mie_select_graph *mie_select_builder_finish(struct mie_select_builder *bu
return NULL;
}
clear_node_map(builder);
b_hashmap_unref(builder->b_nodes);
builder->b_nodes = b_hashmap_create(NULL, NULL);
builder->b_graph = NULL;
b_hashmap_unref(builder->b_mem_access);
builder->b_mem_access = b_hashmap_create(NULL, NULL);
builder->b_graph = mie_select_graph_create(builder->b_ctx);
return graph;
}
@@ -251,6 +249,32 @@ static enum mie_status get_data_node(
return MIE_SUCCESS;
}
static enum mie_status get_external_value_node(
struct mie_select_builder *builder, struct mie_value *ir_val,
struct mie_select_value *out)
{
struct mie_type *type = mie_value_get_type(ir_val, builder->b_ctx);
if (!type) {
return MIE_ERR_INVALID_VALUE;
}
struct mie_select_node *node;
enum mie_status status = mie_select_graph_get_node(
builder->b_graph, mie_target_builtin(), MIE_SELECT_OP_REGISTER,
NULL, 0, &type, 1, &node);
if (status != MIE_SUCCESS) {
return status;
}
node->n_flags = MIE_SELECT_NODE_F_PVALUE;
node->n_value.v = ir_val;
mie_select_node_get_value(node, type, 0, out);
return MIE_SUCCESS;
}
struct mie_select_value *mie_select_builder_get_value(
struct mie_select_builder *builder, struct mie_value *ir_val)
{
@@ -280,6 +304,7 @@ struct mie_select_value *mie_select_builder_get_value(
status = get_data_node(builder, ir_val, select_val);
break;
default:
status = get_external_value_node(builder, ir_val, select_val);
break;
}
@@ -368,6 +393,77 @@ enum mie_status mie_select_builder_set_mem_access(
return MIE_SUCCESS;
}
enum mie_status mie_select_builder_collapse_chain_ends(
struct mie_select_builder *builder, struct mie_select_value *out)
{
size_t nr_chains = b_queue_length(&builder->b_graph->g_chain_ends);
b_queue_entry *entry = NULL;
struct mie_select_chain_end *end = NULL;
switch (nr_chains) {
case 0:
memset(out, 0x0, sizeof *out);
return MIE_SUCCESS;
case 1:
entry = b_queue_first(&builder->b_graph->g_chain_ends);
end = b_unbox(struct mie_select_chain_end, entry, c_entry);
memcpy(out, end, sizeof *out);
return MIE_SUCCESS;
default:
break;
}
struct mie_type *chain_type
= mie_ctx_get_type(builder->b_ctx, MIE_TYPE_OTHER);
struct mie_select_value **operands = calloc(nr_chains, sizeof *operands);
if (!operands) {
return MIE_ERR_NO_MEMORY;
}
entry = b_queue_first(&builder->b_graph->g_chain_ends);
size_t i = 0;
while (entry) {
end = b_unbox(struct mie_select_chain_end, entry, c_entry);
operands[i++] = &end->c_value;
entry = b_queue_next(entry);
}
struct mie_select_node *group = NULL;
enum mie_status status = mie_select_graph_get_node(
builder->b_graph, mie_target_builtin(), MIE_SELECT_OP_CHAIN_GROUP,
operands, nr_chains, &chain_type, 1, &group);
free(operands);
if (status != MIE_SUCCESS) {
return status;
}
entry = b_queue_first(&builder->b_graph->g_chain_ends);
while (entry) {
end = b_unbox(struct mie_select_chain_end, entry, c_entry);
b_queue_entry *next = b_queue_next(entry);
b_queue_delete(&builder->b_graph->g_chain_ends, entry);
free(end);
entry = next;
}
struct mie_select_chain_end *group_end = malloc(sizeof *group_end);
if (!group_end) {
return MIE_ERR_NO_MEMORY;
}
memset(group_end, 0x0, sizeof *group_end);
mie_select_node_get_value(group, chain_type, 0, &group_end->c_value);
b_queue_push_back(&builder->b_graph->g_chain_ends, &group_end->c_entry);
*out = group_end->c_value;
return MIE_SUCCESS;
}
struct mie_select_node *mie_select_builder_find_node_with_ivalue(
struct mie_select_builder *builder, const struct mie_target *target,
unsigned int opcode, long long val)

View File

@@ -54,7 +54,7 @@ static b_status write_operand_const(struct mie_value *value, b_stream *out)
static void write_operand(struct mie_value *value, b_stream *out)
{
if (!value) {
b_stream_write_fmt(out, NULL, "<null>");
b_stream_write_fmt(out, NULL, "null");
return;
}
@@ -73,7 +73,7 @@ static void write_operand(struct mie_value *value, b_stream *out)
break;
default:
b_stream_write_fmt(
out, NULL, "<unknown-value:%d>", value->v_type->t_id);
out, NULL, "unknown-value:%d", value->v_type->t_id);
break;
}
}
@@ -254,9 +254,9 @@ void mie_select_graph_dump_text(struct mie_select_graph *graph)
}
}
void mie_select_graph_dump_dot(struct mie_select_graph *graph)
void mie_select_graph_dump_dot(struct mie_select_graph *graph, const char *filename)
{
FILE *fp = fopen("graph.dot", "w");
FILE *fp = fopen(filename, "w");
b_stream *tmpstream = b_stream_open_fp(fp);
@@ -284,7 +284,9 @@ void mie_select_graph_dump_dot(struct mie_select_graph *graph)
b_stream_unref(tmpstream);
system("open graph.dot");
char cmd[256];
snprintf(cmd, sizeof cmd, "open %s", filename);
system(cmd);
fclose(fp);
}

View File

@@ -62,6 +62,43 @@ void mie_select_graph_destroy(struct mie_select_graph *graph)
free(graph);
}
static enum mie_status update_chain_ends(
struct mie_select_graph *graph, struct mie_select_value *new_chain)
{
struct mie_select_node *new_node = new_chain->v_node;
b_queue_entry *entry = b_queue_first(&graph->g_chain_ends);
while (entry) {
struct mie_select_chain_end *end
= b_unbox(struct mie_select_chain_end, entry, c_entry);
struct mie_select_node *value_node = end->c_value.v_node;
for (size_t i = 0; i < new_node->n_nr_operands; i++) {
struct mie_select_node *operand_node
= new_node->n_operands[i].u_value.v_node;
if (value_node == operand_node) {
memcpy(&end->c_value, new_chain, sizeof *new_chain);
return MIE_SUCCESS;
}
}
entry = b_queue_next(entry);
}
struct mie_select_chain_end *end = malloc(sizeof *end);
if (!end) {
return MIE_ERR_NO_MEMORY;
}
memset(end, 0x0, sizeof *end);
memcpy(&end->c_value, new_chain, sizeof *new_chain);
b_queue_push_back(&graph->g_chain_ends, &end->c_entry);
return MIE_SUCCESS;
}
enum mie_status mie_select_graph_get_node(
struct mie_select_graph *graph, const struct mie_target *target,
unsigned int op, struct mie_select_value **operands, size_t nr_operands,
@@ -87,9 +124,18 @@ enum mie_status mie_select_graph_get_node(
node->n_target = target;
for (size_t i = 0; i < nr_values; i++) {
if (values[i]->t_id == MIE_TYPE_OTHER) {
graph->g_last_chain.v_node = node;
graph->g_last_chain.v_index = i;
if (values[i]->t_id != MIE_TYPE_OTHER) {
continue;
}
struct mie_select_value chain = {
.v_node = node,
.v_index = i,
};
enum mie_status status = update_chain_ends(graph, &chain);
if (status != MIE_SUCCESS) {
return status;
}
}

View File

@@ -11,15 +11,27 @@ DECLARE_INSTR_TYPE(add);
DECLARE_INSTR_TYPE(sub);
DECLARE_INSTR_TYPE(mul);
DECLARE_INSTR_TYPE(div);
DECLARE_INSTR_TYPE(cmp_eq);
DECLARE_INSTR_TYPE(cmp_neq);
DECLARE_INSTR_TYPE(cmp_lt);
DECLARE_INSTR_TYPE(cmp_gt);
DECLARE_INSTR_TYPE(cmp_leq);
DECLARE_INSTR_TYPE(cmp_geq);
DECLARE_INSTR_TYPE(load);
DECLARE_INSTR_TYPE(store);
DECLARE_INSTR_TYPE(msg);
DECLARE_INSTR_TYPE(br);
DECLARE_INSTR_TYPE(br_if);
static const struct select_instr_type *instr_types[] = {
INSTR_TYPE_ENTRY(ALLOCA, alloca), INSTR_TYPE_ENTRY(ADD, add),
INSTR_TYPE_ENTRY(SUB, sub), INSTR_TYPE_ENTRY(MUL, mul),
INSTR_TYPE_ENTRY(DIV, div), INSTR_TYPE_ENTRY(LOAD, load),
INSTR_TYPE_ENTRY(STORE, store), INSTR_TYPE_ENTRY(MSG, msg),
INSTR_TYPE_ENTRY(ALLOCA, alloca), INSTR_TYPE_ENTRY(LOAD, load),
INSTR_TYPE_ENTRY(STORE, store), INSTR_TYPE_ENTRY(MSG, msg),
INSTR_TYPE_ENTRY(BR, br), INSTR_TYPE_ENTRY(BR_IF, br_if),
INSTR_TYPE_ENTRY(ADD, add), INSTR_TYPE_ENTRY(SUB, sub),
INSTR_TYPE_ENTRY(MUL, mul), INSTR_TYPE_ENTRY(DIV, div),
INSTR_TYPE_ENTRY(CMP_EQ, cmp_eq), INSTR_TYPE_ENTRY(CMP_NEQ, cmp_neq),
INSTR_TYPE_ENTRY(CMP_LT, cmp_lt), INSTR_TYPE_ENTRY(CMP_GT, cmp_gt),
INSTR_TYPE_ENTRY(CMP_LEQ, cmp_leq), INSTR_TYPE_ENTRY(CMP_GEQ, cmp_geq),
};
static const size_t nr_instr_types = sizeof instr_types / sizeof instr_types[0];

View File

@@ -13,7 +13,7 @@ static size_t node_name(
switch (opcode) {
NODE_NAME(ENTRY, "Entry");
NODE_NAME(ROOT, "Root");
NODE_NAME(BLOCK, "Root");
NODE_NAME(BLOCK, "Block");
NODE_NAME(CONSTANT, "Constant");
NODE_NAME(FRAME_INDEX, "FrameIndex");
NODE_NAME(REGISTER, "Register");
@@ -27,6 +27,12 @@ static size_t node_name(
NODE_NAME(SUB, "Sub");
NODE_NAME(MUL, "Mul");
NODE_NAME(DIV, "Div");
NODE_NAME(CMP_EQ, "Cmp.Eq");
NODE_NAME(CMP_NEQ, "Cmp.Neq");
NODE_NAME(CMP_LT, "Cmp.Lt");
NODE_NAME(CMP_GT, "Cmp.Gt");
NODE_NAME(CMP_LEQ, "Cmp.Leq");
NODE_NAME(CMP_GEQ, "Cmp.Geq");
NODE_NAME(XOR, "Xor");
NODE_NAME(BR, "Branch");
NODE_NAME(BR_COND, "CondBranch");