kaiser-ruby 0.2.3 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +32 -0
- data/Gemfile.lock +1 -1
- data/README.md +33 -1
- data/TODO.md +11 -31
- data/lib/kaiser_ruby.rb +1 -0
- data/lib/kaiser_ruby/cli.rb +2 -0
- data/lib/kaiser_ruby/rockstar_parser.rb +138 -18
- data/lib/kaiser_ruby/rockstar_transform.rb +140 -4
- data/lib/kaiser_ruby/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e49970a2460c4b355e49a2dd465dae3035c135caa619d11b43b7b47b09166676
|
4
|
+
data.tar.gz: cde51c100d01c71158aa70b10af6e91400cd53322165b2a34c2d85db994a1aab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b2a0a4d21511e943449860b4058be59f186937447c7accd22fc44d8487792392baee54d33f76f6248c27478d82ef5d1702e352826d5066677f04c89cd795ce2f
|
7
|
+
data.tar.gz: 9f7aa127cd0a2aa13c9ba523073ea96d01aaa6ebcc104a7c1974bd8387dcba176dfa6bb1089b846f2d753693b19ed5fdd7f4bb302769dc389bbfa51034da21a8
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# 0.1
|
2
|
+
|
3
|
+
- [x] Initial implementation of the Rockstar Language based using `Parslet::Parser`
|
4
|
+
|
5
|
+
# 0.2
|
6
|
+
|
7
|
+
- [x] Rewrote the Parser and Transform classes from scratch
|
8
|
+
- [x] basic CLI and REPL
|
9
|
+
- [x] Metal umlauts
|
10
|
+
- [x] Most variable types, assignmnents, output, conditionals are working.
|
11
|
+
|
12
|
+
# 0.3
|
13
|
+
|
14
|
+
Language Implementation:
|
15
|
+
|
16
|
+
- [x] Handle null type differently - nil in Ruby isn't really comparable to 0
|
17
|
+
- [x] Handle mysterious type - probably this should be nil and what is now nil should be 0 instead
|
18
|
+
- [x] Handle gt, gte, lt, lte comparisons
|
19
|
+
- [x] Handle inequality
|
20
|
+
- [x] While loop
|
21
|
+
- [x] Until loop
|
22
|
+
- [x] Break and continue
|
23
|
+
- [x] And/Or keywords for conditionals
|
24
|
+
- [x] Define functions
|
25
|
+
- [x] Handle function calls
|
26
|
+
- [x] Return can return math operations directly
|
27
|
+
|
28
|
+
Other stuff:
|
29
|
+
|
30
|
+
- [x] FizzBuzz example is working
|
31
|
+
- [x] Fibonacci example is working
|
32
|
+
- [x] Added comments to resulting ruby code flow control statements, so it's easier to see where what ends. This should help making the code more readable (and easier to figure out if it's actually correct), at least while the indentation feature is not fully working yet.
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
This tool translates a file containing a program written in the [Rockstar language](https://github.com/dylanbeattie/rockstar) to Ruby code.
|
4
4
|
|
5
|
-
This is still a work in progress. For details on
|
5
|
+
This is still a work in progress, however most of the language implementation is already finished and working (as are the fibonacci sequence and fizzbuzz examples in the repository). For details on what is done, see the TODO.md and CHANGELOG.md files.
|
6
6
|
|
7
7
|
## Installation
|
8
8
|
|
@@ -73,6 +73,38 @@ $ kaiser-ruby execute ./examples/assignment.rock
|
|
73
73
|
|
74
74
|
```
|
75
75
|
|
76
|
+
Or even better, this:
|
77
|
+
|
78
|
+
```
|
79
|
+
$ kaiser-ruby execute ./examples/fibonacci.rock
|
80
|
+
1
|
81
|
+
1
|
82
|
+
2
|
83
|
+
3
|
84
|
+
5
|
85
|
+
8
|
86
|
+
13
|
87
|
+
21
|
88
|
+
34
|
89
|
+
55
|
90
|
+
89
|
91
|
+
144
|
92
|
+
233
|
93
|
+
377
|
94
|
+
610
|
95
|
+
987
|
96
|
+
1597
|
97
|
+
2584
|
98
|
+
4181
|
99
|
+
6765
|
100
|
+
10946
|
101
|
+
17711
|
102
|
+
28657
|
103
|
+
46368
|
104
|
+
|
105
|
+
$
|
106
|
+
```
|
107
|
+
|
76
108
|
## Contributing
|
77
109
|
|
78
110
|
Bug reports and pull requests are welcome on GitHub at https://github.com/marcinruszkiewicz/kaiser-ruby.
|
data/TODO.md
CHANGED
@@ -1,48 +1,28 @@
|
|
1
1
|
# TODO notes for KaiserRuby transpiler
|
2
2
|
|
3
|
-
##
|
3
|
+
## Language Implementation
|
4
4
|
|
5
5
|
- [ ] Handle pronouns - he, she, it, and others should refer to the last used variable
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
- [x] Handle null type differently - nil in Ruby isn't really comparable to 0
|
10
|
-
- [x] Handle mysterious type - probably this should be nil and what is now nil should be 0 instead
|
6
|
+
- [ ] Handle "Janie's got a gun"
|
7
|
+
- [ ] Ignore comments in parentheses
|
11
8
|
- [ ] Handle object type
|
12
|
-
|
13
|
-
## Comparisons
|
14
|
-
|
15
|
-
- [ ] Handle gt, gte, lt, lte comparisons
|
16
|
-
- [ ] Handle negation
|
17
|
-
|
18
|
-
## Input
|
19
|
-
|
20
9
|
- [ ] Handle input from STDIN
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
- [ ] While loop
|
25
|
-
- [ ] Until loop
|
26
|
-
- [ ] Break and continue
|
27
|
-
|
28
|
-
## Functions
|
29
|
-
|
30
|
-
- [ ] Define functions
|
31
|
-
- [ ] Handle function calls
|
10
|
+
- [ ] Function calls can be used as expressions in flow statements
|
11
|
+
- [ ] Handle ',' instead of 'and' in function calls
|
12
|
+
- [ ] Somehow handle function variable scope
|
32
13
|
|
33
14
|
## Examples
|
34
15
|
|
35
|
-
- [ ] FizzBuzz example (should also be in tests to check if it runs)
|
36
16
|
- [ ] Should be able to run the [Cellular Rockomata](https://github.com/Rifhutch/cellular-rocktomata)
|
37
17
|
- [ ] Fibonacci example https://github.com/dylanbeattie/rockstar/issues/94#issuecomment-408217504
|
38
18
|
- [ ] Math module https://gist.github.com/wrenoud/6be6f7509c88a3d8f9867ae782fb768f
|
39
19
|
- [ ] Primality checker https://www.reddit.com/r/RockstarDevs/comments/92i6sm/primality_checker_in_rockstar/
|
20
|
+
- [ ] Make a demo command in the CLI that runs all examples (would that even work as a gem? it should be doable somehow)
|
40
21
|
|
41
22
|
## Other stuff
|
42
23
|
|
43
|
-
- [x] Test if it handles metal umlauts (Ruby shouldn't care much, but tests should be made)
|
44
|
-
- [ ] Ignore comments in parentheses
|
45
|
-
- [x] Nicely indent blocks
|
46
24
|
- [ ] Fix indenting of nested blocks that doesn't really work well
|
47
|
-
- [
|
48
|
-
- [ ]
|
25
|
+
- [ ] Add code history to the REPL
|
26
|
+
- [ ] Make REPL work with multiline input also, not only singular lines
|
27
|
+
- [ ] Better error handling
|
28
|
+
- [ ] Suppress warnign about eval from Thor
|
data/lib/kaiser_ruby.rb
CHANGED
data/lib/kaiser_ruby/cli.rb
CHANGED
@@ -1,10 +1,15 @@
|
|
1
1
|
module KaiserRuby
|
2
2
|
class RockstarParser < Parslet::Parser
|
3
|
+
# ORDER OF THESE RULES ABSOLUTELY MATTERS
|
4
|
+
# DON'T MESS WITH IT
|
5
|
+
|
6
|
+
# all the keywords separately, so that variable names can't use them
|
7
|
+
|
3
8
|
rule(:reserved) do
|
4
9
|
mysterious_value_keywords | null_value_keywords | true_value_keywords | false_value_keywords |
|
5
|
-
plus_keywords | minus_keywords | times_keywords | over_keywords |
|
6
|
-
|
7
|
-
|
10
|
+
plus_keywords | minus_keywords | times_keywords | over_keywords | increment_keywords |
|
11
|
+
assignment_keywords | poetic_string_keywords | poetic_number_keywords |
|
12
|
+
say_keywords | flow_keywords | comparison_keywords | function_keywords
|
8
13
|
end
|
9
14
|
|
10
15
|
rule(:mysterious_value_keywords) { str('mysterious') }
|
@@ -19,6 +24,14 @@ module KaiserRuby
|
|
19
24
|
rule(:poetic_number_keywords) { str('is') | str('was') | str('were') }
|
20
25
|
rule(:say_keywords) { str('Say') | str('Shout') | str('Scream') | str('Whisper') }
|
21
26
|
rule(:flow_keywords) { str('If') | str('Else') | str('While') | str('Until') }
|
27
|
+
rule(:increment_keywords) { str('Knock') | str('Build') }
|
28
|
+
rule(:assignment_keywords) { str('Put') | str('into') }
|
29
|
+
rule(:poetic_string_keywords) { str('says') }
|
30
|
+
rule(:comparison_keywords) { str("is") | not_keywords | gt_keywords | gte_keywords | lt_keywords | lte_keywords }
|
31
|
+
rule(:function_keywords) { str('Break it down') | str('Take it to the top') | str('Give back') | str('takes') | str('taking') }
|
32
|
+
|
33
|
+
# variable names
|
34
|
+
# using [[:upper:]] etc here allows for metal umlauts and other UTF characters
|
22
35
|
|
23
36
|
rule(:proper_word) { reserved.absent? >> match['[[:upper:]]'] >> match['[[:alpha:]]'].repeat }
|
24
37
|
rule(:common_variable_name) do
|
@@ -28,16 +41,18 @@ module KaiserRuby
|
|
28
41
|
str('The ') | str('the ') |
|
29
42
|
str('My ') | str('my ') |
|
30
43
|
str('Your ') | str('your ')
|
31
|
-
) >> reserved.absent? >> match['[[:lower:]]'].repeat
|
44
|
+
) >> reserved.absent? >> match['[[:lower:]]'].repeat >> match[','].maybe.ignore
|
32
45
|
end
|
33
46
|
rule(:proper_variable_name) do
|
34
|
-
(proper_word >> (space >> proper_word).repeat).
|
47
|
+
(proper_word >> (space >> proper_word).repeat) >> match[','].maybe.ignore
|
35
48
|
end
|
36
49
|
|
37
50
|
rule(:variable_names) do
|
38
51
|
(common_variable_name | proper_variable_name).as(:variable_name)
|
39
52
|
end
|
40
53
|
|
54
|
+
# all the different value types (except Object for now)
|
55
|
+
|
41
56
|
rule(:mysterious_value) { mysterious_value_keywords.as(:mysterious_value) }
|
42
57
|
rule(:null_value) { null_value_keywords.as(:null_value) }
|
43
58
|
rule(:true_value) { true_value_keywords.as(:true_value) }
|
@@ -47,6 +62,8 @@ module KaiserRuby
|
|
47
62
|
rule(:unquoted_string) { match['^\n'].repeat.as(:unquoted_string) }
|
48
63
|
rule(:string_as_number) { reserved.absent? >> match['^\n'].repeat.as(:string_as_number) }
|
49
64
|
|
65
|
+
# assignment
|
66
|
+
|
50
67
|
rule(:basic_assignment_expression) do
|
51
68
|
match('Put ').present? >>
|
52
69
|
(
|
@@ -54,6 +71,8 @@ module KaiserRuby
|
|
54
71
|
).as(:assignment)
|
55
72
|
end
|
56
73
|
|
74
|
+
# math operations
|
75
|
+
|
57
76
|
rule(:increment) do
|
58
77
|
(
|
59
78
|
str('Build ') >> variable_names.as(:variable_name) >> str(' up')
|
@@ -66,8 +85,6 @@ module KaiserRuby
|
|
66
85
|
).as(:decrement)
|
67
86
|
end
|
68
87
|
|
69
|
-
# math operations
|
70
|
-
|
71
88
|
rule(:addition) do
|
72
89
|
(match('.*? plus') | match('.*? with')).present? >>
|
73
90
|
(
|
@@ -96,6 +113,27 @@ module KaiserRuby
|
|
96
113
|
).as(:multiplication)
|
97
114
|
end
|
98
115
|
|
116
|
+
# functions
|
117
|
+
|
118
|
+
rule(:function) do
|
119
|
+
match('.*? takes').present? >>
|
120
|
+
(
|
121
|
+
variable_names.as(:function_name) >> str(' takes') >>
|
122
|
+
(space >> str('and ').maybe >> variable_names.as(:argument_name)).repeat.as(:arguments) >> eol >>
|
123
|
+
scope {
|
124
|
+
inner_block_line.repeat.as(:function_block) >>
|
125
|
+
(eol | eof).as(:enddef)
|
126
|
+
}
|
127
|
+
).as(:function_definition)
|
128
|
+
end
|
129
|
+
|
130
|
+
rule(:function_call) do
|
131
|
+
(
|
132
|
+
variable_names.as(:function_name) >> str(' taking') >>
|
133
|
+
(space >> str('and ').maybe >> variable_names.as(:argument_name)).repeat.as(:arguments)
|
134
|
+
).as(:function_call)
|
135
|
+
end
|
136
|
+
|
99
137
|
# poetic assignments
|
100
138
|
|
101
139
|
rule(:poetic_type_literal) do
|
@@ -118,35 +156,85 @@ module KaiserRuby
|
|
118
156
|
).as(:assignment)
|
119
157
|
end
|
120
158
|
|
159
|
+
# single statements
|
160
|
+
|
121
161
|
rule(:print_function) do
|
122
162
|
(
|
123
163
|
say_keywords >> space >> value_or_variable.as(:output)
|
124
164
|
).as(:print)
|
125
165
|
end
|
126
166
|
|
167
|
+
rule(:break_function) do
|
168
|
+
str('Break it down').as(:break)
|
169
|
+
end
|
170
|
+
|
171
|
+
rule(:continue_function) do
|
172
|
+
str('Take it to the top').as(:continue)
|
173
|
+
end
|
174
|
+
|
175
|
+
rule(:return_function) do
|
176
|
+
str('Give back ') >> (math_operations | value_or_variable).as(:return_value)
|
177
|
+
end
|
178
|
+
|
127
179
|
# comparisons
|
128
180
|
|
129
181
|
rule(:equality) do
|
130
182
|
(
|
131
|
-
value_or_variable.as(:left) >> str(' is ') >>
|
183
|
+
value_or_variable.as(:left) >> str(' is ') >> value_or_variable.as(:right)
|
132
184
|
).as(:equals)
|
133
185
|
end
|
134
186
|
|
135
|
-
|
187
|
+
rule(:not_keywords) { str(' is not ') | str(" ain't ")}
|
188
|
+
rule(:inequality) do
|
189
|
+
(
|
190
|
+
value_or_variable.as(:left) >> not_keywords >> value_or_variable.as(:right)
|
191
|
+
).as(:not_equals)
|
192
|
+
end
|
193
|
+
|
194
|
+
rule(:gt_keywords) { str(' is ') >> (str('higher') | str('greater') | str('bigger') | str('stronger')) >> str(' than ') }
|
195
|
+
rule(:gt) do
|
196
|
+
(
|
197
|
+
value_or_variable.as(:left) >> gt_keywords >> value_or_variable.as(:right)
|
198
|
+
).as(:gt)
|
199
|
+
end
|
200
|
+
|
201
|
+
rule(:lt_keywords) { str(' is ') >> (str('lower') | str('less') | str('smaller') | str('weaker')) >> str(' than ') }
|
202
|
+
rule(:lt) do
|
203
|
+
(
|
204
|
+
value_or_variable.as(:left) >> lt_keywords >> value_or_variable.as(:right)
|
205
|
+
).as(:lt)
|
206
|
+
end
|
207
|
+
|
208
|
+
rule(:gte_keywords) { str(' is as ') >> (str('high') | str('great') | str('big') | str('strong')) >> str(' as ') }
|
209
|
+
rule(:gte) do
|
210
|
+
(
|
211
|
+
value_or_variable.as(:left) >> gte_keywords >> value_or_variable.as(:right)
|
212
|
+
).as(:gte)
|
213
|
+
end
|
214
|
+
|
215
|
+
rule(:lte_keywords) { str(' is as ') >> (str('low') | str('little') | str('small') | str('weak')) >> str(' as ') }
|
216
|
+
rule(:lte) do
|
217
|
+
(
|
218
|
+
value_or_variable.as(:left) >> lte_keywords >> value_or_variable.as(:right)
|
219
|
+
).as(:lte)
|
220
|
+
end
|
221
|
+
|
222
|
+
# flow control - if, else, while, until
|
136
223
|
|
137
224
|
rule(:if_block) do
|
138
225
|
(
|
139
|
-
str('If ') >> comparisons.as(:if_condition) >>
|
226
|
+
str('If ') >> comparisons.as(:if_condition) >>
|
227
|
+
(space >> (str('and') | str('or')).as(:and_or) >> space >> comparisons.as(:second_condition)).maybe >> eol >>
|
140
228
|
scope {
|
141
|
-
inner_block_line.repeat.as(:if_block)
|
142
|
-
|
143
|
-
}
|
229
|
+
inner_block_line.repeat.as(:if_block)
|
230
|
+
} >> (eol | eof).as(:endif)
|
144
231
|
).as(:if)
|
145
232
|
end
|
146
233
|
|
147
234
|
rule(:if_else_block) do
|
148
235
|
(
|
149
|
-
str('If ') >> comparisons.as(:if_condition) >>
|
236
|
+
str('If ') >> comparisons.as(:if_condition) >>
|
237
|
+
(space >> (str('and') | str('or')).as(:and_or) >> space >> comparisons.as(:second_condition)).maybe >> eol >>
|
150
238
|
scope {
|
151
239
|
inner_block_line.repeat.as(:if_block)
|
152
240
|
} >>
|
@@ -158,26 +246,58 @@ module KaiserRuby
|
|
158
246
|
).as(:if_else)
|
159
247
|
end
|
160
248
|
|
249
|
+
rule(:while_block) do
|
250
|
+
(
|
251
|
+
str('While ') >> comparisons.as(:while_condition) >>
|
252
|
+
(space >> (str('and') | str('or')).as(:and_or) >> space >> comparisons.as(:second_condition)).maybe >> eol >>
|
253
|
+
scope {
|
254
|
+
inner_block_line.repeat.as(:while_block) >>
|
255
|
+
(eol | eof).as(:endwhile)
|
256
|
+
}
|
257
|
+
).as(:while)
|
258
|
+
end
|
259
|
+
|
260
|
+
rule(:until_block) do
|
261
|
+
(
|
262
|
+
str('Until ') >> comparisons.as(:until_condition) >>
|
263
|
+
(space >> (str('and') | str('or')).as(:and_or) >> space >> comparisons.as(:second_condition)).maybe >> eol >>
|
264
|
+
scope {
|
265
|
+
inner_block_line.repeat.as(:until_block)
|
266
|
+
|
267
|
+
} >> (eol | eof).as(:enduntil)
|
268
|
+
).as(:until)
|
269
|
+
end
|
270
|
+
|
271
|
+
# sets of rules
|
272
|
+
|
161
273
|
rule(:simple_values) { mysterious_value | null_value | false_value | true_value | string_value | numeric_value }
|
162
274
|
rule(:value_or_variable) { variable_names | simple_values }
|
163
|
-
rule(:
|
164
|
-
rule(:
|
165
|
-
rule(:
|
275
|
+
rule(:math_operations) { increment | decrement | addition | subtraction | multiplication | division }
|
276
|
+
rule(:expressions) { basic_assignment_expression | math_operations }
|
277
|
+
rule(:comparisons) { gte | gt | lte | lt | inequality | equality }
|
278
|
+
rule(:flow_control) { if_block | if_else_block | while_block | until_block }
|
166
279
|
rule(:poetics) { poetic_type_literal | poetic_string_literal | poetic_number_literal }
|
167
|
-
rule(:functions) { print_function }
|
280
|
+
rule(:functions) { function_call | function | print_function | break_function | continue_function | return_function }
|
168
281
|
rule(:line_elements) { flow_control | poetics | expressions | functions | eol }
|
169
282
|
|
283
|
+
# handle multiple lines in a file
|
284
|
+
|
170
285
|
rule(:string_input) { line_elements | value_or_variable }
|
171
286
|
rule(:line) { (line_elements >> eol.maybe).as(:line) }
|
172
287
|
rule(:inner_block_line) { ( (flow_control | poetics | expressions | functions) >> eol.maybe).as(:line) }
|
173
288
|
rule(:lyrics) { line.repeat.as(:lyrics) }
|
174
289
|
root(:lyrics)
|
175
290
|
|
291
|
+
# DRY helpers
|
292
|
+
|
176
293
|
rule(:eol) { match["\n"] }
|
177
294
|
rule(:eof) { any.absent? }
|
178
295
|
rule(:space) { match[' \t'].repeat(1) }
|
179
296
|
end
|
180
297
|
|
298
|
+
# this is an alternative parser that enables all the RSpec tests to pass
|
299
|
+
# it specifically has a single line rule that matches a string instead of lines
|
300
|
+
# it also matches the value_or_variable rule, so that the value creation can be tested
|
181
301
|
class RockstarSingleLineParser < KaiserRuby::RockstarParser
|
182
302
|
root(:string_input)
|
183
303
|
end
|
@@ -29,18 +29,51 @@ module KaiserRuby
|
|
29
29
|
rule(division: { left: simple(:left), right: simple(:right) }) { "#{left} / #{right}" }
|
30
30
|
|
31
31
|
rule(print: { output: simple(:output) }) { "puts #{output}" }
|
32
|
+
rule(continue: simple(:_)) { "next" }
|
33
|
+
rule(break: simple(:_)) { "break" }
|
32
34
|
|
33
35
|
rule(equals: { left: simple(:left), right: simple(:right) }) { "#{left} == #{right}" }
|
34
|
-
rule(
|
36
|
+
rule(not_equals: { left: simple(:left), right: simple(:right) }) { "#{left} != #{right}" }
|
37
|
+
rule(gt: { left: simple(:left), right: simple(:right) }) { "#{left} > #{right}" }
|
38
|
+
rule(gte: { left: simple(:left), right: simple(:right) }) { "#{left} >= #{right}" }
|
39
|
+
rule(lte: { left: simple(:left), right: simple(:right) }) { "#{left} <= #{right}" }
|
40
|
+
rule(lt: { left: simple(:left), right: simple(:right) }) { "#{left} < #{right}" }
|
41
|
+
|
42
|
+
rule(if: {
|
43
|
+
if_condition: simple(:if_condition),
|
44
|
+
if_block: sequence(:if_block_lines),
|
45
|
+
endif: simple(:_)
|
46
|
+
} ) do
|
35
47
|
output = "#{' ' * KaiserRuby.indent}if #{if_condition}\n"
|
36
48
|
KaiserRuby.up_indent
|
37
49
|
output += if_block_lines.map { |l| "#{' ' * KaiserRuby.indent}#{l}\n" }.join
|
38
50
|
KaiserRuby.down_indent
|
39
|
-
output += "#{' ' * KaiserRuby.indent}end"
|
51
|
+
output += "#{' ' * KaiserRuby.indent}end # endif"
|
52
|
+
output
|
53
|
+
end
|
54
|
+
|
55
|
+
rule(if: {
|
56
|
+
if_condition: simple(:if_condition),
|
57
|
+
and_or: simple(:and_or),
|
58
|
+
second_condition: simple(:second_condition),
|
59
|
+
if_block: sequence(:if_block_lines),
|
60
|
+
endif: simple(:_)
|
61
|
+
} ) do
|
62
|
+
proper_and_or = and_or == 'and' ? '&&' : '||'
|
63
|
+
output = "#{' ' * KaiserRuby.indent}if #{if_condition} #{proper_and_or} #{second_condition}\n"
|
64
|
+
KaiserRuby.up_indent
|
65
|
+
output += if_block_lines.map { |l| "#{' ' * KaiserRuby.indent}#{l}\n" }.join
|
66
|
+
KaiserRuby.down_indent
|
67
|
+
output += "#{' ' * KaiserRuby.indent}end # endif"
|
40
68
|
output
|
41
69
|
end
|
42
70
|
|
43
|
-
rule(if_else: {
|
71
|
+
rule(if_else: {
|
72
|
+
if_condition: simple(:if_condition),
|
73
|
+
if_block: sequence(:if_block_lines),
|
74
|
+
else_block: sequence(:else_block_lines),
|
75
|
+
endif: simple(:_)
|
76
|
+
} ) do
|
44
77
|
output = "#{' ' * KaiserRuby.indent}if #{if_condition}\n"
|
45
78
|
KaiserRuby.up_indent
|
46
79
|
output += if_block_lines.map { |l| "#{' ' * KaiserRuby.indent}#{l}\n" }.join
|
@@ -49,10 +82,113 @@ module KaiserRuby
|
|
49
82
|
KaiserRuby.up_indent
|
50
83
|
output += else_block_lines.map { |l| "#{' ' * KaiserRuby.indent}#{l}\n" }.join
|
51
84
|
KaiserRuby.down_indent
|
52
|
-
output += "#{' ' * KaiserRuby.indent}end"
|
85
|
+
output += "#{' ' * KaiserRuby.indent}end # endifelse"
|
53
86
|
output
|
54
87
|
end
|
55
88
|
|
89
|
+
rule(if_else: {
|
90
|
+
if_condition: simple(:if_condition),
|
91
|
+
and_or: simple(:and_or),
|
92
|
+
second_condition: simple(:second_condition),
|
93
|
+
if_block: sequence(:if_block_lines),
|
94
|
+
else_block: sequence(:else_block_lines),
|
95
|
+
endif: simple(:_)
|
96
|
+
} ) do
|
97
|
+
proper_and_or = and_or == 'and' ? '&&' : '||'
|
98
|
+
output = "#{' ' * KaiserRuby.indent}if #{if_condition} #{proper_and_or} #{second_condition}\n"
|
99
|
+
KaiserRuby.up_indent
|
100
|
+
output += if_block_lines.map { |l| "#{' ' * KaiserRuby.indent}#{l}\n" }.join
|
101
|
+
KaiserRuby.down_indent
|
102
|
+
output += "#{' ' * KaiserRuby.indent}else\n"
|
103
|
+
KaiserRuby.up_indent
|
104
|
+
output += else_block_lines.map { |l| "#{' ' * KaiserRuby.indent}#{l}\n" }.join
|
105
|
+
KaiserRuby.down_indent
|
106
|
+
output += "#{' ' * KaiserRuby.indent}end # endifelse"
|
107
|
+
output
|
108
|
+
end
|
109
|
+
|
110
|
+
rule(while: {
|
111
|
+
while_condition: simple(:while_condition),
|
112
|
+
while_block: sequence(:while_block_lines),
|
113
|
+
endwhile: simple(:_)
|
114
|
+
} ) do
|
115
|
+
output = "#{' ' * KaiserRuby.indent}while #{while_condition}\n"
|
116
|
+
KaiserRuby.up_indent
|
117
|
+
output += while_block_lines.map { |l| "#{' ' * KaiserRuby.indent}#{l}\n" }.join
|
118
|
+
KaiserRuby.down_indent
|
119
|
+
output += "#{' ' * KaiserRuby.indent}end # endwhile"
|
120
|
+
output
|
121
|
+
end
|
122
|
+
|
123
|
+
rule(while: {
|
124
|
+
while_condition: simple(:while_condition),
|
125
|
+
and_or: simple(:and_or),
|
126
|
+
second_condition: simple(:second_condition),
|
127
|
+
while_block: sequence(:while_block_lines),
|
128
|
+
endwhile: simple(:_)
|
129
|
+
} ) do
|
130
|
+
proper_and_or = and_or == 'and' ? '&&' : '||'
|
131
|
+
output = "#{' ' * KaiserRuby.indent}while #{while_condition} #{proper_and_or} #{second_condition}\n"
|
132
|
+
KaiserRuby.up_indent
|
133
|
+
output += while_block_lines.map { |l| "#{' ' * KaiserRuby.indent}#{l}\n" }.join
|
134
|
+
KaiserRuby.down_indent
|
135
|
+
output += "#{' ' * KaiserRuby.indent}end # endwhile"
|
136
|
+
output
|
137
|
+
end
|
138
|
+
|
139
|
+
rule(until: {
|
140
|
+
until_condition: simple(:until_condition),
|
141
|
+
until_block: sequence(:until_block_lines),
|
142
|
+
enduntil: simple(:_)
|
143
|
+
} ) do
|
144
|
+
output = "#{' ' * KaiserRuby.indent}until #{until_condition}\n"
|
145
|
+
KaiserRuby.up_indent
|
146
|
+
output += until_block_lines.map { |l| "#{' ' * KaiserRuby.indent}#{l}\n" }.join
|
147
|
+
KaiserRuby.down_indent
|
148
|
+
output += "#{' ' * KaiserRuby.indent}end # enduntil"
|
149
|
+
output
|
150
|
+
end
|
151
|
+
|
152
|
+
rule(until: {
|
153
|
+
until_condition: simple(:until_condition),
|
154
|
+
and_or: simple(:and_or),
|
155
|
+
second_condition: simple(:second_condition),
|
156
|
+
until_block: sequence(:until_block_lines),
|
157
|
+
enduntil: simple(:_)
|
158
|
+
} ) do
|
159
|
+
proper_and_or = and_or == 'and' ? '&&' : '||'
|
160
|
+
output = "#{' ' * KaiserRuby.indent}until #{until_condition} #{proper_and_or} #{second_condition}\n"
|
161
|
+
KaiserRuby.up_indent
|
162
|
+
output += until_block_lines.map { |l| "#{' ' * KaiserRuby.indent}#{l}\n" }.join
|
163
|
+
KaiserRuby.down_indent
|
164
|
+
output += "#{' ' * KaiserRuby.indent}end # enduntil"
|
165
|
+
output
|
166
|
+
end
|
167
|
+
|
168
|
+
rule(argument_name: simple(:str)) { str }
|
169
|
+
rule(return_value: simple(:value)) { "return #{value}" }
|
170
|
+
|
171
|
+
rule(function_definition: {
|
172
|
+
function_name: simple(:function_name),
|
173
|
+
arguments: sequence(:arguments),
|
174
|
+
function_block: sequence(:function_block_lines),
|
175
|
+
enddef: simple(:_)
|
176
|
+
} ) do
|
177
|
+
output = "#{' ' * KaiserRuby.indent}def #{function_name}(#{arguments.join(', ')})\n"
|
178
|
+
KaiserRuby.up_indent
|
179
|
+
output += function_block_lines.map { |l| "#{' ' * KaiserRuby.indent}#{l}\n" }.join
|
180
|
+
KaiserRuby.down_indent
|
181
|
+
output += "#{' ' * KaiserRuby.indent}end # enddef"
|
182
|
+
output
|
183
|
+
end
|
184
|
+
|
185
|
+
rule(function_call: {
|
186
|
+
function_name: simple(:function_name),
|
187
|
+
arguments: sequence(:arguments)
|
188
|
+
} ) do
|
189
|
+
"#{function_name}(#{arguments.join(', ')})"
|
190
|
+
end
|
191
|
+
|
56
192
|
rule(line: simple(:line)) { line == "\n" ? nil : line }
|
57
193
|
rule(lyrics: sequence(:lines)) { lines.join("\n") + "\n" }
|
58
194
|
|
data/lib/kaiser_ruby/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kaiser-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marcin Ruszkiewicz
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-08-
|
11
|
+
date: 2018-08-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -105,6 +105,7 @@ files:
|
|
105
105
|
- ".gitignore"
|
106
106
|
- ".rspec"
|
107
107
|
- ".travis.yml"
|
108
|
+
- CHANGELOG.md
|
108
109
|
- Gemfile
|
109
110
|
- Gemfile.lock
|
110
111
|
- LICENSE.txt
|