electr 0.0.5 → 0.0.6

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.
@@ -68,6 +68,36 @@ describe Sya do
68
68
  expect(sya.run).to eq [added, a, b]
69
69
  end
70
70
 
71
+ specify 'R1 R2' do
72
+ a = LexicalUnit.variable('R1')
73
+ b = LexicalUnit.variable('R2')
74
+ added = LexicalUnit.operator('*')
75
+ sya = Sya.new([a, b])
76
+
77
+ # * R1 R2
78
+ expect(sya.run).to eq [added, a, b]
79
+ end
80
+
81
+ specify 'R1 5' do
82
+ a = LexicalUnit.variable('R1')
83
+ b = LexicalUnit.numeric('5')
84
+ added = LexicalUnit.operator('*')
85
+ sya = Sya.new([a, b])
86
+
87
+ # * R1 5
88
+ expect(sya.run).to eq [added, a, b]
89
+ end
90
+
91
+ specify '5 R1' do
92
+ a = LexicalUnit.numeric('5')
93
+ b = LexicalUnit.variable('R1')
94
+ added = LexicalUnit.operator('*')
95
+ sya = Sya.new([a, b])
96
+
97
+ # * R1 5
98
+ expect(sya.run).to eq [added, a, b]
99
+ end
100
+
71
101
  specify 'sqrt(49) + 1' do
72
102
  a = LexicalUnit.fname('sqrt')
73
103
  b = LexicalUnit.open_parenthesis
@@ -185,4 +215,38 @@ describe Sya do
185
215
  expect(sya.run).to eq [f, a, b, d, g]
186
216
  end
187
217
 
218
+ specify "R1 = 100" do
219
+ a = LexicalUnit.variable("R1")
220
+ b = LexicalUnit.assign
221
+ c = LexicalUnit.numeric("100")
222
+
223
+ sya = Sya.new([a, b, c])
224
+
225
+ expect(sya.run).to eq [b, a, c]
226
+ end
227
+
228
+ specify "R1 = 200 + 100" do
229
+ a = LexicalUnit.variable("R1")
230
+ b = LexicalUnit.assign
231
+ c = LexicalUnit.numeric("200")
232
+ d = LexicalUnit.operator("+")
233
+ e = LexicalUnit.numeric("100")
234
+
235
+ sya = Sya.new([a, b, c, d, e])
236
+
237
+ expect(sya.run).to eq [b, a, d, c, e]
238
+ end
239
+
240
+ specify "R1 = R2 = 100" do
241
+ a = LexicalUnit.variable("R1")
242
+ b = LexicalUnit.assign
243
+ c = LexicalUnit.variable("R2")
244
+ d = LexicalUnit.assign
245
+ e = LexicalUnit.numeric("100")
246
+
247
+ sya = Sya.new([a, b, c, d, e])
248
+
249
+ expect(sya.run).to eq [b, a, d, c, e]
250
+ end
251
+
188
252
  end
@@ -207,6 +207,19 @@ describe Tokenizer do
207
207
  expect(tkr.next_token).to eq "2"
208
208
  end
209
209
 
210
+ specify "R1" do
211
+ tkr = Tokenizer.new("R1")
212
+ expect(tkr.next_token).to eq "R1"
213
+ end
214
+
215
+ specify "R1 = 100" do
216
+ tkr = Tokenizer.new("R1 = 100")
217
+
218
+ expect(tkr.next_token).to eq "R1"
219
+ expect(tkr.next_token).to eq "="
220
+ expect(tkr.next_token).to eq "100"
221
+ end
222
+
210
223
  it 'tokenize units and prefixes' do
211
224
  units = %w( A Hz W C V F R Ω S ℧ H )
212
225
  prefixes = %w( k M G T m μ u n p )
@@ -0,0 +1,86 @@
1
+ require 'spec_helper'
2
+
3
+ include Electr
4
+
5
+ describe ElectrValue do
6
+
7
+ describe "number" do
8
+
9
+ it "holds a number" do
10
+ result = ElectrValue.number(10)
11
+ expect(result.number).to eq 10
12
+ end
13
+
14
+ it "has type number" do
15
+ result = ElectrValue.number(10)
16
+ expect(result.type).to eq :number
17
+ end
18
+
19
+ it "knows it is a number" do
20
+ result = ElectrValue.number(10)
21
+ expect(result.number?).to eq true
22
+ expect(result.error?).to eq false
23
+ end
24
+ end
25
+
26
+ describe "error" do
27
+
28
+ it "holds an error message" do
29
+ result = ElectrValue.error("message")
30
+ expect(result.error).to eq "message"
31
+ end
32
+
33
+ it "has type error" do
34
+ result = ElectrValue.error("message")
35
+ expect(result.type).to eq :error
36
+ end
37
+
38
+ it "knows it is a error" do
39
+ result = ElectrValue.error("message")
40
+ expect(result.error?).to eq true
41
+ expect(result.number?).to eq false
42
+ end
43
+ end
44
+
45
+ describe "hidden" do
46
+
47
+ it "holds a hidden number" do
48
+ result = ElectrValue.hidden(10)
49
+ expect(result.number).to eq 10
50
+ end
51
+
52
+ it "has type hidden" do
53
+ result = ElectrValue.hidden(10)
54
+ expect(result.type).to eq :hidden
55
+ end
56
+
57
+ it "knows it is a hidden number" do
58
+ result = ElectrValue.hidden(10)
59
+ expect(result.number?).to eq false
60
+ expect(result.hidden?).to eq true
61
+ end
62
+ end
63
+
64
+ describe "==" do
65
+ it "is equal when all same members" do
66
+ a = ElectrValue.number(10)
67
+ b = ElectrValue.number(10)
68
+ expect(a.object_id).not_to eq b.object_id
69
+ expect(a).to eq b
70
+ end
71
+
72
+ it "isn't equal when different types" do
73
+ a = ElectrValue.number(10)
74
+ b = ElectrValue.error("foo")
75
+ expect(a).not_to eq b
76
+ end
77
+
78
+ it "isn't equal when different classes" do
79
+ a = ElectrValue.number(10)
80
+ b = 10
81
+ expect(a).not_to eq b
82
+ end
83
+
84
+ end
85
+
86
+ end
@@ -45,19 +45,128 @@ describe Evaluator do
45
45
  evaluator = Evaluator.new
46
46
  result = evaluator.evaluate_pn(pns)
47
47
 
48
- expect(result).to eq code[:result]
48
+ expect(result).to eq ElectrValue.number(code[:result])
49
49
  end
50
50
  end
51
51
 
52
52
  specify do
53
53
  pns = Compiler.compile_to_pn("2 * 3")
54
-
54
+
55
55
  evaluator = Evaluator.new
56
56
  result = evaluator.evaluate_pn(pns)
57
57
 
58
- expect(result).to eq 6
58
+ expect(result).to eq ElectrValue.number(6.0)
59
59
  end
60
60
 
61
+ describe "environment" do
62
+
63
+ it "don't raise on unbound variable" do
64
+ evaluator = Evaluator.new
65
+
66
+ pns = Compiler.compile_to_pn("R1")
67
+ expect {
68
+ evaluator.evaluate_pn(pns)
69
+ }.not_to raise_error
70
+ end
71
+
72
+ it "evalutes an assignment" do
73
+ evaluator = Evaluator.new
74
+
75
+ pns = Compiler.compile_to_pn("R1 = 100")
76
+ result = evaluator.evaluate_pn(pns)
77
+
78
+ expect(result).to eq ElectrValue.hidden(100.0)
79
+ end
80
+
81
+ it "does chain assignment" do
82
+ evaluator = Evaluator.new
83
+
84
+ pns = Compiler.compile_to_pn("R1 = R2 = 100")
85
+ evaluator.evaluate_pn(pns)
86
+
87
+ expect(evaluator.environment["R1"]).to eq ElectrValue.number(100.0)
88
+ expect(evaluator.environment["R2"]).to eq ElectrValue.number(100.0)
89
+ end
90
+
91
+ it "retains variable" do
92
+ evaluator = Evaluator.new
93
+
94
+ pns = Compiler.compile_to_pn("R1 = 100")
95
+ evaluator.evaluate_pn(pns)
96
+ expect(evaluator.environment["R1"]).to eq ElectrValue.number(100.0)
97
+ end
98
+
99
+ it "starts empty" do
100
+ evaluator = Evaluator.new
101
+ expect(evaluator.environment).to be_empty
102
+ end
103
+
104
+ it "assigns an expression" do
105
+ evaluator = Evaluator.new
106
+
107
+ pns = Compiler.compile_to_pn("R2 = 10 + 7")
108
+ evaluator.evaluate_pn(pns)
109
+ expect(evaluator.environment["R2"]).to eq ElectrValue.number(17.0)
110
+ end
111
+
112
+ it "assigns a variable's value" do
113
+ evaluator = Evaluator.new
114
+
115
+ pns = Compiler.compile_to_pn("R1 = 100")
116
+ evaluator.evaluate_pn(pns)
117
+
118
+ pns = Compiler.compile_to_pn("R2 = R1")
119
+ evaluator.evaluate_pn(pns)
120
+ expect(evaluator.environment["R2"]).to eq ElectrValue.number(100.0)
121
+ end
122
+
123
+ it "gets the value" do
124
+ evaluator = Evaluator.new
125
+
126
+ pns = Compiler.compile_to_pn("R1 = 100")
127
+ evaluator.evaluate_pn(pns)
128
+
129
+ pns = Compiler.compile_to_pn("R1")
130
+ result = evaluator.evaluate_pn(pns)
131
+ expect(result).to eq ElectrValue.number(100.0)
61
132
 
133
+ end
134
+
135
+ it "can add two variables" do
136
+ evaluator = Evaluator.new
137
+
138
+ pns = Compiler.compile_to_pn("R1 = 100")
139
+ evaluator.evaluate_pn(pns)
140
+
141
+ pns = Compiler.compile_to_pn("R2 = 200")
142
+ evaluator.evaluate_pn(pns)
143
+
144
+ pns = Compiler.compile_to_pn("R1 + R2")
145
+ result = evaluator.evaluate_pn(pns)
146
+ expect(result).to eq ElectrValue.number(300.0)
147
+ end
148
+
149
+ it "can add a variable and a numeric" do
150
+ evaluator = Evaluator.new
151
+
152
+ pns = Compiler.compile_to_pn("R1 = 100")
153
+ evaluator.evaluate_pn(pns)
154
+
155
+ pns = Compiler.compile_to_pn("R1 + 50")
156
+ result = evaluator.evaluate_pn(pns)
157
+ expect(result).to eq ElectrValue.number(150.0)
158
+ end
159
+
160
+ it "can add a numeric and a variable" do
161
+ evaluator = Evaluator.new
162
+
163
+ pns = Compiler.compile_to_pn("R1 = 100")
164
+ evaluator.evaluate_pn(pns)
165
+
166
+ pns = Compiler.compile_to_pn("50 + R1")
167
+ result = evaluator.evaluate_pn(pns)
168
+ expect(result).to eq ElectrValue.number(150.0)
169
+ end
170
+ end
62
171
 
63
172
  end
@@ -6,12 +6,52 @@ describe Printer do
6
6
 
7
7
  describe ".run" do
8
8
 
9
+ it 'accepts ElectrValue objects' do
10
+ expect {
11
+
12
+ Printer.run(ElectrValue.number(10.0))
13
+
14
+ }.not_to raise_error
15
+ end
16
+
17
+ it 'accepts only ElectrValue objects' do
18
+ expect {
19
+
20
+ Printer.run(10.0)
21
+
22
+ }.to raise_error
23
+ end
24
+
9
25
  it 'truncates integer like number' do
10
- expect { Printer.run(10.0) }.to output("10\n").to_stdout
26
+ expect {
27
+
28
+ Printer.run(ElectrValue.number(10.0))
29
+
30
+ }.to output("10\n").to_stdout
11
31
  end
12
32
 
13
33
  it 'rounds number' do
14
- expect { Printer.run(1.0 / 3) }.to output("0.3333333333\n").to_stdout
34
+ expect {
35
+
36
+ Printer.run(ElectrValue.number(1.0 / 3))
37
+
38
+ }.to output("0.3333333333\n").to_stdout
39
+ end
40
+
41
+ it 'display the error message if any' do
42
+ expect {
43
+
44
+ Printer.run(ElectrValue.error("foo"))
45
+
46
+ }.to output("foo\n").to_stdout
47
+ end
48
+
49
+ it "doesn't display a hidden value" do
50
+ expect {
51
+
52
+ Printer.run(ElectrValue.hidden(10))
53
+
54
+ }.to_not output.to_stdout
15
55
  end
16
56
 
17
57
  end
@@ -24,7 +24,7 @@ describe Repl do
24
24
 
25
25
  it 'runs the toolchain' do
26
26
  repl = Repl.new(TestReader.new, Evaluator.new, TestPrinter)
27
- expect(repl.run_once).to eq 3
27
+ expect(repl.run_once).to eq ElectrValue.number(3)
28
28
  end
29
29
 
30
30
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: electr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - lkdjiin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-28 00:00:00.000000000 Z
11
+ date: 2015-11-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -84,9 +84,6 @@ files:
84
84
  - README.md
85
85
  - Rakefile
86
86
  - bin/electr
87
- - documentation/developer.md
88
- - documentation/grammar.md
89
- - documentation/precedence.md
90
87
  - electr.gemspec
91
88
  - lib/electr.rb
92
89
  - lib/electr/ast.rb
@@ -99,6 +96,7 @@ files:
99
96
  - lib/electr/ast/operator_ast.rb
100
97
  - lib/electr/ast/root_ast.rb
101
98
  - lib/electr/ast/value_ast.rb
99
+ - lib/electr/ast/variable_ast.rb
102
100
  - lib/electr/compiler.rb
103
101
  - lib/electr/exceptions.rb
104
102
  - lib/electr/option.rb
@@ -118,6 +116,7 @@ files:
118
116
  - lib/electr/repl/ast_printer.rb
119
117
  - lib/electr/repl/ast_reader.rb
120
118
  - lib/electr/repl/base_reader.rb
119
+ - lib/electr/repl/electr_value.rb
121
120
  - lib/electr/repl/eval_function.rb
122
121
  - lib/electr/repl/evaluator.rb
123
122
  - lib/electr/repl/nil_evaluator.rb
@@ -136,6 +135,7 @@ files:
136
135
  - spec/parser/value_spec.rb
137
136
  - spec/repl/ast_printer_spec.rb
138
137
  - spec/repl/ast_reader_spec.rb
138
+ - spec/repl/electr_value_spec.rb
139
139
  - spec/repl/evaluator_spec.rb
140
140
  - spec/repl/nil_evaluator_spec.rb
141
141
  - spec/repl/printer_spec.rb
@@ -165,7 +165,7 @@ rubyforge_project:
165
165
  rubygems_version: 2.4.5
166
166
  signing_key:
167
167
  specification_version: 4
168
- summary: Interactive language for electronic formulas
168
+ summary: Interactive tiny language for electronic formulas
169
169
  test_files:
170
170
  - spec/ast/ast_spec.rb
171
171
  - spec/compiler_spec.rb
@@ -178,6 +178,7 @@ test_files:
178
178
  - spec/parser/value_spec.rb
179
179
  - spec/repl/ast_printer_spec.rb
180
180
  - spec/repl/ast_reader_spec.rb
181
+ - spec/repl/electr_value_spec.rb
181
182
  - spec/repl/evaluator_spec.rb
182
183
  - spec/repl/nil_evaluator_spec.rb
183
184
  - spec/repl/printer_spec.rb
@@ -1,21 +0,0 @@
1
- The parsing process
2
- ===================
3
-
4
- The aim of the parsing process it to transform a source code into an AST.
5
-
6
- AST: [Abstract Syntax Tree][AST]
7
-
8
- SYA: [Shunting Yard Algorithm][SYA]
9
-
10
- PN: [Prefix Notation][PN]
11
-
12
- This is the stages of the parser:
13
-
14
- 1. Tokenizer
15
- 2. Lexer
16
- 3. Syntaxer
17
- 4. AST (using SYA for formulas)
18
-
19
- [AST]: https://en.wikipedia.org/wiki/Abstract_syntax_tree
20
- [SYA]: https://en.wikipedia.org/wiki/Shunting-yard_algorithm
21
- [PN]: https://en.wikipedia.org/wiki/Polish_notation