skeem 0.2.16 → 0.2.20

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