skeem 0.2.17 → 0.2.18

Sign up to get free protection for your applications and to get access to all the features.
data/lib/skeem/grammar.rb CHANGED
@@ -9,7 +9,7 @@ module Skeem
9
9
  # Official Small Scheme 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
 
@@ -108,7 +108,7 @@ module Skeem
108
108
  rule('derived_expression' => 'LPAREN LET LPAREN binding_spec_star RPAREN body RPAREN').as 'short_let_form'
109
109
  # TODO: implement "named let"
110
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'
111
+ rule('derived_expression' => 'LPAREN LET_STAR LPAREN binding_spec_star RPAREN body RPAREN').as 'let_star_form'
112
112
 
113
113
  # As the R7RS grammar is too restrictive,
114
114
  # the next rule was made more general than its standard counterpart
@@ -45,7 +45,7 @@ module Skeem
45
45
  end
46
46
 
47
47
  def add_standard(_runtime)
48
- std_pathname = File.dirname(__FILE__) + '/standard/base.skm'
48
+ std_pathname = "#{File.dirname(__FILE__)}/standard/base.skm"
49
49
  load_lib(std_pathname)
50
50
  end
51
51
 
@@ -234,20 +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]
247
+ when [Integer, Rational]
251
248
  raw_result *= reciprocal(elem_value)
252
249
 
253
250
  when [Rational, Rational]
@@ -827,8 +824,6 @@ module Skeem
827
824
  cloned = arg.klone
828
825
  if result.kind_of?(SkmEmptyList)
829
826
  result = cloned
830
- elsif result.kind_of?(SkmEmptyList)
831
- result = SkmPair.new(arg, SkmEmptyList.instance)
832
827
  else
833
828
  result.append_list(cloned)
834
829
  end
@@ -945,7 +940,7 @@ module Skeem
945
940
  break
946
941
  end
947
942
  pair = pair.cdr
948
- break unless pair&.kind_of?(SkmPair)
943
+ break unless pair.kind_of?(SkmPair)
949
944
  end
950
945
  end
951
946
 
@@ -967,7 +962,7 @@ module Skeem
967
962
  break
968
963
  end
969
964
  pair = pair.cdr
970
- break unless pair&.kind_of?(SkmPair)
965
+ break unless pair.kind_of?(SkmPair)
971
966
  end
972
967
  end
973
968
 
@@ -1142,7 +1137,7 @@ module Skeem
1142
1137
  # Error: assertion failed: (> 1 2)
1143
1138
  msg1 = "assertion failed on line #{pos.line}, column #{pos.column}"
1144
1139
  msg2 = ", with #{arg_evaluated.inspect}"
1145
- raise StandardError, 'Error: ' + msg1 + msg2
1140
+ raise StandardError, "Error: #{msg1}#{msg2}"
1146
1141
  else
1147
1142
  boolean(true)
1148
1143
  end
@@ -1165,7 +1160,7 @@ module Skeem
1165
1160
  # Non-standard procedure reserved for internal testing/debugging purposes.
1166
1161
  def create_inspect(aRuntime)
1167
1162
  primitive = lambda do |_runtime, arg_evaluated|
1168
- $stderr.puts 'INSPECT>' + arg_evaluated.inspect
1163
+ $stderr.puts "INSPECT>#{arg_evaluated.inspect}"
1169
1164
  Skeem::SkmUndefined.instance
1170
1165
  end
1171
1166
  define_primitive_proc(aRuntime, '_inspect', unary, primitive)
@@ -1233,7 +1228,7 @@ module Skeem
1233
1228
  else
1234
1229
  msg2 = "but got #{argument.class}"
1235
1230
  end
1236
- raise StandardError, msg1 + ' ' + msg2
1231
+ raise StandardError, "#{msg1} #{msg2}"
1237
1232
  end
1238
1233
 
1239
1234
  def remaining_args(arglist, aRuntime)
@@ -42,10 +42,11 @@ module Skeem
42
42
  check_actual_count(actuals)
43
43
  # TODO: check that next line became useless
44
44
  # aProcedureCall.operands_consumed = true
45
- result = do_call(aRuntime, actuals)
45
+ # result = do_call(aRuntime, actuals)
46
46
  # $stderr.puts " Result: #{result.inspect}"
47
47
  # $stderr.puts "--- End of procedure #{identifier}"
48
- result
48
+ # result
49
+ do_call(aRuntime, actuals)
49
50
  end
50
51
 
51
52
  def skm_equal?(other)
@@ -146,20 +147,20 @@ module Skeem
146
147
 
147
148
  def error_lambda(message_suffix)
148
149
  msg1 = "Primitive procedure '#{identifier.value}'"
149
- raise StandardError, msg1 + ' ' + message_suffix
150
+ raise StandardError, "#{msg1} #{message_suffix}"
150
151
  end
151
152
 
152
153
  def discrepancy_arity_argument_count(arity_required, count_param, delta)
153
154
  msg1 = "Discrepancy in primitive procedure '#{identifier.value}'"
154
155
  msg2 = "between arity (#{arity_required}) + #{delta}"
155
156
  msg3 = "and parameter count of lambda #{count_param}."
156
- raise StandardError, msg1 + ' ' + msg2 + ' ' + msg3
157
+ raise StandardError, "#{msg1} #{msg2} #{msg3}"
157
158
  end
158
159
 
159
160
  def wrong_number_arguments(required, actual)
160
161
  msg1 = "Wrong number of arguments for #<Procedure #{identifier.value}>"
161
162
  msg2 = "(required at least #{required}, got #{actual})"
162
- raise StandardError, msg1 + ' ' + msg2
163
+ raise StandardError, "#{msg1} #{msg2}"
163
164
  end
164
165
  end # class
165
166
  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
@@ -24,17 +24,6 @@ module Skeem
24
24
  'STRING_LIT' => SkmString
25
25
  }.freeze
26
26
 
27
- # Create a new AST builder instance.
28
- # @param theTokens [Array<Token>] The sequence of input tokens.
29
- def initialize(theTokens)
30
- super(theTokens)
31
- end
32
-
33
- # Notification that the parse tree construction is complete.
34
- def done!
35
- super
36
- end
37
-
38
27
  protected
39
28
 
40
29
  def terminal2node
@@ -191,9 +180,10 @@ module Skeem
191
180
 
192
181
  # rule('lambda_expression' => 'LPAREN LAMBDA formals body RPAREN').as 'lambda_expression'
193
182
  def reduce_lambda_expression(_production, aRange, _tokens, theChildren)
194
- lmbd = SkmLambdaRep.new(aRange, theChildren[2], theChildren[3])
183
+ # lmbd = SkmLambdaRep.new(aRange, theChildren[2], theChildren[3])
195
184
  # $stderr.puts lmbd.inspect
196
- lmbd
185
+ # lmbd
186
+ SkmLambdaRep.new(aRange, theChildren[2], theChildren[3])
197
187
  end
198
188
 
199
189
  # rule('formals' => 'LPAREN identifier_star RPAREN').as 'fixed_arity_formals'
@@ -103,8 +103,8 @@ module Skeem
103
103
  end
104
104
 
105
105
  def inspect
106
- result = inspect_prefix + operator.inspect + ', '
107
- result << '@operands ' + operands.inspect + inspect_suffix
106
+ result = +"#{inspect_prefix}#{operator.inspect}, "
107
+ result << "@operands #{operands.inspect}#{inspect_suffix}"
108
108
  result
109
109
  end
110
110
 
@@ -127,12 +127,10 @@ module Skeem
127
127
 
128
128
  callee = result
129
129
  # callee = fetch_callee(aRuntime, result)
130
- when Primitive::PrimitiveProcedure
130
+ when Primitive::PrimitiveProcedure, SkmLambda
131
131
  callee = operator
132
132
  when SkmLambdaRep
133
133
  callee = operator.evaluate(aRuntime)
134
- when SkmLambda
135
- callee = operator
136
134
  else
137
135
  result = operator.evaluate(aRuntime)
138
136
  if result.kind_of?(Primitive::PrimitiveProcedure)
@@ -225,9 +223,9 @@ module Skeem
225
223
  end
226
224
 
227
225
  def inspect
228
- result = inspect_prefix + '@test ' + test.inspect + ', '
229
- result << '@consequent ' + consequent.inspect + ', '
230
- result << '@alternate ' + alternate.inspect + inspect_suffix
226
+ result = +"#{inspect_prefix}@test #{test.inspect}, "
227
+ result << "@consequent #{consequent.inspect}, "
228
+ result << "@alternate #{alternate.inspect}#{inspect_suffix}"
231
229
  result
232
230
  end
233
231
 
@@ -236,7 +234,6 @@ module Skeem
236
234
  end
237
235
  end # class
238
236
 
239
-
240
237
  class SkmConditional < SkmMultiExpression
241
238
  # An array of couples [test, sequence]
242
239
  attr_reader :clauses
@@ -280,20 +277,23 @@ module Skeem
280
277
  end
281
278
 
282
279
  def inspect
283
- result = inspect_prefix + '@test ' + test.inspect + ', '
280
+ result = "#{inspect_prefix}@test #{test.inspect} , "
284
281
  result << "@clauses \n"
285
282
  clauses.each do |(test, consequent)|
286
283
  result << ' ' << test.inspect << ' ' << consequent.inspect << "\n"
287
284
  end
288
- result << '@alternate ' + alternate.inspect + inspect_suffix
285
+ result << "@alternate #{alternate.inspect}#{inspect_suffix}"
289
286
  result
290
287
  end
291
288
  end # class
292
289
 
293
290
  SkmArity = Struct.new(:low, :high) do
291
+ # rubocop: disable Style/NumericPredicate
292
+
294
293
  def nullary?
295
294
  low.zero? && high == 0
296
295
  end
296
+ # rubocop: enable Style/NumericPredicate
297
297
 
298
298
  def variadic?
299
299
  high == '*'
@@ -446,6 +446,7 @@ module Skeem
446
446
  attr_reader :update_steps
447
447
 
448
448
  def initialize(aTest, doResult, theCommands, theUpdates)
449
+ super(nil)
449
450
  @test = aTest
450
451
  @do_result = doResult
451
452
  @commands = theCommands
@@ -546,7 +547,6 @@ module Skeem
546
547
  end
547
548
  end # class
548
549
 
549
-
550
550
  # Parse tree representation of a Lambda
551
551
  # - Not bound to a frame (aka environment)
552
552
  # - Knows the parse representation of its embedded definitions
@@ -629,9 +629,7 @@ module Skeem
629
629
  variadic_part_raw = actuals.drop(required_arity)
630
630
  variadic_part = variadic_part_raw.map do |actual|
631
631
  case actual
632
- when ProcedureCall
633
- actual.evaluate(aRuntime)
634
- when SkmQuotation
632
+ when ProcedureCall, SkmQuotation
635
633
  actual.evaluate(aRuntime)
636
634
  else
637
635
  to_datum(actual)
@@ -697,9 +695,9 @@ module Skeem
697
695
 
698
696
  def inspect_specific
699
697
  result = +''
700
- result << '@formals ' + formals.inspect + ', '
701
- result << '@definitions ' + definitions.inspect + ', '
702
- result << '@sequence ' + sequence.inspect + inspect_suffix
698
+ result << "@formals #{formals.inspect}, "
699
+ result << "@definitions #{definitions.inspect}, "
700
+ result << "@sequence #{sequence.inspect}#{inspect_suffix}"
703
701
 
704
702
  result
705
703
  end
@@ -715,6 +713,7 @@ module Skeem
715
713
  def_delegators(:@representation, :formals, :definitions, :sequence)
716
714
 
717
715
  def initialize(aRepresentation, aRuntime)
716
+ super(nil)
718
717
  @representation = aRepresentation
719
718
  @environment = aRuntime.environment
720
719
  end
@@ -790,9 +789,7 @@ module Skeem
790
789
  variadic_part_raw = actuals.drop(required_arity)
791
790
  variadic_part = variadic_part_raw.map do |actual|
792
791
  case actual
793
- when ProcedureCall
794
- actual.evaluate(aRuntime)
795
- when SkmQuotation
792
+ when ProcedureCall, SkmQuotation
796
793
  actual.evaluate(aRuntime)
797
794
  else
798
795
  to_datum(actual)
@@ -814,20 +811,17 @@ module Skeem
814
811
 
815
812
  def evaluate_sequence(aRuntime)
816
813
  result = nil
817
- if sequence&.each do |cmd|
818
- begin
819
- if cmd.kind_of?(SkmLambda)
820
- result = cmd.dup_cond(aRuntime)
821
- else
822
- result = cmd.evaluate(aRuntime)
823
- end
824
- rescue NoMethodError => e
825
- $stderr.puts inspect
826
- $stderr.puts sequence.inspect
827
- $stderr.puts cmd.inspect
828
- raise e
829
- end
814
+ sequence&.each do |cmd|
815
+ if cmd.kind_of?(SkmLambda)
816
+ result = cmd.dup_cond(aRuntime)
817
+ else
818
+ result = cmd.evaluate(aRuntime)
830
819
  end
820
+ rescue NoMethodError => e
821
+ $stderr.puts inspect
822
+ $stderr.puts sequence.inspect
823
+ $stderr.puts cmd.inspect
824
+ raise e
831
825
  end
832
826
 
833
827
  result
@@ -835,22 +829,18 @@ module Skeem
835
829
 
836
830
  def dup_cond(aRuntime)
837
831
  if environment
838
- result = self
832
+ self
839
833
  else
840
834
  twin = dup
841
835
  twin.set_cond_environment(aRuntime.environment)
842
- result = twin
836
+ twin
843
837
  end
844
-
845
- result
846
838
  end
847
839
 
848
840
  def doppelganger(aRuntime)
849
841
  twin = dup
850
842
  twin.set_cond_environment(aRuntime.environment.dup)
851
- result = twin
852
-
853
- result
843
+ twin
854
844
  end
855
845
 
856
846
  def set_cond_environment(theFrame)
@@ -917,9 +907,9 @@ module Skeem
917
907
  result << "Parent environment #{environment.parent.object_id.to_s(16)}, "
918
908
  result << environment.inspect
919
909
  end
920
- result << '@formals ' + formals.inspect + ', '
921
- result << '@definitions ' + definitions.inspect + ', '
922
- result << '@sequence ' + sequence.inspect + inspect_suffix
910
+ result << "@formals #{formals.inspect}, "
911
+ result << "@definitions #{definitions.inspect}, "
912
+ result << "@sequence #{sequence.inspect}#{inspect_suffix}"
923
913
 
924
914
  result
925
915
  end
@@ -0,0 +1 @@
1
+ # frozen_string_literal: true
@@ -17,10 +17,13 @@ module Skeem
17
17
  # @param anIdentifier [SkmIdentifier] The variable name
18
18
  # @param aValue [SkmElement] The value to bind to the variable.
19
19
  def initialize(anIdentifier, aValue)
20
+ super(nil)
20
21
  @variable = anIdentifier
21
22
  @value = aValue
22
23
  end
23
24
 
25
+ # rubocop: disable Style/NegatedIfElseCondition
26
+
24
27
  def evaluate(aRuntime)
25
28
  name = variable.evaluate(aRuntime)
26
29
 
@@ -42,6 +45,7 @@ module Skeem
42
45
  binding_action(aRuntime, name, result)
43
46
  result
44
47
  end
48
+ # rubocop: enable Style/NegatedIfElseCondition
45
49
 
46
50
  protected
47
51
 
@@ -59,7 +63,6 @@ module Skeem
59
63
  end
60
64
  end # class
61
65
 
62
-
63
66
  class SkmUpdateBinding < SkmBinding
64
67
  protected
65
68
 
@@ -71,10 +74,6 @@ module Skeem
71
74
  class SkmDelayedUpdateBinding < SkmBinding
72
75
  attr_reader :new_val
73
76
 
74
- def initialize(anIdentifier, aValue)
75
- super(anIdentifier, aValue)
76
- end
77
-
78
77
  def do_it!(aRuntime)
79
78
  aRuntime.update_binding(variable, new_val)
80
79
  end
@@ -22,13 +22,12 @@ module Skeem
22
22
  def ==(other)
23
23
  return true if equal?(other)
24
24
 
25
- result = case other
25
+ case other
26
26
  when SkmCompoundDatum
27
27
  self.class == other.class && members == other.members
28
28
  when Array
29
29
  members == other
30
30
  end
31
- result
32
31
  end
33
32
 
34
33
  alias eqv? equal?
@@ -70,7 +69,7 @@ module Skeem
70
69
 
71
70
  def inspect_specific
72
71
  result = +''
73
- members.each { |elem| result << elem.inspect + ', ' }
72
+ members.each { |elem| result << "#{elem.inspect}, " }
74
73
  result.sub!(/, $/, '')
75
74
  result
76
75
  end