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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c9907100633d80e63603f094700423139f320600
4
- data.tar.gz: 5d4b89ed16eb0c029d98ce02c88eed4cc459404d
3
+ metadata.gz: e19432168939085384bceaf28be0364177ddf91b
4
+ data.tar.gz: 1256c3c464d7edb6fcf7d3cf6c1d1fd1bd2446ab
5
5
  SHA512:
6
- metadata.gz: edd237e0152cbac2cf89bd0724436db40865fddddec40eb4cd3de595909c8a1c09e424f0903903a3cbacf2e3c6fc63fb98770523acda5ffa2099a382f8eccd41
7
- data.tar.gz: 3d9605b4577d2701c18cb675b4ea37907b8d7c990c3a9139b6227931b2b68ddf0be8617b6980bf03e640821a958e5d3419b423c95bda128dc6db2837dda4a21e
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 the addition operator
36
- (+ 3 4 5)
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 # => 12
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
- operands = arglist.to_eval_enum(runtime)
19
- raw_result = operands.reduce(0) do |interim, elem|
20
- interim += elem.value
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)
@@ -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 rest()
113
- members.slice(1..-1)
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
- procedure_key = operator.evaluate(aRuntime)
159
- err = StandardError
160
- err_msg = "Unknown function #{procedure_key}"
161
- raise err, err_msg unless aRuntime.include?(procedure_key.value)
162
- procedure = aRuntime.environment.bindings[procedure_key.value]
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
@@ -1,3 +1,3 @@
1
1
  module Skeem
2
- VERSION = '0.0.7'.freeze
2
+ VERSION = '0.0.8'.freeze
3
3
  end
@@ -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
- it 'should support procedure calls' do
93
- result = subject.run('(+ 3 4)')
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(7)
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.7
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-12 00:00:00.000000000 Z
11
+ date: 2018-09-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rley