skeem 0.2.15 → 0.2.16

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +17 -11
  3. data/CHANGELOG.md +5 -0
  4. data/Gemfile +2 -0
  5. data/README.md +3 -2
  6. data/Rakefile +2 -0
  7. data/appveyor.yml +3 -4
  8. data/bin/skeem +15 -15
  9. data/lib/skeem.rb +2 -0
  10. data/lib/skeem/datum_dsl.rb +12 -3
  11. data/lib/skeem/element_visitor.rb +5 -2
  12. data/lib/skeem/grammar.rb +86 -24
  13. data/lib/skeem/interpreter.rb +5 -3
  14. data/lib/skeem/parser.rb +6 -4
  15. data/lib/skeem/primitive/primitive_builder.rb +128 -115
  16. data/lib/skeem/primitive/primitive_procedure.rb +17 -20
  17. data/lib/skeem/runtime.rb +9 -5
  18. data/lib/skeem/s_expr_builder.rb +46 -104
  19. data/lib/skeem/s_expr_nodes.rb +116 -90
  20. data/lib/skeem/skeem_exception.rb +0 -0
  21. data/lib/skeem/skm_binding.rb +6 -7
  22. data/lib/skeem/skm_compound_datum.rb +8 -4
  23. data/lib/skeem/skm_element.rb +14 -12
  24. data/lib/skeem/skm_empty_list.rb +6 -4
  25. data/lib/skeem/skm_exception.rb +9 -0
  26. data/lib/skeem/skm_expression.rb +3 -1
  27. data/lib/skeem/skm_frame.rb +3 -2
  28. data/lib/skeem/skm_pair.rb +23 -18
  29. data/lib/skeem/skm_procedure_exec.rb +8 -6
  30. data/lib/skeem/skm_simple_datum.rb +13 -12
  31. data/lib/skeem/skm_unary_expression.rb +15 -17
  32. data/lib/skeem/tokenizer.rb +32 -25
  33. data/lib/skeem/version.rb +3 -1
  34. data/skeem.gemspec +6 -4
  35. data/spec/skeem/add4.skm +4 -0
  36. data/spec/skeem/datum_dsl_spec.rb +13 -12
  37. data/spec/skeem/element_visitor_spec.rb +12 -10
  38. data/spec/skeem/interpreter_spec.rb +74 -46
  39. data/spec/skeem/lambda_spec.rb +9 -7
  40. data/spec/skeem/parser_spec.rb +21 -19
  41. data/spec/skeem/primitive/primitive_builder_spec.rb +57 -48
  42. data/spec/skeem/primitive/primitive_procedure_spec.rb +15 -13
  43. data/spec/skeem/runtime_spec.rb +18 -16
  44. data/spec/skeem/s_expr_nodes_spec.rb +8 -6
  45. data/spec/skeem/skm_compound_datum_spec.rb +11 -9
  46. data/spec/skeem/skm_element_spec.rb +7 -5
  47. data/spec/skeem/skm_empty_list_spec.rb +7 -5
  48. data/spec/skeem/skm_frame_spec.rb +5 -4
  49. data/spec/skeem/skm_pair_spec.rb +4 -3
  50. data/spec/skeem/skm_procedure_exec_spec.rb +2 -0
  51. data/spec/skeem/skm_simple_datum_spec.rb +24 -22
  52. data/spec/skeem/skm_unary_expression_spec.rb +11 -9
  53. data/spec/skeem/tokenizer_spec.rb +53 -44
  54. data/spec/skeem_spec.rb +2 -0
  55. data/spec/spec_helper.rb +4 -2
  56. metadata +7 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 182cf920c536bb07dd813c34eae74af24181813a9d96fdd39c786cc28043f135
4
- data.tar.gz: ba4cf5ce2df8d1708f3504e57a14b62734146f3c8a47043cf2d5ffdf591e35d6
3
+ metadata.gz: c6b187bafcc1084e3c45a68f552bb5756b8dc51338f5241fa64ad5f60f1f94c7
4
+ data.tar.gz: f6925b7497ab8a2ab678c7b5483907b374caed4f7a9b00e1d22d3d53c141191c
5
5
  SHA512:
6
- metadata.gz: bd03dfab05470ee167464113844c3a8b0b3174f58cd4607034f417218b91ec024e26aff941ac78e750be30ff216d18be97171b030c3f3055803443f421ad6c19
7
- data.tar.gz: 2cd279dca2e9202e6a924373a01c1a49e493ea2379131284639b07977714c72df751574a8252231d15182dc6b23d55206aaa11be062502b4840a5d9a27143199
6
+ metadata.gz: b8e2cd533cd3e1661f1c205ab87179e8d1a48a1e23d5c5867c6106f54b56fe076fda0ae2eaa1a28045633dc4e3eb80ec891abf8dd3f03f6698e53c5e308173be
7
+ data.tar.gz: 68e3b66e4821062f9792e37b9b2d89134e10a21fcb6f0e3fc1a591243a1be8930cb5a18fcc9add86850a47cbfa9be4f7c2a2239bb94e3f187082efb2a2392412
data/.rubocop.yml CHANGED
@@ -5,6 +5,9 @@ AllCops:
5
5
  Layout/CaseIndentation:
6
6
  Enabled: false
7
7
 
8
+ Layout/ClosingHeredocIndentation:
9
+ Enabled: false
10
+
8
11
  Layout/CommentIndentation:
9
12
  Enabled: false
10
13
 
@@ -13,7 +16,7 @@ Layout/ElseAlignment:
13
16
 
14
17
  Layout/EmptyLines:
15
18
  Enabled: false
16
-
19
+
17
20
  Layout/EndAlignment:
18
21
  Enabled: false
19
22
 
@@ -26,10 +29,10 @@ Layout/IndentationWidth:
26
29
 
27
30
  Layout/IndentationConsistency:
28
31
  Enabled: true
29
-
32
+
30
33
  Layout/IndentHeredoc:
31
34
  Enabled: false
32
-
35
+
33
36
  Layout/MultilineHashBraceLayout:
34
37
  Enabled: true
35
38
 
@@ -38,10 +41,10 @@ Layout/SpaceAroundOperators:
38
41
 
39
42
  Layout/SpaceInsideParens:
40
43
  Enabled: true
41
-
44
+
42
45
  Layout/Tab:
43
46
  Enabled: true
44
-
47
+
45
48
  Layout/TrailingBlankLines:
46
49
  Enabled: true
47
50
 
@@ -100,10 +103,10 @@ Naming/ConstantName:
100
103
 
101
104
  Naming/ClassAndModuleCamelCase:
102
105
  Enabled: false
103
-
106
+
104
107
  Naming/UncommunicativeBlockParamName:
105
108
  Enabled: true
106
-
109
+
107
110
  Naming/UncommunicativeMethodParamName:
108
111
  Enabled: false
109
112
 
@@ -167,12 +170,15 @@ Style/InverseMethods:
167
170
  Style/Next:
168
171
  Enabled: false
169
172
 
173
+ Style/NumericLiterals:
174
+ Enabled: false
175
+
170
176
  Style/RaiseArgs:
171
177
  Enabled: true
172
178
 
173
179
  Style/RedundantReturn:
174
180
  Enabled: false
175
-
181
+
176
182
  Style/RedundantSelf:
177
183
  Enabled: true
178
184
 
@@ -181,15 +187,15 @@ Style/RegexpLiteral:
181
187
 
182
188
  Style/PercentLiteralDelimiters:
183
189
  Enabled: false
184
-
190
+
185
191
  Style/StderrPuts:
186
- Enabled: false
192
+ Enabled: false
187
193
 
188
194
  Style/StringLiterals:
189
195
  Enabled: true
190
196
 
191
197
  Style/TernaryParentheses:
192
198
  Enabled: false
193
-
199
+
194
200
  Style/UnlessElse:
195
201
  Enabled: false
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## [0.2.16] - 2019-08-18
2
+ - Code refactoring to use string frozen magic comments (as a consequence, srl_ruby runs only on Rubies 2.3 or newer).
3
+ - Code restyling to please rubocop 0.7.40.
4
+
5
+
1
6
  ## [0.2.15] - 2019-07-02
2
7
  - Added a basic command-line and console interface for Skeem interpreter.
3
8
  - Added procedures: `display!`, `newline`, `make-list`
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
data/README.md CHANGED
@@ -32,7 +32,8 @@ If you're not familiar to Scheme, the section [About Scheme](#about-scheme) cont
32
32
 
33
33
  ## Usage
34
34
  Once the gem is installed, the `skeem` executable can be used.
35
- It allows to run the interpreter from the command line.
35
+ It allows to run the interpreter from a REPL console or from the command line.
36
+ Another way to interact with the Skeem interpreter is to embed it in your Ruby code.
36
37
 
37
38
  ### Launching a REPL session
38
39
  To start a REPL (Read-Eval-Print-Loop) session, just type:
@@ -42,7 +43,7 @@ To start a REPL (Read-Eval-Print-Loop) session, just type:
42
43
 
43
44
  Skeem displays a greeting, a prompt and then waits for your input:
44
45
  ```
45
- Welcome to Skeem 0.2.15.
46
+ Welcome to Skeem 0.2.16.
46
47
  >
47
48
  ```
48
49
 
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler/gem_tasks'
2
4
  require 'rspec/core/rake_task'
3
5
 
data/appveyor.yml CHANGED
@@ -1,17 +1,16 @@
1
1
  version: '{build}'
2
- max_jobs: 3
2
+ max_jobs: 5
3
3
  environment:
4
4
  matrix:
5
+ - Ruby_version: 26-x64
5
6
  - Ruby_version: 25-x64
6
7
  - Ruby_version: 24-x64
7
8
  - Ruby_version: 23-x64
9
+ - Ruby_version: 26
8
10
  - Ruby_version: 25
9
11
  - Ruby_version: 24
10
12
  - Ruby_version: 23
11
13
 
12
- # These are failing
13
- # - Ruby_version: 26
14
- # - Ruby_version: 26-x64
15
14
 
16
15
  install:
17
16
  - set PATH=C:\Ruby%Ruby_version%\bin;%PATH%
data/bin/skeem CHANGED
@@ -1,20 +1,22 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'skeem'
4
5
 
5
6
  class SkeemREPL
6
7
  attr_reader :interpreter
7
8
 
8
- def initialize()
9
+ def initialize
9
10
  @interpreter = Skeem::Interpreter.new
10
11
  end
11
12
 
12
13
  def run_session
13
- puts "Welcome to Skeem #{Skeem::VERSION}."
14
+ puts "Welcome to Skeem #{Skeem::VERSION}."
14
15
  loop do
15
16
  print '> '
16
17
  input = gets.chomp.strip
17
- break if input == '(quit)' || input == '(exit)'
18
+ break if %w[(quit) (exit)].include?(input)
19
+
18
20
  process_input(input)
19
21
  end
20
22
  end
@@ -22,15 +24,13 @@ class SkeemREPL
22
24
  def run_file(aFilename)
23
25
  if File.exist?(aFilename)
24
26
  valid_fname = aFilename
25
- else # Retry by adding extension...
26
- if File.extname(aFilename).empty?
27
- if File.exist?(aFilename + '.skm')
28
- valid_fname = aFilename + '.skm'
29
- elsif File.exist?(aFilename + '.scm')
30
- valid_fname = aFilename + '.scm'
31
- else
32
- valid_fname = nil
33
- end
27
+ elsif File.extname(aFilename).empty? # Retry by adding extension...
28
+ if File.exist?(aFilename + '.skm')
29
+ valid_fname = aFilename + '.skm'
30
+ elsif File.exist?(aFilename + '.scm')
31
+ valid_fname = aFilename + '.scm'
32
+ else
33
+ valid_fname = nil
34
34
  end
35
35
  end
36
36
 
@@ -43,8 +43,8 @@ class SkeemREPL
43
43
  def process_input(input)
44
44
  begin
45
45
  ptree = interpreter.parse(input)
46
- rescue StandardError => exc
47
- $stderr.puts exc.message
46
+ rescue StandardError => e
47
+ $stderr.puts e.message
48
48
  return
49
49
  end
50
50
 
@@ -69,4 +69,4 @@ if ARGV.empty?
69
69
  djinn.run_session
70
70
  else
71
71
  djinn.run_file(ARGV[0])
72
- end
72
+ end
data/lib/skeem.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # File: skeem.rb
2
4
  # This file acts as a jumping-off point for loading dependencies expected
3
5
  # for a Skeem client.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'skm_simple_datum'
2
4
  require_relative 'skm_compound_datum'
3
5
  require_relative 'skm_pair'
@@ -19,6 +21,7 @@ module Skeem
19
21
  else
20
22
  raise StandardError, aBoolean.inspect
21
23
  end
24
+ result
22
25
  end
23
26
 
24
27
  def integer(aLiteral)
@@ -32,6 +35,7 @@ module Skeem
32
35
  else
33
36
  raise StandardError, aLiteral.inspect
34
37
  end
38
+ result
35
39
  end
36
40
 
37
41
  def rational(aLiteral)
@@ -45,6 +49,7 @@ module Skeem
45
49
  else
46
50
  raise StandardError, aLiteral.inspect
47
51
  end
52
+ result
48
53
  end
49
54
 
50
55
  def real(aLiteral)
@@ -58,6 +63,7 @@ module Skeem
58
63
  else
59
64
  raise StandardError, aLiteral.inspect
60
65
  end
66
+ result
61
67
  end
62
68
 
63
69
  def char(aLiteral)
@@ -75,6 +81,7 @@ module Skeem
75
81
  else
76
82
  raise StandardError, aLiteral.inspect
77
83
  end
84
+ result
78
85
  end
79
86
 
80
87
  def string(aLiteral)
@@ -88,6 +95,7 @@ module Skeem
88
95
  else
89
96
  SkmString.create(aLiteral.to_s)
90
97
  end
98
+ result
91
99
  end
92
100
 
93
101
  def identifier(aLiteral)
@@ -101,6 +109,7 @@ module Skeem
101
109
  else
102
110
  raise StandardError, aLiteral.inspect
103
111
  end
112
+ result
104
113
  end
105
114
 
106
115
  alias symbol identifier
@@ -150,7 +159,7 @@ module Skeem
150
159
  SkmBoolean.create(aLiteral)
151
160
  when String
152
161
  parse_literal(aLiteral)
153
- when SkmPair # Special case: not a PORO literal
162
+ when SkmPair # Special case: not a PORO literal
154
163
  # One assumes that a Skeem list contains only Skeem datum objects
155
164
  SkmPair.create_from_a(aLiteral.to_a)
156
165
  when SkmUndefined
@@ -158,6 +167,7 @@ module Skeem
158
167
  else
159
168
  raise StandardError, aLiteral.inspect
160
169
  end
170
+ result
161
171
  end
162
172
 
163
173
  private
@@ -177,6 +187,5 @@ module Skeem
177
187
  string(aLiteral)
178
188
  end
179
189
  end
180
-
181
190
  end # module
182
- end # module
191
+ end # module
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Skeem
2
4
  class SkmElementVisitor
3
5
  # Link to the root element to visit
@@ -12,6 +14,7 @@ module Skeem
12
14
  # @param aRoot [SkmElement] the parse tree to visit.
13
15
  def initialize(aRoot)
14
16
  raise StandardError if aRoot.nil?
17
+
15
18
  @root = aRoot
16
19
  @subscribers = []
17
20
  end
@@ -57,7 +60,6 @@ module Skeem
57
60
  broadcast(:after_empty_list, anEmptyList)
58
61
  end
59
62
 
60
-
61
63
  def visit_pair(aPair)
62
64
  broadcast(:before_pair, aPair)
63
65
  traverse_car_cdr(aPair)
@@ -110,8 +112,9 @@ module Skeem
110
112
  def broadcast(msg, *args)
111
113
  subscribers.each do |subscr|
112
114
  next unless subscr.respond_to?(msg) || subscr.respond_to?(:accept_all)
115
+
113
116
  subscr.send(msg, runtime, *args)
114
117
  end
115
118
  end
116
119
  end # class
117
- end # module
120
+ end # module
data/lib/skeem/grammar.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Grammar for Skeem (a subset of Scheme language)
2
4
  require 'rley' # Load the gem
3
5
 
@@ -11,7 +13,7 @@ module Skeem
11
13
  # Delimiters, separators...
12
14
  add_terminals('APOSTROPHE', 'COMMA', 'COMMA_AT_SIGN')
13
15
  add_terminals('GRAVE_ACCENT', 'LPAREN', 'RPAREN')
14
- add_terminals('PERIOD', 'ARROW')
16
+ add_terminals('PERIOD', 'UNDERSCORE', 'ARROW', 'ELLIPSIS')
15
17
  add_terminals('VECTOR_BEGIN')
16
18
 
17
19
  # Literal values...
@@ -19,9 +21,9 @@ module Skeem
19
21
  add_terminals('CHAR', 'STRING_LIT', 'IDENTIFIER')
20
22
 
21
23
  # Keywords...
22
- add_terminals('BEGIN', 'COND', 'DEFINE', 'DO', 'ELSE')
23
- add_terminals('IF', 'LAMBDA', 'LET', 'LET*')
24
- add_terminals('QUOTE', 'QUASIQUOTE', 'SET!')
24
+ add_terminals('BEGIN', 'COND', 'DEFINE', 'DEFINE-SYNTAX', 'DO')
25
+ add_terminals('ELSE', 'IF', 'INCLUDE', 'LAMBDA', 'LET', 'LET*')
26
+ add_terminals('QUOTE', 'QUASIQUOTE', 'SET!', 'SYNTAX-RULES')
25
27
  add_terminals('UNQUOTE', 'UNQUOTE-SPLICING')
26
28
 
27
29
  rule('program' => 'cmd_or_def_plus').as 'main'
@@ -33,6 +35,7 @@ module Skeem
33
35
  rule 'command' => 'expression'
34
36
  rule('definition' => 'LPAREN DEFINE IDENTIFIER expression RPAREN').as 'definition'
35
37
  rule('definition' => 'LPAREN DEFINE LPAREN IDENTIFIER def_formals RPAREN body RPAREN').as 'alt_definition'
38
+ rule('definition' => 'syntax_definition')
36
39
  rule('definition' => 'LPAREN BEGIN definition_star RPAREN').as 'definitions_within_begin'
37
40
  rule('expression' => 'IDENTIFIER').as 'variable_reference'
38
41
  rule 'expression' => 'literal'
@@ -41,8 +44,9 @@ module Skeem
41
44
  rule 'expression' => 'conditional'
42
45
  rule 'expression' => 'assignment'
43
46
  rule 'expression' => 'derived_expression'
47
+ rule 'expression' => 'includer'
44
48
  rule 'literal' => 'quotation'
45
- rule 'literal' => 'self-evaluating'
49
+ rule 'literal' => 'self-evaluating'
46
50
  rule('quotation' => 'APOSTROPHE datum').as 'quotation_short'
47
51
  rule('quotation' => 'LPAREN QUOTE datum RPAREN').as 'quotation'
48
52
  rule 'self-evaluating' => 'BOOLEAN'
@@ -64,8 +68,8 @@ module Skeem
64
68
  rule('vector' => 'VECTOR_BEGIN datum_star RPAREN').as 'vector'
65
69
  rule('datum_plus' => 'datum_plus datum').as 'multiple_datums'
66
70
  rule('datum_plus' => 'datum').as 'last_datum'
67
- rule('datum_star' => 'datum_star datum').as 'datum_star'
68
- rule('datum_star' => []).as 'no_datum_yet'
71
+ rule('datum_star' => 'datum_star datum').as 'star_default'
72
+ rule('datum_star' => []).as 'star_base' ## 'no_datum_yet'
69
73
  rule 'symbol' => 'IDENTIFIER'
70
74
  rule('procedure_call' => 'LPAREN operator RPAREN').as 'proc_call_nullary'
71
75
  rule('procedure_call' => 'LPAREN operator operand_plus RPAREN').as 'proc_call_args'
@@ -79,16 +83,17 @@ module Skeem
79
83
  rule('formals' => 'LPAREN identifier_star RPAREN').as 'fixed_arity_formals'
80
84
  rule('formals' => 'IDENTIFIER').as 'variadic_formals'
81
85
  rule('formals' => 'LPAREN identifier_plus PERIOD IDENTIFIER RPAREN').as 'dotted_formals'
82
- rule('identifier_star' => 'identifier_star IDENTIFIER').as 'identifier_star'
83
- rule('identifier_star' => []).as 'no_identifier_yet'
86
+ rule('syntax_definition' => 'LPAREN DEFINE-SYNTAX keyword transformer_spec RPAREN').as 'syntax_definition'
87
+ rule('identifier_star' => 'identifier_star IDENTIFIER').as 'star_default'
88
+ rule('identifier_star' => []).as 'star_base' ## 'no_identifier_yet'
84
89
  rule('identifier_plus' => 'identifier_plus IDENTIFIER').as 'multiple_identifiers'
85
90
  rule('identifier_plus' => 'IDENTIFIER').as 'last_identifier'
86
91
  rule('body' => 'definition_star sequence').as 'body'
87
- rule('definition_star' => 'definition_star definition').as 'definition_star'
88
- rule('definition_star' => []).as 'no_definition_yet'
92
+ rule('definition_star' => 'definition_star definition').as 'star_default'
93
+ rule('definition_star' => []).as 'star_base' ## 'no_definition_yet'
89
94
  rule('sequence' => 'command_star expression').as 'sequence'
90
- rule('command_star' => 'command_star command').as 'multiple_commands'
91
- rule('command_star' => []).as 'no_command_yet'
95
+ rule('command_star' => 'command_star command').as 'star_default'
96
+ rule('command_star' => []).as 'star_base' ## 'no_command_yet'
92
97
  rule('conditional' => 'LPAREN IF test consequent alternate RPAREN').as 'conditional'
93
98
  rule 'test' => 'expression'
94
99
  rule 'consequent' => 'expression'
@@ -101,13 +106,15 @@ module Skeem
101
106
  rule('derived_expression' => 'LPAREN COND cond_clause_plus RPAREN').as 'cond_form'
102
107
  rule('derived_expression' => 'LPAREN COND cond_clause_star LPAREN ELSE sequence RPAREN RPAREN').as 'cond_else_form'
103
108
  rule('derived_expression' => 'LPAREN LET LPAREN binding_spec_star RPAREN body RPAREN').as 'short_let_form'
109
+ # TODO: implement "named let"
110
+ rule('derived_expression' => 'LPAREN LET IDENTIFIER LPAREN binding_spec_star RPAREN body RPAREN') # .as 'named_form'
104
111
  rule('derived_expression' => 'LPAREN LET* LPAREN binding_spec_star RPAREN body RPAREN').as 'let_star_form'
105
112
 
106
- # As the R7RS grammar is too restrictive,
113
+ # As the R7RS grammar is too restrictive,
107
114
  # the next rule was made more general than its standard counterpart
108
115
  rule('derived_expression' => 'LPAREN BEGIN body RPAREN').as 'begin_expression'
109
116
  do_syntax = <<-END_SYNTAX
110
- LPAREN DO LPAREN iteration_spec_star RPAREN
117
+ LPAREN DO LPAREN iteration_spec_star RPAREN
111
118
  LPAREN test do_result RPAREN
112
119
  command_star RPAREN
113
120
  END_SYNTAX
@@ -115,25 +122,29 @@ END_SYNTAX
115
122
  rule 'derived_expression' => 'quasiquotation'
116
123
  rule('cond_clause_plus' => 'cond_clause_plus cond_clause').as 'multiple_cond_clauses'
117
124
  rule('cond_clause_plus' => 'cond_clause').as 'last_cond_clauses'
118
- rule('cond_clause_star' => 'cond_clause_star cond_clause').as 'cond_clauses_star'
119
- rule('cond_clause_star' => []).as 'last_cond_clauses_star'
125
+ rule('cond_clause_star' => 'cond_clause_star cond_clause').as 'star_default'
126
+ rule('cond_clause_star' => []).as 'star_base' ## 'last_cond_clauses_star'
120
127
  rule('cond_clause' => 'LPAREN test sequence RPAREN').as 'cond_clause'
121
128
  rule('cond_clause' => 'LPAREN test RPAREN')
122
129
  rule('cond_clause' => 'LPAREN test ARROW recipient RPAREN').as 'cond_arrow_clause'
123
130
  rule('recipient' => 'expression')
124
131
  rule('quasiquotation' => 'LPAREN QUASIQUOTE qq_template RPAREN').as 'quasiquotation'
125
132
  rule('quasiquotation' => 'GRAVE_ACCENT qq_template').as 'quasiquotation_short'
126
- rule('binding_spec_star' => 'binding_spec_star binding_spec').as 'multiple_binding_specs'
127
- rule('binding_spec_star' => []).as 'no_binding_spec_yet'
133
+ rule('binding_spec_star' => 'binding_spec_star binding_spec').as 'star_default'
134
+ rule('binding_spec_star' => []).as 'star_base' ## 'no_binding_spec_yet'
128
135
  rule('binding_spec' => 'LPAREN IDENTIFIER expression RPAREN').as 'binding_spec'
129
- rule('iteration_spec_star' => 'iteration_spec_star iteration_spec').as 'multiple_iter_specs'
130
- rule('iteration_spec_star' => []).as 'no_iter_spec_yet'
136
+ rule('iteration_spec_star' => 'iteration_spec_star iteration_spec').as 'star_default'
137
+ rule('iteration_spec_star' => []).as 'star_base' ## 'no_iter_spec_yet'
131
138
  rule('iteration_spec' => 'LPAREN IDENTIFIER init step RPAREN').as 'iteration_spec_long'
132
139
  rule('iteration_spec' => 'LPAREN IDENTIFIER init RPAREN').as 'iteration_spec_short'
133
140
  rule('init' => 'expression')
134
141
  rule('step' => 'expression')
135
142
  rule 'do_result' => 'sequence'
136
- rule('do_result' => []).as 'empty_do_result'
143
+ rule('do_result' => []).as 'star_base' ## 'empty_do_result'
144
+ rule('keyword' => 'IDENTIFIER')
145
+ rule('includer' => 'LPAREN INCLUDE string_plus RPAREN').as 'include'
146
+ rule('string_plus' => 'string_plus STRING_LIT').as 'multiple_string'
147
+ rule('string_plus' => 'STRING_LIT').as 'last_single_string'
137
148
  rule 'qq_template' => 'simple_datum'
138
149
  rule 'qq_template' => 'list_qq_template'
139
150
  rule 'qq_template' => 'vector_qq_template'
@@ -144,14 +155,65 @@ END_SYNTAX
144
155
  rule('vector_qq_template' => 'VECTOR_BEGIN qq_template_or_splice_star RPAREN').as 'vector_qq'
145
156
  rule('unquotation' => 'COMMA qq_template').as 'unquotation_short'
146
157
  rule 'unquotation' => 'LPAREN UNQUOTE qq_template RPAREN'
147
- rule('qq_template_or_splice_star' => 'qq_template_or_splice_star qq_template_or_splice').as 'multiple_template_splice'
148
- rule('qq_template_or_splice_star' => []).as 'no_template_splice_yet'
158
+ rule('qq_template_or_splice_star' => 'qq_template_or_splice_star qq_template_or_splice').as 'star_default'
159
+ rule('qq_template_or_splice_star' => []).as 'star_base' ## 'no_template_splice_yet'
149
160
  rule 'qq_template_or_splice_plus' => 'qq_template_or_splice_plus qq_template_or_splice'
150
161
  rule 'qq_template_or_splice_plus' => 'qq_template_or_splice'
151
162
  rule 'qq_template_or_splice' => 'qq_template'
152
163
  rule 'qq_template_or_splice' => 'splicing_unquotation'
153
164
  rule 'splicing_unquotation' => 'COMMA_AT_SIGN qq_template'
154
165
  rule 'splicing_unquotation' => 'LPAREN UNQUOTE-SPLICING qq_template RPAREN'
166
+ rule('transformer_spec' => 'LPAREN SYNTAX-RULES LPAREN identifier_star RPAREN syntax_rule_star RPAREN').as 'transformer_syntax'
167
+ rule('transformer_spec' => 'LPAREN SYNTAX-RULES IDENTIFIER LPAREN identifier_star RPAREN syntax_rule_star RPAREN')
168
+ rule('syntax_rule_star' => 'syntax_rule_star syntax_rule').as 'star_default'
169
+ rule('syntax_rule_star' => []).as 'star_base'
170
+ rule('syntax_rule' => 'LPAREN pattern template RPAREN').as 'syntax_rule'
171
+ rule('pattern' => 'pattern_identifier')
172
+ rule('pattern' => 'UNDERSCORE')
173
+ rule('pattern' => 'LPAREN pattern_star RPAREN')
174
+ rule('pattern' => 'LPAREN pattern_plus PERIOD pattern RPAREN')
175
+ rule('pattern' => 'LPAREN pattern_plus ELLIPSIS pattern_star RPAREN')
176
+ rule('pattern' => 'LPAREN pattern_plus ELLIPSIS pattern_star PERIOD pattern RPAREN')
177
+ rule('pattern' => 'VECTOR_BEGIN pattern_star RPAREN')
178
+ rule('pattern' => 'VECTOR_BEGIN pattern_plus ELLIPSIS pattern_star RPAREN')
179
+ rule('pattern' => 'pattern_datum')
180
+ rule('pattern_star' => 'pattern_star pattern').as 'star_default'
181
+ rule('pattern_star' => []).as 'star_base'
182
+ rule('pattern_plus' => 'pattern_plus pattern')
183
+ rule('pattern_plus' => 'pattern')
184
+ rule('pattern_datum' => 'STRING_LIT')
185
+ rule('pattern_datum' => 'CHAR')
186
+ rule('pattern_datum' => 'BOOLEAN')
187
+ rule('pattern_datum' => 'number')
188
+ # rule('pattern_datum' => 'bytevector')
189
+ rule('template' => 'pattern_identifier')
190
+ rule('template' => 'LPAREN template_element_star RPAREN')
191
+ rule('template' => 'LPAREN template_element_plus PERIOD template RPAREN')
192
+ rule('template' => 'VECTOR_BEGIN template_element_star RPAREN')
193
+ rule('template' => 'template_datum')
194
+ rule('template_element_star' => 'template_element_star template_element').as 'star_default'
195
+ rule('template_element_star' => []).as 'star_base'
196
+ rule('template_element_plus' => 'template_element_plus template_element')
197
+ rule('template_element_plus' => 'template_element')
198
+ rule('template_element' => 'template')
199
+ rule('template_element' => 'template ELLIPSIS')
200
+ rule('template_datum' => 'pattern_datum')
201
+ rule('pattern_identifier' => 'IDENTIFIER')
202
+ # Ugly: specailized production rule per keyword...
203
+ rule('pattern_identifier' => 'BEGIN')
204
+ rule('pattern_identifier' => 'COND')
205
+ rule('pattern_identifier' => 'DEFINE')
206
+ rule('pattern_identifier' => 'ELSE')
207
+ rule('pattern_identifier' => 'IF')
208
+ rule('pattern_identifier' => 'INCLUDE')
209
+ rule('pattern_identifier' => 'LAMBDA')
210
+ rule('pattern_identifier' => 'LET')
211
+ rule('pattern_identifier' => 'LET*')
212
+ rule('pattern_identifier' => 'QUOTE')
213
+ rule('pattern_identifier' => 'QUASIQUOTE')
214
+ rule('pattern_identifier' => 'SET!')
215
+ rule('pattern_identifier' => 'UNQUOTE')
216
+ rule('pattern_identifier' => 'UNQUOTE-SPLICING')
155
217
  end
156
218
 
157
219
  # And now build the grammar and make it accessible via a global constant