skeem 0.0.7 → 0.0.8
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 +4 -4
- data/CHANGELOG.md +15 -3
- data/README.md +3 -3
- data/lib/skeem/primitive/primitive_builder.rb +59 -4
- data/lib/skeem/s_expr_nodes.rb +17 -13
- data/lib/skeem/version.rb +1 -1
- data/spec/skeem/interpreter_spec.rb +30 -4
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e19432168939085384bceaf28be0364177ddf91b
|
4
|
+
data.tar.gz: 1256c3c464d7edb6fcf7d3cf6c1d1fd1bd2446ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7817ca715480e6d21c46ba46da12bb6652592f258348968dc3e3c705c717542ddca63b63493758ba2a470e300a5d1263b61762ae21746fc81afede599eae36e7
|
7
|
+
data.tar.gz: 948438de92a59ada9b5589a312df5c71fbd9e884328a6b4c8ad1422578ae0471dbdb170354499a4fa5cd7811809ca38f97785ec183b5c820edce1121b770a656
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,18 @@
|
|
1
|
+
## [0.0.8] - 2018-09-13
|
2
|
+
Added primitive operators: '-', '*', '/' operators.
|
3
|
+
|
4
|
+
### Added
|
5
|
+
- Class `PrimitiveBuilder`. Added methods to implement the arithmetic operators - (subtraction), * (product), / (division)
|
6
|
+
- Class `SExprList`. Class refactoring
|
7
|
+
- Class `PrimitiveFunc` Internal representation of primitive functions.
|
8
|
+
|
9
|
+
### Changed
|
10
|
+
- File `interpreter_spec.rb` Added tests for arithmetic expressions.
|
11
|
+
- File `README.md` Changed demo snippet with example of arithmetic expression.
|
12
|
+
|
1
13
|
## [0.0.7] - 2018-09-12
|
2
|
-
Proof of concept of a primitive function: '+' operator.
|
3
|
-
Demo works but code needs some polishing and testing.
|
14
|
+
Proof of concept of a primitive function: '+' operator.
|
15
|
+
Demo works but code needs some polishing and testing.
|
4
16
|
|
5
17
|
### Added
|
6
18
|
- Class `Environment`. Holds a mapping between symbol names and their associated value.
|
@@ -62,7 +74,7 @@ Parser now generates correct parse trees for expressions consisting of a single
|
|
62
74
|
|
63
75
|
## [0.0.0] - 2018-08-24
|
64
76
|
### Added
|
65
|
-
- Initial Github commit
|
77
|
+
- Initial Github commit
|
66
78
|
|
67
79
|
## Unreleased
|
68
80
|
### Added
|
data/README.md
CHANGED
@@ -32,11 +32,11 @@ At this stage, the gem consists of a bare-bones interpreter.
|
|
32
32
|
|
33
33
|
schemer = Skeem::Interpreter.new
|
34
34
|
scheme_code =<<-SKEEM
|
35
|
-
; Let's try
|
36
|
-
(+
|
35
|
+
; Let's try some arithmetic expression
|
36
|
+
(+ (* 2 100) (* 1 10))
|
37
37
|
SKEEM
|
38
38
|
result = schemer.run(scheme_code)
|
39
|
-
puts result.value # =>
|
39
|
+
puts result.value # => 210
|
40
40
|
```
|
41
41
|
|
42
42
|
Roadmap:
|
@@ -11,20 +11,75 @@ module Skeem
|
|
11
11
|
|
12
12
|
def add_arithmetic(aRuntime)
|
13
13
|
def_func(aRuntime, create_plus)
|
14
|
+
def_func(aRuntime, create_minus)
|
15
|
+
def_func(aRuntime, create_multiply)
|
16
|
+
def_func(aRuntime, create_divide)
|
14
17
|
end
|
15
18
|
|
16
19
|
def create_plus()
|
17
20
|
plus_code = ->(runtime, arglist) do
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
+
first_one = arglist.head.evaluate(runtime)
|
22
|
+
operands = arglist.tail.to_eval_enum(runtime)
|
23
|
+
raw_result = first_one.value
|
24
|
+
operands.each { |elem| raw_result += elem.value }
|
25
|
+
if raw_result.kind_of?(Float)
|
26
|
+
SExprReal.create(raw_result)
|
27
|
+
else
|
28
|
+
SExprInteger.create(raw_result)
|
21
29
|
end
|
22
|
-
SExprInteger.create(raw_result)
|
23
30
|
end
|
24
31
|
|
25
32
|
['+', plus_code]
|
26
33
|
end
|
27
34
|
|
35
|
+
def create_minus()
|
36
|
+
minus_code = ->(runtime, arglist) do
|
37
|
+
first_one = arglist.head.evaluate(runtime)
|
38
|
+
operands = arglist.tail.to_eval_enum(runtime)
|
39
|
+
raw_result = first_one.value
|
40
|
+
operands.each { |elem| raw_result -= elem.value }
|
41
|
+
if raw_result.kind_of?(Float)
|
42
|
+
SExprReal.create(raw_result)
|
43
|
+
else
|
44
|
+
SExprInteger.create(raw_result)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
['-', minus_code]
|
49
|
+
end
|
50
|
+
|
51
|
+
def create_multiply()
|
52
|
+
multiply_code = ->(runtime, arglist) do
|
53
|
+
first_one = arglist.head.evaluate(runtime)
|
54
|
+
operands = arglist.tail.to_eval_enum(runtime)
|
55
|
+
raw_result = first_one.value
|
56
|
+
operands.each { |elem| raw_result *= elem.value }
|
57
|
+
if raw_result.kind_of?(Float)
|
58
|
+
SExprReal.create(raw_result)
|
59
|
+
else
|
60
|
+
SExprInteger.create(raw_result)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
['*', multiply_code]
|
65
|
+
end
|
66
|
+
|
67
|
+
def create_divide()
|
68
|
+
divide_code = ->(runtime, arglist) do
|
69
|
+
first_one = arglist.head.evaluate(runtime)
|
70
|
+
operands = arglist.tail.to_eval_enum(runtime)
|
71
|
+
raw_result = first_one.value
|
72
|
+
operands.each { |elem| raw_result /= elem.value }
|
73
|
+
if raw_result.kind_of?(Float)
|
74
|
+
SExprReal.create(raw_result)
|
75
|
+
else
|
76
|
+
SExprInteger.create(raw_result)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
['/', divide_code]
|
81
|
+
end
|
82
|
+
|
28
83
|
def def_func(aRuntime, aPair)
|
29
84
|
func = PrimitiveFunc.new(aPair.first, aPair.last)
|
30
85
|
define(aRuntime, func.identifier, func)
|
data/lib/skeem/s_expr_nodes.rb
CHANGED
@@ -104,13 +104,17 @@ module Skeem
|
|
104
104
|
|
105
105
|
def_delegator :@members, :first, :empty?
|
106
106
|
|
107
|
-
def initialize()
|
107
|
+
def initialize(theMembers)
|
108
108
|
super(nil)
|
109
|
-
@members = []
|
109
|
+
@members = theMembers.nil? ? [] : theMembers
|
110
110
|
end
|
111
111
|
|
112
|
-
def
|
113
|
-
members.
|
112
|
+
def head()
|
113
|
+
return members.first
|
114
|
+
end
|
115
|
+
|
116
|
+
def tail()
|
117
|
+
SExprList.new(members.slice(1..-1))
|
114
118
|
end
|
115
119
|
|
116
120
|
# Factory method.
|
@@ -139,8 +143,6 @@ module Skeem
|
|
139
143
|
|
140
144
|
alias children members
|
141
145
|
alias subnodes members
|
142
|
-
alias head first
|
143
|
-
alias tail rest
|
144
146
|
end # class
|
145
147
|
|
146
148
|
class ProcedureCall < SExprElement
|
@@ -150,16 +152,18 @@ module Skeem
|
|
150
152
|
def initialize(aPosition, anOperator, theOperands)
|
151
153
|
super(aPosition)
|
152
154
|
@operator = anOperator
|
153
|
-
@operands = SExprList.new
|
154
|
-
@operands.instance_variable_set(:@members, theOperands)
|
155
|
+
@operands = SExprList.new(theOperands)
|
155
156
|
end
|
156
157
|
|
157
158
|
def evaluate(aRuntime)
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
159
|
+
proc_key = operator.evaluate(aRuntime)
|
160
|
+
unless aRuntime.include?(proc_key.value)
|
161
|
+
err = StandardError
|
162
|
+
key = proc_key.kind_of?(SExprIdentifier) ? proc_key.value : proc_key
|
163
|
+
err_msg = "Unknown function '#{key}'"
|
164
|
+
raise err, err_msg
|
165
|
+
end
|
166
|
+
procedure = aRuntime.environment.bindings[proc_key.value]
|
163
167
|
result = procedure.call(aRuntime, self)
|
164
168
|
end
|
165
169
|
|
data/lib/skeem/version.rb
CHANGED
@@ -15,7 +15,7 @@ module Skeem
|
|
15
15
|
it 'should have a runtime object' do
|
16
16
|
expect(subject.runtime).to be_kind_of(Runtime)
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
it 'should come with built-in functions' do
|
20
20
|
expect(subject.runtime.environment).not_to be_empty
|
21
21
|
end
|
@@ -88,12 +88,38 @@ module Skeem
|
|
88
88
|
expect(result.value).to eq(predicted)
|
89
89
|
end
|
90
90
|
end
|
91
|
+
end # context
|
91
92
|
|
92
|
-
|
93
|
-
|
93
|
+
context 'Built-in primitive functions' do
|
94
|
+
it 'should support the addition of integers' do
|
95
|
+
result = subject.run('(+ 2 2)')
|
94
96
|
expect(result).to be_kind_of(SExprInteger)
|
95
|
-
expect(result.value).to eq(
|
97
|
+
expect(result.value).to eq(4)
|
96
98
|
end
|
99
|
+
|
100
|
+
it 'should support the addition of real numbers' do
|
101
|
+
result = subject.run('(+ 2 2.34)')
|
102
|
+
expect(result).to be_kind_of(SExprReal)
|
103
|
+
expect(result.value).to eq(4.34)
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'should support the product of numbers' do
|
107
|
+
result = subject.run('(* 2 3 4)')
|
108
|
+
expect(result).to be_kind_of(SExprInteger)
|
109
|
+
expect(result.value).to eq(24)
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'should support the division of numbers' do
|
113
|
+
result = subject.run('(/ 24 3)')
|
114
|
+
expect(result).to be_kind_of(SExprInteger)
|
115
|
+
expect(result.value).to eq(8)
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'should support the arithmetic expressions' do
|
119
|
+
result = subject.run('(+ (* 2 100) (* 1 10))')
|
120
|
+
expect(result).to be_kind_of(SExprInteger)
|
121
|
+
expect(result.value).to eq(210)
|
122
|
+
end
|
97
123
|
end # context
|
98
124
|
end # describe
|
99
125
|
end # module
|
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.0.
|
4
|
+
version: 0.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dimitri Geshef
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-09-
|
11
|
+
date: 2018-09-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rley
|