skeem 0.2.18 → 0.2.21
Sign up to get free protection for your applications and to get access to all the features.
- 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
|