electr 0.0.2

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.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +3 -0
  5. data/CHANGELOG.md +17 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +196 -0
  9. data/Rakefile +7 -0
  10. data/bin/electr +27 -0
  11. data/electr.gemspec +25 -0
  12. data/lib/electr.rb +20 -0
  13. data/lib/electr/ast.rb +9 -0
  14. data/lib/electr/ast/ast.rb +62 -0
  15. data/lib/electr/ast/constant_ast.rb +14 -0
  16. data/lib/electr/ast/func_args_ast.rb +11 -0
  17. data/lib/electr/ast/func_ast.rb +12 -0
  18. data/lib/electr/ast/func_name_ast.rb +14 -0
  19. data/lib/electr/ast/numeric_ast.rb +13 -0
  20. data/lib/electr/ast/operator_ast.rb +13 -0
  21. data/lib/electr/ast/root_ast.rb +11 -0
  22. data/lib/electr/ast/value_ast.rb +12 -0
  23. data/lib/electr/compiler.rb +24 -0
  24. data/lib/electr/evaluator.rb +64 -0
  25. data/lib/electr/exceptions.rb +6 -0
  26. data/lib/electr/option.rb +70 -0
  27. data/lib/electr/parser.rb +5 -0
  28. data/lib/electr/parser/lexer.rb +50 -0
  29. data/lib/electr/parser/lexical_unit.rb +67 -0
  30. data/lib/electr/parser/rules/base_rule.rb +60 -0
  31. data/lib/electr/parser/rules/expression_rule.rb +79 -0
  32. data/lib/electr/parser/rules/root_rule.rb +21 -0
  33. data/lib/electr/parser/sya.rb +105 -0
  34. data/lib/electr/parser/syntaxer.rb +21 -0
  35. data/lib/electr/parser/tokenizer.rb +79 -0
  36. data/lib/electr/repl.rb +56 -0
  37. data/lib/electr/rules.rb +3 -0
  38. data/lib/electr/version.rb +3 -0
  39. data/spec/compiler_spec.rb +42 -0
  40. data/spec/electr_spec.rb +7 -0
  41. data/spec/evaluator_spec.rb +47 -0
  42. data/spec/lexer_spec.rb +29 -0
  43. data/spec/spec_helper.rb +8 -0
  44. data/spec/sya_spec.rb +153 -0
  45. data/spec/tokenizer_spec.rb +102 -0
  46. metadata +138 -0
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ include Electr
4
+
5
+ describe Lexer do
6
+ before { @lexer = Lexer.new }
7
+
8
+ TOKENS = [
9
+ [ :numeric, "123" ],
10
+ [ :numeric, "0.6" ],
11
+ [ :operator, "+" ],
12
+ [ :constant, "pi" ],
13
+ [ :value, "11K" ],
14
+ [ :value, "11kΩ" ],
15
+ [ :name, "foobar" ],
16
+ [ :fname, "sqrt" ],
17
+ [ :open_parenthesis, "(" ],
18
+ [ :closed_parenthesis, ")" ],
19
+ ]
20
+
21
+ it "lexify" do
22
+ TOKENS.each do |token|
23
+ lexeme = @lexer.lexify(token.last)
24
+ expect(lexeme.type).to eq token.first
25
+ expect(lexeme.value).to eq token.last
26
+ end
27
+ end
28
+
29
+ end
@@ -0,0 +1,8 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'electr'
3
+
4
+ RSpec.configure do |config|
5
+ if config.files_to_run.one?
6
+ config.default_formatter = 'documentation'
7
+ end
8
+ end
@@ -0,0 +1,153 @@
1
+ require 'spec_helper'
2
+
3
+ include Electr
4
+
5
+ describe Sya do
6
+
7
+ specify '2 + 3' do
8
+ a = LexicalUnit.numeric('2')
9
+ b = LexicalUnit.operator('+')
10
+ c = LexicalUnit.numeric('3')
11
+ sya = Sya.new([a, b, c])
12
+
13
+ expect(sya.run).to eq [b, a, c]
14
+ end
15
+
16
+ specify '2 3 + 4' do
17
+ a = LexicalUnit.numeric('2')
18
+ b = LexicalUnit.numeric('3')
19
+ c = LexicalUnit.operator('+')
20
+ d = LexicalUnit.numeric('4')
21
+ added = LexicalUnit.operator('*')
22
+ sya = Sya.new([a, b, c, d])
23
+
24
+ # + * 2 3 4
25
+ expect(sya.run).to eq [c, added, a, b, d]
26
+ end
27
+
28
+ specify '2 + 3 4' do
29
+ a = LexicalUnit.numeric('2')
30
+ b = LexicalUnit.operator('+')
31
+ c = LexicalUnit.numeric('3')
32
+ d = LexicalUnit.numeric('4')
33
+ added = LexicalUnit.operator('*')
34
+ sya = Sya.new([a, b, c, d])
35
+
36
+ # + 2 * 3 4
37
+ expect(sya.run).to eq [b, a, added, c, d]
38
+ end
39
+
40
+ specify '2 pi' do
41
+ a = LexicalUnit.numeric('2')
42
+ b = LexicalUnit.constant('pi')
43
+ added = LexicalUnit.operator('*')
44
+ sya = Sya.new([a, b])
45
+
46
+ # * 2 pi
47
+ expect(sya.run).to eq [added, a, b]
48
+ end
49
+
50
+ specify '2 11K' do
51
+ a = LexicalUnit.numeric('2')
52
+ b = LexicalUnit.constant('11K')
53
+ added = LexicalUnit.operator('*')
54
+ sya = Sya.new([a, b])
55
+
56
+ # * 2 11K
57
+ expect(sya.run).to eq [added, a, b]
58
+ end
59
+
60
+ specify 'sqrt(49) + 1' do
61
+ a = LexicalUnit.fname('sqrt')
62
+ b = LexicalUnit.open_parenthesis
63
+ c = LexicalUnit.numeric('49')
64
+ d = LexicalUnit.closed_parenthesis
65
+ e = LexicalUnit.operator('+')
66
+ f = LexicalUnit.numeric('1')
67
+ sya = Sya.new([a, b, c, d, e, f])
68
+
69
+ # + sqrt 49 1
70
+ expect(sya.run).to eq [e, a, c, f]
71
+ end
72
+
73
+ specify '1 + sqrt(7)' do
74
+ a = LexicalUnit.numeric('1')
75
+ b = LexicalUnit.operator('+')
76
+ c = LexicalUnit.fname('sqrt')
77
+ d = LexicalUnit.open_parenthesis
78
+ e = LexicalUnit.numeric('7')
79
+ f = LexicalUnit.closed_parenthesis
80
+ sya = Sya.new([a, b, c, d, e, f])
81
+
82
+ # + 1 sqrt 7
83
+ expect(sya.run).to eq [b, a, c, e]
84
+ end
85
+
86
+ specify '3 / 2 + 1' do
87
+ a = LexicalUnit.numeric('3')
88
+ b = LexicalUnit.operator('/')
89
+ c = LexicalUnit.numeric('2')
90
+ d = LexicalUnit.operator('+')
91
+ e = LexicalUnit.numeric('1')
92
+ sya = Sya.new([a, b, c, d, e])
93
+
94
+ # + / 3 2 1
95
+ expect(sya.run).to eq [d, b, a, c, e]
96
+ end
97
+
98
+ specify '2 - 3 + 5' do
99
+ a = LexicalUnit.numeric('2')
100
+ b = LexicalUnit.operator('-')
101
+ c = LexicalUnit.numeric('3')
102
+ d = LexicalUnit.operator('+')
103
+ e = LexicalUnit.numeric('5')
104
+ sya = Sya.new([a, b, c, d, e])
105
+
106
+ # + - 2 3 5
107
+ expect(sya.run).to eq [d, b, a, c, e]
108
+ end
109
+
110
+ specify '1 - 1 + 4 - 1 - 1' do
111
+ a = LexicalUnit.numeric('1')
112
+ b = LexicalUnit.operator('-')
113
+ c = LexicalUnit.numeric('1')
114
+ d = LexicalUnit.operator('+')
115
+ e = LexicalUnit.numeric('4')
116
+ f = LexicalUnit.operator('-')
117
+ g = LexicalUnit.numeric('1')
118
+ h = LexicalUnit.operator('-')
119
+ i = LexicalUnit.numeric('1')
120
+ sya = Sya.new([a, b, c, d, e, f, g, h, i])
121
+
122
+ # - - + - 1 1 4 1 1
123
+ expect(sya.run).to eq [b, b, d, b, a, c, e, g, i]
124
+ end
125
+
126
+ specify '3 / (2 + 1)' do
127
+ a = LexicalUnit.numeric('3')
128
+ b = LexicalUnit.operator('/')
129
+ c = LexicalUnit.open_parenthesis
130
+ d = LexicalUnit.numeric('2')
131
+ e = LexicalUnit.operator('+')
132
+ f = LexicalUnit.numeric('1')
133
+ g = LexicalUnit.closed_parenthesis
134
+ sya = Sya.new([a, b, c, d, e, f, g])
135
+
136
+ # / 3 + 2 1
137
+ expect(sya.run).to eq [b, a, e, d, f]
138
+ end
139
+
140
+ specify 'sqrt(40 + 9)' do
141
+ a = LexicalUnit.fname('sqrt')
142
+ b = LexicalUnit.open_parenthesis
143
+ c = LexicalUnit.numeric('40')
144
+ d = LexicalUnit.operator('+')
145
+ e = LexicalUnit.numeric('9')
146
+ f = LexicalUnit.closed_parenthesis
147
+ sya = Sya.new([a, b, c, d, e, f])
148
+
149
+ # sqrt + 40 9
150
+ expect(sya.run).to eq [a, d, c, e]
151
+ end
152
+
153
+ end
@@ -0,0 +1,102 @@
1
+ require 'spec_helper'
2
+
3
+ include Electr
4
+
5
+ describe Tokenizer do
6
+
7
+ describe "#has_more_token?" do
8
+ it "returns true when a token is available" do
9
+ tkr = Tokenizer.new("2 3")
10
+ expect(tkr.has_more_token?).to eq true
11
+ tkr.next_token
12
+ expect(tkr.has_more_token?).to eq true
13
+ end
14
+
15
+ it "returns false when no more tokens are available" do
16
+ tkr = Tokenizer.new("0")
17
+ tkr.next_token
18
+ expect(tkr.has_more_token?).to eq false
19
+ end
20
+ end
21
+
22
+ specify "21 300" do
23
+ tkr = Tokenizer.new("21 300")
24
+ expect(tkr.next_token).to eq "21"
25
+ expect(tkr.next_token).to eq "300"
26
+ end
27
+
28
+ specify "2 0.6" do
29
+ tkr = Tokenizer.new("2 0.6")
30
+ expect(tkr.next_token).to eq "2"
31
+ expect(tkr.next_token).to eq "0.6"
32
+ end
33
+
34
+ specify "2 0.6 3" do
35
+ tkr = Tokenizer.new("2 0.6 3")
36
+ expect(tkr.next_token).to eq "2"
37
+ expect(tkr.next_token).to eq "0.6"
38
+ expect(tkr.next_token).to eq "3"
39
+ end
40
+
41
+ specify "2 + 3" do
42
+ tkr = Tokenizer.new("2 + 3")
43
+ expect(tkr.next_token).to eq "2"
44
+ expect(tkr.next_token).to eq "+"
45
+ expect(tkr.next_token).to eq "3"
46
+ end
47
+
48
+ specify "2 pi" do
49
+ tkr = Tokenizer.new("2 pi")
50
+ expect(tkr.next_token).to eq "2"
51
+ expect(tkr.next_token).to eq "pi"
52
+ end
53
+
54
+ specify "11K 22k 33kΩ" do
55
+ tkr = Tokenizer.new("11K 22k 33kΩ")
56
+ expect(tkr.next_token).to eq "11K"
57
+ expect(tkr.next_token).to eq "22k"
58
+ expect(tkr.next_token).to eq "33kΩ"
59
+ end
60
+
61
+ specify "100R 200Ω" do
62
+ tkr = Tokenizer.new("100R 200Ω")
63
+ expect(tkr.next_token).to eq "100R"
64
+ expect(tkr.next_token).to eq "200Ω"
65
+ end
66
+
67
+ specify "10uF 100u 470μF 1000μ 10pF 100p" do
68
+ tkr = Tokenizer.new("10uF 100u 470μF 1000μ 10pF 100p")
69
+ expect(tkr.next_token).to eq "10uF"
70
+ expect(tkr.next_token).to eq "100u"
71
+ expect(tkr.next_token).to eq "470μF"
72
+ expect(tkr.next_token).to eq "1000μ"
73
+ expect(tkr.next_token).to eq "10pF"
74
+ expect(tkr.next_token).to eq "100p"
75
+ end
76
+
77
+ specify "sqrt(11k 22k)" do
78
+ tkr = Tokenizer.new("sqrt(11k 22k)")
79
+ expect(tkr.next_token).to eq "sqrt"
80
+ expect(tkr.next_token).to eq "("
81
+ expect(tkr.next_token).to eq "11k"
82
+ expect(tkr.next_token).to eq "22k"
83
+ expect(tkr.next_token).to eq ")"
84
+ end
85
+
86
+ specify "1 / (2 pi 0.5uF sqrt(11K 22K))" do
87
+ tkr = Tokenizer.new("1 / (2 pi 0.5uF sqrt(11K 22K))")
88
+ expect(tkr.next_token).to eq "1"
89
+ expect(tkr.next_token).to eq "/"
90
+ expect(tkr.next_token).to eq "("
91
+ expect(tkr.next_token).to eq "2"
92
+ expect(tkr.next_token).to eq "pi"
93
+ expect(tkr.next_token).to eq "0.5uF"
94
+ expect(tkr.next_token).to eq "sqrt"
95
+ expect(tkr.next_token).to eq "("
96
+ expect(tkr.next_token).to eq "11K"
97
+ expect(tkr.next_token).to eq "22K"
98
+ expect(tkr.next_token).to eq ")"
99
+ expect(tkr.next_token).to eq ")"
100
+ end
101
+
102
+ end
metadata ADDED
@@ -0,0 +1,138 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: electr
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - lkdjiin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-09-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description:
56
+ email:
57
+ - xavier.nayrac@gmail.com
58
+ executables:
59
+ - electr
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - ".gitignore"
64
+ - ".rspec"
65
+ - ".travis.yml"
66
+ - CHANGELOG.md
67
+ - Gemfile
68
+ - LICENSE.txt
69
+ - README.md
70
+ - Rakefile
71
+ - bin/electr
72
+ - electr.gemspec
73
+ - lib/electr.rb
74
+ - lib/electr/ast.rb
75
+ - lib/electr/ast/ast.rb
76
+ - lib/electr/ast/constant_ast.rb
77
+ - lib/electr/ast/func_args_ast.rb
78
+ - lib/electr/ast/func_ast.rb
79
+ - lib/electr/ast/func_name_ast.rb
80
+ - lib/electr/ast/numeric_ast.rb
81
+ - lib/electr/ast/operator_ast.rb
82
+ - lib/electr/ast/root_ast.rb
83
+ - lib/electr/ast/value_ast.rb
84
+ - lib/electr/compiler.rb
85
+ - lib/electr/evaluator.rb
86
+ - lib/electr/exceptions.rb
87
+ - lib/electr/option.rb
88
+ - lib/electr/parser.rb
89
+ - lib/electr/parser/lexer.rb
90
+ - lib/electr/parser/lexical_unit.rb
91
+ - lib/electr/parser/rules/base_rule.rb
92
+ - lib/electr/parser/rules/expression_rule.rb
93
+ - lib/electr/parser/rules/root_rule.rb
94
+ - lib/electr/parser/sya.rb
95
+ - lib/electr/parser/syntaxer.rb
96
+ - lib/electr/parser/tokenizer.rb
97
+ - lib/electr/repl.rb
98
+ - lib/electr/rules.rb
99
+ - lib/electr/version.rb
100
+ - spec/compiler_spec.rb
101
+ - spec/electr_spec.rb
102
+ - spec/evaluator_spec.rb
103
+ - spec/lexer_spec.rb
104
+ - spec/spec_helper.rb
105
+ - spec/sya_spec.rb
106
+ - spec/tokenizer_spec.rb
107
+ homepage: https://github.com/lkdjiin/electr
108
+ licenses:
109
+ - MIT
110
+ metadata: {}
111
+ post_install_message:
112
+ rdoc_options: []
113
+ require_paths:
114
+ - lib
115
+ required_ruby_version: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: '2.2'
120
+ required_rubygems_version: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ requirements: []
126
+ rubyforge_project:
127
+ rubygems_version: 2.4.5
128
+ signing_key:
129
+ specification_version: 4
130
+ summary: Interactive language for electronic formulas
131
+ test_files:
132
+ - spec/compiler_spec.rb
133
+ - spec/electr_spec.rb
134
+ - spec/evaluator_spec.rb
135
+ - spec/lexer_spec.rb
136
+ - spec/spec_helper.rb
137
+ - spec/sya_spec.rb
138
+ - spec/tokenizer_spec.rb