rockstar-ruby 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +11 -7
- data/lib/rockstar/rockstar_parser.rb +76 -63
- data/lib/rockstar/rockstar_transformer.rb +73 -52
- data/lib/rockstar/version.rb +1 -1
- data/rockstar.gemspec +0 -9
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: facd05fe9654bc604190a3fe38db6857f8af62ef67b66fb1a860f67e23cf6cfc
|
4
|
+
data.tar.gz: 47f7dea44eb3640339a81b109dd7843bdc52015445843699218a9aa019a5fe5c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ed433223bd3b7447c547e1e00b241cc35a40f8bd4ee4ba817e216555ae8253498e090d07605b359ac53697522bc90ff2b24c2741654d1cd822ec06793d9a94ea
|
7
|
+
data.tar.gz: 9f5d53f02188b8d2f02931d95fd3b017cd380fccfd0117ee864f7469dc7153c0f23d2e83bc447be18304a2b4ffae918820b772cc116b98f31c281304d28b0ffe
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,15 +1,17 @@
|
|
1
|
-
# Rockstar
|
1
|
+
# Rockstar-ruby [![Build Status](https://travis-ci.org/scizor666/rockstar-ruby.svg?branch=master)](https://travis-ci.org/scizor666/rockstar-ruby) [![Gem Version](https://badge.fury.io/rb/rockstar-ruby.svg)](https://badge.fury.io/rb/rockstar-ruby)
|
2
2
|
|
3
|
-
|
3
|
+
## Development is in progress, some features are still not ready
|
4
4
|
|
5
|
-
|
5
|
+
Rockstar-ruby gem helps to translate rockstar language to ruby.
|
6
|
+
|
7
|
+
Generally it's following [Rockstar language specification](https://github.com/dylanbeattie/rockstar)
|
6
8
|
|
7
9
|
## Installation
|
8
10
|
|
9
11
|
Add this line to your application's Gemfile:
|
10
12
|
|
11
13
|
```ruby
|
12
|
-
gem 'rockstar'
|
14
|
+
gem 'rockstar-ruby'
|
13
15
|
```
|
14
16
|
|
15
17
|
And then execute:
|
@@ -18,11 +20,13 @@ And then execute:
|
|
18
20
|
|
19
21
|
Or install it yourself as:
|
20
22
|
|
21
|
-
$ gem install rockstar
|
23
|
+
$ gem install rockstar-ruby
|
22
24
|
|
23
25
|
## Usage
|
24
26
|
|
25
|
-
|
27
|
+
$ rockstar-ruby $'Some Rockstar Code is here'
|
28
|
+
|
29
|
+
Currently output will be in the file rockstar.rb in the current directory
|
26
30
|
|
27
31
|
## Development
|
28
32
|
|
@@ -32,7 +36,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
32
36
|
|
33
37
|
## Contributing
|
34
38
|
|
35
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
39
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/scizor666/rockstar-ruby.
|
36
40
|
|
37
41
|
## License
|
38
42
|
|
@@ -1,77 +1,90 @@
|
|
1
|
-
|
1
|
+
module Rockstar
|
2
|
+
class RockstarParser < Parslet::Parser
|
2
3
|
|
3
|
-
|
4
|
+
root(:blocks)
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
6
|
+
# general
|
7
|
+
rule(:blocks) {(function | conditional_block | block).repeat(1).as(:blocks)}
|
8
|
+
rule(:eol) {match['\n']}
|
9
|
+
rule(:eof) {any.absent?}
|
10
|
+
rule(:space) {match('[ \t]').repeat(1)}
|
11
|
+
rule(:block) {(block_part >> (eol >> block_part).repeat >> (eol.repeat(2) | eof)).as(:block)}
|
12
|
+
rule(:block_part) {loop_block | function_call | increment | decrement | loop_continue | loop_break | poetic_literal}
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
# types
|
15
|
+
rule(:poetic_literal) {(poetic_string_literal | poetic_type_literal | poetic_number_literal).as(:var)}
|
16
|
+
rule(:poetic_string_literal) {proper_variable.as(:var_name) >> space >> str('says') >> space >> string_literal.as(:var_value)}
|
17
|
+
rule(:poetic_type_literal) {proper_variable.as(:var_name) >> space >> to_be >> type_literal.as(:var_value)}
|
18
|
+
rule(:poetic_number_literal) {proper_variable.as(:var_name) >> space >> to_be >> (math_expression | number_literal).as(:var_value)}
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
rule(:type_literal) {null_type_literal.as(:nil) | true_type_literal.as(:true) | false_type_literal.as(:false)}
|
21
|
+
rule(:true_type_literal) {str('true') | str('right') | str('yes') | str('ok')}
|
22
|
+
rule(:false_type_literal) {str('false') | str('wrong') | str('no') | str('lies')}
|
23
|
+
rule(:null_type_literal) {str('null') | str('nothing') | str('nowhere') | str('nobody')}
|
23
24
|
|
24
|
-
|
25
|
-
|
25
|
+
rule(:string_literal) {match("[^\n]").repeat(1).as(:str)}
|
26
|
+
rule(:number_literal) {(unique_variable_name >> (space >> unique_variable_name).repeat).as(:number_str)}
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
28
|
+
rule(:proper_variable) {(keyword.absent? >> match('[A-Z]') >> match('[a-z]').repeat >> (space >> proper_variable).repeat).repeat(1)}
|
29
|
+
rule(:common_variable) {str('a') | str('an') | str('the') | str('my') | str('your')}
|
30
|
+
rule(:unique_variable_name) {(keyword.absent? >> match('[a-z]')).repeat(1) >> (space >> unique_variable_name).repeat}
|
30
31
|
|
31
|
-
|
32
|
-
|
32
|
+
rule(:to_be) {(str('is') | str('was') | str('were')) >> space}
|
33
|
+
rule(:keyword) {math_operation | comparison_operation | str('up') | str('down') | str('and') | if_keyword | else_keyword}
|
33
34
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
35
|
+
# math
|
36
|
+
rule(:plus) {(str('plus') | str('with')).as(:+)}
|
37
|
+
rule(:minus) {(str('minus') | str('without')).as(:-)}
|
38
|
+
rule(:multiply) {(str('times') | str('of')).as(:*)}
|
39
|
+
rule(:divide) {(str('over') | str('by')).as(:/)}
|
40
|
+
rule(:math_operation) {(minus | plus | multiply | divide).as(:op)}
|
41
|
+
rule(:math_expression) {unique_variable_name.as(:l_op) >> space >> math_operation >> space >> unique_variable_name.as(:r_op)}
|
42
|
+
rule(:operand) {function_call | unique_variable_name}
|
41
43
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
44
|
+
# comparison
|
45
|
+
rule(:comparison_operand) {math_expression | operand}
|
46
|
+
rule(:comparison) {(comparison_operand.as(:l_op) >> space >> comparison_operation >> space >> comparison_operand.as(:r_op)).as(:comparison)}
|
47
|
+
rule(:comparison_operation) {(greater.as(:>) | less.as(:<) | greater_or_equal.as(:>=) | less_or_equal.as(:<=) | not_equal.as(:!=) | equal.as(:==)).as(:comparison_op)}
|
48
|
+
rule(:greater) {equal >> space >> (str('higher') | str('greater') | str('bigger') | str('stronger')) >> space >> str('than')}
|
49
|
+
rule(:less) {equal >> space >> (str('lower') | str('less') | str('smaller') | str('weaker')) >> space >> str('than')}
|
50
|
+
rule(:greater_or_equal) {equal >> space >> str('as') >> space >> (str('high') | str('great') | str('big') | str('strong')) >> space >> str('as')}
|
51
|
+
rule(:less_or_equal) {equal >> space >> str('as') >> space >> (str('low') | str('little') | str('small') | str('weak')) >> space >> str('as')}
|
52
|
+
rule(:equal) {str('is')}
|
53
|
+
rule(:not_equal) {str("ain't") | (equal >> space >> str('not'))}
|
52
54
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
55
|
+
# conditionals
|
56
|
+
rule(:if_keyword) {str('If')}
|
57
|
+
rule(:else_keyword) {str('Else')}
|
58
|
+
rule(:conditional_block) {(if_else_block | if_block.as(:if_block))}
|
59
|
+
rule(:comparison_expression) { (comparison | comparison_operand).as(:comparison_expression)}
|
60
|
+
rule(:if_block) {if_keyword >> space >> comparison_expression >> eol >> block}
|
61
|
+
rule(:else_block) {else_keyword >> space.maybe >> eol >> block}
|
62
|
+
rule(:if_else_block) {if_block.as(:if_block) >> else_block.as(:else_block)}
|
58
63
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
64
|
+
# loops
|
65
|
+
rule(:loop_block) {until_block.as(:until_block) | while_block.as(:while_block)}
|
66
|
+
rule(:until_block) {str('Until') >> space >> comparison >> eol >> block}
|
67
|
+
rule(:while_block) {str('While') >> space >> comparison >> eol >> block}
|
68
|
+
rule(:loop_break) {str('Break') | str('Break it down')}
|
69
|
+
rule(:loop_continue) {str('Continue') | str('Take it to the top')}
|
70
|
+
rule(:increment) {str('Build') >> space >> unique_variable_name.as(:increment) >> space >> str('up')}
|
71
|
+
rule(:decrement) {str('Knock') >> space >> unique_variable_name.as(:decrement) >> space >> str('down')}
|
67
72
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
+
# functions definition
|
74
|
+
rule(:function) do
|
75
|
+
proper_variable.as(:function_name) >> space >> str('takes') >> space >> function_args.as(:function_args) >> eol >>
|
76
|
+
function_body.as(:function_body) >> function_return
|
77
|
+
end
|
78
|
+
rule(:function_args) {function_arg >> (space >> str('and') >> space >> function_arg).repeat}
|
79
|
+
rule(:function_arg) {unique_variable_name.as(:function_arg)}
|
80
|
+
rule(:function_body) {(conditional_block | loop_block | (block_part >> eol)).repeat(1)}
|
81
|
+
rule(:function_return) {str('Give back') >> space >> unique_variable_name.as(:function_return) >> (eol.repeat(2) | eof)}
|
82
|
+
|
83
|
+
# functions call
|
84
|
+
rule(:function_call) do
|
85
|
+
proper_variable.as(:function_name) >> space >> str('taking') >> space >> function_passed_args.as(:function_passed_args)
|
86
|
+
end
|
87
|
+
rule(:function_passed_args) {function_passed_arg >> (str(',') >> space >> function_passed_arg).repeat}
|
88
|
+
rule(:function_passed_arg) {unique_variable_name.as(:function_passed_arg)}
|
73
89
|
end
|
74
|
-
rule(:function_arg) {unique_variable_name.as(:function_arg)}
|
75
|
-
rule(:function_body) {(conditional_block | loop_block | (block_part >> eol)).repeat(1)}
|
76
|
-
rule(:function_return) {str('Give back') >> space >> unique_variable_name >> (eol.repeat(2) | eof)}
|
77
90
|
end
|
@@ -1,60 +1,81 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
# math
|
10
|
-
rule(:- => simple(:_)) {'-'}
|
11
|
-
rule(:+ => simple(:_)) {'+'}
|
12
|
-
rule(:* => simple(:_)) {'*'}
|
13
|
-
rule(:/ => simple(:_)) {'/'}
|
14
|
-
rule(:l_op => simple(:left), :op => simple(:operation), :r_op => simple(:right)) do |context|
|
15
|
-
"#{to_snake_case(context[:left])}.to_f#{context[:operation]}#{to_snake_case(context[:right])}.to_f"
|
16
|
-
end
|
1
|
+
module Rockstar
|
2
|
+
class RockstarTransformer < Parslet::Transform
|
3
|
+
# types
|
4
|
+
rule(:true => simple(:_)) {'true'}
|
5
|
+
rule(:false => simple(:_)) {'false'}
|
6
|
+
rule(:nil => simple(:_)) {'nil'}
|
7
|
+
rule(:str => simple(:str)) {"'#{str.to_s.gsub("'", "\\'")}'"}
|
8
|
+
rule(:number_str => simple(:str)) {str.to_s.split(/\s+/).map {|e| e.length % 10}.join.to_i}
|
17
9
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
10
|
+
# math
|
11
|
+
rule(:- => simple(:_)) {'-'}
|
12
|
+
rule(:+ => simple(:_)) {'+'}
|
13
|
+
rule(:* => simple(:_)) {'*'}
|
14
|
+
rule(:/ => simple(:_)) {'/'}
|
15
|
+
rule(:l_op => simple(:left), :op => simple(:operation), :r_op => simple(:right)) do |context|
|
16
|
+
"#{to_snake_case(context[:left])}.to_f#{context[:operation]}#{to_snake_case(context[:right])}.to_f"
|
17
|
+
end
|
22
18
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
rule(:<= => simple(:_)) {'<='}
|
28
|
-
rule(:== => simple(:_)) {'=='}
|
29
|
-
rule(:!= => simple(:_)) {'!='}
|
30
|
-
rule(:l_op => simple(:left), :comparison_op => simple(:operation), :r_op => simple(:right)) do |context|
|
31
|
-
"((#{to_snake_case(context[:left])}).to_f#{context[:operation]}(#{to_snake_case(context[:right])}).to_f)"
|
32
|
-
end
|
33
|
-
rule(:comparison => simple(:comparison), :block => simple(:block)) {"#{comparison};#{block}"}
|
19
|
+
# assignment
|
20
|
+
rule(:var => {:var_name => simple(:name), :var_value => simple(:value)}) do |context|
|
21
|
+
"#{to_snake_case(context[:name])}=#{context[:value]}"
|
22
|
+
end
|
34
23
|
|
35
|
-
|
36
|
-
|
37
|
-
|
24
|
+
# comparison
|
25
|
+
rule(:> => simple(:_)) {'>'}
|
26
|
+
rule(:< => simple(:_)) {'<'}
|
27
|
+
rule(:>= => simple(:_)) {'>='}
|
28
|
+
rule(:<= => simple(:_)) {'<='}
|
29
|
+
rule(:== => simple(:_)) {'=='}
|
30
|
+
rule(:!= => simple(:_)) {'!='}
|
31
|
+
rule(:l_op => simple(:left), :comparison_op => simple(:operation), :r_op => simple(:right)) do |context|
|
32
|
+
"((#{to_snake_case(context[:left])}).to_f#{context[:operation]}(#{to_snake_case(context[:right])}).to_f)"
|
33
|
+
end
|
34
|
+
rule(:comparison => simple(:comparison), :block => simple(:block)) {"#{comparison};#{block}"}
|
35
|
+
rule(:comparison_expression => simple(:comparison_exp), :block => simple(:block)) {"(#{comparison_exp});#{block}"}
|
38
36
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
37
|
+
# conditionals
|
38
|
+
rule(:if_block => simple(:if_blk), :else_block => simple(:else_blk)) {"if#{if_blk};else;#{else_blk};end"}
|
39
|
+
rule(:if_block => simple(:if_blk)) {"if#{if_blk};end"}
|
40
|
+
|
41
|
+
# loops
|
42
|
+
rule(:increment => simple(:increment)) do |context|
|
43
|
+
var_name = to_snake_case(context[:increment])
|
44
|
+
"#{var_name}=#{var_name}.to_f+1"
|
45
|
+
end
|
46
|
+
rule(:decrement => simple(:decrement)) do |context|
|
47
|
+
var_name = to_snake_case(context[:decrement])
|
48
|
+
"#{var_name}=#{var_name}.to_f-1"
|
49
|
+
end
|
50
|
+
rule(:comparison => simple(:comparison)) {"#{comparison}"}
|
51
|
+
rule(:until_block => simple(:block)) {"until#{block};end"}
|
52
|
+
rule(:while_block => simple(:block)) {"while#{block};end"}
|
53
|
+
|
54
|
+
# function definitions
|
55
|
+
rule(:function_arg => simple(:arg)) { arg }
|
56
|
+
rule(:function_name => simple(:name),
|
57
|
+
:function_args => sequence(:args),
|
58
|
+
:function_body => sequence(:body_parts),
|
59
|
+
:function_return => simple(:return)) do |context|
|
60
|
+
"def #{to_snake_case(context[:name])}(#{context[:args].map {|arg| to_snake_case(arg)}.join(',')});\
|
61
|
+
#{context[:body_parts].join(';')};\
|
62
|
+
return #{to_snake_case(context[:return])};\
|
63
|
+
end"
|
64
|
+
end
|
65
|
+
|
66
|
+
# function calls
|
67
|
+
rule(:function_passed_arg => simple(:arg)) {arg}
|
68
|
+
rule(:function_name => simple(:name), :function_passed_args => sequence(:args)) do |context|
|
69
|
+
"#{to_snake_case(context[:name])}(#{context[:args].map {|arg| to_snake_case(arg)}.join(',')})"
|
70
|
+
end
|
51
71
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
72
|
+
# general
|
73
|
+
rule(:block => simple(:blk)) {blk}
|
74
|
+
rule(:block => sequence(:lines)) {lines.join(';')}
|
75
|
+
rule(:blocks => sequence(:blocks)) {blocks.join(';')}
|
56
76
|
|
57
|
-
|
58
|
-
|
77
|
+
def self.to_snake_case(str)
|
78
|
+
str.to_s.downcase.gsub(/\s+/, '_')
|
79
|
+
end
|
59
80
|
end
|
60
81
|
end
|
data/lib/rockstar/version.rb
CHANGED
data/rockstar.gemspec
CHANGED
@@ -13,15 +13,6 @@ Gem::Specification.new do |spec|
|
|
13
13
|
spec.homepage = "https://github.com/scizor666/rockstar-ruby"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
|
-
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
17
|
-
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
18
|
-
# if spec.respond_to?(:metadata)
|
19
|
-
# spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
|
20
|
-
# else
|
21
|
-
# raise "RubyGems 2.0 or newer is required to protect against " \
|
22
|
-
# "public gem pushes."
|
23
|
-
# end
|
24
|
-
|
25
16
|
# Specify which files should be added to the gem when it is released.
|
26
17
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
27
18
|
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rockstar-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexander Teplyashin
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-07-
|
11
|
+
date: 2018-07-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|