keisan 0.3.0 → 0.4.0
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/README.md +57 -9
- data/lib/keisan.rb +21 -12
- data/lib/keisan/ast.rb +50 -0
- data/lib/keisan/ast/arithmetic_operator.rb +0 -3
- data/lib/keisan/ast/assignment.rb +72 -0
- data/lib/keisan/ast/bitwise_and.rb +4 -4
- data/lib/keisan/ast/bitwise_operator.rb +0 -3
- data/lib/keisan/ast/bitwise_or.rb +4 -4
- data/lib/keisan/ast/bitwise_xor.rb +4 -4
- data/lib/keisan/ast/boolean.rb +25 -1
- data/lib/keisan/ast/builder.rb +98 -63
- data/lib/keisan/ast/constant_literal.rb +13 -0
- data/lib/keisan/ast/exponent.rb +62 -8
- data/lib/keisan/ast/function.rb +37 -26
- data/lib/keisan/ast/functions/diff.rb +57 -0
- data/lib/keisan/ast/functions/if.rb +47 -0
- data/lib/keisan/ast/indexing.rb +44 -4
- data/lib/keisan/ast/list.rb +4 -0
- data/lib/keisan/ast/literal.rb +8 -0
- data/lib/keisan/ast/logical_and.rb +9 -4
- data/lib/keisan/ast/logical_equal.rb +4 -4
- data/lib/keisan/ast/logical_greater_than.rb +4 -4
- data/lib/keisan/ast/logical_greater_than_or_equal_to.rb +4 -4
- data/lib/keisan/ast/logical_less_than.rb +4 -4
- data/lib/keisan/ast/logical_less_than_or_equal_to.rb +4 -4
- data/lib/keisan/ast/logical_not_equal.rb +4 -4
- data/lib/keisan/ast/logical_operator.rb +0 -3
- data/lib/keisan/ast/logical_or.rb +10 -5
- data/lib/keisan/ast/modulo.rb +4 -4
- data/lib/keisan/ast/node.rb +132 -20
- data/lib/keisan/ast/null.rb +1 -1
- data/lib/keisan/ast/number.rb +172 -1
- data/lib/keisan/ast/operator.rb +66 -8
- data/lib/keisan/ast/parent.rb +50 -0
- data/lib/keisan/ast/plus.rb +38 -4
- data/lib/keisan/ast/string.rb +10 -1
- data/lib/keisan/ast/times.rb +47 -4
- data/lib/keisan/ast/unary_bitwise_not.rb +9 -1
- data/lib/keisan/ast/unary_identity.rb +18 -1
- data/lib/keisan/ast/unary_inverse.rb +35 -1
- data/lib/keisan/ast/unary_logical_not.rb +5 -1
- data/lib/keisan/ast/unary_minus.rb +31 -1
- data/lib/keisan/ast/unary_operator.rb +29 -1
- data/lib/keisan/ast/unary_plus.rb +14 -1
- data/lib/keisan/ast/variable.rb +44 -0
- data/lib/keisan/calculator.rb +2 -2
- data/lib/keisan/context.rb +32 -16
- data/lib/keisan/evaluator.rb +10 -65
- data/lib/keisan/exceptions.rb +2 -0
- data/lib/keisan/function.rb +11 -5
- data/lib/keisan/function_definition_context.rb +34 -0
- data/lib/keisan/functions/default_registry.rb +13 -5
- data/lib/keisan/functions/diff.rb +82 -0
- data/lib/keisan/functions/expression_function.rb +63 -0
- data/lib/keisan/functions/if.rb +62 -0
- data/lib/keisan/functions/proc_function.rb +52 -0
- data/lib/keisan/functions/rand.rb +1 -1
- data/lib/keisan/functions/registry.rb +20 -10
- data/lib/keisan/functions/replace.rb +49 -0
- data/lib/keisan/functions/sample.rb +1 -1
- data/lib/keisan/parser.rb +13 -1
- data/lib/keisan/parsing/assignment.rb +9 -0
- data/lib/keisan/parsing/operator.rb +8 -0
- data/lib/keisan/parsing/unary_operator.rb +1 -1
- data/lib/keisan/tokenizer.rb +1 -0
- data/lib/keisan/tokens/assignment.rb +15 -0
- data/lib/keisan/variables/default_registry.rb +4 -4
- data/lib/keisan/variables/registry.rb +17 -8
- data/lib/keisan/version.rb +1 -1
- metadata +15 -3
- data/lib/keisan/ast/priorities.rb +0 -27
data/lib/keisan/parser.rb
CHANGED
@@ -17,6 +17,7 @@ module Keisan
|
|
17
17
|
@components = []
|
18
18
|
|
19
19
|
parse_components!
|
20
|
+
remove_unary_identity!
|
20
21
|
end
|
21
22
|
|
22
23
|
def ast
|
@@ -36,6 +37,12 @@ module Keisan
|
|
36
37
|
end
|
37
38
|
end
|
38
39
|
|
40
|
+
def remove_unary_identity!
|
41
|
+
@components = @components.select do |component|
|
42
|
+
!component.is_a?(Keisan::Parsing::Operator) || !(component.node_class <= Keisan::AST::UnaryIdentity)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
39
46
|
# Elements are groups of tokens separated by (non-unary) operators
|
40
47
|
# The following are basic elements:
|
41
48
|
# number
|
@@ -58,8 +65,10 @@ module Keisan
|
|
58
65
|
end
|
59
66
|
|
60
67
|
elsif @components[-1].is_a?(Parsing::UnaryOperator)
|
61
|
-
# Expect an element
|
68
|
+
# Expect an element or another unary operator
|
62
69
|
case token.type
|
70
|
+
when :operator
|
71
|
+
add_unary_operator_to_components!(token)
|
63
72
|
when :number, :string, :word, :group, :null, :boolean
|
64
73
|
add_element_to_components!(token)
|
65
74
|
else
|
@@ -154,6 +163,9 @@ module Keisan
|
|
154
163
|
|
155
164
|
def add_operator_to_components!(token)
|
156
165
|
case token.operator_type
|
166
|
+
# Assignment
|
167
|
+
when :"="
|
168
|
+
@components << Keisan::Parsing::Assignment.new
|
157
169
|
# Arithmetic
|
158
170
|
when :+
|
159
171
|
@components << Keisan::Parsing::Plus.new
|
@@ -1,10 +1,18 @@
|
|
1
1
|
module Keisan
|
2
2
|
module Parsing
|
3
3
|
class Operator < Component
|
4
|
+
def arity
|
5
|
+
node_class.arity
|
6
|
+
end
|
7
|
+
|
4
8
|
def priority
|
5
9
|
node_class.priority
|
6
10
|
end
|
7
11
|
|
12
|
+
def associativity
|
13
|
+
node_class.associativity
|
14
|
+
end
|
15
|
+
|
8
16
|
def node_class
|
9
17
|
raise Keisan::Exceptions::NotImplementedError.new
|
10
18
|
end
|
data/lib/keisan/tokenizer.rb
CHANGED
@@ -7,13 +7,13 @@ module Keisan
|
|
7
7
|
end
|
8
8
|
|
9
9
|
VARIABLES = {
|
10
|
-
"
|
11
|
-
"
|
12
|
-
"
|
10
|
+
"PI" => Math::PI,
|
11
|
+
"E" => Math::E,
|
12
|
+
"I" => Complex(0,1)
|
13
13
|
}
|
14
14
|
|
15
15
|
def self.registry
|
16
|
-
@registry ||= Registry.new(variables: VARIABLES, parent: nil).freeze
|
16
|
+
@registry ||= Registry.new(variables: VARIABLES, parent: nil, force: true).freeze
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
@@ -1,19 +1,23 @@
|
|
1
1
|
module Keisan
|
2
2
|
module Variables
|
3
3
|
class Registry
|
4
|
-
def initialize(variables: {}, parent: nil, use_defaults: true)
|
4
|
+
def initialize(variables: {}, parent: nil, use_defaults: true, force: false)
|
5
5
|
@hash = {}
|
6
6
|
@parent = parent
|
7
7
|
@use_defaults = use_defaults
|
8
8
|
|
9
9
|
variables.each do |name, value|
|
10
|
-
register!(name, value)
|
10
|
+
register!(name, value, force: force)
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
14
|
def [](name)
|
15
15
|
return @hash[name] if @hash.has_key?(name)
|
16
|
-
|
16
|
+
|
17
|
+
if @parent && (parent_value = @parent[name])
|
18
|
+
return parent_value
|
19
|
+
end
|
20
|
+
|
17
21
|
return default_registry[name] if @use_defaults && default_registry.has_name?(name)
|
18
22
|
raise Keisan::Exceptions::UndefinedVariableError.new name
|
19
23
|
end
|
@@ -24,16 +28,21 @@ module Keisan
|
|
24
28
|
false
|
25
29
|
end
|
26
30
|
|
31
|
+
def register!(name, value, force: false)
|
32
|
+
raise Keisan::Exceptions::UnmodifiableError.new("Cannot modify frozen variables registry") if frozen?
|
33
|
+
if !force && @use_defaults && default_registry.has_name?(name)
|
34
|
+
raise Keisan::Exceptions::UnmodifiableError.new("Cannot overwrite default variable")
|
35
|
+
end
|
36
|
+
self[name.to_s] = value
|
37
|
+
end
|
38
|
+
|
39
|
+
protected
|
40
|
+
|
27
41
|
# For checking if locally defined
|
28
42
|
def has_name?(name)
|
29
43
|
@hash.has_key?(name)
|
30
44
|
end
|
31
45
|
|
32
|
-
def register!(name, value)
|
33
|
-
raise Keisan::Exceptions::UnmodifiableError.new("Cannot modify frozen variables registry") if frozen?
|
34
|
-
self[name.to_s] = value
|
35
|
-
end
|
36
|
-
|
37
46
|
private
|
38
47
|
|
39
48
|
def []=(name, value)
|
data/lib/keisan/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: keisan
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Christopher Locke
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-04-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -112,15 +112,20 @@ files:
|
|
112
112
|
- bin/setup
|
113
113
|
- keisan.gemspec
|
114
114
|
- lib/keisan.rb
|
115
|
+
- lib/keisan/ast.rb
|
115
116
|
- lib/keisan/ast/arithmetic_operator.rb
|
117
|
+
- lib/keisan/ast/assignment.rb
|
116
118
|
- lib/keisan/ast/bitwise_and.rb
|
117
119
|
- lib/keisan/ast/bitwise_operator.rb
|
118
120
|
- lib/keisan/ast/bitwise_or.rb
|
119
121
|
- lib/keisan/ast/bitwise_xor.rb
|
120
122
|
- lib/keisan/ast/boolean.rb
|
121
123
|
- lib/keisan/ast/builder.rb
|
124
|
+
- lib/keisan/ast/constant_literal.rb
|
122
125
|
- lib/keisan/ast/exponent.rb
|
123
126
|
- lib/keisan/ast/function.rb
|
127
|
+
- lib/keisan/ast/functions/diff.rb
|
128
|
+
- lib/keisan/ast/functions/if.rb
|
124
129
|
- lib/keisan/ast/indexing.rb
|
125
130
|
- lib/keisan/ast/list.rb
|
126
131
|
- lib/keisan/ast/literal.rb
|
@@ -140,7 +145,6 @@ files:
|
|
140
145
|
- lib/keisan/ast/operator.rb
|
141
146
|
- lib/keisan/ast/parent.rb
|
142
147
|
- lib/keisan/ast/plus.rb
|
143
|
-
- lib/keisan/ast/priorities.rb
|
144
148
|
- lib/keisan/ast/string.rb
|
145
149
|
- lib/keisan/ast/times.rb
|
146
150
|
- lib/keisan/ast/unary_bitwise_not.rb
|
@@ -156,13 +160,20 @@ files:
|
|
156
160
|
- lib/keisan/evaluator.rb
|
157
161
|
- lib/keisan/exceptions.rb
|
158
162
|
- lib/keisan/function.rb
|
163
|
+
- lib/keisan/function_definition_context.rb
|
159
164
|
- lib/keisan/functions/default_registry.rb
|
165
|
+
- lib/keisan/functions/diff.rb
|
166
|
+
- lib/keisan/functions/expression_function.rb
|
167
|
+
- lib/keisan/functions/if.rb
|
168
|
+
- lib/keisan/functions/proc_function.rb
|
160
169
|
- lib/keisan/functions/rand.rb
|
161
170
|
- lib/keisan/functions/registry.rb
|
171
|
+
- lib/keisan/functions/replace.rb
|
162
172
|
- lib/keisan/functions/sample.rb
|
163
173
|
- lib/keisan/parser.rb
|
164
174
|
- lib/keisan/parsing/argument.rb
|
165
175
|
- lib/keisan/parsing/arithmetic_operator.rb
|
176
|
+
- lib/keisan/parsing/assignment.rb
|
166
177
|
- lib/keisan/parsing/bitwise_and.rb
|
167
178
|
- lib/keisan/parsing/bitwise_not.rb
|
168
179
|
- lib/keisan/parsing/bitwise_not_not.rb
|
@@ -209,6 +220,7 @@ files:
|
|
209
220
|
- lib/keisan/token.rb
|
210
221
|
- lib/keisan/tokenizer.rb
|
211
222
|
- lib/keisan/tokens/arithmetic_operator.rb
|
223
|
+
- lib/keisan/tokens/assignment.rb
|
212
224
|
- lib/keisan/tokens/bitwise_operator.rb
|
213
225
|
- lib/keisan/tokens/boolean.rb
|
214
226
|
- lib/keisan/tokens/comma.rb
|
@@ -1,27 +0,0 @@
|
|
1
|
-
module Keisan
|
2
|
-
module AST
|
3
|
-
class Priorities
|
4
|
-
PRIORITIES = {
|
5
|
-
"**": 100,
|
6
|
-
"*": 95,
|
7
|
-
"%": 90,
|
8
|
-
"+": 85,
|
9
|
-
"&": 80,
|
10
|
-
"|": 75,
|
11
|
-
"^": 70,
|
12
|
-
">": 65,
|
13
|
-
">=": 60,
|
14
|
-
"<": 55,
|
15
|
-
"<=": 50,
|
16
|
-
"==": 45,
|
17
|
-
"!=": 40,
|
18
|
-
"&&": 35,
|
19
|
-
"||": 30
|
20
|
-
}.freeze
|
21
|
-
|
22
|
-
def self.priorities
|
23
|
-
PRIORITIES
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|