rus3 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rus3
4
+ module Procedure
5
+
6
+ # This module holds comparison operation procedures of Scheme.
7
+
8
+ module Comparison
9
+
10
+ def lt?(*args)
11
+ c_calc(:<, *args)
12
+ end
13
+
14
+ def le?(*args)
15
+ c_calc(:<=, *args)
16
+ end
17
+
18
+ def gt?(*args)
19
+ c_calc(:>, *args)
20
+ end
21
+
22
+ def ge?(*args)
23
+ c_calc(:>=, *args)
24
+ end
25
+
26
+ def same_value?(*args)
27
+ c_calc(:==, *args)
28
+ end
29
+
30
+ private
31
+
32
+ def c_calc(op, *args)
33
+ case args.size
34
+ when 0, 1
35
+ raise ArgumentError, args.to_s
36
+ when 2
37
+ args[0].send(op, args[1]) ? true : false
38
+ else
39
+ args[0].send(op, args[1]) and c_calc(op, *args[1..-1]) ? true : false
40
+ end
41
+ end
42
+
43
+ end
44
+ end
45
+ end
data/lib/rus3/repl.rb CHANGED
@@ -21,13 +21,13 @@ module Rus3
21
21
  class Repl
22
22
 
23
23
  # Indicates the version of the Repl class.
24
- REPL_VERSION = "0.2.0"
24
+ REPL_VERSION = "0.2.1"
25
25
 
26
26
  class << self
27
27
 
28
28
  # Starts REPL.
29
- def start(parser: nil, evaluator: nil, verbose: false)
30
- repl = Repl.new(parser: parser, evaluator: evaluator, verbose: verbose)
29
+ def start(evaluator: nil, verbose: false)
30
+ repl = Repl.new(evaluator: evaluator, verbose: verbose)
31
31
  repl.loop
32
32
  end
33
33
 
@@ -35,9 +35,9 @@ module Rus3
35
35
 
36
36
  # Hods major component names of the REPL.
37
37
  COMPONENTS = {
38
- :parser => Parser::DEFAULT_PARSER,
38
+ :parser => Rubasteme::Parser,
39
39
  :evaluator => Evaluator::DEFAULT_EVALUATOR,
40
- :printer => nil,
40
+ :printer => Printer::ChainPrinter,
41
41
  }
42
42
 
43
43
  # Prompt for input.
@@ -51,18 +51,16 @@ module Rus3
51
51
  attr_accessor :verbose # :nodoc:
52
52
  attr_accessor :prompt # :nodoc:
53
53
 
54
- def initialize(parser: nil, evaluator: nil, verbose: false)
54
+ def initialize(evaluator: nil, verbose: false)
55
55
  comps = COMPONENTS.dup
56
56
 
57
- comps[:parser] = Parser.const_get("#{parser.capitalize}Parser") if parser
58
57
  comps[:evaluator] = Evaluator.const_get("#{evaluator.capitalize}Evaluator") if evaluator
59
58
 
60
59
  comps.each { |name, klass|
61
- instance_variable_set("@#{name}", klass.nil? ? self : klass.new)
60
+ instance_variable_set("@#{name}", klass.new)
62
61
  }
63
62
 
64
63
  @prompt = PROMPT
65
- @parser.prompt = PROMPT
66
64
 
67
65
  @verbose = verbose
68
66
  @evaluator.verbose = verbose
@@ -77,17 +75,18 @@ module Rus3
77
75
  end
78
76
 
79
77
  def loop
80
- msg = Kernel.loop { # LOOP
78
+ msg = Kernel.loop { # LOOP
81
79
  begin
82
- ast = @parser.read(STDIN) # READ
80
+ source = read(STDIN) # READ
81
+ break FAREWELL_MESSAGE if source.nil?
82
+ ast = @parser.parse(Rbscmlex::Lexer.new(source))
83
83
  rescue SchemeSyntaxError => e
84
84
  puts "ERROR" + (@verbose ? "(READ)" : "") + ": %s" % e
85
85
  next
86
86
  end
87
- break FAREWELL_MESSAGE if ast.nil?
88
87
 
89
88
  begin
90
- value = @evaluator.eval(ast) # EVAL
89
+ value = @evaluator.eval(ast) # EVAL
91
90
  rescue SyntaxError, StandardError => e
92
91
  puts "ERROR" + (@verbose ? "(EVAL)" : "") + ": %s" % e
93
92
  next
@@ -95,7 +94,7 @@ module Rus3
95
94
 
96
95
  history_push(value)
97
96
 
98
- @printer.print(value) # PRINT
97
+ @printer.print(value) # PRINT
99
98
  }
100
99
  puts "#{msg}" unless msg.nil?
101
100
  end
@@ -125,28 +124,23 @@ module Rus3
125
124
  require "readline"
126
125
 
127
126
  def read(io = STDIN)
128
- Readline::readline(@prompt, true)
129
- end
130
-
131
- def eval(ast)
132
- ast
133
- end
134
-
135
- def print(obj)
136
- prefix = "==> "
137
- prefix += "[#{obj.class}]: " if @verbose
138
- Kernel.print prefix
139
- pp obj
127
+ program_source = nil
128
+ if io == STDIN
129
+ program_source = Readline::readline(@prompt, true)
130
+ else
131
+ program_source = io.readlines(chomp: true).join(" ")
132
+ end
133
+ program_source
140
134
  end
141
135
 
142
136
  private
143
137
 
144
138
  def version_message(comp_name)
145
- vmsg = nil
139
+ vmsg = ""
146
140
  component = instance_variable_get("@#{comp_name}")
147
- if component.nil? or component == self
148
- vmsg = ":using :built-in :#{comp_name}"
149
- else
141
+ if component.class.respond_to?(:version)
142
+ vmsg = "#{component.class.version}"
143
+ elsif component.respond_to?(:version)
150
144
  vmsg = "#{component.version}"
151
145
  end
152
146
  vmsg
@@ -225,7 +219,8 @@ HELP
225
219
  scheme_source = File.readlines(path, chomp: true).join(" ")
226
220
  result = ast = nil
227
221
  if @scm_parser.respond_to?(:parse)
228
- ast = @scm_parser.parse(scheme_source)
222
+ lexer = Rbscmlex::Lexer.new(scheme_source)
223
+ ast = @scm_parser.parse(lexer)
229
224
  end
230
225
  if @scm_evaluator.respond_to?(:eval)
231
226
  result = @scm_evaluator.eval(ast)
data/lib/rus3/version.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rus3
4
- VERSION = "0.2.0"
5
- RELEASE = "2021-05-03"
4
+ VERSION = "0.2.1"
5
+ RELEASE = "2021-05-20"
6
6
  end
data/rus3.gemspec CHANGED
@@ -9,10 +9,10 @@ Gem::Specification.new do |spec|
9
9
  spec.email = ["mnbi@users.noreply.github.com"]
10
10
 
11
11
  spec.summary = "Ruby with Syntax Sugar of Scheme"
12
- spec.description = "Ruby with Syntax Sugar of Scheme"
12
+ spec.description = "Ruby with Syntax Sugar of Scheme, or Scheme to Ruby translator."
13
13
  spec.homepage = "https://github.com/mnbi/rus3"
14
14
  spec.license = "MIT"
15
- spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
15
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.7.0")
16
16
 
17
17
  spec.metadata["homepage_uri"] = spec.homepage
18
18
  spec.metadata["source_code_uri"] = "https://github.com/mnbi/rus3"
@@ -27,9 +27,6 @@ Gem::Specification.new do |spec|
27
27
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
28
28
  spec.require_paths = ["lib"]
29
29
 
30
- # Uncomment to register a new dependency of your gem
31
- # spec.add_dependency "example-gem", "~> 1.0"
32
-
33
- # For more information and examples about making a new gem, checkout our
34
- # guide at: https://bundler.io/guides/creating_gem.html
30
+ spec.add_dependency "rbscmlex", ">= 0.1.3"
31
+ spec.add_dependency "rubasteme", ">= 0.1.3"
35
32
  end
metadata CHANGED
@@ -1,16 +1,44 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rus3
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - mnbi
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-05-03 00:00:00.000000000 Z
12
- dependencies: []
13
- description: Ruby with Syntax Sugar of Scheme
11
+ date: 2021-05-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rbscmlex
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.1.3
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 0.1.3
27
+ - !ruby/object:Gem::Dependency
28
+ name: rubasteme
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.1.3
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 0.1.3
41
+ description: Ruby with Syntax Sugar of Scheme, or Scheme to Ruby translator.
14
42
  email:
15
43
  - mnbi@users.noreply.github.com
16
44
  executables:
@@ -33,23 +61,18 @@ files:
33
61
  - examples/iota.scm
34
62
  - exe/rus3
35
63
  - lib/rus3.rb
36
- - lib/rus3/ast.rb
37
- - lib/rus3/ast/branch_node.rb
38
- - lib/rus3/ast/error.rb
39
- - lib/rus3/ast/leaf_node.rb
40
64
  - lib/rus3/char.rb
41
65
  - lib/rus3/error.rb
42
66
  - lib/rus3/evaluator.rb
43
67
  - lib/rus3/evaluator/environment.rb
44
68
  - lib/rus3/evaluator/scheme_evaluator.rb
45
69
  - lib/rus3/evaluator/translator.rb
46
- - lib/rus3/lexer.rb
47
70
  - lib/rus3/pair.rb
48
- - lib/rus3/parser.rb
49
- - lib/rus3/parser/scheme_parser.rb
50
71
  - lib/rus3/port.rb
51
72
  - lib/rus3/printer.rb
73
+ - lib/rus3/procedure/arithmetic.rb
52
74
  - lib/rus3/procedure/char.rb
75
+ - lib/rus3/procedure/comparison.rb
53
76
  - lib/rus3/procedure/control.rb
54
77
  - lib/rus3/procedure/list.rb
55
78
  - lib/rus3/procedure/predicate.rb
@@ -57,7 +80,6 @@ files:
57
80
  - lib/rus3/procedure/vector.rb
58
81
  - lib/rus3/procedure/write.rb
59
82
  - lib/rus3/repl.rb
60
- - lib/rus3/token.rb
61
83
  - lib/rus3/vector.rb
62
84
  - lib/rus3/version.rb
63
85
  - rus3.gemspec
@@ -76,7 +98,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
76
98
  requirements:
77
99
  - - ">="
78
100
  - !ruby/object:Gem::Version
79
- version: 2.3.0
101
+ version: 2.7.0
80
102
  required_rubygems_version: !ruby/object:Gem::Requirement
81
103
  requirements:
82
104
  - - ">="
data/lib/rus3/ast.rb DELETED
@@ -1,70 +0,0 @@
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
@@ -1,412 +0,0 @@
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