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 +4 -4
- data/CHANGELOG.md +13 -0
- data/README.md +1 -0
- data/lib/skeem/datum_dsl.rb +0 -1
- data/lib/skeem/grammar.rb +8 -8
- data/lib/skeem/primitive/primitive_builder.rb +72 -24
- data/lib/skeem/s_expr_builder.rb +1 -1
- data/lib/skeem/skm_compound_datum.rb +0 -55
- data/lib/skeem/skm_element.rb +5 -0
- data/lib/skeem/version.rb +1 -1
- data/spec/skeem/primitive/primitive_builder_spec.rb +26 -3
- data/spec/skeem/skm_compound_datum_spec.rb +0 -36
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cd3683235600881fa4fdbef83d8921aff335ee90388eef9f564b60e3d9217e49
|
4
|
+
data.tar.gz: 90c6402cc9f6367438ff8121741222edeab5712f747d3e498dc4a55c50f7047b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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`
|
data/lib/skeem/datum_dsl.rb
CHANGED
@@ -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' =>
|
38
|
-
rule 'expression' =>
|
39
|
-
rule 'expression' =>
|
40
|
-
rule 'expression' =>
|
41
|
-
rule 'expression' =>
|
42
|
-
rule 'expression' =>
|
43
|
-
rule '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
|
-
|
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
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
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',
|
623
|
-
end
|
666
|
+
check_argtype(alist, [SkmPair, SkmEmptyList], 'association list', proc_name)
|
624
667
|
|
625
|
-
|
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)
|
data/lib/skeem/s_expr_builder.rb
CHANGED
@@ -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
|
data/lib/skeem/skm_element.rb
CHANGED
@@ -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
@@ -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
|
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.
|
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-
|
11
|
+
date: 2019-06-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rley
|