skeem 0.2.16 → 0.2.20

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.
@@ -11,7 +11,7 @@ module Skeem
11
11
  def boolean(aBoolean)
12
12
  return aBoolean if aBoolean.kind_of?(SkmBoolean)
13
13
 
14
- result = case aBoolean
14
+ case aBoolean
15
15
  when TrueClass, FalseClass
16
16
  SkmBoolean.create(aBoolean)
17
17
  when /^#t(?:rue)?|true$/
@@ -21,13 +21,12 @@ module Skeem
21
21
  else
22
22
  raise StandardError, aBoolean.inspect
23
23
  end
24
- result
25
24
  end
26
25
 
27
26
  def integer(aLiteral)
28
27
  return aLiteral if aLiteral.kind_of?(SkmInteger)
29
28
 
30
- result = case aLiteral
29
+ case aLiteral
31
30
  when Integer
32
31
  SkmInteger.create(aLiteral)
33
32
  when /^[+-]?\d+$/
@@ -35,13 +34,12 @@ module Skeem
35
34
  else
36
35
  raise StandardError, aLiteral.inspect
37
36
  end
38
- result
39
37
  end
40
38
 
41
39
  def rational(aLiteral)
42
40
  return aLiteral if aLiteral.kind_of?(SkmRational)
43
41
 
44
- result = case aLiteral
42
+ case aLiteral
45
43
  when Rational
46
44
  SkmRational.create(aLiteral)
47
45
  when /^[+-]?\d+\/\d+$/
@@ -49,13 +47,12 @@ module Skeem
49
47
  else
50
48
  raise StandardError, aLiteral.inspect
51
49
  end
52
- result
53
50
  end
54
51
 
55
52
  def real(aLiteral)
56
53
  return aLiteral if aLiteral.kind_of?(SkmReal)
57
54
 
58
- result = case aLiteral
55
+ case aLiteral
59
56
  when Numeric
60
57
  SkmReal.create(aLiteral)
61
58
  when /^[+-]?\d+(?:\.\d*)?(?:[eE][+-]?\d+)?$/
@@ -63,13 +60,12 @@ module Skeem
63
60
  else
64
61
  raise StandardError, aLiteral.inspect
65
62
  end
66
- result
67
63
  end
68
64
 
69
65
  def char(aLiteral)
70
66
  return aLiteral if aLiteral.kind_of?(SkmChar)
71
67
 
72
- result = case aLiteral
68
+ case aLiteral
73
69
  when Numeric
74
70
  SkmChar.create_from_int(aLiteral)
75
71
  when String
@@ -81,13 +77,12 @@ module Skeem
81
77
  else
82
78
  raise StandardError, aLiteral.inspect
83
79
  end
84
- result
85
80
  end
86
81
 
87
82
  def string(aLiteral)
88
83
  return aLiteral if aLiteral.kind_of?(SkmString)
89
84
 
90
- result = case aLiteral
85
+ case aLiteral
91
86
  when String
92
87
  SkmString.create(aLiteral)
93
88
  when SkmIdentifier
@@ -95,13 +90,12 @@ module Skeem
95
90
  else
96
91
  SkmString.create(aLiteral.to_s)
97
92
  end
98
- result
99
93
  end
100
94
 
101
95
  def identifier(aLiteral)
102
96
  return aLiteral if aLiteral.kind_of?(SkmIdentifier)
103
97
 
104
- result = case aLiteral
98
+ case aLiteral
105
99
  when String
106
100
  SkmIdentifier.create(aLiteral)
107
101
  when SkmString
@@ -109,13 +103,12 @@ module Skeem
109
103
  else
110
104
  raise StandardError, aLiteral.inspect
111
105
  end
112
- result
113
106
  end
114
107
 
115
108
  alias symbol identifier
116
109
 
117
110
  def list(aLiteral)
118
- result = case aLiteral
111
+ case aLiteral
119
112
  when Array
120
113
  SkmPair.create_from_a(to_datum(aLiteral))
121
114
  when SkmPair
@@ -123,12 +116,10 @@ module Skeem
123
116
  else
124
117
  SkmPair.new(to_datum(aLiteral), SkmEmptyList.instance)
125
118
  end
126
-
127
- result
128
119
  end
129
120
 
130
121
  def vector(aLiteral)
131
- result = case aLiteral
122
+ case aLiteral
132
123
  when Array
133
124
  SkmVector.new(to_datum(aLiteral))
134
125
  when SkmVector
@@ -136,8 +127,6 @@ module Skeem
136
127
  else
137
128
  SkmVector.new([to_datum(aLiteral)])
138
129
  end
139
-
140
- result
141
130
  end
142
131
 
143
132
  # Conversion from Ruby object value to Skeem datum
@@ -146,7 +135,7 @@ module Skeem
146
135
  return vector(aLiteral.members) if aLiteral.kind_of?(SkmVector)
147
136
  return aLiteral if aLiteral.kind_of?(Primitive::PrimitiveProcedure)
148
137
 
149
- result = case aLiteral
138
+ case aLiteral
150
139
  when Array
151
140
  aLiteral.map { |elem| to_datum(elem) }
152
141
  when Integer
@@ -166,25 +155,37 @@ module Skeem
166
155
  aLiteral
167
156
  else
168
157
  raise StandardError, aLiteral.inspect
169
- end
170
- result
158
+ end
171
159
  end
172
160
 
173
161
  private
174
162
 
175
163
  def parse_literal(aLiteral)
176
- if aLiteral =~ /^#t(?:rue)?|true$/
177
- boolean(aLiteral)
178
- elsif aLiteral =~ /^#f(?:alse)?|false$/
179
- boolean(aLiteral)
180
- elsif aLiteral =~ /^[+-]?\d+\/\d+$/
181
- rational(aLiteral)
182
- elsif aLiteral =~ /^[+-]?\d+$/
183
- integer(aLiteral)
184
- elsif aLiteral =~ /^[+-]?\d+(?:\.\d*)?(?:[eE][+-]?\d+)?$/
185
- real(aLiteral)
186
- else
187
- string(aLiteral)
164
+ # if aLiteral =~ /^#t(?:rue)?|true$/
165
+ # boolean(aLiteral)
166
+ # elsif aLiteral =~ /^#f(?:alse)?|false$/
167
+ # boolean(aLiteral)
168
+ # elsif aLiteral =~ /^[+-]?\d+\/\d+$/
169
+ # rational(aLiteral)
170
+ # elsif aLiteral =~ /^[+-]?\d+$/
171
+ # integer(aLiteral)
172
+ # elsif aLiteral =~ /^[+-]?\d+(?:\.\d*)?(?:[eE][+-]?\d+)?$/
173
+ # real(aLiteral)
174
+ # else
175
+ # string(aLiteral)
176
+ # end
177
+
178
+ case aLiteral
179
+ when /^#t(?:rue)?|true$/, /^#f(?:alse)?|false$/
180
+ boolean(aLiteral)
181
+ when /^[+-]?\d+\/\d+$/
182
+ rational(aLiteral)
183
+ when /^[+-]?\d+$/
184
+ integer(aLiteral)
185
+ when /^[+-]?\d+(?:\.\d*)?(?:[eE][+-]?\d+)?$/
186
+ real(aLiteral)
187
+ else
188
+ string(aLiteral)
188
189
  end
189
190
  end
190
191
  end # module
data/lib/skeem/grammar.rb CHANGED
@@ -6,10 +6,10 @@ 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
- builder = Rley::Syntax::GrammarBuilder.new do
12
+ builder = Rley::grammar_builder do
13
13
  # Delimiters, separators...
14
14
  add_terminals('APOSTROPHE', 'COMMA', 'COMMA_AT_SIGN')
15
15
  add_terminals('GRAVE_ACCENT', 'LPAREN', 'RPAREN')
@@ -22,7 +22,7 @@ module Skeem
22
22
 
23
23
  # Keywords...
24
24
  add_terminals('BEGIN', 'COND', 'DEFINE', 'DEFINE-SYNTAX', 'DO')
25
- add_terminals('ELSE', 'IF', 'INCLUDE', 'LAMBDA', 'LET', 'LET*')
25
+ add_terminals('ELSE', 'IF', 'INCLUDE', 'LAMBDA', 'LET', 'LET_STAR')
26
26
  add_terminals('QUOTE', 'QUASIQUOTE', 'SET!', 'SYNTAX-RULES')
27
27
  add_terminals('UNQUOTE', 'UNQUOTE-SPLICING')
28
28
 
@@ -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,104 @@ 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+ RPAREN').as 'cond_form'
93
+ rule('derived_expression' => 'LPAREN COND cond_clause* LPAREN ELSE sequence RPAREN RPAREN').as 'cond_else_form'
94
+ rule('derived_expression' => 'LPAREN LET LPAREN binding_spec* RPAREN body RPAREN').as 'short_let_form'
109
95
  # 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* LPAREN binding_spec_star RPAREN body RPAREN').as 'let_star_form'
96
+ rule('derived_expression' => 'LPAREN LET IDENTIFIER LPAREN binding_spec* RPAREN body RPAREN') # .as 'named_form'
97
+ rule('derived_expression' => 'LPAREN LET_STAR LPAREN binding_spec* RPAREN body RPAREN').as 'let_star_form'
112
98
 
113
99
  # As the R7RS grammar is too restrictive,
114
100
  # the next rule was made more general than its standard counterpart
115
101
  rule('derived_expression' => 'LPAREN BEGIN body RPAREN').as 'begin_expression'
116
102
  do_syntax = <<-END_SYNTAX
117
- LPAREN DO LPAREN iteration_spec_star RPAREN
103
+ LPAREN DO LPAREN iteration_spec* RPAREN
118
104
  LPAREN test do_result RPAREN
119
- command_star RPAREN
105
+ rep_command_star RPAREN
120
106
  END_SYNTAX
121
107
  rule('derived_expression' => do_syntax).as 'do_expression'
122
108
  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
109
  rule('cond_clause' => 'LPAREN test sequence RPAREN').as 'cond_clause'
128
110
  rule('cond_clause' => 'LPAREN test RPAREN')
129
111
  rule('cond_clause' => 'LPAREN test ARROW recipient RPAREN').as 'cond_arrow_clause'
130
112
  rule('recipient' => 'expression')
131
113
  rule('quasiquotation' => 'LPAREN QUASIQUOTE qq_template RPAREN').as 'quasiquotation'
132
114
  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
115
  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
116
  rule('iteration_spec' => 'LPAREN IDENTIFIER init step RPAREN').as 'iteration_spec_long'
139
117
  rule('iteration_spec' => 'LPAREN IDENTIFIER init RPAREN').as 'iteration_spec_short'
140
118
  rule('init' => 'expression')
141
119
  rule('step' => 'expression')
142
- rule 'do_result' => 'sequence'
143
- rule('do_result' => []).as 'star_base' ## 'empty_do_result'
120
+ rule('do_result' => 'sequence?').tag 'do_result'
144
121
  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'
122
+ rule('includer' => 'LPAREN INCLUDE STRING_LIT+ RPAREN').as 'include'
148
123
  rule 'qq_template' => 'simple_datum'
149
124
  rule 'qq_template' => 'list_qq_template'
150
125
  rule 'qq_template' => 'vector_qq_template'
151
126
  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'
127
+ rule('list_qq_template' => 'LPAREN qq_template_or_splice* RPAREN').as 'list_qq'
128
+ rule 'list_qq_template' => 'LPAREN qq_template_or_splice+ PERIOD qq_template RPAREN'
154
129
  rule 'list_qq_template' => 'GRAVE_ACCENT qq_template'
155
- rule('vector_qq_template' => 'VECTOR_BEGIN qq_template_or_splice_star RPAREN').as 'vector_qq'
130
+ rule('vector_qq_template' => 'VECTOR_BEGIN qq_template_or_splice* RPAREN').as 'vector_qq'
156
131
  rule('unquotation' => 'COMMA qq_template').as 'unquotation_short'
157
132
  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
133
  rule 'qq_template_or_splice' => 'qq_template'
163
134
  rule 'qq_template_or_splice' => 'splicing_unquotation'
164
135
  rule 'splicing_unquotation' => 'COMMA_AT_SIGN qq_template'
165
136
  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'
137
+ rule('transformer_spec' => 'LPAREN SYNTAX-RULES LPAREN IDENTIFIER* RPAREN syntax_rule* RPAREN').as 'transformer_syntax'
138
+ rule('transformer_spec' => 'LPAREN SYNTAX-RULES IDENTIFIER LPAREN IDENTIFIER* RPAREN syntax_rule* RPAREN')
170
139
  rule('syntax_rule' => 'LPAREN pattern template RPAREN').as 'syntax_rule'
171
140
  rule('pattern' => 'pattern_identifier')
172
141
  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')
142
+ rule('pattern' => 'LPAREN pattern* RPAREN')
143
+ rule('pattern' => 'LPAREN pattern+ PERIOD pattern RPAREN')
144
+ rule('pattern' => 'LPAREN pattern+ ELLIPSIS pattern* RPAREN')
145
+ rule('pattern' => 'LPAREN pattern+ ELLIPSIS pattern* PERIOD pattern RPAREN')
146
+ rule('pattern' => 'VECTOR_BEGIN pattern* RPAREN')
147
+ rule('pattern' => 'VECTOR_BEGIN pattern+ ELLIPSIS pattern* RPAREN')
179
148
  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
149
  rule('pattern_datum' => 'STRING_LIT')
185
150
  rule('pattern_datum' => 'CHAR')
186
151
  rule('pattern_datum' => 'BOOLEAN')
187
152
  rule('pattern_datum' => 'number')
188
153
  # rule('pattern_datum' => 'bytevector')
189
154
  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')
155
+ rule('template' => 'LPAREN template_element* RPAREN')
156
+ rule('template' => 'LPAREN template_element+ PERIOD template RPAREN')
157
+ rule('template' => 'VECTOR_BEGIN template_element* RPAREN')
193
158
  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
159
  rule('template_element' => 'template')
199
160
  rule('template_element' => 'template ELLIPSIS')
200
161
  rule('template_datum' => 'pattern_datum')
201
162
  rule('pattern_identifier' => 'IDENTIFIER')
202
- # Ugly: specailized production rule per keyword...
163
+ # Ugly: specialized production rule per keyword...
203
164
  rule('pattern_identifier' => 'BEGIN')
204
165
  rule('pattern_identifier' => 'COND')
205
166
  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
@@ -27,11 +31,11 @@ module Skeem
27
31
  add_standard(runtime)
28
32
  end
29
33
 
30
- def parse(source, mode = nil)
34
+ def parse(source, _mode = nil)
31
35
  @parser ||= Parser.new
32
36
  @ptree = parser.parse(source)
33
- # $stderr.puts @ptree.root.inspect if mode.nil?
34
- # require 'debug' unless mode.nil?
37
+ # $stderr.puts @ptree.root.inspect if _mode.nil?
38
+ # require 'debug' unless _mode.nil?
35
39
  end
36
40
 
37
41
  def run(source, mode = nil)
@@ -45,7 +49,7 @@ module Skeem
45
49
  end
46
50
 
47
51
  def add_standard(_runtime)
48
- std_pathname = File.dirname(__FILE__) + '/standard/base.skm'
52
+ std_pathname = "#{File.dirname(__FILE__)}/standard/base.skm"
49
53
  load_lib(std_pathname)
50
54
  end
51
55
 
@@ -234,23 +234,17 @@ module Skeem
234
234
  if arglist.empty?
235
235
  raw_result = reciprocal(raw_result)
236
236
  else
237
- # Ugly: Ruby version dependency: Rubies older than 2.4 have class Fixnum instead of Integer
238
- int_class = (RUBY_VERSION[0..2] < '2.4') ? Fixnum : Integer
239
-
240
237
  arglist.each do |elem|
241
238
  elem_value = elem.value
242
239
  case [raw_result.class, elem_value.class]
243
- when [int_class, int_class]
240
+ when [Integer, Integer]
244
241
  if raw_result.modulo(elem_value).zero?
245
242
  raw_result /= elem_value
246
243
  else
247
244
  raw_result = Rational(raw_result, elem_value)
248
245
  end
249
246
 
250
- when [int_class, Rational]
251
- raw_result *= reciprocal(elem_value)
252
-
253
- when [Rational, Rational]
247
+ when [Integer, Rational], [Rational, Rational]
254
248
  raw_result *= reciprocal(elem_value)
255
249
  else
256
250
  raw_result = raw_result.to_f
@@ -827,8 +821,6 @@ module Skeem
827
821
  cloned = arg.klone
828
822
  if result.kind_of?(SkmEmptyList)
829
823
  result = cloned
830
- elsif result.kind_of?(SkmEmptyList)
831
- result = SkmPair.new(arg, SkmEmptyList.instance)
832
824
  else
833
825
  result.append_list(cloned)
834
826
  end
@@ -945,7 +937,7 @@ module Skeem
945
937
  break
946
938
  end
947
939
  pair = pair.cdr
948
- break unless pair&.kind_of?(SkmPair)
940
+ break unless pair.kind_of?(SkmPair)
949
941
  end
950
942
  end
951
943
 
@@ -967,7 +959,7 @@ module Skeem
967
959
  break
968
960
  end
969
961
  pair = pair.cdr
970
- break unless pair&.kind_of?(SkmPair)
962
+ break unless pair.kind_of?(SkmPair)
971
963
  end
972
964
  end
973
965
 
@@ -1142,7 +1134,7 @@ module Skeem
1142
1134
  # Error: assertion failed: (> 1 2)
1143
1135
  msg1 = "assertion failed on line #{pos.line}, column #{pos.column}"
1144
1136
  msg2 = ", with #{arg_evaluated.inspect}"
1145
- raise StandardError, 'Error: ' + msg1 + msg2
1137
+ raise StandardError, "Error: #{msg1}#{msg2}"
1146
1138
  else
1147
1139
  boolean(true)
1148
1140
  end
@@ -1165,7 +1157,7 @@ module Skeem
1165
1157
  # Non-standard procedure reserved for internal testing/debugging purposes.
1166
1158
  def create_inspect(aRuntime)
1167
1159
  primitive = lambda do |_runtime, arg_evaluated|
1168
- $stderr.puts 'INSPECT>' + arg_evaluated.inspect
1160
+ $stderr.puts "INSPECT>#{arg_evaluated.inspect}"
1169
1161
  Skeem::SkmUndefined.instance
1170
1162
  end
1171
1163
  define_primitive_proc(aRuntime, '_inspect', unary, primitive)
@@ -1233,7 +1225,7 @@ module Skeem
1233
1225
  else
1234
1226
  msg2 = "but got #{argument.class}"
1235
1227
  end
1236
- raise StandardError, msg1 + ' ' + msg2
1228
+ raise StandardError, "#{msg1} #{msg2}"
1237
1229
  end
1238
1230
 
1239
1231
  def remaining_args(arglist, aRuntime)
@@ -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)
@@ -42,10 +47,11 @@ module Skeem
42
47
  check_actual_count(actuals)
43
48
  # TODO: check that next line became useless
44
49
  # aProcedureCall.operands_consumed = true
45
- result = do_call(aRuntime, actuals)
50
+ # result = do_call(aRuntime, actuals)
46
51
  # $stderr.puts " Result: #{result.inspect}"
47
52
  # $stderr.puts "--- End of procedure #{identifier}"
48
- result
53
+ # result
54
+ do_call(aRuntime, actuals)
49
55
  end
50
56
 
51
57
  def skm_equal?(other)
@@ -146,20 +152,20 @@ module Skeem
146
152
 
147
153
  def error_lambda(message_suffix)
148
154
  msg1 = "Primitive procedure '#{identifier.value}'"
149
- raise StandardError, msg1 + ' ' + message_suffix
155
+ raise StandardError, "#{msg1} #{message_suffix}"
150
156
  end
151
157
 
152
158
  def discrepancy_arity_argument_count(arity_required, count_param, delta)
153
159
  msg1 = "Discrepancy in primitive procedure '#{identifier.value}'"
154
160
  msg2 = "between arity (#{arity_required}) + #{delta}"
155
161
  msg3 = "and parameter count of lambda #{count_param}."
156
- raise StandardError, msg1 + ' ' + msg2 + ' ' + msg3
162
+ raise StandardError, "#{msg1} #{msg2} #{msg3}"
157
163
  end
158
164
 
159
165
  def wrong_number_arguments(required, actual)
160
166
  msg1 = "Wrong number of arguments for #<Procedure #{identifier.value}>"
161
167
  msg2 = "(required at least #{required}, got #{actual})"
162
- raise StandardError, msg1 + ' ' + msg2
168
+ raise StandardError, "#{msg1} #{msg2}"
163
169
  end
164
170
  end # class
165
171
  end # module
data/lib/skeem/runtime.rb CHANGED
@@ -124,16 +124,14 @@ module Skeem
124
124
  private
125
125
 
126
126
  def normalize_key(aKey)
127
- result = case aKey
128
- when String
129
- aKey
130
- when SkmVariableReference
131
- aKey.child.value
132
- else
133
- aKey.evaluate(self).value
134
- end
135
-
136
- result
127
+ case aKey
128
+ when String
129
+ aKey
130
+ when SkmVariableReference
131
+ aKey.child.value
132
+ else
133
+ aKey.evaluate(self).value
134
+ end
137
135
  end
138
136
  end # class
139
137
  end # module