skeem 0.0.7 → 0.0.8

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
  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