rus3 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e00bc6347634a3d6fd3ee9da17b18334e49373bab389c9c0126e5ee983504b56
4
- data.tar.gz: 369f1e8627bdcb5c8ece22d0ba4971b417fa4924fa67ca31da3665bebb6a3aa8
3
+ metadata.gz: 8b1f3c9f79ba7f452ff3a2f6d7ec904ac3a1e0ffd836bafd4b4892a8cb0b12ac
4
+ data.tar.gz: 8c65e739832e954d9ca16fac40e437ca73bb3cddf48c35fbd3eb2f86658d8fd6
5
5
  SHA512:
6
- metadata.gz: 4eac508d23d36f6f1f7f6b60879bfbb80921c16ed669ed2d60e5d4d8926a62189269c8cef2373e6489d3dae3b47af01ee888116ecd8a85070f84ce3c8493e57a
7
- data.tar.gz: ac9f76be872b9a5d70822f4bf0d4fab3da83d931002fd2f7b749648f704e65b7063487f9e9d095630a8c5bb8e9dd2f3e3b24fef3f24338d83e49cc73404a603c
6
+ metadata.gz: 9b87669992f65b1279ceb003d2767d7ae6173374c6d810c646ee2914643050514c483aadb81cebafbd505fbbea41b89e297e6026f20749e571e84b423bc3cc8c
7
+ data.tar.gz: fec0ac13faa9880b10f6245d660b3e95430bfcd6cf48a65787634a55fe32c32e4e5f2eeb8f9321467c6a8dede5c03d34d7ab23ef0a0045de698e8bdf821c5534
data/CHANGELOG.md CHANGED
@@ -5,7 +5,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/)
5
5
  and this project adheres to [Semantic Versioning](https://semver.org/).
6
6
 
7
7
  ## [Unreleased]
8
- - (nothing to record)
8
+ - (nothing to record here)
9
+
10
+ ## [0.2.0] - 2021-05-03
11
+ ### Added
12
+ - Re-write the parser and evaluator mechanism.
13
+ - Add tests for SchemeParser and Translator.
14
+ - Add a mechanism to replace comparison operator characters in
15
+ identifiers.
16
+ - e.g. `char<?` -> `char_lt?`
9
17
 
10
18
  ## [0.1.2] - 2021-04-23
11
19
  ### Added
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rus3 (0.1.2)
4
+ rus3 (0.2.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -17,12 +17,7 @@ You can start the Rus3 REPL with the command, `rus3`.
17
17
 
18
18
  ``` scheme
19
19
  > rus3
20
- A simple REPL for Rus3:
21
- - Rus3 version: 0.1.0
22
- - REPL version: 0.1.0
23
- - Parser version 0.1.0 ((scheme-parser-version . 0.1.0) (scheme-lexer-version . 0.1.0))
24
- - Evaluator version: 0.1.0
25
- - using built-in PRINTER
20
+ A simple REPL to run Rus3:
26
21
  Rus3(scheme)>
27
22
  ```
28
23
 
@@ -32,6 +27,19 @@ In the REPL, you can enter Scheme expressions. The REPL reads your
32
27
  Scheme expressions, translates it to Ruby expressions, and
33
28
  evaluated them. Then, the REPL prints the result after `==> `.
34
29
 
30
+ If you want to run verbosely, use "-d" (or "--debug") option, then it
31
+ will become very verbose:
32
+
33
+ ``` scheme
34
+ A simple REPL to run Rus3:
35
+ (rus3 :version 0.2.0 :release 2021-05-02
36
+ (repl :version 0.2.0
37
+ (parser-module :version 0.2.0 ((scheme-parser :version 0.2.0) (scheme-lexer :version 0.2.0)))
38
+ (evaluator-module version: 0.2.0 ((scheme-evaluator :version 0.2.0) (scheme-ruby-translator :version 0.1.0)))
39
+ (:using :built-in :printer)))
40
+ Rus3(scheme)>
41
+ ```
42
+
35
43
  ### Literal of Scheme values
36
44
 
37
45
  Boolean (`#f` and `#t`), an empty list (`()`), a string, and numbers
data/exe/rus3 CHANGED
@@ -2,17 +2,41 @@
2
2
 
3
3
  require "rus3"
4
4
 
5
+ def usage
6
+ puts <<HELP
7
+ usage:
8
+ rus3 [option]
9
+ option:
10
+ -e, --evaluator NAME : specify evaluator
11
+ -d, --debug : specify to run verbose mode
12
+ -v, --version : print version
13
+ -h, --help : show this message
14
+
15
+ Following names are available as evaluator name:
16
+ scheme (use by default), passthrough
17
+ HELP
18
+ end
19
+
5
20
  opts = {}
6
21
 
7
22
  while ARGV.size > 0
8
23
  arg = ARGV.shift
9
24
  case arg
25
+ when "-p", "--parser"
26
+ parser_name = ARGV.shift
27
+ opts[:parser] = parser_name
28
+ when "-e", "--evaluator"
29
+ evaluator_name = ARGV.shift
30
+ opts[:evaluator] = evaluator_name
10
31
  when "-d", "--debug"
11
- opts[:debug] = true
32
+ opts[:verbose] = true
12
33
  when "-v", "--version"
13
34
  puts "rus3 version #{Rus3::VERSION} (#{Rus3::RELEASE})"
14
35
  exit 0
36
+ when "-h", "--help"
37
+ usage
38
+ exit 0
15
39
  end
16
40
  end
17
41
 
18
- Rus3::Repl.start(verbose: opts[:debug])
42
+ Rus3::Repl.start(**opts)
data/lib/rus3.rb CHANGED
@@ -49,6 +49,9 @@ module Rus3
49
49
  require_relative "rus3/procedure/control"
50
50
  require_relative "rus3/procedure/write"
51
51
 
52
+ require_relative "rus3/ast"
53
+ require_relative "rus3/token"
54
+ require_relative "rus3/lexer"
52
55
  require_relative "rus3/parser"
53
56
  require_relative "rus3/evaluator"
54
57
  require_relative "rus3/printer"
data/lib/rus3/ast.rb ADDED
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rus3
4
+
5
+ module AST
6
+
7
+ require_relative "ast/error"
8
+
9
+ module Utils
10
+ class << self
11
+ def camel_case(snake_case)
12
+ snake_case.to_s.split("_").map(&:capitalize).join("")
13
+ end
14
+ end
15
+ end
16
+
17
+ class Node
18
+ attr_reader :literal
19
+
20
+ def initialize(literal = nil)
21
+ @literal = literal
22
+ end
23
+
24
+ def leaf?; false; end
25
+ def branch?; false; end
26
+ def illegal?; false; end
27
+
28
+ def type; nil; end
29
+
30
+ def to_s
31
+ @literal
32
+ end
33
+ end
34
+
35
+ class IllegalNode < Node
36
+ def initialize(ast_type, literal)
37
+ super(literal)
38
+ @given_type = ast_type
39
+ end
40
+
41
+ def illegal?
42
+ true
43
+ end
44
+
45
+ def type
46
+ @given_type
47
+ end
48
+
49
+ def to_s
50
+ "type: #{@given_type}, literal: #{@literal}"
51
+ end
52
+ end
53
+
54
+ require_relative "ast/leaf_node"
55
+ require_relative "ast/branch_node"
56
+
57
+ class << self
58
+ def instantiate(ast_type, literal = nil)
59
+ klass_name = Utils.camel_case(ast_type) + "Node"
60
+ klass = AST.const_get(klass_name)
61
+ if klass.nil? or klass == IllegalNode
62
+ IllegalNode.new(ast_type, literal)
63
+ else
64
+ klass.new(literal)
65
+ end
66
+ end
67
+
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,412 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rus3
4
+ module AST
5
+
6
+ class BranchNode < Node
7
+ include Enumerable
8
+
9
+ def initialize(size = nil)
10
+ super(nil)
11
+ @nodes = size.nil? ? [] : Array.new(size)
12
+ end
13
+
14
+ def branch?
15
+ true
16
+ end
17
+
18
+ def <<(node)
19
+ @nodes << node
20
+ end
21
+
22
+ def [](index)
23
+ raise OutOfRangeError, index if index >= @nodes.size
24
+ @nodes[index]
25
+ end
26
+
27
+ def each(&block)
28
+ if block.nil?
29
+ @nodes.each
30
+ else
31
+ @nodes.each(&block)
32
+ self
33
+ end
34
+ end
35
+
36
+ def to_s
37
+ @nodes.map(&:to_s).join(" ")
38
+ end
39
+
40
+ end
41
+
42
+ class ProgramNode < BranchNode
43
+ def initialize(_ = nil)
44
+ super(nil)
45
+ end
46
+
47
+ def type
48
+ :program
49
+ end
50
+ end
51
+
52
+ class VectorNode < BranchNode
53
+ def initialize(_ = nil)
54
+ super(nil)
55
+ end
56
+
57
+ def type
58
+ :vector
59
+ end
60
+
61
+ def to_s
62
+ "#(" + super + ")"
63
+ end
64
+ end
65
+
66
+ class ListNode < BranchNode
67
+ def initialize(first_literal = nil, initial_size = nil)
68
+ super(initial_size)
69
+ @nodes[0] = IdentifierNode.new(first_literal) if first_literal
70
+ end
71
+
72
+ def type
73
+ :list
74
+ end
75
+
76
+ def car
77
+ @nodes[0]
78
+ end
79
+
80
+ def cdr
81
+ @nodes[1..-1]
82
+ end
83
+
84
+ def to_s
85
+ "(" + super + ")"
86
+ end
87
+ end
88
+
89
+ class QuotationNode < ListNode
90
+ def initialize(_ = nil)
91
+ super("quote")
92
+ end
93
+
94
+ def type
95
+ :quotation
96
+ end
97
+ end
98
+
99
+ class ProcedureCallNode < ListNode
100
+ def initialize(_ = nil)
101
+ # @nodes = [<operator>, <operand>*]
102
+ super(nil, 1)
103
+ end
104
+
105
+ def type
106
+ :procedure_call
107
+ end
108
+
109
+ def operator
110
+ @nodes[0]
111
+ end
112
+
113
+ def operator=(node)
114
+ @nodes[0] = node
115
+ end
116
+
117
+ def operands
118
+ @nodes[1..-1]
119
+ end
120
+
121
+ def add_operand(node)
122
+ @nodes << node
123
+ end
124
+ end
125
+
126
+ class LambdaExpressionNode < ListNode
127
+ def initialize(_ = nil)
128
+ # @nodes = [<lambda>, <formals>, <body> ...]
129
+ super("lambda", 2)
130
+ end
131
+
132
+ def type
133
+ :lambda_expression
134
+ end
135
+
136
+ def formals
137
+ @nodes[1]
138
+ end
139
+
140
+ def formals=(list_node)
141
+ @nodes[1] = list_node
142
+ end
143
+
144
+ def body
145
+ @nodes[2..-1]
146
+ end
147
+
148
+ def body=(nodes)
149
+ nodes.each_with_index { |node, i|
150
+ @nodes[i + 2] = node
151
+ }
152
+ end
153
+ end
154
+
155
+ class ConditionalNode < ListNode
156
+ def initialize(_ = nil)
157
+ # @nodes = [<if>, <test>, <consequent>] or
158
+ # [<if>, <test>, <consequent>, <alternate>]
159
+ super("if", 3)
160
+ end
161
+
162
+ def type
163
+ :conditional
164
+ end
165
+
166
+ def test
167
+ @nodes[1]
168
+ end
169
+
170
+ def consequent
171
+ @nodes[2]
172
+ end
173
+
174
+ def alternate
175
+ if @nodes.size > 3
176
+ @nodes[3]
177
+ else
178
+ nil
179
+ end
180
+ end
181
+
182
+ def test=(node)
183
+ @nodes[1] = node
184
+ end
185
+
186
+ def consequent=(node)
187
+ @nodes[2] = node
188
+ end
189
+
190
+ def alternate=(node)
191
+ @nodes[3] = node
192
+ end
193
+ end
194
+
195
+ class AssignmentNode < ListNode
196
+ def initialize(_ = nil)
197
+ super("set!", 3)
198
+ end
199
+
200
+ def type
201
+ :assignment
202
+ end
203
+
204
+ def identifier
205
+ @nodes[1]
206
+ end
207
+
208
+ def identifier=(node)
209
+ @nodes[1] = node
210
+ end
211
+
212
+ def expression
213
+ @nodes[2]
214
+ end
215
+
216
+ def expression=(node)
217
+ @nodes[2] = node
218
+ end
219
+ end
220
+
221
+ class IdentifierDefinitionNode < ListNode
222
+ def initialize(_ = nil)
223
+ super("define", 3)
224
+ end
225
+
226
+ def type
227
+ :identifier_definition
228
+ end
229
+
230
+ def identifier
231
+ @nodes[1]
232
+ end
233
+
234
+ def identifier=(node)
235
+ @nodes[1] = node
236
+ end
237
+
238
+ def expression
239
+ @nodes[2]
240
+ end
241
+
242
+ def expression=(node)
243
+ @nodes[2] = node
244
+ end
245
+
246
+ def def_formals
247
+ if lambda?
248
+ expression.formals
249
+ else
250
+ nil
251
+ end
252
+ end
253
+
254
+ def body
255
+ if lambda?
256
+ expression.body
257
+ else
258
+ nil
259
+ end
260
+ end
261
+
262
+ private
263
+
264
+ def lambda?
265
+ expression.type == :lambda_expression
266
+ end
267
+
268
+ end
269
+
270
+ class SyntaxDefinitionNode < ListNode
271
+ def type
272
+ :syntax_definition
273
+ end
274
+
275
+ end
276
+
277
+ class ValuesDefinitionNode < ListNode
278
+ def type
279
+ :values_definition
280
+ end
281
+
282
+ end
283
+
284
+ class RecordTypeDefinitionNode < ListNode
285
+ def type
286
+ :record_type_definition
287
+ end
288
+
289
+ end
290
+
291
+ class MacroBlockNode < ListNode
292
+ def initialize(literal)
293
+ super(literal)
294
+ end
295
+
296
+ def type
297
+ :macro_block
298
+ end
299
+
300
+ end
301
+
302
+ class CondNode < ListNode
303
+ def initialize(_ = nil)
304
+ super("cond")
305
+ end
306
+
307
+ def type
308
+ :cond
309
+ end
310
+
311
+ def cond_clauses
312
+ @nodes[1..-1]
313
+ end
314
+
315
+ def add_clause(node)
316
+ @nodes << node
317
+ end
318
+ end
319
+
320
+ class CondClauseNode < ListNode
321
+ def initialize(_ = nil)
322
+ super(nil, 1)
323
+ end
324
+
325
+ def type
326
+ :cond_clause
327
+ end
328
+
329
+ def test
330
+ @nodes[0]
331
+ end
332
+
333
+ def test=(node)
334
+ @nodes[0] = node
335
+ end
336
+
337
+ def sequence
338
+ @nodes[1..-1]
339
+ end
340
+
341
+ def add_expression(node)
342
+ @nodes << node
343
+ end
344
+ end
345
+
346
+ class LetNode < ListNode
347
+ def initialize(_ = nil)
348
+ super("let", 2)
349
+ end
350
+
351
+ def type
352
+ :let
353
+ end
354
+
355
+ def bind_specs
356
+ @nodes[1]
357
+ end
358
+
359
+ def bind_specs=(node)
360
+ @nodes[1] = node
361
+ end
362
+
363
+ def body
364
+ @nodes[2..-1]
365
+ end
366
+
367
+ def body=(nodes)
368
+ nodes.each_with_index { |node, i|
369
+ @nodes[i + 2] = node
370
+ }
371
+ end
372
+ end
373
+
374
+ class BindSpecNode < ListNode
375
+ def initialize(_ = nil)
376
+ super(nil, 2)
377
+ end
378
+
379
+ def type
380
+ :bind_spec
381
+ end
382
+
383
+ def identifier
384
+ @nodes[1]
385
+ end
386
+
387
+ def identifier=(node)
388
+ @nodes[1] = node
389
+ end
390
+
391
+ def expression
392
+ @nodes[2]
393
+ end
394
+
395
+ def expression=(node)
396
+ @nodes[2] = node
397
+ end
398
+ end
399
+
400
+ class AndNode < ListNode
401
+ def initialize(_ = nil)
402
+ super("and")
403
+ end
404
+
405
+ def type
406
+ :and
407
+ end
408
+
409
+ end
410
+
411
+ end
412
+ end