skeem 0.2.07 → 0.2.08

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