keisan 0.5.0 → 0.6.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.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +49 -1
  3. data/keisan.gemspec +1 -0
  4. data/lib/keisan.rb +30 -0
  5. data/lib/keisan/ast/assignment.rb +44 -17
  6. data/lib/keisan/ast/block.rb +60 -0
  7. data/lib/keisan/ast/boolean.rb +5 -5
  8. data/lib/keisan/ast/builder.rb +10 -207
  9. data/lib/keisan/ast/cell.rb +60 -0
  10. data/lib/keisan/ast/constant_literal.rb +9 -0
  11. data/lib/keisan/ast/exponent.rb +6 -6
  12. data/lib/keisan/ast/function.rb +12 -8
  13. data/lib/keisan/ast/indexing.rb +25 -15
  14. data/lib/keisan/ast/line_builder.rb +230 -0
  15. data/lib/keisan/ast/list.rb +28 -1
  16. data/lib/keisan/ast/literal.rb +0 -8
  17. data/lib/keisan/ast/logical_and.rb +1 -1
  18. data/lib/keisan/ast/logical_or.rb +1 -1
  19. data/lib/keisan/ast/multi_line.rb +28 -0
  20. data/lib/keisan/ast/node.rb +32 -24
  21. data/lib/keisan/ast/number.rb +31 -31
  22. data/lib/keisan/ast/operator.rb +12 -4
  23. data/lib/keisan/ast/parent.rb +4 -4
  24. data/lib/keisan/ast/plus.rb +10 -10
  25. data/lib/keisan/ast/string.rb +3 -3
  26. data/lib/keisan/ast/times.rb +8 -8
  27. data/lib/keisan/ast/unary_identity.rb +1 -1
  28. data/lib/keisan/ast/unary_inverse.rb +7 -7
  29. data/lib/keisan/ast/unary_minus.rb +5 -5
  30. data/lib/keisan/ast/unary_operator.rb +2 -2
  31. data/lib/keisan/ast/unary_plus.rb +2 -2
  32. data/lib/keisan/ast/variable.rb +26 -10
  33. data/lib/keisan/context.rb +5 -5
  34. data/lib/keisan/evaluator.rb +15 -8
  35. data/lib/keisan/function.rb +24 -6
  36. data/lib/keisan/functions/cbrt.rb +1 -1
  37. data/lib/keisan/functions/cos.rb +1 -1
  38. data/lib/keisan/functions/cosh.rb +1 -1
  39. data/lib/keisan/functions/cot.rb +1 -1
  40. data/lib/keisan/functions/coth.rb +1 -1
  41. data/lib/keisan/functions/csc.rb +1 -1
  42. data/lib/keisan/functions/csch.rb +1 -1
  43. data/lib/keisan/functions/default_registry.rb +53 -74
  44. data/lib/keisan/functions/diff.rb +18 -14
  45. data/lib/keisan/functions/erf.rb +15 -0
  46. data/lib/keisan/functions/exp.rb +1 -1
  47. data/lib/keisan/functions/expression_function.rb +15 -21
  48. data/lib/keisan/functions/filter.rb +13 -15
  49. data/lib/keisan/functions/if.rb +14 -20
  50. data/lib/keisan/functions/let.rb +36 -0
  51. data/lib/keisan/functions/map.rb +11 -13
  52. data/lib/keisan/functions/math_function.rb +2 -2
  53. data/lib/keisan/functions/proc_function.rb +10 -6
  54. data/lib/keisan/functions/rand.rb +2 -1
  55. data/lib/keisan/functions/range.rb +74 -0
  56. data/lib/keisan/functions/reduce.rb +12 -14
  57. data/lib/keisan/functions/registry.rb +7 -7
  58. data/lib/keisan/functions/replace.rb +8 -8
  59. data/lib/keisan/functions/sample.rb +2 -1
  60. data/lib/keisan/functions/sec.rb +1 -1
  61. data/lib/keisan/functions/sech.rb +1 -1
  62. data/lib/keisan/functions/sin.rb +1 -1
  63. data/lib/keisan/functions/sinh.rb +1 -1
  64. data/lib/keisan/functions/sqrt.rb +1 -1
  65. data/lib/keisan/functions/tan.rb +1 -1
  66. data/lib/keisan/functions/tanh.rb +1 -1
  67. data/lib/keisan/functions/while.rb +46 -0
  68. data/lib/keisan/parser.rb +121 -79
  69. data/lib/keisan/parsing/assignment.rb +1 -1
  70. data/lib/keisan/parsing/bitwise_and.rb +1 -1
  71. data/lib/keisan/parsing/bitwise_not.rb +1 -1
  72. data/lib/keisan/parsing/bitwise_not_not.rb +1 -1
  73. data/lib/keisan/parsing/bitwise_or.rb +1 -1
  74. data/lib/keisan/parsing/bitwise_xor.rb +1 -1
  75. data/lib/keisan/parsing/curly_group.rb +6 -0
  76. data/lib/keisan/parsing/divide.rb +1 -1
  77. data/lib/keisan/parsing/exponent.rb +1 -1
  78. data/lib/keisan/parsing/function.rb +1 -1
  79. data/lib/keisan/parsing/group.rb +1 -1
  80. data/lib/keisan/parsing/indexing.rb +1 -1
  81. data/lib/keisan/parsing/line_separator.rb +6 -0
  82. data/lib/keisan/parsing/logical_and.rb +1 -1
  83. data/lib/keisan/parsing/logical_equal.rb +1 -1
  84. data/lib/keisan/parsing/logical_greater_than.rb +1 -1
  85. data/lib/keisan/parsing/logical_greater_than_or_equal_to.rb +1 -1
  86. data/lib/keisan/parsing/logical_less_than.rb +1 -1
  87. data/lib/keisan/parsing/logical_less_than_or_equal_to.rb +1 -1
  88. data/lib/keisan/parsing/logical_not.rb +1 -1
  89. data/lib/keisan/parsing/logical_not_equal.rb +1 -1
  90. data/lib/keisan/parsing/logical_not_not.rb +1 -1
  91. data/lib/keisan/parsing/logical_or.rb +1 -1
  92. data/lib/keisan/parsing/minus.rb +1 -1
  93. data/lib/keisan/parsing/modulo.rb +1 -1
  94. data/lib/keisan/parsing/operator.rb +1 -1
  95. data/lib/keisan/parsing/plus.rb +1 -1
  96. data/lib/keisan/parsing/times.rb +1 -1
  97. data/lib/keisan/parsing/unary_minus.rb +1 -1
  98. data/lib/keisan/parsing/unary_operator.rb +1 -1
  99. data/lib/keisan/parsing/unary_plus.rb +1 -1
  100. data/lib/keisan/repl.rb +1 -1
  101. data/lib/keisan/tokenizer.rb +4 -9
  102. data/lib/keisan/tokens/group.rb +3 -1
  103. data/lib/keisan/tokens/line_separator.rb +11 -0
  104. data/lib/keisan/variables/default_registry.rb +0 -5
  105. data/lib/keisan/variables/registry.rb +7 -7
  106. data/lib/keisan/version.rb +1 -1
  107. metadata +27 -2
@@ -1,14 +1,41 @@
1
1
  module Keisan
2
2
  module AST
3
3
  class List < Parent
4
+ def initialize(children = [])
5
+ super(children)
6
+ cellify!
7
+ end
8
+
9
+ def evaluate(context = nil)
10
+ context ||= Context.new
11
+ super(context)
12
+ cellify!
13
+ self
14
+ end
15
+
16
+ def simplify(context = nil)
17
+ context ||= Context.new
18
+ super(context)
19
+ cellify!
20
+ self
21
+ end
22
+
4
23
  def value(context = nil)
5
- context ||= Keisan::Context.new
24
+ context ||= Context.new
6
25
  children.map {|child| child.value(context)}
7
26
  end
8
27
 
9
28
  def to_s
10
29
  "[#{children.map(&:to_s).join(',')}]"
11
30
  end
31
+
32
+ private
33
+
34
+ def cellify!
35
+ @children = @children.map do |child|
36
+ child.is_a?(Cell) ? child : Cell.new(child)
37
+ end
38
+ end
12
39
  end
13
40
  end
14
41
  end
@@ -1,14 +1,6 @@
1
1
  module Keisan
2
2
  module AST
3
3
  class Literal < Node
4
- def ==(other)
5
- case other
6
- when Literal
7
- value == other.value
8
- else
9
- false
10
- end
11
- end
12
4
  end
13
5
  end
14
6
  end
@@ -14,7 +14,7 @@ module Keisan
14
14
  end
15
15
 
16
16
  def value(context = nil)
17
- context ||= Keisan::Context.new
17
+ context ||= Context.new
18
18
  children[0].value(context) && children[1].value(context)
19
19
  end
20
20
  end
@@ -14,7 +14,7 @@ module Keisan
14
14
  end
15
15
 
16
16
  def value(context = nil)
17
- context ||= Keisan::Context.new
17
+ context ||= Context.new
18
18
  children[0].value(context) || children[1].value(context)
19
19
  end
20
20
  end
@@ -0,0 +1,28 @@
1
+ module Keisan
2
+ module AST
3
+ class MultiLine < Parent
4
+ def value(context = nil)
5
+ context ||= Context.new
6
+ evaluate(context).value(context)
7
+ end
8
+
9
+ def evaluate_assignments(context = nil)
10
+ self
11
+ end
12
+
13
+ def evaluate(context = nil)
14
+ context ||= Context.new
15
+ @children = children.map {|child| child.evaluate(context)}
16
+ @children.last
17
+ end
18
+
19
+ def simplify(context = nil)
20
+ evaluate(context)
21
+ end
22
+
23
+ def to_s
24
+ children.map(&:to_s).join(";")
25
+ end
26
+ end
27
+ end
28
+ end
@@ -2,7 +2,7 @@ module Keisan
2
2
  module AST
3
3
  class Node
4
4
  def value(context = nil)
5
- raise Keisan::Exceptions::NotImplementedError.new
5
+ raise Exceptions::NotImplementedError.new
6
6
  end
7
7
 
8
8
  def unbound_variables(context = nil)
@@ -29,12 +29,20 @@ module Keisan
29
29
  self
30
30
  end
31
31
 
32
+ def evaluated(context = nil)
33
+ deep_dup.evaluate(context)
34
+ end
35
+
32
36
  def evaluate(context = nil)
37
+ value(context)
38
+ end
39
+
40
+ def evaluate_assignments(context = nil)
33
41
  self
34
42
  end
35
43
 
36
44
  def differentiate(variable, context = nil)
37
- raise Keisan::Exceptions::NonDifferentiableError.new
45
+ raise Exceptions::NonDifferentiableError.new
38
46
  end
39
47
 
40
48
  def replace(variable, replacement)
@@ -50,41 +58,41 @@ module Keisan
50
58
  end
51
59
 
52
60
  def +(other)
53
- AST::Plus.new(
61
+ Plus.new(
54
62
  [self, other.to_node]
55
63
  )
56
64
  end
57
65
 
58
66
  def -(other)
59
- AST::Plus.new(
60
- [self, AST::UnaryMinus.new(other.to_node)]
67
+ Plus.new(
68
+ [self, UnaryMinus.new(other.to_node)]
61
69
  )
62
70
  end
63
71
 
64
72
  def *(other)
65
- AST::Times.new(
73
+ Times.new(
66
74
  [self, other.to_node]
67
75
  )
68
76
  end
69
77
 
70
78
  def /(other)
71
- AST::Times.new(
72
- [self, AST::UnaryInverse.new(other.to_node)]
79
+ Times.new(
80
+ [self, UnaryInverse.new(other.to_node)]
73
81
  )
74
82
  end
75
83
 
76
84
  def %(other)
77
- AST::Modulo.new(
85
+ Modulo.new(
78
86
  [self, other.to_node]
79
87
  )
80
88
  end
81
89
 
82
90
  def !
83
- AST::UnaryLogicalNot.new(self)
91
+ UnaryLogicalNot.new(self)
84
92
  end
85
93
 
86
94
  def ~
87
- AST::UnaryBitwiseNot.new(self)
95
+ UnaryBitwiseNot.new(self)
88
96
  end
89
97
 
90
98
  def +@
@@ -92,55 +100,55 @@ module Keisan
92
100
  end
93
101
 
94
102
  def -@
95
- AST::UnaryMinus.new(self)
103
+ UnaryMinus.new(self)
96
104
  end
97
105
 
98
106
  def **(other)
99
- AST::Exponent.new([self, other.to_node])
107
+ Exponent.new([self, other.to_node])
100
108
  end
101
109
 
102
110
  def &(other)
103
- AST::BitwiseAnd.new([self, other.to_node])
111
+ BitwiseAnd.new([self, other.to_node])
104
112
  end
105
113
 
106
114
  def ^(other)
107
- AST::BitwiseXor.new([self, other.to_node])
115
+ BitwiseXor.new([self, other.to_node])
108
116
  end
109
117
 
110
118
  def |(other)
111
- AST::BitwiseOr.new([self, other.to_node])
119
+ BitwiseOr.new([self, other.to_node])
112
120
  end
113
121
 
114
122
  def >(other)
115
- AST::LogicalGreaterThan.new([self, other.to_node])
123
+ LogicalGreaterThan.new([self, other.to_node])
116
124
  end
117
125
 
118
126
  def >=(other)
119
- AST::LogicalGreaterThanOrEqualTo.new([self, other.to_node])
127
+ LogicalGreaterThanOrEqualTo.new([self, other.to_node])
120
128
  end
121
129
 
122
130
  def <(other)
123
- AST::LogicalLessThan.new([self, other.to_node])
131
+ LogicalLessThan.new([self, other.to_node])
124
132
  end
125
133
 
126
134
  def <=(other)
127
- AST::LogicalLessThanOrEqualTo.new([self, other.to_node])
135
+ LogicalLessThanOrEqualTo.new([self, other.to_node])
128
136
  end
129
137
 
130
138
  def equal(other)
131
- AST::LogicalEqual.new([self, other.to_node])
139
+ LogicalEqual.new([self, other.to_node])
132
140
  end
133
141
 
134
142
  def not_equal(other)
135
- AST::LogicalNotEqual.new([self, other.to_node])
143
+ LogicalNotEqual.new([self, other.to_node])
136
144
  end
137
145
 
138
146
  def and(other)
139
- AST::LogicalAnd.new([self, other.to_node])
147
+ LogicalAnd.new([self, other.to_node])
140
148
  end
141
149
 
142
150
  def or(other)
143
- AST::LogicalOr.new([self, other.to_node])
151
+ LogicalOr.new([self, other.to_node])
144
152
  end
145
153
  end
146
154
  end
@@ -12,18 +12,18 @@ module Keisan
12
12
  end
13
13
 
14
14
  def -@
15
- AST::Number.new(-value)
15
+ Number.new(-value)
16
16
  end
17
17
 
18
18
  def +@
19
- AST::Number.new(value)
19
+ Number.new(value)
20
20
  end
21
21
 
22
22
  def +(other)
23
23
  other = other.to_node
24
24
  case other
25
- when AST::Number
26
- AST::Number.new(value + other.value)
25
+ when Number
26
+ Number.new(value + other.value)
27
27
  else
28
28
  super
29
29
  end
@@ -36,8 +36,8 @@ module Keisan
36
36
  def *(other)
37
37
  other = other.to_node
38
38
  case other
39
- when AST::Number
40
- AST::Number.new(value * other.value)
39
+ when Number
40
+ Number.new(value * other.value)
41
41
  else
42
42
  super
43
43
  end
@@ -46,8 +46,8 @@ module Keisan
46
46
  def /(other)
47
47
  other = other.to_node
48
48
  case other
49
- when AST::Number
50
- AST::Number.new(Rational(value, other.value))
49
+ when Number
50
+ Number.new(Rational(value, other.value))
51
51
  else
52
52
  super
53
53
  end
@@ -56,8 +56,8 @@ module Keisan
56
56
  def **(other)
57
57
  other = other.to_node
58
58
  case other
59
- when AST::Number
60
- AST::Number.new(value ** other.value)
59
+ when Number
60
+ Number.new(value ** other.value)
61
61
  else
62
62
  super
63
63
  end
@@ -66,8 +66,8 @@ module Keisan
66
66
  def %(other)
67
67
  other = other.to_node
68
68
  case other
69
- when AST::Number
70
- AST::Number.new(value % other.value)
69
+ when Number
70
+ Number.new(value % other.value)
71
71
  else
72
72
  super
73
73
  end
@@ -76,22 +76,22 @@ module Keisan
76
76
  def &(other)
77
77
  other = other.to_node
78
78
  case other
79
- when AST::Number
80
- AST::Number.new(value & other.value)
79
+ when Number
80
+ Number.new(value & other.value)
81
81
  else
82
82
  super
83
83
  end
84
84
  end
85
85
 
86
86
  def ~
87
- AST::Number.new(~value)
87
+ Number.new(~value)
88
88
  end
89
89
 
90
90
  def ^(other)
91
91
  other = other.to_node
92
92
  case other
93
- when AST::Number
94
- AST::Number.new(value ^ other.value)
93
+ when Number
94
+ Number.new(value ^ other.value)
95
95
  else
96
96
  super
97
97
  end
@@ -100,8 +100,8 @@ module Keisan
100
100
  def |(other)
101
101
  other = other.to_node
102
102
  case other
103
- when AST::Number
104
- AST::Number.new(value | other.value)
103
+ when Number
104
+ Number.new(value | other.value)
105
105
  else
106
106
  super
107
107
  end
@@ -110,8 +110,8 @@ module Keisan
110
110
  def >(other)
111
111
  other = other.to_node
112
112
  case other
113
- when AST::Number
114
- AST::Boolean.new(value > other.value)
113
+ when Number
114
+ Boolean.new(value > other.value)
115
115
  else
116
116
  super
117
117
  end
@@ -120,8 +120,8 @@ module Keisan
120
120
  def >=(other)
121
121
  other = other.to_node
122
122
  case other
123
- when AST::Number
124
- AST::Boolean.new(value >= other.value)
123
+ when Number
124
+ Boolean.new(value >= other.value)
125
125
  else
126
126
  super
127
127
  end
@@ -130,8 +130,8 @@ module Keisan
130
130
  def <(other)
131
131
  other = other.to_node
132
132
  case other
133
- when AST::Number
134
- AST::Boolean.new(value < other.value)
133
+ when Number
134
+ Boolean.new(value < other.value)
135
135
  else
136
136
  super
137
137
  end
@@ -140,8 +140,8 @@ module Keisan
140
140
  def <=(other)
141
141
  other = other.to_node
142
142
  case other
143
- when AST::Number
144
- AST::Boolean.new(value <= other.value)
143
+ when Number
144
+ Boolean.new(value <= other.value)
145
145
  else
146
146
  super
147
147
  end
@@ -150,8 +150,8 @@ module Keisan
150
150
  def equal(other)
151
151
  other = other.to_node
152
152
  case other
153
- when AST::Number
154
- AST::Boolean.new(value == other.value)
153
+ when Number
154
+ Boolean.new(value == other.value)
155
155
  else
156
156
  super
157
157
  end
@@ -160,8 +160,8 @@ module Keisan
160
160
  def not_equal(other)
161
161
  other = other.to_node
162
162
  case other
163
- when AST::Number
164
- AST::Boolean.new(value != other.value)
163
+ when Number
164
+ Boolean.new(value != other.value)
165
165
  else
166
166
  super
167
167
  end
@@ -38,7 +38,7 @@ module Keisan
38
38
 
39
39
  def initialize(children = [], parsing_operators = [])
40
40
  unless parsing_operators.empty? || children.count == parsing_operators.count + 1
41
- raise Keisan::Exceptions::ASTError.new("Mismatch of children and operators")
41
+ raise Exceptions::ASTError.new("Mismatch of children and operators")
42
42
  end
43
43
 
44
44
  children = Array.wrap(children)
@@ -47,6 +47,14 @@ module Keisan
47
47
  @parsing_operators = parsing_operators
48
48
  end
49
49
 
50
+ def evaluate_assignments(context = nil)
51
+ context ||= Context.new
52
+ @children = children.map do |child|
53
+ child.evaluate_assignments(context)
54
+ end
55
+ self
56
+ end
57
+
50
58
  def self.associativity_of_priority(priority)
51
59
  ASSOCIATIVITY_OF_PRIORITY[priority]
52
60
  end
@@ -80,11 +88,11 @@ module Keisan
80
88
  end
81
89
 
82
90
  def self.symbol
83
- raise Keisan::Exceptions::NotImplementedError.new
91
+ raise Exceptions::NotImplementedError.new
84
92
  end
85
93
 
86
94
  def blank_value
87
- raise Keisan::Exceptions::NotImplementedError.new
95
+ raise Exceptions::NotImplementedError.new
88
96
  end
89
97
 
90
98
  def value(context = nil)
@@ -103,7 +111,7 @@ module Keisan
103
111
  def to_s
104
112
  children.map do |child|
105
113
  case child
106
- when AST::Operator
114
+ when Operator
107
115
  "(#{child.to_s})"
108
116
  else
109
117
  "#{child.to_s}"