skeem 0.2.14 → 0.2.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +451 -195
  3. data/.travis.yml +27 -0
  4. data/CHANGELOG.md +35 -1
  5. data/Gemfile +2 -0
  6. data/README.md +125 -56
  7. data/Rakefile +2 -0
  8. data/appveyor.yml +3 -4
  9. data/bin/cubic.skm +4 -0
  10. data/bin/hello-world.skm +1 -0
  11. data/bin/skeem +72 -0
  12. data/lib/skeem/datum_dsl.rb +40 -30
  13. data/lib/skeem/element_visitor.rb +5 -2
  14. data/lib/skeem/grammar.rb +88 -26
  15. data/lib/skeem/interpreter.rb +9 -7
  16. data/lib/skeem/parser.rb +6 -4
  17. data/lib/skeem/primitive/primitive_builder.rb +148 -122
  18. data/lib/skeem/primitive/primitive_procedure.rb +23 -25
  19. data/lib/skeem/runtime.rb +17 -15
  20. data/lib/skeem/s_expr_builder.rb +49 -117
  21. data/lib/skeem/s_expr_nodes.rb +147 -132
  22. data/lib/skeem/skeem_exception.rb +1 -0
  23. data/lib/skeem/skm_binding.rb +9 -11
  24. data/lib/skeem/skm_compound_datum.rb +9 -6
  25. data/lib/skeem/skm_element.rb +15 -13
  26. data/lib/skeem/skm_empty_list.rb +6 -4
  27. data/lib/skeem/skm_exception.rb +9 -0
  28. data/lib/skeem/skm_expression.rb +3 -1
  29. data/lib/skeem/skm_frame.rb +3 -2
  30. data/lib/skeem/skm_pair.rb +26 -18
  31. data/lib/skeem/skm_procedure_exec.rb +11 -6
  32. data/lib/skeem/skm_simple_datum.rb +23 -20
  33. data/lib/skeem/skm_unary_expression.rb +34 -37
  34. data/lib/skeem/standard/base.skm +4 -0
  35. data/lib/skeem/tokenizer.rb +38 -28
  36. data/lib/skeem/version.rb +3 -1
  37. data/lib/skeem.rb +2 -0
  38. data/skeem.gemspec +9 -6
  39. data/spec/skeem/add4.skm +4 -0
  40. data/spec/skeem/datum_dsl_spec.rb +13 -12
  41. data/spec/skeem/element_visitor_spec.rb +14 -10
  42. data/spec/skeem/interpreter_spec.rb +84 -44
  43. data/spec/skeem/lambda_spec.rb +13 -11
  44. data/spec/skeem/parser_spec.rb +23 -19
  45. data/spec/skeem/primitive/primitive_builder_spec.rb +65 -48
  46. data/spec/skeem/primitive/primitive_procedure_spec.rb +14 -12
  47. data/spec/skeem/runtime_spec.rb +20 -18
  48. data/spec/skeem/s_expr_nodes_spec.rb +8 -6
  49. data/spec/skeem/skm_compound_datum_spec.rb +12 -10
  50. data/spec/skeem/skm_element_spec.rb +7 -5
  51. data/spec/skeem/skm_empty_list_spec.rb +7 -5
  52. data/spec/skeem/skm_frame_spec.rb +5 -4
  53. data/spec/skeem/skm_pair_spec.rb +9 -8
  54. data/spec/skeem/skm_procedure_exec_spec.rb +2 -0
  55. data/spec/skeem/skm_simple_datum_spec.rb +24 -22
  56. data/spec/skeem/skm_unary_expression_spec.rb +11 -9
  57. data/spec/skeem/tokenizer_spec.rb +54 -43
  58. data/spec/skeem_spec.rb +2 -0
  59. data/spec/spec_helper.rb +15 -10
  60. metadata +18 -10
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'ostruct'
2
4
  require_relative '../spec_helper' # Use the RSpec framework
3
5
  require_relative '../../lib/skeem/runtime'
@@ -6,7 +8,7 @@ require_relative '../../lib/skeem/s_expr_nodes' # Load the classes under test
6
8
 
7
9
  module Skeem
8
10
  describe ProcedureCall do
9
- let(:pos) { double('fake-position') }
11
+ let(:pos) { double('fake-position') }
10
12
  let(:operator) { SkmIdentifier.create('+') }
11
13
  let(:operands) { [1, 2, 3] }
12
14
 
@@ -14,7 +16,7 @@ module Skeem
14
16
 
15
17
  context 'Initialization:' do
16
18
  it 'should be initialized with an operator symbol and its operands' do
17
- expect{ ProcedureCall.new(pos, operator, operands) }.not_to raise_error
19
+ expect { ProcedureCall.new(pos, operator, operands) }.not_to raise_error
18
20
  end
19
21
 
20
22
  it 'should know its operator' do
@@ -45,7 +47,7 @@ module Skeem
45
47
 
46
48
  context 'Initialization:' do
47
49
  it 'should be initialized with a pos and 3 expressions' do
48
- expect{ SkmCondition.new(pos, s_test, s_consequent, s_alt) }.not_to raise_error
50
+ expect { SkmCondition.new(pos, s_test, s_consequent, s_alt) }.not_to raise_error
49
51
  end
50
52
 
51
53
  it 'should know its test' do
@@ -76,13 +78,13 @@ module Skeem
76
78
  let(:s_formals) { double('fake-formals') }
77
79
  let(:s_defs) { double('fake-definitions') }
78
80
  let(:s_sequence) { double('fake-sequence') }
79
- let(:s_body) do { defs: s_defs, sequence: s_sequence } end
81
+ let(:s_body) { { defs: s_defs, sequence: s_sequence } }
80
82
 
81
83
  subject { SkmLambdaRep.new(pos, s_formals, s_body) }
82
84
 
83
85
  context 'Initialization:' do
84
86
  it 'should be initialized with a pos and 3 expressions' do
85
- expect{ SkmLambdaRep.new(pos, s_formals, s_body) }.not_to raise_error
87
+ expect { SkmLambdaRep.new(pos, s_formals, s_body) }.not_to raise_error
86
88
  end
87
89
 
88
90
  it 'should know its formals' do
@@ -106,7 +108,7 @@ module Skeem
106
108
  # Remove "unpredictable" part of actual text
107
109
  expectation = subject.inspect.gsub(/@object_id=[0-9a-z]+, /, '')
108
110
  expect(expectation).to eq(txt1 + txt2 + txt3)
109
- end
111
+ end
110
112
  end # context
111
113
  end # describe
112
114
  end # module
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative '../spec_helper' # Use the RSpec framework
2
4
  require_relative '../../lib/skeem/datum_dsl'
3
5
  require_relative '../../lib/skeem/skm_compound_datum' # Load the classes under test
@@ -12,7 +14,7 @@ module Skeem
12
14
 
13
15
  context 'Initialization:' do
14
16
  it 'should be initialized with its members' do
15
- expect{ SkmCompoundDatum.new(sample_members) }.not_to raise_error
17
+ expect { SkmCompoundDatum.new(sample_members) }.not_to raise_error
16
18
  end
17
19
 
18
20
  it 'should know its members' do
@@ -28,7 +30,7 @@ module Skeem
28
30
  expect(subject).to eq(subject)
29
31
  end
30
32
 
31
- it 'should assert the equality by member values' do
33
+ it 'should assert the equality by member values' do
32
34
  # Comparison with other instances
33
35
  expect(subject).to eq(SkmCompoundDatum.new(sample_members))
34
36
  expect(subject).not_to eq(SkmCompoundDatum.new([]))
@@ -44,12 +46,12 @@ module Skeem
44
46
  expect(visitor).to receive(:visit_compound_datum).with(subject)
45
47
  expect { subject.accept(visitor) }.not_to raise_error
46
48
  end
47
-
49
+
48
50
  it 'should return its text representation' do
49
51
  txt1 = '<Skeem::SkmCompoundDatum: <Skeem::SkmInteger: 1>,'
50
52
  txt2 = '<Skeem::SkmInteger: 2>, <Skeem::SkmInteger: 3>>'
51
- expect(subject.inspect).to eq(txt1 + ' ' + txt2)
52
- end
53
+ expect(subject.inspect).to eq("#{txt1} #{txt2}")
54
+ end
53
55
  end # context
54
56
 
55
57
  context 'Provided runtime services:' do
@@ -78,19 +80,19 @@ module Skeem
78
80
  end
79
81
  end # context
80
82
  end # describe
81
-
83
+
82
84
  describe SkmVector do
83
85
  let(:sample_members) { [1, 2, 3] }
84
86
  subject { SkmVector.new(sample_members) }
85
87
 
86
88
  context 'Initialization:' do
87
89
  it 'should be initialized with its members' do
88
- expect{ SkmVector.new(sample_members) }.not_to raise_error
90
+ expect { SkmVector.new(sample_members) }.not_to raise_error
89
91
  end
90
-
92
+
91
93
  it 'should react positively to vector? predicate' do
92
94
  expect(subject).to be_vector
93
- end
95
+ end
94
96
  end # context
95
97
  end # describe
96
- end # module
98
+ end # module
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative '../spec_helper' # Use the RSpec framework
2
4
  require_relative '../../lib/skeem/skm_element' # Load the class under test
3
5
 
@@ -35,11 +37,11 @@ module Skeem
35
37
  let(:runtime) { double('fake-runtime') }
36
38
  let(:visitor) { double('fake-visitor') }
37
39
  let(:not_implemented) { NotImplementedError }
38
-
40
+
39
41
  it 'should be equivalent to itself' do
40
42
  expect(subject).to be_eqv(subject)
41
43
  expect(subject).not_to be_eqv(subject.clone)
42
- end
44
+ end
43
45
 
44
46
  it "should ignore the 'done!' message" do
45
47
  expect { subject.done! }.not_to raise_error
@@ -52,11 +54,11 @@ module Skeem
52
54
  it "should ignore the 'unquoted!' message" do
53
55
  expect { subject.unquoted! }.not_to raise_error
54
56
  end
55
-
57
+
56
58
  it "should complain when receiving 'skm_equal?' message" do
57
59
  msg = 'Missing implementation of method Skeem::SkmElement#skm_equal?'
58
60
  expect { subject.skm_equal?('omg') }.to raise_error(NotImplementedError, msg)
59
- end
61
+ end
60
62
 
61
63
  it "should complain when receiving 'evaluate' message" do
62
64
  expect { subject.evaluate(runtime) }.to raise_error(not_implemented)
@@ -71,4 +73,4 @@ module Skeem
71
73
  end
72
74
  end # context
73
75
  end # describe
74
- end # module
76
+ end # module
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative '../spec_helper' # Use the RSpec framework
2
4
  require_relative '../../lib/skeem/skm_empty_list' # Load the class under test
3
5
 
@@ -20,10 +22,10 @@ module Skeem
20
22
 
21
23
  context 'Provided services:' do
22
24
  let(:runtime) { double('fake-runtime') }
23
-
25
+
24
26
  it 'should be equivalent to itself' do
25
27
  expect(subject).to be_eqv(SkmEmptyList.instance)
26
- expect(subject).not_to be_eqv("()")
28
+ expect(subject).not_to be_eqv('()')
27
29
  end
28
30
 
29
31
  it "should return itself when receiving 'evaluate' message" do
@@ -36,14 +38,14 @@ module Skeem
36
38
 
37
39
  it "should reply to visitor's 'accept' message" do
38
40
  visitor = double('fake-visitor')
39
- expect(visitor).to receive(:visit_empty_list).with(subject)
41
+ expect(visitor).to receive(:visit_empty_list).with(subject)
40
42
  expect { subject.accept(visitor) }.not_to raise_error
41
43
  end
42
-
44
+
43
45
  it 'should return its representation upon inspection' do
44
46
  predicted = '<Skeem::SkmEmptyList: ()>'
45
47
  expect(subject.inspect).to eq(predicted)
46
48
  end
47
49
  end # context
48
50
  end # describe
49
- end # module
51
+ end # module
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative '../spec_helper' # Use the RSpec framework
2
- require_relative '../../lib/skeem/datum_dsl'
4
+ require_relative '../../lib/skeem/datum_dsl'
3
5
  require_relative '../../lib/skeem/skm_frame' # Load the class under test
4
6
 
5
7
  module Skeem
@@ -9,7 +11,7 @@ module Skeem
9
11
  let(:sample_env) { SkmFrame.new }
10
12
  context 'Initialization:' do
11
13
  it 'could be initialized without argument' do
12
- expect { SkmFrame.new() }.not_to raise_error
14
+ expect { SkmFrame.new }.not_to raise_error
13
15
  end
14
16
 
15
17
  it 'could be initialized with optional argument' do
@@ -114,6 +116,5 @@ module Skeem
114
116
  expect(nested.size).to eq(1)
115
117
  end
116
118
  end # context
117
-
118
119
  end # describe
119
- end # module
120
+ end # module
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative '../spec_helper' # Use the RSpec framework
2
4
  require_relative '../../lib/skeem/datum_dsl'
3
5
  require_relative '../../lib/skeem/runtime'
@@ -35,7 +37,7 @@ module Skeem
35
37
 
36
38
  context 'Provided services:' do
37
39
  let(:runtime) { Runtime.new(SkmFrame.new) }
38
- let(:list_length_2) { SkmPair.new(integer(10), subject) }
40
+ let(:list_length2) { SkmPair.new(integer(10), subject) }
39
41
  let(:quirk_element) { double('three') }
40
42
  let(:quirk_members) { [integer(10), quirk_element] }
41
43
 
@@ -69,7 +71,7 @@ module Skeem
69
71
  expect(subject.length).to eq(1)
70
72
 
71
73
  # Use a list of length 2
72
- expect(list_length_2.length).to eq(2)
74
+ expect(list_length2.length).to eq(2)
73
75
  end
74
76
 
75
77
  it 'should respond false to `eqv?` message' do
@@ -111,7 +113,7 @@ module Skeem
111
113
  expect(subject.to_a).to eq([sample_car])
112
114
 
113
115
  # Use a list of length 2
114
- expect(list_length_2.to_a).to eq([integer(10), sample_car])
116
+ expect(list_length2.to_a).to eq([integer(10), sample_car])
115
117
  end
116
118
 
117
119
  it 'should return the last pair of a proper list' do
@@ -131,7 +133,7 @@ module Skeem
131
133
 
132
134
  it 'should return the last element of a list' do
133
135
  expect(subject.last).to eq(sample_car)
134
- expect(list_length_2.last).to eq(sample_car)
136
+ expect(list_length2.last).to eq(sample_car)
135
137
  end
136
138
 
137
139
  it 'should append a new element to a list' do
@@ -172,7 +174,7 @@ module Skeem
172
174
 
173
175
  it 'should support the each method' do
174
176
  my_list = SkmPair.new('w', SkmPair.new('o', SkmPair.new('w', SkmEmptyList.instance)))
175
- text = ''
177
+ text = +''
176
178
  my_list.each { |ch| text << ch.upcase }
177
179
  expect(text).to eq('WOW')
178
180
  end
@@ -225,9 +227,8 @@ module Skeem
225
227
  expect(subject.inspect).to eq(predicted)
226
228
 
227
229
  predicted = '<Skeem::SkmPair: <Skeem::SkmInteger: 10>, <Skeem::SkmInteger: 3>>'
228
- expect(list_length_2.inspect).to eq(predicted)
230
+ expect(list_length2.inspect).to eq(predicted)
229
231
  end
230
232
  end # context
231
-
232
233
  end # describe
233
- end # module
234
+ end # module
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative '../spec_helper' # Use the RSpec framework
2
4
 
3
5
  require_relative '../../lib/skeem/interpreter'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'ostruct'
2
4
  require_relative '../spec_helper' # Use the RSpec framework
3
5
  require_relative '../../lib/skeem/skm_simple_datum' # Load the classes under test
@@ -47,7 +49,7 @@ module Skeem
47
49
  expect(subject).to eq(subject)
48
50
  end
49
51
 
50
- it 'should assert the equality by value' do
52
+ it 'should assert the equality by value' do
51
53
  # Comparison with other instances
52
54
  expect(instance).to eq(SkmSimpleDatum.create(3))
53
55
  expect(instance).not_to eq(SkmSimpleDatum.create('foo'))
@@ -56,24 +58,24 @@ module Skeem
56
58
  expect(instance).to eq(3)
57
59
  expect(instance).not_to eq('foo')
58
60
  end
59
-
61
+
60
62
  it 'should be equivalent to itself' do
61
63
  expect(subject).to be_eqv(subject)
62
64
  end
63
-
65
+
64
66
  it 'should be equivalent by value' do
65
67
  same = SkmSimpleDatum.create(3)
66
68
  expect(instance).to be_eqv(same)
67
- end
69
+ end
68
70
 
69
71
  it 'should be Skeem equal to itself' do
70
72
  expect(subject).to be_skm_equal(subject)
71
- end
72
-
73
+ end
74
+
73
75
  it 'should be Skeem equal by value' do
74
76
  same = SkmSimpleDatum.create(3)
75
77
  expect(instance).to be_skm_equal(same)
76
- end
78
+ end
77
79
 
78
80
  it 'should be self-evaluating' do
79
81
  expect(subject.evaluate(runtime)).to be_equal(subject)
@@ -84,7 +86,7 @@ module Skeem
84
86
  end
85
87
 
86
88
  it 'should return its text representation' do
87
- expect(subject.inspect).to eq("<Skeem::SkmSimpleDatum: sample-value>")
89
+ expect(subject.inspect).to eq('<Skeem::SkmSimpleDatum: sample-value>')
88
90
  end
89
91
 
90
92
  it 'should respond to visitor' do
@@ -173,7 +175,7 @@ module Skeem
173
175
  it 'should react positively to real? predicate' do
174
176
  expect(subject).to be_real
175
177
  end
176
-
178
+
177
179
  it 'should react negatively to exact? predicate' do
178
180
  expect(subject).not_to be_exact
179
181
  end
@@ -181,11 +183,11 @@ module Skeem
181
183
  it 'should implement the eqv? predicate' do
182
184
  same = SkmReal.create(0.51)
183
185
  different = SkmReal.create(1.21)
184
-
186
+
185
187
  expect(subject).to be_eqv(subject)
186
188
  expect(subject).to be_eqv(same)
187
189
  expect(subject).not_to be_eqv(different)
188
- end
190
+ end
189
191
  end # context
190
192
  end # describe
191
193
 
@@ -213,24 +215,24 @@ module Skeem
213
215
  it 'should react positively to integer? predicate' do
214
216
  expect(subject).to be_real
215
217
  end
216
-
218
+
217
219
  it 'should react positively to exact? predicate' do
218
220
  expect(subject).to be_exact
219
221
  end
220
222
 
221
223
  it 'should implement the eqv? predicate' do
222
224
  three = SkmInteger.create(3)
223
- real_3 = SkmReal.create(3.0)
225
+ real3 = SkmReal.create(3.0)
224
226
  four = SkmInteger.create(4)
225
-
227
+
226
228
  expect(subject).to be_eqv(three)
227
- expect(subject).not_to be_eqv(real_3)
229
+ expect(subject).not_to be_eqv(real3)
228
230
  expect(subject).not_to be_eqv(four)
229
231
  end
230
232
  end # context
231
233
  end # describe
232
234
 
233
- describe SkmString do
235
+ describe SkmString do
234
236
  let(:pos) { double('fake-position') }
235
237
  let(:dummy_symbol) { double('dummy') }
236
238
  let(:sample_value) { 'Hello' }
@@ -272,28 +274,28 @@ describe SkmString do
272
274
 
273
275
  it 'could be initialized with a token, a position and a flag' do
274
276
  expect { SkmIdentifier.new(dummy_token, pos, true) }.not_to raise_error
275
- end
277
+ end
276
278
 
277
279
  it 'should know whether it is used as a variable name' do
278
280
  expect(subject.is_var_name).to eq(false)
279
-
281
+
280
282
  instance = SkmIdentifier.new(dummy_token, pos, true)
281
283
  expect(instance.is_var_name).to eq(true)
282
284
  end
283
-
285
+
284
286
  it 'should react positively to symbol? predicate' do
285
287
  expect(subject).to be_symbol
286
288
  end
287
-
289
+
288
290
  it 'should react to verbatim? predicate' do
289
291
  expect(subject).to be_verbatim
290
292
  instance = SkmIdentifier.new(dummy_token, pos, true)
291
293
  expect(instance).not_to be_verbatim
292
- end
294
+ end
293
295
 
294
296
  it 'should return its text representation' do
295
297
  expect(subject.inspect).to eq('<Skeem::SkmIdentifier: this-is-it!>')
296
298
  end
297
299
  end # context
298
300
  end # describe
299
- end # module
301
+ end # module
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative '../spec_helper' # Use the RSpec framework
2
4
  require_relative '../../lib/skeem/datum_dsl'
3
5
  require_relative '../../lib/skeem/s_expr_nodes'
@@ -12,7 +14,7 @@ module Skeem
12
14
 
13
15
  context 'Initialization:' do
14
16
  it 'should be initialized with a position and a child element' do
15
- expect{ SkmUnaryExpression.new(pos, sample_child) }.not_to raise_error
17
+ expect { SkmUnaryExpression.new(pos, sample_child) }.not_to raise_error
16
18
  end
17
19
 
18
20
  it 'should know its child' do
@@ -38,7 +40,7 @@ module Skeem
38
40
 
39
41
  context 'Initialization:' do
40
42
  it 'should be initialized with a Skeem element' do
41
- expect{ SkmQuotation.new(sample_literal) }.not_to raise_error
43
+ expect { SkmQuotation.new(sample_literal) }.not_to raise_error
42
44
  end
43
45
 
44
46
  it 'should know its datum' do
@@ -84,7 +86,7 @@ module Skeem
84
86
 
85
87
  context 'Initialization:' do
86
88
  it 'should be initialized with a Skeem element' do
87
- expect{ SkmQuasiquotation.new(sample_literal) }.not_to raise_error
89
+ expect { SkmQuasiquotation.new(sample_literal) }.not_to raise_error
88
90
  end
89
91
  end # context
90
92
 
@@ -116,7 +118,7 @@ module Skeem
116
118
  end # describe
117
119
 
118
120
 
119
- describe SkmUnquotation do
121
+ describe SkmUnquotation do
120
122
  include DatumDSL
121
123
 
122
124
  let(:sample_literal) { string('foo') }
@@ -125,7 +127,7 @@ module Skeem
125
127
 
126
128
  context 'Initialization:' do
127
129
  it 'should be initialized with a Skeem element' do
128
- expect{ SkmUnquotation.new(sample_literal) }.not_to raise_error
130
+ expect { SkmUnquotation.new(sample_literal) }.not_to raise_error
129
131
  end
130
132
  end # context
131
133
 
@@ -156,7 +158,7 @@ module Skeem
156
158
  end
157
159
  end # context
158
160
  end # describe
159
-
161
+
160
162
  describe SkmVariableReference do
161
163
  include DatumDSL
162
164
 
@@ -167,7 +169,7 @@ module Skeem
167
169
 
168
170
  context 'Initialization:' do
169
171
  it 'should be initialized with a position and a symbol' do
170
- expect{ SkmVariableReference.new(pos, sample_var) }.not_to raise_error
172
+ expect { SkmVariableReference.new(pos, sample_var) }.not_to raise_error
171
173
  end
172
174
 
173
175
  it 'should know its variable' do
@@ -187,7 +189,7 @@ module Skeem
187
189
  expect(subject.evaluate(runtime)).to eq(3)
188
190
  end
189
191
 
190
- it "should return itself at quasiquotation" do
192
+ it 'should return itself at quasiquotation' do
191
193
  expect(subject.quasiquote(runtime)).to be_equal(subject)
192
194
  end
193
195
 
@@ -197,4 +199,4 @@ module Skeem
197
199
  end
198
200
  end # context
199
201
  end # describe
200
- end # module
202
+ end # module