Compare commits
10 Commits
8150e218ee
...
db1eba08b8
| Author | SHA1 | Date | |
|---|---|---|---|
| db1eba08b8 | |||
| 42fcfafa38 | |||
| 43f821b8d1 | |||
| 4d1918bb77 | |||
| ec8a1a72a3 | |||
| fe4abeb96d | |||
| c18d719b7d | |||
| 77791d91e3 | |||
| c8f0be14a1 | |||
| aca3c0c456 |
@@ -1,9 +1,9 @@
|
|||||||
pkg2 = {
|
pkg2 = {
|
||||||
onEnter => [
|
on-enter => [
|
||||||
cout put:'start!'
|
cout put:'start!'
|
||||||
],
|
],
|
||||||
|
|
||||||
onExit => [
|
on-exit => [
|
||||||
cout put:'end!'
|
cout put:'end!'
|
||||||
]
|
]
|
||||||
}.
|
}.
|
||||||
|
|||||||
@@ -15,32 +15,31 @@ while true do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
shiftWidth = 0
|
shift-width = 0
|
||||||
|
|
||||||
while true do
|
while true do
|
||||||
cout print:'Shift size: '
|
cout print:'Shift size: '
|
||||||
cout flush
|
cout flush
|
||||||
|
|
||||||
shiftStr = ''
|
shift-str = cin read-line.
|
||||||
cin get:shiftStr
|
|
||||||
|
|
||||||
if shiftStr == '' then
|
if shift-str == '' then
|
||||||
continue
|
continue
|
||||||
end
|
end
|
||||||
|
|
||||||
try
|
try
|
||||||
shiftWidth = Int parse:shiftStr
|
shift-width = Int parse:shift-str
|
||||||
catch (#err:number_format, err)
|
catch ($err:number-format, err)
|
||||||
continue
|
continue
|
||||||
end
|
end
|
||||||
|
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
|
||||||
encodedMessage = ''
|
encoded-message = ''
|
||||||
|
|
||||||
for c in message do
|
for c in message do
|
||||||
i = c toOrdinal
|
i = c to-ordinal
|
||||||
sub = 0
|
sub = 0
|
||||||
|
|
||||||
if i >= 65 && i <= 90 then
|
if i >= 65 && i <= 90 then
|
||||||
@@ -52,14 +51,14 @@ for c in message do
|
|||||||
end
|
end
|
||||||
|
|
||||||
i -= sub
|
i -= sub
|
||||||
i += shiftWidth
|
i += shift-width
|
||||||
|
|
||||||
if i >= 26 then
|
if i >= 26 then
|
||||||
i -= 26
|
i -= 26
|
||||||
end
|
end
|
||||||
|
|
||||||
c2 = i toChar
|
c2 = i to-char
|
||||||
encodedMessage += c2
|
encoded-message += c2
|
||||||
end
|
end
|
||||||
|
|
||||||
cout put:encodedMessage
|
cout put:encoded-message
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
try
|
try
|
||||||
x = 0
|
x = 0
|
||||||
--v = Int parse:'342'
|
--v = Int parse:'342'
|
||||||
catch ($err:number_format, err) in
|
catch ($err:number-format, err) in
|
||||||
x = 1
|
x = 1
|
||||||
--cout put:'Cannot parse integer string ({err})'
|
--cout put:'Cannot parse integer string ({err})'
|
||||||
catch (_, err) in
|
catch (_, err) in
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
y = 1 + 2 * 3 / 4 * 5 - 6 + 7 multiplyBy:2.
|
y = 1 + 2 * 3 / 4 * 5 - 6 + 7 multiply-by:2.
|
||||||
z = w = 2 + 3 multiplyBy:2.
|
z = w = 2 + 3 multiply-by:2.
|
||||||
x = (((1 + 2 * 3) multiplyBy:3) add: 5) + 2.
|
x = (((1 + 2 * 3) multiply-by:3) add: 5) + 2.
|
||||||
x = ((1 + 2 * 3) multiplyBy:3).
|
x = ((1 + 2 * 3) multiply-by:3).
|
||||||
p = 5 multiply(by:3, add:(2 + 1)).
|
p = 5 multiply(by:3, add:(2 + 1)).
|
||||||
q = 10 squared squared.
|
q = 10 squared squared.
|
||||||
|
|
||||||
p1
|
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".
|
in:"mon" + "ths".
|
||||||
|
|
||||||
m = xz multiply(by:3 add:2) squared.
|
m = xz multiply(by:3 add:2) squared.
|
||||||
@@ -20,7 +20,7 @@ x = OrderedCollection new
|
|||||||
yourself.
|
yourself.
|
||||||
|
|
||||||
age = Person new(name:"John Doe", age:34)
|
age = Person new(name:"John Doe", age:34)
|
||||||
setAge:144 inUnit:"months";
|
set-age:144 in-unit:"months";
|
||||||
ageInMonths.
|
ageInMonths.
|
||||||
|
|
||||||
x = 5.
|
x = 5.
|
||||||
@@ -76,10 +76,10 @@ pkg = { 1, 2, 3, 4, 5 }.
|
|||||||
pkg = { 10, 2 => "Hello", 9, 5 => "World", 14 }.
|
pkg = { 10, 2 => "Hello", 9, 5 => "World", 14 }.
|
||||||
pkg = { { 0 }, { 1 }, { y for y in huh } }.
|
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.
|
pkg->x = 32.
|
||||||
k = (1 multiplyBy:2, 4).
|
k = (1 multiply-by:2, 4).
|
||||||
|
|
||||||
for (x, y) in pkg do
|
for (x, y) in pkg do
|
||||||
cout put:'{x}: {y}'
|
cout put:'{x}: {y}'
|
||||||
@@ -97,11 +97,11 @@ v = pkg->x.
|
|||||||
v = pkg at:'x'.
|
v = pkg at:'x'.
|
||||||
|
|
||||||
pkg2 = {
|
pkg2 = {
|
||||||
onEnter => [
|
on-enter => [
|
||||||
cout put:'start!'
|
cout put:'start!'
|
||||||
],
|
],
|
||||||
|
|
||||||
onExit => [
|
on-exit => [
|
||||||
cout put:'end!'
|
cout put:'end!'
|
||||||
]
|
]
|
||||||
}.
|
}.
|
||||||
|
|||||||
@@ -58,13 +58,13 @@ class Person
|
|||||||
|
|
||||||
- age | ^self::age.
|
- 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
|
match units in
|
||||||
$years => self::age = age,
|
$years => self::age = age,
|
||||||
$months => self::age = age / 12,
|
$months => self::age = age / 12,
|
||||||
@@ -72,7 +72,7 @@ class Person
|
|||||||
_ => self::age = 0
|
_ => self::age = 0
|
||||||
end!
|
end!
|
||||||
|
|
||||||
- getAgeInUnit:units
|
- get-age-in-units:units
|
||||||
^match units in
|
^match units in
|
||||||
$years => self::age,
|
$years => self::age,
|
||||||
$months => self::age / 12,
|
$months => self::age / 12,
|
||||||
@@ -104,12 +104,12 @@ class Person
|
|||||||
is converted to the lambda
|
is converted to the lambda
|
||||||
[ :x | self::val = x ]
|
[ :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:
|
/* Without the lambda synthesis, the property would look like this:
|
||||||
Note that this is the only time it is legal to access private fields
|
Note that this is the only time it is legal to access private fields
|
||||||
via `self` from a lambda. */
|
via `self` from a lambda. */
|
||||||
-> exampleProperty |
|
-> example-property |
|
||||||
get => [ ^self::val ],
|
get => [ ^self::val ],
|
||||||
set => [ :x | self::val = x ].
|
set => [ :x | self::val = x ].
|
||||||
|
|
||||||
@@ -119,7 +119,7 @@ class Person
|
|||||||
|
|
||||||
If either the `set` or `get` elements are not provided, the property
|
If either the `set` or `get` elements are not provided, the property
|
||||||
becomes read-only or write-only respectively */
|
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,
|
/* A property can also be configured to act just like a regular variable,
|
||||||
by setting the getter and setters to default implementations.
|
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
|
Similarly, the default setter will set the value of a private member
|
||||||
variable named by prepending two underscores to the property name
|
variable named by prepending two underscores to the property name
|
||||||
(__exampleProperty3 in this case) to the value provided to the setter. */
|
(__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
|
/* Just like in the earlier examples, either `get` or `set` can be omitted
|
||||||
to create a write-only or read-only property respectively */
|
to create a write-only or read-only property respectively */
|
||||||
-> exampleProperty4 (get)
|
-> example-property-4 (get)
|
||||||
end
|
end
|
||||||
|
|
||||||
p1 = Person new(name:'John Doe', age:34).
|
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').
|
p1 test(param:'Hello', 'World').
|
||||||
|
|
||||||
@@ -299,7 +299,7 @@ a = (32, 64).
|
|||||||
|
|
||||||
try
|
try
|
||||||
v = Int parse:'342'
|
v = Int parse:'342'
|
||||||
catch ($err:number_format, err) in
|
catch ($err:number-format, err) in
|
||||||
cout put:'Cannot parse integer string ({err})'
|
cout put:'Cannot parse integer string ({err})'
|
||||||
catch (_, err) in
|
catch (_, err) in
|
||||||
cout put:'Unknown error occurred ({err})'
|
cout put:'Unknown error occurred ({err})'
|
||||||
@@ -308,7 +308,7 @@ end
|
|||||||
/* equivalent 'pure' syntax */
|
/* equivalent 'pure' syntax */
|
||||||
|
|
||||||
[ v = Int parse:'342' ]
|
[ 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})'
|
cout put:'Cannot parse integer string ({err})'
|
||||||
];
|
];
|
||||||
onError:[ :err :data |
|
onError:[ :err :data |
|
||||||
@@ -382,10 +382,10 @@ cout put:'Hello, world!' if x > 10.
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
p1
|
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'.
|
in:'mon' + 'ths'.
|
||||||
(p1
|
(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')).
|
in:('mon' + 'ths')).
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@@ -440,7 +440,7 @@ pkg2 = pkg1 map:[ :x | ^x * 2 ].
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
age = Person new(name:'John Doe', age:34);
|
age = Person new(name:'John Doe', age:34);
|
||||||
setAge:144 inUnit:$months;
|
set-age:144 in-unit:$months;
|
||||||
ageInMonths.
|
ageInMonths.
|
||||||
|
|
||||||
-- age now has the value 144
|
-- age now has the value 144
|
||||||
@@ -448,7 +448,7 @@ age = Person new(name:'John Doe', age:34);
|
|||||||
|
|
||||||
age = do
|
age = do
|
||||||
x = Person new(name:'John Doe', age:34).
|
x = Person new(name:'John Doe', age:34).
|
||||||
x setAge:144 inUnit:$months.
|
x set-age:144 in-unit:$months.
|
||||||
x ageInMonths
|
x ageInMonths
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -471,15 +471,15 @@ end
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
p1 = Person new(name:'John Doe', age:34);
|
p1 = Person new(name:'John Doe', age:34);
|
||||||
setAge:100 inUnit:$months;
|
set-age:100 in-unit:$months;
|
||||||
yourself::
|
yourself
|
||||||
|
|
||||||
/* p1 now contains the Person object */
|
/* p1 now contains the Person object */
|
||||||
/* again, with do..end */
|
/* again, with do..end */
|
||||||
|
|
||||||
p1 = do
|
p1 = do
|
||||||
x = Person new(name:'John Doe', age:34).
|
x = Person new(name:'John Doe', age:34).
|
||||||
x setAge:100 inUnit:$months.
|
x set-age:100 in-unit:$months.
|
||||||
x
|
x
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|||||||
@@ -1,27 +1,27 @@
|
|||||||
y = 1 + 2 * 3 / 4 * 5 - 6 + 7 multiplyBy:2.
|
y = -1 + 2 * 3 / 4 * 5 - 6 + 7 multiply-by:2.
|
||||||
z = w = 2 + 3 multiplyBy:2.
|
z = w = 2 + 3 multiply-by:2.
|
||||||
x = (((1 + 2 * 3) multiplyBy:3) add: 5) + 2.
|
x = (((1 + 2 * 3) multiply-by:3) add: 5) + 2.
|
||||||
x = ((1 + 2 * 3) multiplyBy:3).
|
x = ((1 + 2 * 3) multiply-by:3).
|
||||||
p = 5 multiply(by:3, add:(2 + 1)).
|
p = 5 multiply(by:3, add:(2 + 1)).
|
||||||
q = 10 squared squared.
|
q = 10 squared squared.
|
||||||
|
|
||||||
p1
|
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".
|
in:"mon" + "ths".
|
||||||
|
|
||||||
m = xz multiply(by:3 add:2) squared.
|
m = xz multiply(by:3 add:2) squared.
|
||||||
|
|
||||||
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: 2;
|
||||||
add: 4;
|
add: 4;
|
||||||
add: 6;
|
add: 6;
|
||||||
yourself.
|
yourself.
|
||||||
|
|
||||||
age = Person new(name:"John Doe", age:34)
|
age = Person new(name:"John Doe", age:34)
|
||||||
setAge:144 inUnit:"months";
|
set-age:144 in-unit:"months";
|
||||||
ageInMonths.
|
age-in-months.
|
||||||
|
|
||||||
x = 5.
|
x = 5.
|
||||||
q = 10 if x > 2 else 20.
|
q = 10 if x > 2 else 20.
|
||||||
|
|||||||
@@ -3,4 +3,4 @@ package net.doorstuck.test
|
|||||||
s1 = 'hello world'
|
s1 = 'hello world'
|
||||||
|
|
||||||
s2 = s1 map:[ :c | ^c uppercase ]
|
s2 = s1 map:[ :c | ^c uppercase ]
|
||||||
s3 = s1 map:[ :c | ^((c ordinal) + 1) toChar ]
|
s3 = s1 map:[ :c | ^((c ordinal) + 1) to-char ]
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ while true do
|
|||||||
cout flush.
|
cout flush.
|
||||||
|
|
||||||
v = 0.
|
v = 0.
|
||||||
input = cin readLine.
|
input = cin read-line.
|
||||||
|
|
||||||
if input == '' then
|
if input == '' then
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ package net.doorstuck.vehicles
|
|||||||
protocol Vehicle
|
protocol Vehicle
|
||||||
- startup
|
- startup
|
||||||
- shutdown
|
- shutdown
|
||||||
- nrWheels
|
- nr-wheels
|
||||||
- nrDoors
|
- nr-doors
|
||||||
- turn(direction:dir)
|
- turn(direction:dir)
|
||||||
- accelerate(direction:dir)
|
- accelerate(direction:dir)
|
||||||
- velocity
|
- velocity
|
||||||
@@ -12,33 +12,33 @@ end
|
|||||||
|
|
||||||
class Car <Vehicle>
|
class Car <Vehicle>
|
||||||
- startup
|
- startup
|
||||||
self.engineRunning = true
|
self.engine-running = true
|
||||||
end
|
end
|
||||||
|
|
||||||
- shutdown
|
- shutdown
|
||||||
self.engineRunning = false
|
self.engine-running = false
|
||||||
end
|
end
|
||||||
|
|
||||||
- nrWheels
|
- nr-wheels
|
||||||
^4
|
^4
|
||||||
end
|
end
|
||||||
|
|
||||||
- nrDoors
|
- nr-doors
|
||||||
^4
|
^4
|
||||||
end
|
end
|
||||||
|
|
||||||
- turn(direction:dir)
|
- turn(direction:dir)
|
||||||
self.currentDirection = dir
|
self.current-direction = dir
|
||||||
end
|
end
|
||||||
|
|
||||||
- accelerate(direction:dir)
|
- accelerate(direction:dir)
|
||||||
match dir
|
match dir
|
||||||
#forward => self.currentVelocity += 1,
|
$forward => self.current-velocity += 1,
|
||||||
#backward => self.currentVelocity -= 1,
|
$backward => self.current-velocity -= 1,
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
- velicity
|
- velocity
|
||||||
^self.currentVelocity
|
^self.current-velocity
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -30,10 +30,10 @@ version: 1.0
|
|||||||
|
|
||||||
-is:
|
-is:
|
||||||
-implements:
|
-implements:
|
||||||
-respondsTo:
|
-responds-to:
|
||||||
-doesNotUnderstand(selector:args:)
|
-does-not-understand(selector:args:)
|
||||||
-sendMsg(selector:args:)
|
-send-msg(selector:args:)
|
||||||
-toString
|
-to-string
|
||||||
|
|
||||||
|
|
||||||
3.2 Int
|
3.2 Int
|
||||||
@@ -78,8 +78,8 @@ version: 1.0
|
|||||||
|
|
||||||
-size
|
-size
|
||||||
-exists:
|
-exists:
|
||||||
-put:at:
|
-at:
|
||||||
-get:
|
-at:put:
|
||||||
-map:
|
-map:
|
||||||
-select:
|
-select:
|
||||||
-select:collect:
|
-select:collect:
|
||||||
@@ -92,7 +92,7 @@ version: 1.0
|
|||||||
Messages:
|
Messages:
|
||||||
|
|
||||||
-value
|
-value
|
||||||
-moveNext
|
-move-next
|
||||||
-select:
|
-select:
|
||||||
-select:collect:
|
-select:collect:
|
||||||
-iterator
|
-iterator
|
||||||
@@ -103,7 +103,7 @@ version: 1.0
|
|||||||
|
|
||||||
Messages:
|
Messages:
|
||||||
|
|
||||||
-argCount
|
-arg-count
|
||||||
-call
|
-call
|
||||||
-call:
|
-call:
|
||||||
-call(_:_:)
|
-call(_:_:)
|
||||||
@@ -130,7 +130,7 @@ version: 1.0
|
|||||||
|
|
||||||
-msg
|
-msg
|
||||||
-data
|
-data
|
||||||
-withMsg:andData:
|
-with-msg:and-data:
|
||||||
|
|
||||||
|
|
||||||
4 std.io
|
4 std.io
|
||||||
|
|||||||
@@ -4,9 +4,30 @@ endif
|
|||||||
|
|
||||||
let s:save_cpo = &cpoptions
|
let s:save_cpo = &cpoptions
|
||||||
set cpoptions&vim
|
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
|
" 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
|
" 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 ivyBuiltinVar /\(error\|cout\|cin\|cerr\)\>\(\:\)\@!/
|
||||||
syn match ivyUnspecifiedStatement /\(var\|end\|package\|use\|as\|then\|in\|do\|get\|set\)\>\(\:\)\@!/
|
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 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\)\@=\>/
|
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 ivyBraces "[{}]" display
|
||||||
syn match ivyBrackets "[[\]]" display
|
syn match ivyBrackets "[[\]]" display
|
||||||
syn match ivyParens "[()]" 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 "::" display
|
||||||
syn match ivyOpSymbols "=\{1,2}" display
|
syn match ivyOpSymbols "=\{1,2}" display
|
||||||
syn match ivyOpSymbols ">\{1,2}" 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 ivyOtherSymbols "=>" display
|
||||||
syn match ivyLambdaSymbols "|" display
|
|
||||||
syn match ivyLogicSymbols "&&" display
|
syn match ivyLogicSymbols "&&" display
|
||||||
syn match ivyLogicSymbols "||" display
|
syn match ivyLogicSymbols "||" display
|
||||||
syn match ivyStatementSeparator "\.\s*" 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
|
syn keyword ivyWordOperator is not understands and or
|
||||||
|
|
||||||
" PROVIDES: @ivyCommentHook
|
" PROVIDES: @ivyCommentHook
|
||||||
@@ -94,6 +92,7 @@ syn match ivyCharacter "'[^\\]'" display
|
|||||||
syn case ignore
|
syn case ignore
|
||||||
syn match ivyInteger "\<0b[01_]*[01]\%([lu]\|lu\|ul\)\=\>" display
|
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 "\<-\d\+\%(_\+\d\+\)*\%([lu]\|lu\|ul\)\=\>" display
|
||||||
syn match ivyInteger "\<0x[[:xdigit:]_]*\x\%([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\+\)*\.\d\+\%(_\+\d\+\)*\%\(e[-+]\=\d\+\%(_\+\d\+\)*\)\=[fdm]\=" display
|
||||||
syn match ivyReal "\.\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 ivySpecialChar SpecialChar
|
||||||
hi def link ivyInteger Number
|
hi def link ivyInteger Number
|
||||||
hi def link ivyReal Float
|
hi def link ivyReal Float
|
||||||
|
hi def link ivyWord Identifier
|
||||||
hi def link ivyUnicodeNumber SpecialChar
|
hi def link ivyUnicodeNumber SpecialChar
|
||||||
hi def link ivyUnicodeSpecifier SpecialChar
|
hi def link ivyUnicodeSpecifier SpecialChar
|
||||||
hi def link ivyInterpolationDelimiter Delimiter
|
hi def link ivyInterpolationDelimiter Delimiter
|
||||||
|
|||||||
@@ -76,6 +76,8 @@ static void to_string(struct ivy_ast_node *node, b_string *str)
|
|||||||
|
|
||||||
b_string_append_cstr(str, tok->t_str);
|
b_string_append_cstr(str, tok->t_str);
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
|
entry = b_queue_next(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
b_string_append_cstr(str, ")");
|
b_string_append_cstr(str, ")");
|
||||||
|
|||||||
@@ -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_builder *builder, struct mie_value *ir_val,
|
||||||
struct mie_select_value *graph_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
|
#endif
|
||||||
|
|||||||
@@ -21,11 +21,16 @@ struct mie_select_use {
|
|||||||
b_queue_entry u_entry;
|
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 {
|
struct mie_select_graph {
|
||||||
b_queue g_nodes;
|
b_queue g_nodes;
|
||||||
struct mie_select_node *g_root;
|
struct mie_select_node *g_root;
|
||||||
struct mie_select_value g_entry;
|
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_frame_index;
|
||||||
size_t g_node_id;
|
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);
|
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_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
|
#endif
|
||||||
|
|||||||
@@ -20,6 +20,12 @@ enum mie_select_opcode {
|
|||||||
MIE_SELECT_OP_MUL,
|
MIE_SELECT_OP_MUL,
|
||||||
MIE_SELECT_OP_DIV,
|
MIE_SELECT_OP_DIV,
|
||||||
MIE_SELECT_OP_XOR,
|
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,
|
||||||
MIE_SELECT_OP_BR_COND,
|
MIE_SELECT_OP_BR_COND,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -581,7 +581,7 @@ struct mie_value *mie_builder_cmp_eq(
|
|||||||
|
|
||||||
sub->op_left = left;
|
sub->op_left = left;
|
||||||
sub->op_right = right;
|
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)) {
|
if (!mie_block_add_instr(builder->b_current_block, &sub->op_base)) {
|
||||||
free(sub);
|
free(sub);
|
||||||
@@ -617,7 +617,7 @@ struct mie_value *mie_builder_cmp_neq(
|
|||||||
|
|
||||||
sub->op_left = left;
|
sub->op_left = left;
|
||||||
sub->op_right = right;
|
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)) {
|
if (!mie_block_add_instr(builder->b_current_block, &sub->op_base)) {
|
||||||
free(sub);
|
free(sub);
|
||||||
@@ -653,7 +653,7 @@ struct mie_value *mie_builder_cmp_lt(
|
|||||||
|
|
||||||
sub->op_left = left;
|
sub->op_left = left;
|
||||||
sub->op_right = right;
|
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)) {
|
if (!mie_block_add_instr(builder->b_current_block, &sub->op_base)) {
|
||||||
free(sub);
|
free(sub);
|
||||||
@@ -689,7 +689,7 @@ struct mie_value *mie_builder_cmp_gt(
|
|||||||
|
|
||||||
sub->op_left = left;
|
sub->op_left = left;
|
||||||
sub->op_right = right;
|
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)) {
|
if (!mie_block_add_instr(builder->b_current_block, &sub->op_base)) {
|
||||||
free(sub);
|
free(sub);
|
||||||
@@ -725,7 +725,7 @@ struct mie_value *mie_builder_cmp_leq(
|
|||||||
|
|
||||||
sub->op_left = left;
|
sub->op_left = left;
|
||||||
sub->op_right = right;
|
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)) {
|
if (!mie_block_add_instr(builder->b_current_block, &sub->op_base)) {
|
||||||
free(sub);
|
free(sub);
|
||||||
@@ -761,7 +761,7 @@ struct mie_value *mie_builder_cmp_geq(
|
|||||||
|
|
||||||
sub->op_left = left;
|
sub->op_left = left;
|
||||||
sub->op_right = right;
|
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)) {
|
if (!mie_block_add_instr(builder->b_current_block, &sub->op_base)) {
|
||||||
free(sub);
|
free(sub);
|
||||||
|
|||||||
@@ -50,8 +50,20 @@ DEFINE_PUSH_FUNCTION(add, MIE_SELECT_OP_ADD);
|
|||||||
DEFINE_PUSH_FUNCTION(sub, MIE_SELECT_OP_SUB);
|
DEFINE_PUSH_FUNCTION(sub, MIE_SELECT_OP_SUB);
|
||||||
DEFINE_PUSH_FUNCTION(mul, MIE_SELECT_OP_MUL);
|
DEFINE_PUSH_FUNCTION(mul, MIE_SELECT_OP_MUL);
|
||||||
DEFINE_PUSH_FUNCTION(div, MIE_SELECT_OP_DIV);
|
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(add);
|
||||||
DEFINE_OP(sub);
|
DEFINE_OP(sub);
|
||||||
DEFINE_OP(mul);
|
DEFINE_OP(mul);
|
||||||
DEFINE_OP(div);
|
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
171
mie/select/br.c
Normal 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,
|
||||||
|
};
|
||||||
@@ -94,18 +94,6 @@ const struct mie_target *mie_select_builder_get_target(
|
|||||||
return builder->b_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)
|
struct mie_select_graph *mie_select_builder_finish(struct mie_select_builder *builder)
|
||||||
{
|
{
|
||||||
enum mie_status status = MIE_SUCCESS;
|
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;
|
size_t nr_root_operands = 0;
|
||||||
|
|
||||||
if (graph->g_last_chain.v_node) {
|
struct mie_select_value incoming_chain = {};
|
||||||
root_operands[0] = &graph->g_last_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++;
|
nr_root_operands++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,9 +123,13 @@ struct mie_select_graph *mie_select_builder_finish(struct mie_select_builder *bu
|
|||||||
return NULL;
|
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;
|
return graph;
|
||||||
}
|
}
|
||||||
@@ -251,6 +249,32 @@ static enum mie_status get_data_node(
|
|||||||
return MIE_SUCCESS;
|
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_value *mie_select_builder_get_value(
|
||||||
struct mie_select_builder *builder, struct mie_value *ir_val)
|
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);
|
status = get_data_node(builder, ir_val, select_val);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
status = get_external_value_node(builder, ir_val, select_val);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -368,6 +393,77 @@ enum mie_status mie_select_builder_set_mem_access(
|
|||||||
return MIE_SUCCESS;
|
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_node *mie_select_builder_find_node_with_ivalue(
|
||||||
struct mie_select_builder *builder, const struct mie_target *target,
|
struct mie_select_builder *builder, const struct mie_target *target,
|
||||||
unsigned int opcode, long long val)
|
unsigned int opcode, long long val)
|
||||||
|
|||||||
@@ -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)
|
static void write_operand(struct mie_value *value, b_stream *out)
|
||||||
{
|
{
|
||||||
if (!value) {
|
if (!value) {
|
||||||
b_stream_write_fmt(out, NULL, "<null>");
|
b_stream_write_fmt(out, NULL, "null");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ static void write_operand(struct mie_value *value, b_stream *out)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
b_stream_write_fmt(
|
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;
|
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);
|
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);
|
b_stream_unref(tmpstream);
|
||||||
|
|
||||||
system("open graph.dot");
|
char cmd[256];
|
||||||
|
snprintf(cmd, sizeof cmd, "open %s", filename);
|
||||||
|
system(cmd);
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,6 +62,43 @@ void mie_select_graph_destroy(struct mie_select_graph *graph)
|
|||||||
free(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(
|
enum mie_status mie_select_graph_get_node(
|
||||||
struct mie_select_graph *graph, const struct mie_target *target,
|
struct mie_select_graph *graph, const struct mie_target *target,
|
||||||
unsigned int op, struct mie_select_value **operands, size_t nr_operands,
|
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;
|
node->n_target = target;
|
||||||
|
|
||||||
for (size_t i = 0; i < nr_values; i++) {
|
for (size_t i = 0; i < nr_values; i++) {
|
||||||
if (values[i]->t_id == MIE_TYPE_OTHER) {
|
if (values[i]->t_id != MIE_TYPE_OTHER) {
|
||||||
graph->g_last_chain.v_node = node;
|
continue;
|
||||||
graph->g_last_chain.v_index = i;
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,15 +11,27 @@ DECLARE_INSTR_TYPE(add);
|
|||||||
DECLARE_INSTR_TYPE(sub);
|
DECLARE_INSTR_TYPE(sub);
|
||||||
DECLARE_INSTR_TYPE(mul);
|
DECLARE_INSTR_TYPE(mul);
|
||||||
DECLARE_INSTR_TYPE(div);
|
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(load);
|
||||||
DECLARE_INSTR_TYPE(store);
|
DECLARE_INSTR_TYPE(store);
|
||||||
DECLARE_INSTR_TYPE(msg);
|
DECLARE_INSTR_TYPE(msg);
|
||||||
|
DECLARE_INSTR_TYPE(br);
|
||||||
|
DECLARE_INSTR_TYPE(br_if);
|
||||||
|
|
||||||
static const struct select_instr_type *instr_types[] = {
|
static const struct select_instr_type *instr_types[] = {
|
||||||
INSTR_TYPE_ENTRY(ALLOCA, alloca), INSTR_TYPE_ENTRY(ADD, add),
|
INSTR_TYPE_ENTRY(ALLOCA, alloca), INSTR_TYPE_ENTRY(LOAD, load),
|
||||||
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(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];
|
static const size_t nr_instr_types = sizeof instr_types / sizeof instr_types[0];
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ static size_t node_name(
|
|||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
NODE_NAME(ENTRY, "Entry");
|
NODE_NAME(ENTRY, "Entry");
|
||||||
NODE_NAME(ROOT, "Root");
|
NODE_NAME(ROOT, "Root");
|
||||||
NODE_NAME(BLOCK, "Root");
|
NODE_NAME(BLOCK, "Block");
|
||||||
NODE_NAME(CONSTANT, "Constant");
|
NODE_NAME(CONSTANT, "Constant");
|
||||||
NODE_NAME(FRAME_INDEX, "FrameIndex");
|
NODE_NAME(FRAME_INDEX, "FrameIndex");
|
||||||
NODE_NAME(REGISTER, "Register");
|
NODE_NAME(REGISTER, "Register");
|
||||||
@@ -27,6 +27,12 @@ static size_t node_name(
|
|||||||
NODE_NAME(SUB, "Sub");
|
NODE_NAME(SUB, "Sub");
|
||||||
NODE_NAME(MUL, "Mul");
|
NODE_NAME(MUL, "Mul");
|
||||||
NODE_NAME(DIV, "Div");
|
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(XOR, "Xor");
|
||||||
NODE_NAME(BR, "Branch");
|
NODE_NAME(BR, "Branch");
|
||||||
NODE_NAME(BR_COND, "CondBranch");
|
NODE_NAME(BR_COND, "CondBranch");
|
||||||
|
|||||||
Reference in New Issue
Block a user