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.
- checksums.yaml +4 -4
- data/.rubocop.yml +512 -451
- data/CHANGELOG.md +25 -0
- data/LICENSE.txt +1 -1
- data/README.md +1 -1
- data/lib/skeem/grammar.rb +35 -75
- data/lib/skeem/interpreter.rb +4 -0
- data/lib/skeem/parser.rb +1 -1
- data/lib/skeem/primitive/primitive_builder.rb +4 -5
- data/lib/skeem/primitive/primitive_procedure.rb +5 -0
- data/lib/skeem/runtime.rb +1 -1
- data/lib/skeem/s_expr_builder.rb +22 -51
- data/lib/skeem/s_expr_nodes.rb +17 -5
- data/lib/skeem/skm_simple_datum.rb +2 -2
- data/lib/skeem/tokenizer.rb +9 -5
- data/lib/skeem/version.rb +1 -1
- data/skeem.gemspec +3 -3
- data/spec/skeem/skm_simple_datum_spec.rb +2 -0
- metadata +9 -9
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
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-
|
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
|
-
#
|
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
|
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
|
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
|
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
|
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' => '
|
81
|
-
rule('def_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
|
79
|
+
rule('formals' => 'LPAREN IDENTIFIER* RPAREN').as 'fixed_arity_formals'
|
84
80
|
rule('formals' => 'IDENTIFIER').as 'variadic_formals'
|
85
|
-
rule('formals' => 'LPAREN
|
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('
|
88
|
-
rule('
|
89
|
-
rule('
|
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
|
107
|
-
rule('derived_expression' => 'LPAREN
|
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
|
111
|
-
rule('derived_expression' => 'LPAREN LET_STAR LPAREN
|
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
|
102
|
+
LPAREN DO LPAREN iteration_spec* RPAREN
|
118
103
|
LPAREN test do_result RPAREN
|
119
|
-
|
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
|
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
|
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
|
153
|
-
rule 'list_qq_template' => 'LPAREN
|
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
|
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
|
167
|
-
rule('transformer_spec' => 'LPAREN SYNTAX-RULES IDENTIFIER LPAREN
|
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
|
174
|
-
rule('pattern' => 'LPAREN
|
175
|
-
rule('pattern' => 'LPAREN
|
176
|
-
rule('pattern' => 'LPAREN
|
177
|
-
rule('pattern' => 'VECTOR_BEGIN
|
178
|
-
rule('pattern' => 'VECTOR_BEGIN
|
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
|
191
|
-
rule('template' => 'LPAREN
|
192
|
-
rule('template' => 'VECTOR_BEGIN
|
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:
|
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')
|
data/lib/skeem/interpreter.rb
CHANGED
@@ -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
@@ -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
|
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
data/lib/skeem/s_expr_builder.rb
CHANGED
@@ -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
|
-
|
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
|
217
|
+
# rule('derived_expression' => 'LPAREN COND cond_clause* (LPAREN ELSE sequence RPAREN)? RPAREN')
|
237
218
|
def reduce_cond_form(_production, aRange, _tokens, theChildren)
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
SkmConditional.new(aRange.low, theChildren[2],
|
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' =>
|
322
|
-
def
|
323
|
-
|
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])
|
data/lib/skeem/s_expr_nodes.rb
CHANGED
@@ -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
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
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
|
-
|
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
|
-
|
65
|
+
self
|
66
66
|
end
|
67
67
|
|
68
68
|
# Return this object un-evaluated.
|
data/lib/skeem/tokenizer.rb
CHANGED
@@ -58,7 +58,7 @@ module Skeem
|
|
58
58
|
SYNTAX-RULES
|
59
59
|
UNQUOTE
|
60
60
|
UNQUOTE-SPLICING
|
61
|
-
].
|
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)|[
|
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(/([
|
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
|
-
|
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
|
-
|
301
|
+
value
|
298
302
|
end
|
299
303
|
|
300
304
|
def named_char(aLexeme)
|
data/lib/skeem/version.rb
CHANGED
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.
|
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.
|
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', '
|
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
|