rossoc 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 1c1044e8d160f0b6790e4bdf78ab4d638ed82e32cb50d3841946a5ac56110981
4
+ data.tar.gz: fe607e717eb85c61496d9b2727e26d3fa2f35afc503ced70164f22e032e9dc49
5
+ SHA512:
6
+ metadata.gz: c28e9e8620c54f03803d9f44ca35809eaff57ba4b3d58864d514631f6455034ebf17d1735b55357e26399c6ef59b0bfaf7fee2e13fdc9dcf2d80d5d8c48f2bcf
7
+ data.tar.gz: e2a0cb26b8e45fa2ce99761431ef0c26c285a9918e3463cc577d1003fa90a59d38b593b0382aacd59af828928847d6f1b1a0f7c9d036d0017c73a0fc7639a1d8
data/.rubocop.yml ADDED
@@ -0,0 +1,21 @@
1
+ inherit_from: .rubocop_todo.yml
2
+
3
+ AllCops:
4
+ NewCops: enable
5
+ SuggestExtensions: false
6
+ Exclude:
7
+ - vendor/bundle/**/*
8
+ - "lib/rossoc/parser.racc"
9
+ - "lib/rossoc/parser.racc.rb"
10
+ - "lib/rossoc/parser.rex"
11
+ - "lib/rossoc/parser.rex.rb"
12
+ - "lib/rossoc/sql_visitor.rb"
13
+ - "lib/rossoc/statement.rb"
14
+ - "rossoc.gemspec"
15
+
16
+ Metrics/BlockLength:
17
+ Exclude:
18
+ - "spec/**/*"
19
+
20
+ Layout/LineLength:
21
+ Max: 150
data/.rubocop_todo.yml ADDED
@@ -0,0 +1,44 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config`
3
+ # on 2024-07-02 13:07:48 UTC using RuboCop version 1.63.2.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Offense count: 4
10
+ # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
11
+ Metrics/AbcSize:
12
+ Max: 40
13
+
14
+ # Offense count: 1
15
+ # Configuration parameters: CountComments, CountAsOne.
16
+ Metrics/ClassLength:
17
+ Max: 118
18
+
19
+ # Offense count: 1
20
+ # Configuration parameters: AllowedMethods, AllowedPatterns.
21
+ Metrics/CyclomaticComplexity:
22
+ Max: 9
23
+
24
+ # Offense count: 4
25
+ # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
26
+ Metrics/MethodLength:
27
+ Max: 30
28
+
29
+ # Offense count: 1
30
+ # Configuration parameters: CountKeywordArgs, MaxOptionalParameters.
31
+ Metrics/ParameterLists:
32
+ Max: 6
33
+
34
+ # Offense count: 1
35
+ # Configuration parameters: AllowedMethods, AllowedPatterns.
36
+ Metrics/PerceivedComplexity:
37
+ Max: 9
38
+
39
+ # Offense count: 1
40
+ # Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
41
+ # AllowedNames: as, at, by, cc, db, id, if, in, io, ip, of, on, os, pp, to
42
+ Naming/MethodParameterName:
43
+ Exclude:
44
+ - 'lib/rossoc/backend.rb'
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.1.0] - 2024-04-19
4
+
5
+ - Initial release
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 arthur87
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.base.md ADDED
@@ -0,0 +1,190 @@
1
+ <!---------------------------->
2
+ <!-- multilingual suffix: en, ja -->
3
+ <!-- no suffix: en -->
4
+ <!---------------------------->
5
+
6
+ <!-- $ mmg README.base.md -->
7
+
8
+ <!-- [ja] -->
9
+ # rossoc
10
+ rossoc はSQLからコードを生成する実験的なプロジェクトです。
11
+ SQLを mruby, mruby/c, と Arduino に変換します。
12
+
13
+ <!-- [en] -->
14
+ # rossoc
15
+ rossoc is an experimental project to generate code from sql.
16
+ Converts sql to mruby, mruby/c, or Arduino source code.
17
+
18
+ <!-- [ja] -->
19
+ # ガイド
20
+ 例えば、`SELECT din11 FROM mruby WHERE ((din1 = 0 AND din2 <= 1) OR din3 <> 9)` のようなSQLは以下のようなコードに変換されます。
21
+
22
+ <!-- [en] -->
23
+ # Guide
24
+ For example, SQL like `SELECT din11 FROM mruby WHERE ((din1 = 0 AND din2 <= 1) OR din3 <> 9)` is converted to source code like this:
25
+
26
+ <!-- [common] -->
27
+ ```ruby
28
+ # SELECT `din11` FROM `mruby` WHERE ((`din1` = 0 AND `din2` <= 1) OR `din3` <> 9)
29
+
30
+ GPIO.setmode(11, GPIO::IN)
31
+ GPIO.setmode(1, GPIO::IN)
32
+ GPIO.setmode(2, GPIO::IN)
33
+ GPIO.setmode(3, GPIO::IN)
34
+
35
+ uart1 = UART.new(1)
36
+
37
+ while 1 do
38
+ din11 = GPIO.read(11)
39
+ din1 = GPIO.read(1)
40
+ din2 = GPIO.read(2)
41
+ din3 = GPIO.read(3)
42
+
43
+ if ((din1 == 0 && din2 <= 1) || din3 != 9)
44
+ uart1.puts("din11=#{din11}")
45
+ end
46
+
47
+ end
48
+ ```
49
+
50
+ <!-- [ja] -->
51
+ この mruby コードは次のコマンドで出力できます。
52
+
53
+ <!-- [en] -->
54
+ This mruby code can be output with the following command.
55
+
56
+ <!-- [common] -->
57
+ ```bash
58
+ rossoc query -i 'SELECT din11 FROM mruby WHERE ((din1 = 0 AND din2 <= 1) OR din3 <> 9)' -o test.rb
59
+ ```
60
+
61
+ <!-- [ja] -->
62
+ `RSLEEP` は rossoc の独自キーワードです。
63
+ RSLEEPの単位は秒で、指定した秒数分、処理を停止します。
64
+
65
+ <!-- [en] -->
66
+ `RSLEEP` is the original keyword of rossoc.
67
+ RSLEEP is measured in seconds, and processing will be suspended for the specified number of seconds.
68
+
69
+ <!-- [common] -->
70
+ ```bash
71
+ rossoc query -i 'SELECT din11 FROM mruby WHERE ((din1 = 0 AND din2 <= 1) OR din3 <> 9) RSLEEP 100' -o test.rb
72
+ ```
73
+
74
+ <!-- [ja] -->
75
+ `RSLEEP` を使用したコードは以下のようになります。
76
+
77
+ <!-- [en] -->
78
+ The code will look like this.
79
+
80
+ <!-- [common] -->
81
+ ```ruby
82
+ # SELECT `din11` FROM `mruby` WHERE ((`din1` = 0 AND `din2` <= 1) OR `din3` <> 9) RSLEEP 100
83
+
84
+ GPIO.setmode(11, GPIO::IN)
85
+ GPIO.setmode(1, GPIO::IN)
86
+ GPIO.setmode(2, GPIO::IN)
87
+ GPIO.setmode(3, GPIO::IN)
88
+
89
+ uart1 = UART.new(1)
90
+
91
+ while 1 do
92
+ din11 = GPIO.read(11)
93
+ din1 = GPIO.read(1)
94
+ din2 = GPIO.read(2)
95
+ din3 = GPIO.read(3)
96
+
97
+ if ((din1 == 0 && din2 <= 1) || din3 != 9)
98
+ uart1.puts("din11=#{din11}")
99
+ end
100
+
101
+ sleep(100)
102
+
103
+ end
104
+ ```
105
+
106
+ ```c
107
+ // SELECT `din11` FROM `arduino` WHERE ((`din1` = 0 AND `din2` <= 1) OR `din3` <> 9) RSLEEP 100
108
+
109
+ void setup() {
110
+ Serial.begin(9600);
111
+
112
+ pinMode(11, INPUT);
113
+ pinMode(1, INPUT);
114
+ pinMode(2, INPUT);
115
+ pinMode(3, INPUT);
116
+ }
117
+
118
+ void loop() {
119
+
120
+ int din11 = digitalRead(11);
121
+ int din1 = digitalRead(1);
122
+ int din2 = digitalRead(2);
123
+ int din3 = digitalRead(3);
124
+
125
+
126
+ if((din1 == 0 && din2 <= 1) || din3 != 9) {
127
+
128
+ Serial.print("din11=");
129
+ Serial.println(din11);
130
+
131
+ }
132
+
133
+
134
+ delay(100000);
135
+
136
+ }
137
+ ```
138
+
139
+ <!-- [ja] -->
140
+ rossoc は `SELECT` ステートメントのみサポートしています。
141
+ カラムには `din1` から `din20` と `ain1` から `ain20` を指定できます。dinはデジタルピン、ainはアナログピンです。
142
+ テーブル名には `mruby`, `arduino` と `dev` が指定できます。
143
+ もし `dev` を指定したときシンプルなrubyコードを出力します。 このコードは物理的なボードを必要としません。
144
+
145
+ <!-- [en] -->
146
+ rossoc is only `SELECT` statements are supported.
147
+ The values ​​that can be specified for the column name are `din1` to `din20` and `ain1` to `ain20`. din corresponds to digital pin, and ain corresponds to analog pin.
148
+ Possible values ​​for table name are `mruby`, `arduino` and `dev`.
149
+ If you specify `dev`, simple ruby ​​code will be output and you can run it immediately without a board.
150
+
151
+ <!-- [ja] -->
152
+ # 参考
153
+
154
+ このプロジェクトでは以下の文献、コード等を参考にしています。
155
+
156
+ <!-- [en] -->
157
+ # Reference
158
+
159
+ <!-- [common] -->
160
+ The following code is included to extend sql: https://github.com/cryodex/sql-parser
161
+ mruby, mruby/c Common I/O API Guidelines and Community-developed Libraries: https://github.com/mruby/microcontroller-peripheral-interface-guide
162
+
163
+ <!-- [ja] -->
164
+ # アーキテクチャ
165
+ rossoc はフロントエンドとバックエンドから構成されています。
166
+ 独自のIR(中間表現)を介してフロントエンドとバックエンドを接続しています。
167
+ フロントエンドは、字句、構文、意味解析を実行します。
168
+ バックエンドは、ターゲットのコードを生成します。
169
+
170
+ <!-- [en] -->
171
+ # Architecture
172
+ rossoc is composed of a front-end and a back-end.
173
+ An original IR(Intermediate Representation) is used to connect the front-end and the back-end.
174
+ The front-end performs lexical, syntactic and semantic analysis.
175
+ The back-end generates code for the target.
176
+
177
+ <!-- [common] -->
178
+ ```mermaid
179
+ flowchart TB
180
+ input --> FrontEnd
181
+ subgraph FrontEnd
182
+ parser --> columns --> tables --> condition --> rsleep
183
+ end
184
+ FrontEnd --> IR --> BackEnd
185
+ subgraph BackEnd
186
+ generate
187
+ write
188
+ end
189
+ write --> output
190
+ ```
data/README.ja.md ADDED
@@ -0,0 +1,136 @@
1
+
2
+
3
+ # rossoc
4
+ rossoc はSQLからコードを生成する実験的なプロジェクトです。
5
+ SQLを mruby, mruby/c, と Arduino に変換します。
6
+
7
+ # ガイド
8
+ 例えば、`SELECT din11 FROM mruby WHERE ((din1 = 0 AND din2 <= 1) OR din3 <> 9)` のようなSQLは以下のようなコードに変換されます。
9
+
10
+ ```ruby
11
+ # SELECT `din11` FROM `mruby` WHERE ((`din1` = 0 AND `din2` <= 1) OR `din3` <> 9)
12
+
13
+ GPIO.setmode(11, GPIO::IN)
14
+ GPIO.setmode(1, GPIO::IN)
15
+ GPIO.setmode(2, GPIO::IN)
16
+ GPIO.setmode(3, GPIO::IN)
17
+
18
+ uart1 = UART.new(1)
19
+
20
+ while 1 do
21
+ din11 = GPIO.read(11)
22
+ din1 = GPIO.read(1)
23
+ din2 = GPIO.read(2)
24
+ din3 = GPIO.read(3)
25
+
26
+ if ((din1 == 0 && din2 <= 1) || din3 != 9)
27
+ uart1.puts("din11=#{din11}")
28
+ end
29
+
30
+ end
31
+ ```
32
+
33
+ この mruby コードは次のコマンドで出力できます。
34
+
35
+ ```bash
36
+ rossoc query -i 'SELECT din11 FROM mruby WHERE ((din1 = 0 AND din2 <= 1) OR din3 <> 9)' -o test.rb
37
+ ```
38
+
39
+ `RSLEEP` は rossoc の独自キーワードです。
40
+ RSLEEPの単位は秒で、指定した秒数分、処理を停止します。
41
+
42
+ ```bash
43
+ rossoc query -i 'SELECT din11 FROM mruby WHERE ((din1 = 0 AND din2 <= 1) OR din3 <> 9) RSLEEP 100' -o test.rb
44
+ ```
45
+
46
+ `RSLEEP` を使用したコードは以下のようになります。
47
+
48
+ ```ruby
49
+ # SELECT `din11` FROM `mruby` WHERE ((`din1` = 0 AND `din2` <= 1) OR `din3` <> 9) RSLEEP 100
50
+
51
+ GPIO.setmode(11, GPIO::IN)
52
+ GPIO.setmode(1, GPIO::IN)
53
+ GPIO.setmode(2, GPIO::IN)
54
+ GPIO.setmode(3, GPIO::IN)
55
+
56
+ uart1 = UART.new(1)
57
+
58
+ while 1 do
59
+ din11 = GPIO.read(11)
60
+ din1 = GPIO.read(1)
61
+ din2 = GPIO.read(2)
62
+ din3 = GPIO.read(3)
63
+
64
+ if ((din1 == 0 && din2 <= 1) || din3 != 9)
65
+ uart1.puts("din11=#{din11}")
66
+ end
67
+
68
+ sleep(100)
69
+
70
+ end
71
+ ```
72
+
73
+ ```c
74
+ // SELECT `din11` FROM `arduino` WHERE ((`din1` = 0 AND `din2` <= 1) OR `din3` <> 9) RSLEEP 100
75
+
76
+ void setup() {
77
+ Serial.begin(9600);
78
+
79
+ pinMode(11, INPUT);
80
+ pinMode(1, INPUT);
81
+ pinMode(2, INPUT);
82
+ pinMode(3, INPUT);
83
+ }
84
+
85
+ void loop() {
86
+
87
+ int din11 = digitalRead(11);
88
+ int din1 = digitalRead(1);
89
+ int din2 = digitalRead(2);
90
+ int din3 = digitalRead(3);
91
+
92
+
93
+ if((din1 == 0 && din2 <= 1) || din3 != 9) {
94
+
95
+ Serial.print("din11=");
96
+ Serial.println(din11);
97
+
98
+ }
99
+
100
+
101
+ delay(100000);
102
+
103
+ }
104
+ ```
105
+
106
+ rossoc は `SELECT` ステートメントのみサポートしています。
107
+ カラムには `din1` から `din20` と `ain1` から `ain20` を指定できます。dinはデジタルピン、ainはアナログピンです。
108
+ テーブル名には `mruby`, `arduino` と `dev` が指定できます。
109
+ もし `dev` を指定したときシンプルなrubyコードを出力します。 このコードは物理的なボードを必要としません。
110
+
111
+ # 参考
112
+
113
+ このプロジェクトでは以下の文献、コード等を参考にしています。
114
+
115
+ The following code is included to extend sql: https://github.com/cryodex/sql-parser
116
+ mruby, mruby/c Common I/O API Guidelines and Community-developed Libraries: https://github.com/mruby/microcontroller-peripheral-interface-guide
117
+
118
+ # アーキテクチャ
119
+ rossoc はフロントエンドとバックエンドから構成されています。
120
+ 独自のIR(中間表現)を介してフロントエンドとバックエンドを接続しています。
121
+ フロントエンドは、字句、構文、意味解析を実行します。
122
+ バックエンドは、ターゲットのコードを生成します。
123
+
124
+ ```mermaid
125
+ flowchart TB
126
+ input --> FrontEnd
127
+ subgraph FrontEnd
128
+ parser --> columns --> tables --> condition --> rsleep
129
+ end
130
+ FrontEnd --> IR --> BackEnd
131
+ subgraph BackEnd
132
+ generate
133
+ write
134
+ end
135
+ write --> output
136
+ ```
data/README.md ADDED
@@ -0,0 +1,134 @@
1
+
2
+
3
+ # rossoc
4
+ rossoc is an experimental project to generate code from sql.
5
+ Converts sql to mruby, mruby/c, or Arduino source code.
6
+
7
+ # Guide
8
+ For example, SQL like `SELECT din11 FROM mruby WHERE ((din1 = 0 AND din2 <= 1) OR din3 <> 9)` is converted to source code like this:
9
+
10
+ ```ruby
11
+ # SELECT `din11` FROM `mruby` WHERE ((`din1` = 0 AND `din2` <= 1) OR `din3` <> 9)
12
+
13
+ GPIO.setmode(11, GPIO::IN)
14
+ GPIO.setmode(1, GPIO::IN)
15
+ GPIO.setmode(2, GPIO::IN)
16
+ GPIO.setmode(3, GPIO::IN)
17
+
18
+ uart1 = UART.new(1)
19
+
20
+ while 1 do
21
+ din11 = GPIO.read(11)
22
+ din1 = GPIO.read(1)
23
+ din2 = GPIO.read(2)
24
+ din3 = GPIO.read(3)
25
+
26
+ if ((din1 == 0 && din2 <= 1) || din3 != 9)
27
+ uart1.puts("din11=#{din11}")
28
+ end
29
+
30
+ end
31
+ ```
32
+
33
+ This mruby code can be output with the following command.
34
+
35
+ ```bash
36
+ rossoc query -i 'SELECT din11 FROM mruby WHERE ((din1 = 0 AND din2 <= 1) OR din3 <> 9)' -o test.rb
37
+ ```
38
+
39
+ `RSLEEP` is the original keyword of rossoc.
40
+ RSLEEP is measured in seconds, and processing will be suspended for the specified number of seconds.
41
+
42
+ ```bash
43
+ rossoc query -i 'SELECT din11 FROM mruby WHERE ((din1 = 0 AND din2 <= 1) OR din3 <> 9) RSLEEP 100' -o test.rb
44
+ ```
45
+
46
+ The code will look like this.
47
+
48
+ ```ruby
49
+ # SELECT `din11` FROM `mruby` WHERE ((`din1` = 0 AND `din2` <= 1) OR `din3` <> 9) RSLEEP 100
50
+
51
+ GPIO.setmode(11, GPIO::IN)
52
+ GPIO.setmode(1, GPIO::IN)
53
+ GPIO.setmode(2, GPIO::IN)
54
+ GPIO.setmode(3, GPIO::IN)
55
+
56
+ uart1 = UART.new(1)
57
+
58
+ while 1 do
59
+ din11 = GPIO.read(11)
60
+ din1 = GPIO.read(1)
61
+ din2 = GPIO.read(2)
62
+ din3 = GPIO.read(3)
63
+
64
+ if ((din1 == 0 && din2 <= 1) || din3 != 9)
65
+ uart1.puts("din11=#{din11}")
66
+ end
67
+
68
+ sleep(100)
69
+
70
+ end
71
+ ```
72
+
73
+ ```c
74
+ // SELECT `din11` FROM `arduino` WHERE ((`din1` = 0 AND `din2` <= 1) OR `din3` <> 9) RSLEEP 100
75
+
76
+ void setup() {
77
+ Serial.begin(9600);
78
+
79
+ pinMode(11, INPUT);
80
+ pinMode(1, INPUT);
81
+ pinMode(2, INPUT);
82
+ pinMode(3, INPUT);
83
+ }
84
+
85
+ void loop() {
86
+
87
+ int din11 = digitalRead(11);
88
+ int din1 = digitalRead(1);
89
+ int din2 = digitalRead(2);
90
+ int din3 = digitalRead(3);
91
+
92
+
93
+ if((din1 == 0 && din2 <= 1) || din3 != 9) {
94
+
95
+ Serial.print("din11=");
96
+ Serial.println(din11);
97
+
98
+ }
99
+
100
+
101
+ delay(100000);
102
+
103
+ }
104
+ ```
105
+
106
+ rossoc is only `SELECT` statements are supported.
107
+ The values ​​that can be specified for the column name are `din1` to `din20` and `ain1` to `ain20`. din corresponds to digital pin, and ain corresponds to analog pin.
108
+ Possible values ​​for table name are `mruby`, `arduino` and `dev`.
109
+ If you specify `dev`, simple ruby ​​code will be output and you can run it immediately without a board.
110
+
111
+ # Reference
112
+
113
+ The following code is included to extend sql: https://github.com/cryodex/sql-parser
114
+ mruby, mruby/c Common I/O API Guidelines and Community-developed Libraries: https://github.com/mruby/microcontroller-peripheral-interface-guide
115
+
116
+ # Architecture
117
+ rossoc is composed of a front-end and a back-end.
118
+ An original IR(Intermediate Representation) is used to connect the front-end and the back-end.
119
+ The front-end performs lexical, syntactic and semantic analysis.
120
+ The back-end generates code for the target.
121
+
122
+ ```mermaid
123
+ flowchart TB
124
+ input --> FrontEnd
125
+ subgraph FrontEnd
126
+ parser --> columns --> tables --> condition --> rsleep
127
+ end
128
+ FrontEnd --> IR --> BackEnd
129
+ subgraph BackEnd
130
+ generate
131
+ write
132
+ end
133
+ write --> output
134
+ ```
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ task default: %i[]
5
+
6
+ PARSER = 'lib/rossoc/parser.racc'
7
+ LEXER = 'lib/rossoc/parser.rex'
8
+
9
+ task :parser do
10
+ system "rm #{PARSER}.rb #{LEXER}.rb"
11
+ system "racc -o #{PARSER}.rb #{PARSER}"
12
+ system "rex -o #{LEXER}.rb #{LEXER}"
13
+ system 'rspec'
14
+ end
data/exe/rossoc ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'rossoc'
5
+
6
+ Rossoc::CLI.start
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rossoc'
4
+
5
+ # Rossoc
6
+ module Rossoc
7
+ # Backend
8
+ class Backend
9
+ class BackendError < StandardError; end
10
+
11
+ RESERVED_TABLES = %w[mruby arduino dev].freeze
12
+
13
+ def initialize(ir, output, overwrite_enable)
14
+ @ir = ir
15
+ @output = output
16
+ @content = nil
17
+ @overwrite_enable = overwrite_enable
18
+ end
19
+
20
+ def generate
21
+ table = @ir[:table]
22
+ raise BackendError, "unknown table value #{table}." if RESERVED_TABLES.index(table).nil?
23
+
24
+ template = ERB.new(
25
+ File.read("#{__dir__}#{File::SEPARATOR}views#{File::SEPARATOR}#{table}.erb"),
26
+ trim_mode: 2
27
+ )
28
+
29
+ @content = template.result_with_hash(@ir)
30
+ end
31
+
32
+ def write
33
+ raise BackendError, 'No content.' if @content.nil?
34
+
35
+ if @output.blank?
36
+ # ファイルが指定されていないとき標準出力
37
+ puts @content
38
+ else
39
+ raise BackendError, "File exists #{@output}." if File.exist?(@output) && !@overwrite_enable
40
+
41
+ file = File.open(@output, 'w')
42
+ file.write(@content)
43
+ file.close
44
+ end
45
+ end
46
+ end
47
+ end
data/lib/rossoc/cli.rb ADDED
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rossoc'
4
+ require 'thor'
5
+
6
+ module Rossoc
7
+ # entry point
8
+ class CLI < Thor
9
+ class << self
10
+ def exit_on_failure?
11
+ true
12
+ end
13
+ end
14
+
15
+ desc 'version', 'Show Version'
16
+ def version
17
+ puts(Rossoc::VERSION)
18
+ end
19
+
20
+ desc 'query', 'Query'
21
+ method_option :input, desc: 'Input query', aliases: '-i'
22
+ method_option :output, desc: 'Write output to <file>', aliases: '-o'
23
+ method_option :ir, desc: 'Show IR Information', type: :boolean, default: false
24
+ method_option :yes, desc: 'Overwrite output file', type: :boolean, default: false, aliases: '-y'
25
+ def query
26
+ frontend = Rossoc::Frontend.new(options[:input].to_s)
27
+ begin
28
+ ir = frontend.ir
29
+ rescue StandardError => e
30
+ warn e.message
31
+ exit(1)
32
+ end
33
+
34
+ pp ir if options[:ir]
35
+
36
+ begin
37
+ backend = Rossoc::Backend.new(ir, options[:output].to_s, options[:yes])
38
+ backend.generate
39
+ backend.write
40
+ rescue StandardError => e
41
+ warn e.message
42
+ exit(1)
43
+ end
44
+ end
45
+ end
46
+ end