keisan 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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}"