skeem 0.2.18 → 0.2.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,28 @@
1
+ ## [0.2.21] - 2022-04-24
2
+ - Dependencies updates, minor changes
3
+
4
+ ### Changed
5
+ - File `.rubocop.yml` Incorporating new Rubocop cops (up to version 1.28)
6
+ - File `grammar.rb`: Refactoring of a rule with grouping parentheses
7
+ - File `s_expr_builder` Change to relfect changes in grammar
8
+ - File `skeem.gempsec` Updated dependencies; minimal Ruby version is now 2.6+
9
+
10
+ ## [0.2.20] - 2021-11-01
11
+ - Code update to cope with changes in `Rley` v. 0.8.08
12
+
13
+
14
+ - File `s_expr_builder.rb`: Refactoring to cope with ? quantifier changes
15
+ - File `skeem.gemspec` dependency updated for `Rley` v. 0.8.08
16
+
17
+ ## [0.2.19] - 2021-08-30
18
+ - Grammar refactoring: use ?, * and + modifiers in Rley 0.8.03 rules
19
+
20
+ ### Changed
21
+ - File `grammar.rb`: Remove redundant rules after introduction of ?, * and + modifiers
22
+ - Class `SkmBuilder`: Removal of useless methods after removal of their rule counterpart
23
+
24
+
25
+
1
26
  ## [0.2.18] - 2021-08-29
2
27
  - Minor refactoring for Rley 0.8.03
3
28
  - Code restyling to please rubocop 1.19.1.
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2018-2019 Dimitri Geshef
3
+ Copyright (c) 2018-2022 Dimitri Geshef
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -392,7 +392,7 @@ This project is intended to be a safe, welcoming space for collaboration, and co
392
392
 
393
393
  Copyright
394
394
  ---------
395
- Copyright (c) 2018-2019, Dimitri Geshef.
395
+ Copyright (c) 2018-2021, Dimitri Geshef.
396
396
  __Skeem__ is released under the MIT License see [LICENSE.txt](https://github.com/famished-tiger/Skeem/blob/master/LICENSE.txt) for details.
397
397
 
398
398
  ## Code of Conduct
data/lib/skeem/grammar.rb CHANGED
@@ -6,7 +6,7 @@ require 'rley' # Load the gem
6
6
  module Skeem
7
7
  ########################################
8
8
  # Define a grammar for Skeem
9
- # Official Small Scheme grammar is available at:
9
+ # The official Small Scheme language grammar is available at:
10
10
  # https://bitbucket.org/cowan/r7rs/src/draft-10/rnrs/r7rs.pdf
11
11
  # Names of grammar elements are based on the R7RS documentation
12
12
  builder = Rley::grammar_builder do
@@ -36,7 +36,7 @@ module Skeem
36
36
  rule('definition' => 'LPAREN DEFINE IDENTIFIER expression RPAREN').as 'definition'
37
37
  rule('definition' => 'LPAREN DEFINE LPAREN IDENTIFIER def_formals RPAREN body RPAREN').as 'alt_definition'
38
38
  rule('definition' => 'syntax_definition')
39
- rule('definition' => 'LPAREN BEGIN definition_star RPAREN').as 'definitions_within_begin'
39
+ rule('definition' => 'LPAREN BEGIN definition* RPAREN').as 'definitions_within_begin'
40
40
  rule('expression' => 'IDENTIFIER').as 'variable_reference'
41
41
  rule 'expression' => 'literal'
42
42
  rule 'expression' => 'procedure_call'
@@ -63,143 +63,103 @@ module Skeem
63
63
  rule 'simple_datum' => 'symbol'
64
64
  rule 'compound_datum' => 'list'
65
65
  rule 'compound_datum' => 'vector'
66
- rule('list' => 'LPAREN datum_star RPAREN').as 'list'
66
+ rule('list' => 'LPAREN datum* RPAREN').as 'list'
67
67
  rule('list' => 'LPAREN datum_plus PERIOD datum RPAREN').as 'dotted_list'
68
- rule('vector' => 'VECTOR_BEGIN datum_star RPAREN').as 'vector'
68
+ rule('vector' => 'VECTOR_BEGIN datum* RPAREN').as 'vector'
69
69
  rule('datum_plus' => 'datum_plus datum').as 'multiple_datums'
70
70
  rule('datum_plus' => 'datum').as 'last_datum'
71
- rule('datum_star' => 'datum_star datum').as 'star_default'
72
- rule('datum_star' => []).as 'star_base' ## 'no_datum_yet'
73
71
  rule 'symbol' => 'IDENTIFIER'
74
72
  rule('procedure_call' => 'LPAREN operator RPAREN').as 'proc_call_nullary'
75
- rule('procedure_call' => 'LPAREN operator operand_plus RPAREN').as 'proc_call_args'
76
- rule('operand_plus' => 'operand_plus operand').as 'multiple_operands'
77
- rule('operand_plus' => 'operand').as 'last_operand'
73
+ rule('procedure_call' => 'LPAREN operator operand+ RPAREN').as 'proc_call_args'
78
74
  rule 'operator' => 'expression'
79
75
  rule 'operand' => 'expression'
80
- rule('def_formals' => 'identifier_star').as 'def_formals'
81
- rule('def_formals' => 'identifier_star PERIOD IDENTIFIER').as 'pair_formals'
76
+ rule('def_formals' => 'IDENTIFIER*').as 'def_formals'
77
+ rule('def_formals' => 'IDENTIFIER* PERIOD IDENTIFIER').as 'pair_formals'
82
78
  rule('lambda_expression' => 'LPAREN LAMBDA formals body RPAREN').as 'lambda_expression'
83
- rule('formals' => 'LPAREN identifier_star RPAREN').as 'fixed_arity_formals'
79
+ rule('formals' => 'LPAREN IDENTIFIER* RPAREN').as 'fixed_arity_formals'
84
80
  rule('formals' => 'IDENTIFIER').as 'variadic_formals'
85
- rule('formals' => 'LPAREN identifier_plus PERIOD IDENTIFIER RPAREN').as 'dotted_formals'
81
+ rule('formals' => 'LPAREN IDENTIFIER+ PERIOD IDENTIFIER RPAREN').as 'dotted_formals'
86
82
  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'
89
- rule('identifier_plus' => 'identifier_plus IDENTIFIER').as 'multiple_identifiers'
90
- rule('identifier_plus' => 'IDENTIFIER').as 'last_identifier'
91
- rule('body' => 'definition_star sequence').as 'body'
92
- rule('definition_star' => 'definition_star definition').as 'star_default'
93
- rule('definition_star' => []).as 'star_base' ## 'no_definition_yet'
94
- rule('sequence' => 'command_star expression').as 'sequence'
95
- rule('command_star' => 'command_star command').as 'star_default'
96
- rule('command_star' => []).as 'star_base' ## 'no_command_yet'
97
- rule('conditional' => 'LPAREN IF test consequent alternate RPAREN').as 'conditional'
83
+ rule('body' => 'definition* sequence').as 'body'
84
+ rule('sequence' => 'command* expression').as 'sequence'
85
+ rule('conditional' => 'LPAREN IF test consequent expression? RPAREN').as 'conditional'
98
86
  rule 'test' => 'expression'
99
87
  rule 'consequent' => 'expression'
100
- rule 'alternate' => 'expression'
101
- rule 'alternate' => []
102
88
  rule 'number' => 'INTEGER'
103
89
  rule 'number' => 'RATIONAL'
104
90
  rule 'number' => 'REAL'
105
91
  rule('assignment' => 'LPAREN SET! IDENTIFIER expression RPAREN').as 'assignment'
106
- rule('derived_expression' => 'LPAREN COND cond_clause_plus RPAREN').as 'cond_form'
107
- rule('derived_expression' => 'LPAREN COND cond_clause_star LPAREN ELSE sequence RPAREN RPAREN').as 'cond_else_form'
108
- rule('derived_expression' => 'LPAREN LET LPAREN binding_spec_star RPAREN body RPAREN').as 'short_let_form'
92
+ rule('derived_expression' => 'LPAREN COND cond_clause* (LPAREN ELSE sequence RPAREN)? RPAREN').as 'cond_form'
93
+ rule('derived_expression' => 'LPAREN LET LPAREN binding_spec* RPAREN body RPAREN').as 'short_let_form'
109
94
  # TODO: implement "named let"
110
- rule('derived_expression' => 'LPAREN LET IDENTIFIER LPAREN binding_spec_star RPAREN body RPAREN') # .as 'named_form'
111
- rule('derived_expression' => 'LPAREN LET_STAR LPAREN binding_spec_star RPAREN body RPAREN').as 'let_star_form'
95
+ rule('derived_expression' => 'LPAREN LET IDENTIFIER LPAREN binding_spec* RPAREN body RPAREN') # .as 'named_form'
96
+ rule('derived_expression' => 'LPAREN LET_STAR LPAREN binding_spec* RPAREN body RPAREN').as 'let_star_form'
112
97
 
113
98
  # As the R7RS grammar is too restrictive,
114
99
  # the next rule was made more general than its standard counterpart
115
100
  rule('derived_expression' => 'LPAREN BEGIN body RPAREN').as 'begin_expression'
116
101
  do_syntax = <<-END_SYNTAX
117
- LPAREN DO LPAREN iteration_spec_star RPAREN
102
+ LPAREN DO LPAREN iteration_spec* RPAREN
118
103
  LPAREN test do_result RPAREN
119
- command_star RPAREN
104
+ rep_command_star RPAREN
120
105
  END_SYNTAX
121
106
  rule('derived_expression' => do_syntax).as 'do_expression'
122
107
  rule 'derived_expression' => 'quasiquotation'
123
- rule('cond_clause_plus' => 'cond_clause_plus cond_clause').as 'multiple_cond_clauses'
124
- rule('cond_clause_plus' => 'cond_clause').as 'last_cond_clauses'
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'
127
108
  rule('cond_clause' => 'LPAREN test sequence RPAREN').as 'cond_clause'
128
109
  rule('cond_clause' => 'LPAREN test RPAREN')
129
110
  rule('cond_clause' => 'LPAREN test ARROW recipient RPAREN').as 'cond_arrow_clause'
130
111
  rule('recipient' => 'expression')
131
112
  rule('quasiquotation' => 'LPAREN QUASIQUOTE qq_template RPAREN').as 'quasiquotation'
132
113
  rule('quasiquotation' => 'GRAVE_ACCENT qq_template').as 'quasiquotation_short'
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'
135
114
  rule('binding_spec' => 'LPAREN IDENTIFIER expression RPAREN').as 'binding_spec'
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'
138
115
  rule('iteration_spec' => 'LPAREN IDENTIFIER init step RPAREN').as 'iteration_spec_long'
139
116
  rule('iteration_spec' => 'LPAREN IDENTIFIER init RPAREN').as 'iteration_spec_short'
140
117
  rule('init' => 'expression')
141
118
  rule('step' => 'expression')
142
- rule 'do_result' => 'sequence'
143
- rule('do_result' => []).as 'star_base' ## 'empty_do_result'
119
+ rule('do_result' => 'sequence?').tag 'do_result'
144
120
  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'
121
+ rule('includer' => 'LPAREN INCLUDE STRING_LIT+ RPAREN').as 'include'
148
122
  rule 'qq_template' => 'simple_datum'
149
123
  rule 'qq_template' => 'list_qq_template'
150
124
  rule 'qq_template' => 'vector_qq_template'
151
125
  rule 'qq_template' => 'unquotation'
152
- rule('list_qq_template' => 'LPAREN qq_template_or_splice_star RPAREN').as 'list_qq'
153
- rule 'list_qq_template' => 'LPAREN qq_template_or_splice_plus PERIOD qq_template RPAREN'
126
+ rule('list_qq_template' => 'LPAREN qq_template_or_splice* RPAREN').as 'list_qq'
127
+ rule 'list_qq_template' => 'LPAREN qq_template_or_splice+ PERIOD qq_template RPAREN'
154
128
  rule 'list_qq_template' => 'GRAVE_ACCENT qq_template'
155
- rule('vector_qq_template' => 'VECTOR_BEGIN qq_template_or_splice_star RPAREN').as 'vector_qq'
129
+ rule('vector_qq_template' => 'VECTOR_BEGIN qq_template_or_splice* RPAREN').as 'vector_qq'
156
130
  rule('unquotation' => 'COMMA qq_template').as 'unquotation_short'
157
131
  rule 'unquotation' => 'LPAREN UNQUOTE qq_template RPAREN'
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'
160
- rule 'qq_template_or_splice_plus' => 'qq_template_or_splice_plus qq_template_or_splice'
161
- rule 'qq_template_or_splice_plus' => 'qq_template_or_splice'
162
132
  rule 'qq_template_or_splice' => 'qq_template'
163
133
  rule 'qq_template_or_splice' => 'splicing_unquotation'
164
134
  rule 'splicing_unquotation' => 'COMMA_AT_SIGN qq_template'
165
135
  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'
136
+ rule('transformer_spec' => 'LPAREN SYNTAX-RULES LPAREN IDENTIFIER* RPAREN syntax_rule* RPAREN').as 'transformer_syntax'
137
+ rule('transformer_spec' => 'LPAREN SYNTAX-RULES IDENTIFIER LPAREN IDENTIFIER* RPAREN syntax_rule* RPAREN')
170
138
  rule('syntax_rule' => 'LPAREN pattern template RPAREN').as 'syntax_rule'
171
139
  rule('pattern' => 'pattern_identifier')
172
140
  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')
141
+ rule('pattern' => 'LPAREN pattern* RPAREN')
142
+ rule('pattern' => 'LPAREN pattern+ PERIOD pattern RPAREN')
143
+ rule('pattern' => 'LPAREN pattern+ ELLIPSIS pattern* RPAREN')
144
+ rule('pattern' => 'LPAREN pattern+ ELLIPSIS pattern* PERIOD pattern RPAREN')
145
+ rule('pattern' => 'VECTOR_BEGIN pattern* RPAREN')
146
+ rule('pattern' => 'VECTOR_BEGIN pattern+ ELLIPSIS pattern* RPAREN')
179
147
  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
148
  rule('pattern_datum' => 'STRING_LIT')
185
149
  rule('pattern_datum' => 'CHAR')
186
150
  rule('pattern_datum' => 'BOOLEAN')
187
151
  rule('pattern_datum' => 'number')
188
152
  # rule('pattern_datum' => 'bytevector')
189
153
  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')
154
+ rule('template' => 'LPAREN template_element* RPAREN')
155
+ rule('template' => 'LPAREN template_element+ PERIOD template RPAREN')
156
+ rule('template' => 'VECTOR_BEGIN template_element* RPAREN')
193
157
  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
158
  rule('template_element' => 'template')
199
159
  rule('template_element' => 'template ELLIPSIS')
200
160
  rule('template_datum' => 'pattern_datum')
201
161
  rule('pattern_identifier' => 'IDENTIFIER')
202
- # Ugly: specailized production rule per keyword...
162
+ # Ugly: specialized production rule per keyword...
203
163
  rule('pattern_identifier' => 'BEGIN')
204
164
  rule('pattern_identifier' => 'COND')
205
165
  rule('pattern_identifier' => 'DEFINE')
@@ -8,7 +8,11 @@ require_relative './primitive/primitive_builder'
8
8
  module Skeem
9
9
  class Interpreter
10
10
  include Primitive::PrimitiveBuilder
11
+
12
+ # @return [Skeem::Parser] Link to Skeem parser
11
13
  attr_reader(:parser)
14
+
15
+ # @return [Skeem::Runtime] Link to runtime object (holds call stack & frames)
12
16
  attr_reader(:runtime)
13
17
 
14
18
  def initialize
data/lib/skeem/parser.rb CHANGED
@@ -36,7 +36,7 @@ module Skeem
36
36
  raise StandardError, line1 + line2
37
37
  end
38
38
 
39
- return engine.to_ptree(result)
39
+ engine.to_ptree(result)
40
40
  end
41
41
  end # class
42
42
  end # module
@@ -6,6 +6,7 @@ require_relative '../skm_exception'
6
6
  require_relative '../skm_pair'
7
7
 
8
8
  module Skeem
9
+ # rubocop: disable Metrics/ModuleLength
9
10
  module Primitive
10
11
  module PrimitiveBuilder
11
12
  include DatumDSL
@@ -244,10 +245,7 @@ module Skeem
244
245
  raw_result = Rational(raw_result, elem_value)
245
246
  end
246
247
 
247
- when [Integer, Rational]
248
- raw_result *= reciprocal(elem_value)
249
-
250
- when [Rational, Rational]
248
+ when [Integer, Rational], [Rational, Rational]
251
249
  raw_result *= reciprocal(elem_value)
252
250
  else
253
251
  raw_result = raw_result.to_f
@@ -1234,7 +1232,7 @@ module Skeem
1234
1232
  def remaining_args(arglist, aRuntime)
1235
1233
  case arglist
1236
1234
  when Array
1237
- raw_arg = arglist[1..-1]
1235
+ raw_arg = arglist[1..]
1238
1236
  when SkmPair
1239
1237
  raw_arg = arglist.cdr.to_a
1240
1238
  end
@@ -1242,4 +1240,5 @@ module Skeem
1242
1240
  end
1243
1241
  end # module
1244
1242
  end # module
1243
+ # rubocop: enable Metrics/ModuleLength
1245
1244
  end # module
@@ -5,8 +5,13 @@ require_relative '../s_expr_nodes'
5
5
  module Skeem
6
6
  module Primitive
7
7
  class PrimitiveProcedure
8
+ # @return [Skeem::SkmIdentifier] 'name' of the procedure
8
9
  attr_reader(:identifier)
10
+
11
+ # @return [Skeem::Arity] number of arguments of the procedure
9
12
  attr_reader(:arity)
13
+
14
+ # @return [Proc] A Ruby lambda that implements the primitive procedure
10
15
  attr_reader(:code)
11
16
 
12
17
  # param [anArity] Arity of the lambda code (ignoring the runtime object)
data/lib/skeem/runtime.rb CHANGED
@@ -80,7 +80,7 @@ module Skeem
80
80
  end
81
81
 
82
82
  def depth
83
- return env_stack.size
83
+ env_stack.size
84
84
  end
85
85
 
86
86
  def push(anEnvironment)
@@ -157,16 +157,6 @@ module Skeem
157
157
  pcall
158
158
  end
159
159
 
160
- # rule('operand_plus' => 'operand_plus operand').as 'multiple_operands'
161
- def reduce_multiple_operands(_production, _range, _tokens, theChildren)
162
- theChildren[0] << theChildren[1]
163
- end
164
-
165
- # rule('operand_plus' => 'operand').as 'last_operand'
166
- def reduce_last_operand(_production, _range, _tokens, theChildren)
167
- [theChildren.last]
168
- end
169
-
170
160
  # rule('def_formals' => 'identifier_star').as 'def_formals'
171
161
  def reduce_def_formals(_production, _range, _tokens, theChildren)
172
162
  SkmFormals.new(theChildren[0], :fixed)
@@ -202,16 +192,6 @@ module Skeem
202
192
  SkmFormals.new(formals, :variadic)
203
193
  end
204
194
 
205
- # rule('identifier_plus' => 'identifier_plus IDENTIFIER').as 'multiple_identifiers'
206
- def reduce_multiple_identifiers(_production, _range, _tokens, theChildren)
207
- theChildren[0] << theChildren[1]
208
- end
209
-
210
- # rule('identifier_plus' => 'IDENTIFIER').as 'last_identifier'
211
- def reduce_last_identifier(_production, _range, _tokens, theChildren)
212
- [theChildren[0]]
213
- end
214
-
215
195
  # rule('body' => 'definition_star sequence').as 'body'
216
196
  def reduce_body(_production, _range, _tokens, theChildren)
217
197
  definitions = theChildren[0].nil? ? [] : theChildren[0]
@@ -225,7 +205,8 @@ module Skeem
225
205
 
226
206
  # rule('conditional' => 'LPAREN IF test consequent alternate RPAREN').as 'conditional'
227
207
  def reduce_conditional(_production, aRange, _tokens, theChildren)
228
- SkmCondition.new(aRange, theChildren[2], theChildren[3], theChildren[4])
208
+ children = theChildren.flatten
209
+ SkmCondition.new(aRange, children[2], children[3], children[4])
229
210
  end
230
211
 
231
212
  # rule('assignment' => 'LPAREN SET! IDENTIFIER expression RPAREN').as 'assignment'
@@ -233,14 +214,14 @@ module Skeem
233
214
  SkmUpdateBinding.new(theChildren[2], theChildren[3])
234
215
  end
235
216
 
236
- # rule('derived_expression' => 'LPAREN COND cond_clause_plus RPAREN').as 'cond_form'
217
+ # rule('derived_expression' => 'LPAREN COND cond_clause* (LPAREN ELSE sequence RPAREN)? RPAREN')
237
218
  def reduce_cond_form(_production, aRange, _tokens, theChildren)
238
- SkmConditional.new(aRange.low, theChildren[2], nil)
239
- end
240
-
241
- # rule('derived_expression' => 'LPAREN COND cond_clause_star LPAREN ELSE sequence RPAREN RPAREN').as 'cond_else_form'
242
- def reduce_cond_else_form(_production, aRange, _tokens, theChildren)
243
- SkmConditional.new(aRange.low, theChildren[2], SkmSequencingBlock.new(theChildren[5]))
219
+ if theChildren[3]
220
+ else_part = SkmSequencingBlock.new(theChildren[3][2])
221
+ else
222
+ else_part = nil
223
+ end
224
+ SkmConditional.new(aRange.low, theChildren[2], else_part)
244
225
  end
245
226
 
246
227
  # rule('derived_expression' => 'LPAREN LET LPAREN binding_spec_star RPAREN body RPAREN').as 'short_let_form'
@@ -273,16 +254,6 @@ module Skeem
273
254
  SkmBindingBlock.new(:let_star, worker.bindings, body)
274
255
  end
275
256
 
276
- # rule('cond_clause_plus' => 'cond_clause_plus cond_clause').as 'multiple_cond_clauses'
277
- def reduce_multiple_cond_clauses(_production, _range, _tokens, theChildren)
278
- theChildren[0] << theChildren[1]
279
- end
280
-
281
- # rule('cond_clause_plus' => 'cond_clause').as 'last_cond_clauses'
282
- def reduce_last_cond_clauses(_production, _range, _tokens, theChildren)
283
- [theChildren[0]]
284
- end
285
-
286
257
  # rule('cond_clause' => 'LPAREN test sequence RPAREN').as 'cond_clause'
287
258
  def reduce_cond_clause(_production, _range, _tokens, theChildren)
288
259
  [theChildren[1], SkmSequencingBlock.new(SkmPair.create_from_a(theChildren[2]))]
@@ -318,27 +289,27 @@ module Skeem
318
289
  SkmIterationSpec.new(theChildren[1], theChildren[2], nil)
319
290
  end
320
291
 
321
- # rule('do_result' => []).as 'empty_do_result'
322
- def reduce_empty_do_result(_production, _range, _tokens, _children)
323
- SkmEmptyList.instance
292
+ # rule('do_result' => 'sequence?')
293
+ def reduce_do_result(_production, _range, _tokens, theChildren)
294
+ children = theChildren.flatten
295
+ if children.empty?
296
+ SkmEmptyList.instance
297
+ else
298
+ children[0]
299
+ end
324
300
  end
325
301
 
302
+ # rule('do_result' => []).as 'empty_do_result'
303
+ # def reduce_empty_do_result(_production, _range, _tokens, _children)
304
+ # SkmEmptyList.instance
305
+ # end
306
+
326
307
  # rule('includer' => 'LPAREN INCLUDE string_plus RPAREN').as 'include'
327
308
  def reduce_include(_production, _range, _tokens, theChildren)
328
309
  includer = SkmIncluder.new(theChildren[2])
329
310
  includer.build
330
311
  end
331
312
 
332
- # rule('string_plus' => 'string_plus STRING_LIT').as 'multiple_string'
333
- def reduce_multiple_string(_production, _range, _tokens, theChildren)
334
- theChildren[0] << theChildren[1]
335
- end
336
-
337
- # rule('string_plus' => 'STRING_LIT').as 'last_single_string'
338
- def reduce_last_single_string(_production, _range, _tokens, theChildren)
339
- [theChildren[0]]
340
- end
341
-
342
313
  # rule('list_qq_template' => 'LPAREN qq_template_or_splice_star RPAREN').as 'list_qq'
343
314
  def reduce_list_qq(_production, _range, _tokens, theChildren)
344
315
  SkmPair.create_from_a(theChildren[1])
@@ -9,6 +9,8 @@ require_relative 'datum_dsl'
9
9
  require_relative 'skm_unary_expression'
10
10
  require_relative 'skm_procedure_exec'
11
11
 
12
+ # rubocop: disable Style/AccessorGrouping
13
+
12
14
  module Skeem
13
15
  class SkmUndefined
14
16
  include Singleton
@@ -143,6 +145,8 @@ module Skeem
143
145
  [:callee, callee]
144
146
  end
145
147
 
148
+ # rubocop: disable Style/RedundantAssignment
149
+
146
150
  def fetch_callee(aRuntime, var_key)
147
151
  begin
148
152
  aRuntime.include?(var_key.value)
@@ -172,6 +176,8 @@ module Skeem
172
176
  callee
173
177
  end
174
178
 
179
+ # rubocop: enable Style/RedundantAssignment
180
+
175
181
  def transform_operands(aRuntime)
176
182
  return [] if operands == SkmEmptyList.instance
177
183
 
@@ -817,11 +823,11 @@ module Skeem
817
823
  else
818
824
  result = cmd.evaluate(aRuntime)
819
825
  end
820
- rescue NoMethodError => e
821
- $stderr.puts inspect
822
- $stderr.puts sequence.inspect
823
- $stderr.puts cmd.inspect
824
- raise e
826
+ rescue NoMethodError => e
827
+ $stderr.puts inspect
828
+ $stderr.puts sequence.inspect
829
+ $stderr.puts cmd.inspect
830
+ raise e
825
831
  end
826
832
 
827
833
  result
@@ -843,6 +849,8 @@ module Skeem
843
849
  twin
844
850
  end
845
851
 
852
+ # rubocop: disable Naming/AccessorMethodName
853
+
846
854
  def set_cond_environment(theFrame)
847
855
  # $stderr.puts "Lambda #{object_id.to_s(16)}, env [#{environment.object_id.to_s(16)}]"
848
856
  # $stderr.puts " Runtime environment: #{theFrame.object_id.to_s(16)}"
@@ -856,6 +864,8 @@ module Skeem
856
864
  end
857
865
  end
858
866
 
867
+ # rubocop: enable Naming/AccessorMethodName
868
+
859
869
  private
860
870
 
861
871
  # Purpose: bind each formal from lambda to an actual value from the call
@@ -915,4 +925,6 @@ module Skeem
915
925
  end
916
926
  end # class
917
927
  end # module
928
+
929
+ # rubocop: enable Style/AccessorGrouping
918
930
  # End of file
@@ -21,7 +21,7 @@ module Skeem
21
21
  def self.create(aValue)
22
22
  lightweight = allocate
23
23
  lightweight.init_value(aValue)
24
- return lightweight
24
+ lightweight
25
25
  end
26
26
 
27
27
  def symbol
@@ -62,7 +62,7 @@ module Skeem
62
62
  # Reminder: terminals evaluate to themselves.
63
63
  # @param _runtime [Skeem::Runtime]
64
64
  def evaluate(_runtime)
65
- return self
65
+ self
66
66
  end
67
67
 
68
68
  # Return this object un-evaluated.
@@ -58,7 +58,7 @@ module Skeem
58
58
  SYNTAX-RULES
59
59
  UNQUOTE
60
60
  UNQUOTE-SPLICING
61
- ].map { |x| [x, x.sub(/\*$/, '_STAR')] }.to_h
61
+ ].to_h { |x| [x, x.sub(/\*$/, '_STAR')] }
62
62
 
63
63
  class ScanError < StandardError; end
64
64
 
@@ -89,6 +89,8 @@ module Skeem
89
89
 
90
90
  private
91
91
 
92
+ # rubocop: disable Lint/DuplicateBranch
93
+
92
94
  def _next_token
93
95
  skip_intertoken_spaces
94
96
  curr_ch = scanner.peek(1)
@@ -114,7 +116,7 @@ module Skeem
114
116
  elsif (lexeme = scanner.scan(/[+-]?[0-9]+(?:\.[0-9]*)?(?:(?:e|E)[+-]?[0-9]+)?/))
115
117
  # Order dependency: must be tested after INTEGER case
116
118
  token = build_token('REAL', lexeme)
117
- elsif (lexeme = scanner.scan(/#(?:(?:true)|(?:false)|(?:u8)|[\\\(tfeiodx]|(?:\d+[=#]))/))
119
+ elsif (lexeme = scanner.scan(/#(?:(?:true)|(?:false)|(?:u8)|[\\(tfeiodx]|(?:\d+[=#]))/))
118
120
  token = cardinal_token(lexeme)
119
121
  elsif (lexeme = scanner.scan(/"(?:\\"|[^"])*"/)) # Double quotes literal?
120
122
  token = build_token('STRING_LIT', lexeme)
@@ -124,7 +126,7 @@ module Skeem
124
126
  token = build_token(tok_type, lexeme)
125
127
  elsif (lexeme = scanner.scan(/\|(?:[^|])*\|/)) # Vertical bar delimited
126
128
  token = build_token('IDENTIFIER', lexeme)
127
- elsif (lexeme = scanner.scan(/([\+\-])((?=\s|[|()";])|$)/))
129
+ elsif (lexeme = scanner.scan(/([+\-])((?=\s|[|()";])|$)/))
128
130
  # # R7RS peculiar identifiers case 1: isolated plus and minus as identifiers
129
131
  token = build_token('IDENTIFIER', lexeme)
130
132
  elsif (lexeme = scanner.scan(/[+-][a-zA-Z!$%&*\/:<=>?@^_~+-@][a-zA-Z0-9!$%&*+-.\/:<=>?@^_~+-]*/))
@@ -143,6 +145,8 @@ module Skeem
143
145
  return token
144
146
  end
145
147
 
148
+ # rubocop: enable Lint/DuplicateBranch
149
+
146
150
  =begin
147
151
  #u8( This introduces a bytevector constant (section 6.9).
148
152
  Bytevector constants are terminated by ) .
@@ -285,7 +289,7 @@ other literal data (section 2.4).
285
289
  value = aLexeme.gsub(/(^")|("$)/, '')
286
290
  end
287
291
 
288
- return value
292
+ value
289
293
  end
290
294
 
291
295
  def to_identifier(aLexeme, aFormat)
@@ -294,7 +298,7 @@ other literal data (section 2.4).
294
298
  value = aLexeme
295
299
  end
296
300
 
297
- return value
301
+ value
298
302
  end
299
303
 
300
304
  def named_char(aLexeme)
data/lib/skeem/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Skeem
4
- VERSION = '0.2.18'
4
+ VERSION = '0.2.21'
5
5
  end
data/skeem.gemspec CHANGED
@@ -54,7 +54,7 @@ DESCR
54
54
  SUMMARY
55
55
  spec.homepage = 'https://github.com/famished-tiger/Skeem'
56
56
  spec.license = 'MIT'
57
- spec.required_ruby_version = '>= 2.5.0'
57
+ spec.required_ruby_version = '>= 2.6.0'
58
58
 
59
59
  spec.bindir = 'bin'
60
60
  spec.executables << 'skeem'
@@ -62,10 +62,10 @@ SUMMARY
62
62
  PkgExtending.pkg_files(spec)
63
63
  PkgExtending.pkg_documentation(spec)
64
64
  # Runtime dependencies
65
- spec.add_dependency 'rley', '~> 0.8.03'
65
+ spec.add_dependency 'rley', '~> 0.8.11'
66
66
 
67
67
  # Development dependencies
68
68
  spec.add_development_dependency 'bundler', '~> 2.0'
69
- spec.add_development_dependency 'rake', '~> 12.0'
69
+ spec.add_development_dependency 'rake', '>= 12.0'
70
70
  spec.add_development_dependency 'rspec', '~> 3.0'
71
71
  end
@@ -5,6 +5,7 @@ require_relative '../spec_helper' # Use the RSpec framework
5
5
  require_relative '../../lib/skeem/skm_simple_datum' # Load the classes under test
6
6
 
7
7
  module Skeem
8
+ # rubocop: disable Style/OpenStructUse
8
9
  describe SkmSimpleDatum do
9
10
  let(:pos) { double('fake-position') }
10
11
  let(:dummy_symbol) { double('fake-symbol') }
@@ -298,4 +299,5 @@ module Skeem
298
299
  end
299
300
  end # context
300
301
  end # describe
302
+ # rubocop: enable Style/OpenStructUse
301
303
  end # module