skeem 0.2.07 → 0.2.08

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3dd3d2443ae53822f3ebf6f0ce042b52455fff6592bd8aa26e91e4ac548c2c87
4
- data.tar.gz: 8eb8851aa0bf2b643949c1dd21284178a83891982eff75cffc1ec10ab1fbe537
3
+ metadata.gz: cd3683235600881fa4fdbef83d8921aff335ee90388eef9f564b60e3d9217e49
4
+ data.tar.gz: 90c6402cc9f6367438ff8121741222edeab5712f747d3e498dc4a55c50f7047b
5
5
  SHA512:
6
- metadata.gz: ebe0ba16a14e6c08638c63fabb83a38cd001914277a58bada5419020f92fbd83bfe7ad382ffa1bb44bb6307175f34108a407e60401f0c5657f11d484c97973aa
7
- data.tar.gz: 4d61121cce897e2d4c4a6d3cb2b070522aa32785e76c18059cd86d6150bcd5e3d6ac6eb6c4bd2e1531dde19448341c938dc88b0d0722fd3ed1a6d605c7112344
6
+ metadata.gz: dc0e68b644a532d23a8dfac125a48cbb2cf6c13e83e051e7757bf516a80a0d2fc721ea8d85f50d00461d0fa90aaf3e9fac4536f4c2818fbf061ad35110b64288
7
+ data.tar.gz: 7c8ea63a8b08532d8112ae85d0ea93d8c999f87a92ed43e5e6e8e97e0f168de7a69bdaa2d3f72fe0b42f756c158d4e3bcdbb0897312a6ac8be160f657c5a3fa3
data/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ ## [0.2.08] - 2019-06-02
2
+ - New standard procedures implemented: `assq`, `assv`
3
+
4
+ ### Added
5
+ - File `primitive_builder.rb`. New methods for implementing `assq`, `assv`
6
+
7
+ ### Changed
8
+ - File `README.md` Added mentions to new procedures.
9
+
10
+ ### Removed
11
+ - Superseded class `SkmList` removed.
12
+
13
+
1
14
  ## [0.2.07] - 2019-05-31
2
15
  - New standard procedures implemented: `list-copy`, `procedure?`, `apply` and `map`
3
16
 
data/README.md CHANGED
@@ -252,6 +252,7 @@ This section lists the implemented standard procedures
252
252
 
253
253
  #### List procedures
254
254
  * `list?`, `null?`, `pair?`, `append`, `car`, `cdr`, `caar`, `cadr`, `cdar`, `cddr`, `cons`, `length`, `list`, `list-copy`, `list->vector`, `set-car!`, `set-cdr!`
255
+ , `assq`, `assv`
255
256
 
256
257
  #### String procedures
257
258
  * `string?`, `string=?`, `string-append`, `string-length`, `string->symbol`
@@ -104,7 +104,6 @@ module Skeem
104
104
  # Conversion from Ruby object value to Skeem datum
105
105
  def to_datum(aLiteral)
106
106
  return aLiteral if aLiteral.kind_of?(SkmSimpleDatum)
107
- return list(aLiteral.members) if aLiteral.kind_of?(SkmList)
108
107
  return vector(aLiteral.members) if aLiteral.kind_of?(SkmVector)
109
108
  return aLiteral if aLiteral.kind_of?(Primitive::PrimitiveProcedure)
110
109
 
data/lib/skeem/grammar.rb CHANGED
@@ -34,15 +34,15 @@ module Skeem
34
34
  rule('definition' => 'LPAREN DEFINE IDENTIFIER expression RPAREN').as 'definition'
35
35
  rule('definition' => 'LPAREN DEFINE LPAREN IDENTIFIER def_formals RPAREN body RPAREN').as 'alt_definition'
36
36
  rule('definition' => 'LPAREN BEGIN definition_star RPAREN').as 'definitions_within_begin'
37
- rule('expression' => 'IDENTIFIER').as 'variable_reference'
38
- rule 'expression' => 'literal'
39
- rule 'expression' => 'procedure_call'
40
- rule 'expression' => 'lambda_expression'
41
- rule 'expression' => 'conditional'
42
- rule 'expression' => 'assignment'
43
- rule 'expression' => 'derived_expression'
37
+ rule('expression' => 'IDENTIFIER').as 'variable_reference'
38
+ rule 'expression' => 'literal'
39
+ rule 'expression' => 'procedure_call'
40
+ rule 'expression' => 'lambda_expression'
41
+ rule 'expression' => 'conditional'
42
+ rule 'expression' => 'assignment'
43
+ rule 'expression' => 'derived_expression'
44
44
  rule 'literal' => 'quotation'
45
- rule 'literal' => 'self-evaluating'
45
+ rule 'literal' => 'self-evaluating'
46
46
  rule('quotation' => 'APOSTROPHE datum').as 'quotation_short'
47
47
  rule('quotation' => 'LPAREN QUOTE datum RPAREN').as 'quotation'
48
48
  rule 'self-evaluating' => 'BOOLEAN'
@@ -61,6 +61,7 @@ module Skeem
61
61
 
62
62
  def add_comparison(aRuntime)
63
63
  create_eqv?(aRuntime)
64
+ create_eq?(aRuntime)
64
65
  create_equal?(aRuntime)
65
66
  create_equal(aRuntime)
66
67
  create_lt(aRuntime)
@@ -220,17 +221,36 @@ module Skeem
220
221
  define_primitive_proc(aRuntime, 'floor-remainder', binary, primitive)
221
222
  end
222
223
 
224
+ def core_eqv?(eval_arg1, eval_arg2)
225
+ raw_result = eval_arg1.eqv?(eval_arg2)
226
+ boolean(raw_result)
227
+ end
228
+
223
229
  def create_eqv?(aRuntime)
224
230
  primitive = ->(runtime, argument1, argument2) do
225
231
  operand_1 = argument1.evaluate(runtime)
226
232
  operand_2 = argument2.evaluate(runtime)
227
- raw_result = operand_1.eqv?(operand_2)
228
- boolean(raw_result)
233
+ core_eqv?(operand_1, operand_2)
229
234
  end
230
235
 
231
236
  define_primitive_proc(aRuntime, 'eqv?', binary, primitive)
232
237
  end
233
238
 
239
+ def core_eq?(eval_arg1, eval_arg2)
240
+ raw_result = eval_arg1.skm_eq?(eval_arg2)
241
+ boolean(raw_result)
242
+ end
243
+
244
+ def create_eq?(aRuntime)
245
+ primitive = ->(runtime, argument1, argument2) do
246
+ operand_1 = argument1.evaluate(runtime)
247
+ operand_2 = argument2.evaluate(runtime)
248
+ core_eq?(operand1, operand2)
249
+ end
250
+
251
+ define_primitive_proc(aRuntime, 'eq?', binary, primitive)
252
+ end
253
+
234
254
  def create_equal?(aRuntime)
235
255
  primitive = ->(runtime, argument1, argument2) do
236
256
  operand_1 = argument1.evaluate(runtime)
@@ -355,7 +375,7 @@ module Skeem
355
375
  argument = raw_arg.evaluate(aRuntime)
356
376
  last_result = argument
357
377
  raw_result &&= !(argument.boolean? && !argument.value)
358
- break unless raw_result
378
+ break unless raw_result # stop here, a false was found...
359
379
  end
360
380
  raw_result = last_result if raw_result
361
381
  # $stderr.puts raw_result.inspect
@@ -379,7 +399,7 @@ module Skeem
379
399
  argument = raw_arg.evaluate(aRuntime)
380
400
  last_result = argument
381
401
  raw_result ||= (!argument.boolean? || argument.value)
382
- break if raw_result
402
+ break if raw_result # stop here, a true was found...
383
403
  end
384
404
  raw_result = last_result if raw_result
385
405
  to_datum(raw_result)
@@ -596,36 +616,64 @@ module Skeem
596
616
  define_primitive_proc(aRuntime, 'set-cdr!', binary, primitive)
597
617
  end
598
618
 
599
- # create_assv(aRuntime)
600
619
  def create_assq(aRuntime)
601
620
  primitive = ->(runtime, obj_arg, alist_arg) do
602
- # assoc_list = alist_arg.evaluate(runtime)
603
- # check_assoc_list(assoc_list, 'assq')
604
- # result = boolean(false)
605
- # pair = assoc_list
606
- # while (pair.cdr && (pair.cdr.kind_of?(SkmPair)) do
607
- # are_equal = @primitive_map['equal?'].call(runtime, pair.car, obj_arg)
608
- # if are_equal
609
- # result = pair
610
- # break
611
- # else
612
- # pair = pair.cdr
613
- # end
614
- # end
615
-
616
- # result
621
+ assoc_list = alist_arg.evaluate(runtime)
622
+ check_assoc_list(assoc_list, 'assq')
623
+ obj = obj_arg.evaluate(runtime)
624
+ result = boolean(false)
625
+ unless assoc_list.empty?
626
+ pair = assoc_list
627
+ begin
628
+ are_equal = core_eq?(pair.car.car, obj)
629
+ if are_equal.value
630
+ result = pair.car
631
+ break
632
+ end
633
+ pair = pair.cdr
634
+ end while (pair && (pair.kind_of?(SkmPair)))
635
+ end
636
+
637
+ result
617
638
  end
618
639
  define_primitive_proc(aRuntime, 'assq', binary, primitive)
619
640
  end
641
+
642
+ def create_assv(aRuntime)
643
+ primitive = ->(runtime, obj_arg, alist_arg) do
644
+ assoc_list = alist_arg.evaluate(runtime)
645
+ check_assoc_list(assoc_list, 'assq')
646
+ obj = obj_arg.evaluate(runtime)
647
+ result = boolean(false)
648
+ unless assoc_list.empty?
649
+ pair = assoc_list
650
+ begin
651
+ are_equal = core_eqv?(pair.car.car, obj)
652
+ if are_equal.value
653
+ result = pair.car
654
+ break
655
+ end
656
+ pair = pair.cdr
657
+ end while (pair && (pair.kind_of?(SkmPair)))
658
+ end
659
+
660
+ result
661
+ end
662
+ define_primitive_proc(aRuntime, 'assv', binary, primitive)
663
+ end
620
664
 
621
665
  def check_assoc_list(alist, proc_name)
622
- check_argtype(alist, SkmPair, 'association list', 'proc_name')
623
- end
666
+ check_argtype(alist, [SkmPair, SkmEmptyList], 'association list', proc_name)
624
667
 
625
- def create_assv(aRuntime)
668
+ unless alist.empty?
669
+ cell = SkmPair.new(integer(1), alist)
670
+ begin
671
+ cell = cell.cdr
672
+ check_argtype(cell, SkmPair, 'association list', proc_name)
673
+ end while cell.cdr.kind_of?(SkmPair)
674
+ end
626
675
  end
627
676
 
628
-
629
677
  def create_list_copy(aRuntime)
630
678
  primitive = ->(runtime, arg) do
631
679
  arg_evaluated = arg.evaluate(runtime)
@@ -86,7 +86,7 @@ module Skeem
86
86
  # rule('expression' => 'IDENTIFIER').as 'variable_reference'
87
87
  def reduce_variable_reference(_production, aRange, _tokens, theChildren)
88
88
  SkmVariableReference.new(aRange, theChildren[0])
89
- end
89
+ end
90
90
 
91
91
  # rule('quotation' => 'APOSTROPHE datum').as 'quotation_short'
92
92
  def reduce_quotation_short(_production, _range, _tokens, theChildren)
@@ -72,61 +72,6 @@ module Skeem
72
72
  end
73
73
  end # class
74
74
 
75
- # @deprecated Use {#SkmPair} class instead.
76
- class SkmList < SkmCompoundDatum
77
- def tail()
78
- SkmList.new(members.slice(1..-1))
79
- end
80
-
81
- def list?
82
- true
83
- end
84
-
85
- def null?
86
- empty?
87
- end
88
-
89
- def evaluate(aRuntime)
90
- if empty?
91
- self.class.new(nil)
92
- else
93
- first_evaluated = members.first.evaluate(aRuntime)
94
-
95
- if first_evaluated.kind_of?(SkmIdentifier)
96
- aRuntime.evaluate_form(self)
97
- else
98
- members_eval = members.map { |elem| elem.evaluate(aRuntime) }
99
- self.class.new(members_eval)
100
- end
101
- end
102
- end
103
-
104
-
105
- # Factory method.
106
- # Construct an Enumerator that will return iteratively the result
107
- # of 'evaluate' method of each members of self.
108
- def to_eval_enum(aRuntime)
109
- =begin
110
- elements = self.members
111
-
112
- new_enum = Enumerator.new do |result|
113
- context = aRuntime
114
- elements.each { |elem| result << elem.evaluate(context) }
115
- end
116
-
117
- new_enum
118
- =end
119
- members.map { |elem| elem.evaluate(aRuntime) }
120
- end
121
-
122
- def done!()
123
- # Do nothing
124
- end
125
-
126
- alias head first
127
- alias rest tail
128
- end # class
129
-
130
75
  class SkmVector < SkmCompoundDatum
131
76
  def vector?
132
77
  true
@@ -61,6 +61,11 @@ module Skeem
61
61
  msg = "Missing implementation of method #{self.class.name}##{__method__}"
62
62
  raise NotImplementedError, msg
63
63
  end
64
+
65
+ def skm_eq?(other)
66
+ # Default implementation, to override when necessary
67
+ self.eqv?(other)
68
+ end
64
69
 
65
70
  # @return [TrueClass, FalseClass] true if quoted element is identical to itself
66
71
  def verbatim?
data/lib/skeem/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Skeem
2
- VERSION = '0.2.07'.freeze
2
+ VERSION = '0.2.08'.freeze
3
3
  end
@@ -634,6 +634,29 @@ SKEEM
634
634
  expect(result.last.cdr).to eq(1)
635
635
  end
636
636
 
637
+ it 'should implement the assq procedure' do
638
+ subject.run("(define e '((a 1) (b 2) (c 3)))")
639
+ result = subject.run("(assq 'a e)")
640
+ expect(result.to_a).to eq(['a', 1])
641
+ result = subject.run("(assq 'b e)")
642
+ expect(result.to_a).to eq(['b', 2])
643
+ result = subject.run("(assq 'c e)")
644
+ expect(result.to_a).to eq(['c', 3])
645
+ result = subject.run("(assq 'd e)")
646
+ expect(result).to eq(false)
647
+ result = subject.run("(assq 'a '())")
648
+ expect(result).to eq(false)
649
+ result = subject.run("(assq 'a '())")
650
+ expect(result).to eq(false)
651
+ result = subject.run("(assq '(a) '(((a)) ((b)) ((c))))")
652
+ expect(result).to eq(false)
653
+ end
654
+
655
+ it 'should implement the assv procedure' do
656
+ result = subject.run("(assv 5 '((2 3) (5 7) (11 13)))")
657
+ expect(result.to_a).to eq([5, 7])
658
+ end
659
+
637
660
  it 'should implement the list-copy procedure' do
638
661
  checks = [
639
662
  ["(list-copy '())", []],
@@ -737,7 +760,7 @@ SKEEM
737
760
  ["(procedure? car)", true],
738
761
  ["(procedure? 'car)", false],
739
762
  ["(procedure? (lambda (x) (* x x)))", true],
740
- # ["(procedure? '(lambda (x) (* x x)))", false] # Parse failure!
763
+ # ["(procedure? '(lambda (x) (* x x)))", false] # Parse fail: non-standard syntax
741
764
  ]
742
765
  checks.each do |(skeem_expr, expectation)|
743
766
  result = subject.run(skeem_expr)
@@ -754,7 +777,7 @@ SKEEM
754
777
  expect(result).to eq(expectation)
755
778
  end
756
779
  end
757
-
780
+
758
781
  it 'should implement the map procedure' do
759
782
  checks = [
760
783
  ["(map car '((a b) (d e) (g h)))", ['a', 'd', 'g']],
@@ -764,7 +787,7 @@ SKEEM
764
787
  result = subject.run(skeem_expr)
765
788
  expect(result.to_a).to eq(expectation)
766
789
  end
767
- end
790
+ end
768
791
  end # context
769
792
 
770
793
  context 'IO procedures:' do
@@ -78,42 +78,6 @@ module Skeem
78
78
  end
79
79
  end # context
80
80
  end # describe
81
-
82
- describe SkmList do
83
- let(:sample_members) { [1, 2, 3] }
84
- subject { SkmList.new(sample_members) }
85
-
86
- context 'Initialization:' do
87
- it 'should be initialized with its members' do
88
- expect{ SkmList.new(sample_members) }.not_to raise_error
89
- end
90
-
91
- it 'should react positively to list? predicate' do
92
- expect(subject).to be_list
93
- end
94
-
95
- it 'should react correctly to null? predicate' do
96
- expect(subject).not_to be_null
97
- expect(SkmList.new([])).to be_null
98
- end
99
- end # context
100
-
101
- context 'Provided services:' do
102
- it 'should retrieve its first member' do
103
- expect(subject.first).to eq(1)
104
- expect(subject.head).to eq(1)
105
- end
106
-
107
- it 'should retrieve its tail members' do
108
- expect(subject.tail.inspect).to eq('<Skeem::SkmList: 2, 3>')
109
- expect(subject.rest.inspect).to eq('<Skeem::SkmList: 2, 3>')
110
- end
111
-
112
- it 'should return its text representation' do
113
- expect(subject.inspect).to eq('<Skeem::SkmList: 1, 2, 3>')
114
- end
115
- end # context
116
- end # describe
117
81
 
118
82
  describe SkmVector do
119
83
  let(:sample_members) { [1, 2, 3] }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: skeem
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.07
4
+ version: 0.2.08
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dimitri Geshef
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-31 00:00:00.000000000 Z
11
+ date: 2019-06-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rley