code-ruby 0.3.1 → 0.5.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 (206) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/CHANGELOG.md +5 -0
  4. data/Gemfile +4 -0
  5. data/Gemfile.lock +28 -55
  6. data/TODO +17 -0
  7. data/bin/code +56 -31
  8. data/bin/format +3 -0
  9. data/bin/template +62 -20
  10. data/bin/test +17 -0
  11. data/code-ruby.gemspec +1 -6
  12. data/docs/class.code +9 -0
  13. data/docs/euler/1.template +1 -5
  14. data/docs/euler/5.template +0 -1
  15. data/docs/meetup.code +12 -0
  16. data/docs/precedence.template +6 -39
  17. data/docs/rain.code +22 -0
  18. data/docs/slack.code +17 -0
  19. data/docs/stripe.code +7 -0
  20. data/docs/twitter.code +9 -0
  21. data/language-ruby.gemspec +18 -0
  22. data/lib/code/error.rb +3 -0
  23. data/lib/code/node/base_10.rb +29 -0
  24. data/lib/code/node/base_16.rb +13 -0
  25. data/lib/code/node/base_2.rb +13 -0
  26. data/lib/code/node/base_8.rb +13 -0
  27. data/lib/code/node/boolean.rb +7 -7
  28. data/lib/code/node/call.rb +32 -37
  29. data/lib/code/node/call_argument.rb +11 -27
  30. data/lib/code/node/chained_call.rb +10 -25
  31. data/lib/code/node/code.rb +4 -6
  32. data/lib/code/node/decimal.rb +26 -0
  33. data/lib/code/node/dictionnary.rb +20 -9
  34. data/lib/code/node/equal.rb +18 -20
  35. data/lib/code/node/function.rb +10 -7
  36. data/lib/code/node/function_parameter.rb +31 -0
  37. data/lib/code/node/if.rb +36 -32
  38. data/lib/code/node/if_modifier.rb +35 -36
  39. data/lib/code/node/list.rb +6 -9
  40. data/lib/code/node/negation.rb +5 -23
  41. data/lib/code/node/not.rb +15 -0
  42. data/lib/code/node/nothing.rb +1 -1
  43. data/lib/code/node/number.rb +14 -12
  44. data/lib/code/node/operation.rb +21 -16
  45. data/lib/code/node/power.rb +10 -6
  46. data/lib/code/node/rescue.rb +4 -3
  47. data/lib/code/node/splat.rb +15 -0
  48. data/lib/code/node/statement.rb +47 -69
  49. data/lib/code/node/string.rb +41 -10
  50. data/lib/code/node/ternary.rb +7 -9
  51. data/lib/code/node/unary_minus.rb +5 -12
  52. data/lib/code/node/while.rb +17 -24
  53. data/lib/code/node.rb +7 -8
  54. data/lib/code/object/argument.rb +3 -12
  55. data/lib/code/object/decimal.rb +114 -27
  56. data/lib/code/object/dictionnary.rb +29 -12
  57. data/lib/code/object/function.rb +23 -24
  58. data/lib/code/object/global.rb +42 -0
  59. data/lib/code/object/integer.rb +142 -35
  60. data/lib/code/object/list.rb +74 -95
  61. data/lib/code/object/range.rb +38 -50
  62. data/lib/code/object/ruby_function.rb +31 -0
  63. data/lib/code/object/string.rb +36 -16
  64. data/lib/code/object.rb +114 -54
  65. data/lib/code/parser/addition.rb +12 -20
  66. data/lib/code/parser/and_operator.rb +9 -20
  67. data/lib/code/parser/bitwise_and.rb +9 -20
  68. data/lib/code/parser/bitwise_or.rb +12 -20
  69. data/lib/code/parser/boolean.rb +10 -7
  70. data/lib/code/parser/call.rb +92 -60
  71. data/lib/code/parser/chained_call.rb +47 -0
  72. data/lib/code/parser/class.rb +45 -0
  73. data/lib/code/parser/code.rb +17 -10
  74. data/lib/code/parser/dictionnary.rb +56 -30
  75. data/lib/code/parser/equal.rb +87 -35
  76. data/lib/code/parser/equality.rb +23 -24
  77. data/lib/code/parser/equality_lower.rb +9 -0
  78. data/lib/code/parser/function.rb +67 -40
  79. data/lib/code/parser/greater.rb +25 -0
  80. data/lib/code/parser/group.rb +13 -8
  81. data/lib/code/parser/if.rb +51 -21
  82. data/lib/code/parser/if_modifier.rb +43 -16
  83. data/lib/code/parser/list.rb +32 -19
  84. data/lib/code/parser/multiplication.rb +15 -20
  85. data/lib/code/parser/name.rb +96 -84
  86. data/lib/code/parser/negation.rb +20 -9
  87. data/lib/code/parser/not_keyword.rb +14 -12
  88. data/lib/code/parser/nothing.rb +13 -8
  89. data/lib/code/parser/number.rb +124 -68
  90. data/lib/code/parser/operation.rb +35 -0
  91. data/lib/code/parser/or_keyword.rb +12 -20
  92. data/lib/code/parser/or_operator.rb +9 -20
  93. data/lib/code/parser/power.rb +32 -14
  94. data/lib/code/parser/range.rb +9 -17
  95. data/lib/code/parser/rescue.rb +29 -13
  96. data/lib/code/parser/shift.rb +11 -21
  97. data/lib/code/parser/splat.rb +31 -0
  98. data/lib/code/parser/statement.rb +4 -3
  99. data/lib/code/parser/string.rb +53 -62
  100. data/lib/code/parser/ternary.rb +36 -15
  101. data/lib/code/parser/unary_minus.rb +23 -5
  102. data/lib/code/parser/while.rb +26 -15
  103. data/lib/code/parser/whitespace.rb +49 -0
  104. data/lib/code/parser.rb +15 -0
  105. data/lib/code/ruby.rb +162 -0
  106. data/lib/code-ruby.rb +2 -5
  107. data/lib/code.rb +24 -7
  108. data/lib/language/atom.rb +343 -0
  109. data/lib/language/output.rb +130 -0
  110. data/lib/language/parser/absent/present.rb +8 -0
  111. data/lib/language/parser/absent.rb +6 -0
  112. data/lib/language/parser/end_of_input.rb +6 -0
  113. data/lib/language/parser/interuption.rb +38 -0
  114. data/lib/language/parser/not_end_of_input.rb +6 -0
  115. data/lib/language/parser/str/not_found.rb +16 -0
  116. data/lib/language/parser/str.rb +6 -0
  117. data/lib/language/parser.rb +53 -0
  118. data/lib/language-ruby.rb +10 -0
  119. data/lib/language.rb +80 -0
  120. data/lib/template/node/code_part.rb +1 -1
  121. data/lib/template/node/part.rb +1 -1
  122. data/lib/template/node/template.rb +1 -1
  123. data/lib/template/node/text_part.rb +1 -1
  124. data/lib/template/node.rb +1 -1
  125. data/lib/template/parser/template.rb +26 -17
  126. data/lib/template/parser.rb +15 -0
  127. data/lib/template/version.rb +1 -1
  128. data/lib/template-ruby.rb +2 -5
  129. data/lib/template.rb +23 -13
  130. data/spec/code/addition_spec.rb +13 -0
  131. data/spec/code/and_operator_spec.rb +13 -0
  132. data/spec/code/bitwise_and_spec.rb +13 -0
  133. data/spec/code/bitwise_or_spec.rb +13 -0
  134. data/spec/code/boolean_spec.rb +13 -0
  135. data/spec/code/call_spec.rb +21 -0
  136. data/spec/code/chained_call_spec.rb +16 -0
  137. data/spec/code/dictionnary_spec.rb +17 -0
  138. data/spec/code/equal_spec.rb +26 -0
  139. data/spec/code/equality_spec.rb +13 -0
  140. data/spec/code/function_spec.rb +18 -0
  141. data/spec/code/greater_spec.rb +18 -0
  142. data/spec/code/group_spec.rb +12 -0
  143. data/spec/code/if_modifier_spec.rb +20 -0
  144. data/spec/code/if_spec.rb +25 -0
  145. data/spec/code/list_spec.rb +17 -0
  146. data/spec/code/multiplication_spec.rb +18 -0
  147. data/spec/code/negation_spec.rb +20 -0
  148. data/spec/code/not_keyword_spec.rb +13 -0
  149. data/spec/code/nothing_spec.rb +17 -0
  150. data/spec/code/number_spec.rb +22 -0
  151. data/spec/code/or_keyword_spec.rb +17 -0
  152. data/spec/code/or_operator_spec.rb +16 -0
  153. data/spec/code/parser/boolean_spec.rb +5 -7
  154. data/spec/code/parser/call_spec.rb +16 -56
  155. data/spec/code/parser/chained_call.rb +17 -0
  156. data/spec/code/parser/dictionnary_spec.rb +8 -9
  157. data/spec/code/parser/function_spec.rb +5 -21
  158. data/spec/code/parser/group_spec.rb +18 -0
  159. data/spec/code/parser/list_spec.rb +9 -20
  160. data/spec/code/parser/number_spec.rb +4 -109
  161. data/spec/code/parser/string_spec.rb +9 -17
  162. data/spec/code/parser_spec.rb +23 -0
  163. data/spec/code/power_spec.rb +13 -0
  164. data/spec/code/range_spec.rb +16 -0
  165. data/spec/code/rescue_spec.rb +13 -0
  166. data/spec/code/shift_spec.rb +13 -0
  167. data/spec/code/splat_spec.rb +13 -0
  168. data/spec/code/string_spec.rb +25 -0
  169. data/spec/code/ternary_spec.rb +18 -0
  170. data/spec/code/unary_minus_spec.rb +13 -0
  171. data/spec/code/while_spec.rb +18 -0
  172. data/spec/spec_helper.rb +4 -1
  173. data/template-ruby.gemspec +2 -7
  174. metadata +113 -99
  175. data/lib/code/node/base_10_decimal.rb +0 -32
  176. data/lib/code/node/base_10_integer.rb +0 -32
  177. data/lib/code/node/base_10_number.rb +0 -19
  178. data/lib/code/node/base_16_number.rb +0 -19
  179. data/lib/code/node/base_2_number.rb +0 -19
  180. data/lib/code/node/base_8_number.rb +0 -19
  181. data/lib/code/node/block.rb +0 -17
  182. data/lib/code/node/defined.rb +0 -19
  183. data/lib/code/node/dictionnary_key_value.rb +0 -23
  184. data/lib/code/node/function_argument.rb +0 -45
  185. data/lib/code/node/group.rb +0 -13
  186. data/lib/code/node/keyword_call_argument.rb +0 -30
  187. data/lib/code/node/keyword_function_argument.rb +0 -33
  188. data/lib/code/node/name.rb +0 -55
  189. data/lib/code/node/not_keyword.rb +0 -13
  190. data/lib/code/node/or_keyword.rb +0 -34
  191. data/lib/code/node/range.rb +0 -31
  192. data/lib/code/node/regular_call_argument.rb +0 -34
  193. data/lib/code/node/regular_function_argument.rb +0 -36
  194. data/lib/code/node/string_characters.rb +0 -13
  195. data/lib/code/node/string_component.rb +0 -23
  196. data/lib/code/node/string_interpolation.rb +0 -13
  197. data/lib/code/parser/defined.rb +0 -20
  198. data/lib/code/parser/greater_than.rb +0 -33
  199. data/spec/call_spec.rb +0 -22
  200. data/spec/code/error/type_error_spec.rb +0 -63
  201. data/spec/code/parser/name_spec.rb +0 -15
  202. data/spec/code/parser/nothing_spec.rb +0 -19
  203. data/spec/code_spec.rb +0 -120
  204. data/spec/function_spec.rb +0 -26
  205. data/spec/template/parser/template_spec.rb +0 -19
  206. data/spec/template_spec.rb +0 -33
@@ -1,33 +1,15 @@
1
1
  class Code
2
2
  class Node
3
3
  class Negation < Node
4
- EXCLAMATION_POINT = "!"
5
- PLUS = "+"
6
-
7
- def initialize(negation)
8
- @operator = negation.fetch(:operator)
9
- @statement = ::Code::Node::Statement.new(negation.fetch(:statement))
4
+ def initialize(parsed)
5
+ @operator = parsed.delete(:operator)
6
+ @right = Node::Statement.new(parsed.delete(:right))
7
+ super(parsed)
10
8
  end
11
9
 
12
10
  def evaluate(**args)
13
- object = @statement.evaluate(**args)
14
-
15
- if operator == EXCLAMATION_POINT
16
- if object.truthy?
17
- ::Code::Object::Boolean.new(false)
18
- else
19
- ::Code::Object::Boolean.new(true)
20
- end
21
- elsif operator == PLUS
22
- object
23
- else
24
- raise NotImplementedError.new(operator)
25
- end
11
+ @right.evaluate(**args).call(operator: @operator, arguments: [], **args)
26
12
  end
27
-
28
- private
29
-
30
- attr_reader :operator
31
13
  end
32
14
  end
33
15
  end
@@ -0,0 +1,15 @@
1
+ class Code
2
+ class Node
3
+ class Not < Node
4
+ def initialize(parsed)
5
+ @operator = parsed.delete(:operator)
6
+ @right = Node::Statement.new(parsed.delete(:right))
7
+ super(parsed)
8
+ end
9
+
10
+ def evaluate(**args)
11
+ @right.evaluate(**args).call(operator: @operator, arguments: [], **args)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,7 +1,7 @@
1
1
  class Code
2
2
  class Node
3
3
  class Nothing < Node
4
- def initialize
4
+ def initialize(parsed)
5
5
  end
6
6
 
7
7
  def evaluate(**args)
@@ -1,22 +1,24 @@
1
1
  class Code
2
2
  class Node
3
3
  class Number < Node
4
- def initialize(number)
5
- if number.key?(:base_2)
6
- @number = ::Code::Node::Base2Number.new(number[:base_2])
7
- elsif number.key?(:base_8)
8
- @number = ::Code::Node::Base8Number.new(number[:base_8])
9
- elsif number.key?(:base_10)
10
- @number = ::Code::Node::Base10Number.new(number[:base_10])
11
- elsif number.key?(:base_16)
12
- @number = ::Code::Node::Base16Number.new(number[:base_16])
13
- else
14
- raise NotImplementedErorr.new(number.inspect)
4
+ def initialize(parsed)
5
+ if parsed.key?(:decimal)
6
+ @statement = Node::Decimal.new(parsed.delete(:decimal))
7
+ elsif parsed.key?(:base_16)
8
+ @statement = Node::Base16.new(parsed.delete(:base_16))
9
+ elsif parsed.key?(:base_10)
10
+ @statement = Node::Base10.new(parsed.delete(:base_10))
11
+ elsif parsed.key?(:base_8)
12
+ @statement = Node::Base8.new(parsed.delete(:base_8))
13
+ elsif parsed.key?(:base_2)
14
+ @statement = Node::Base2.new(parsed.delete(:base_2))
15
15
  end
16
+
17
+ super(parsed)
16
18
  end
17
19
 
18
20
  def evaluate(**args)
19
- @number.evaluate(**args)
21
+ @statement.evaluate(**args)
20
22
  end
21
23
  end
22
24
  end
@@ -1,32 +1,37 @@
1
1
  class Code
2
2
  class Node
3
3
  class Operation < Node
4
- class Operation
4
+ class Operator < Node
5
5
  attr_reader :operator, :statement
6
6
 
7
- def initialize(operation)
8
- @operator = operation.fetch(:operator).to_s
9
- @statement = ::Code::Node::Statement.new(operation.fetch(:statement))
7
+ def initialize(parsed)
8
+ @operator = parsed.delete(:operator)
9
+ @statement = Node::Statement.new(parsed.delete(:statement))
10
10
  end
11
11
  end
12
12
 
13
- def initialize(operation)
14
- @first = ::Code::Node::Statement.new(operation.fetch(:first))
15
- @rest = operation.fetch(:rest)
16
- @rest.map! do |operation|
17
- ::Code::Node::Operation::Operation.new(operation)
18
- end
13
+ def initialize(parsed)
14
+ @first = Node::Statement.new(parsed.delete(:first))
15
+ @others =
16
+ parsed
17
+ .delete(:others)
18
+ .map { |operator| Node::Operation::Operator.new(operator) }
19
+
20
+ super(parsed)
19
21
  end
20
22
 
21
23
  def evaluate(**args)
22
- object = @first.evaluate(**args)
24
+ first = @first.evaluate(**args)
23
25
 
24
- @rest.each do |operation|
25
- other = operation.statement.evaluate(**args)
26
- object = simple_call(object, operation.operator, other, **args)
27
- end
26
+ @others.reduce(first) do |left, right|
27
+ statement = right.statement.evaluate(**args)
28
28
 
29
- object
29
+ left.call(
30
+ operator: right.operator,
31
+ arguments: [::Code::Object::Argument.new(statement)],
32
+ **args
33
+ )
34
+ end
30
35
  end
31
36
  end
32
37
  end
@@ -1,15 +1,19 @@
1
1
  class Code
2
2
  class Node
3
3
  class Power < Node
4
- def initialize(power)
5
- @left = ::Code::Node::Statement.new(power.fetch(:left))
6
- @right = ::Code::Node::Statement.new(power.fetch(:right))
4
+ def initialize(parsed)
5
+ @operator = parsed.delete(:operator)
6
+ @left = Node::Statement.new(parsed.delete(:left))
7
+ @right = Node::Statement.new(parsed.delete(:right))
8
+ super(parsed)
7
9
  end
8
10
 
9
11
  def evaluate(**args)
10
- right = @right.evaluate(**args)
11
- left = @left.evaluate(**args)
12
- simple_call(left, :**, right, **args)
12
+ @left.evaluate(**args).call(
13
+ operator: @operator,
14
+ arguments: [::Code::Object::Argument.new(@right.evaluate(**args))],
15
+ **args
16
+ )
13
17
  end
14
18
  end
15
19
  end
@@ -1,9 +1,10 @@
1
1
  class Code
2
2
  class Node
3
3
  class Rescue < Node
4
- def initialize(power)
5
- @left = ::Code::Node::Statement.new(power.fetch(:left))
6
- @right = ::Code::Node::Statement.new(power.fetch(:right))
4
+ def initialize(parsed)
5
+ @left = Node::Statement.new(parsed.delete(:left))
6
+ @right = Node::Statement.new(parsed.delete(:right))
7
+ super(parsed)
7
8
  end
8
9
 
9
10
  def evaluate(**args)
@@ -0,0 +1,15 @@
1
+ class Code
2
+ class Node
3
+ class Splat < Node
4
+ def initialize(parsed)
5
+ @operator = parsed.delete(:operator)
6
+ @right = Node::Statement.new(parsed.delete(:right))
7
+ super(parsed)
8
+ end
9
+
10
+ def evaluate(**args)
11
+ @right.evaluate(**args).call(operator: @operator, arguments: [], **args)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,76 +1,54 @@
1
1
  class Code
2
2
  class Node
3
3
  class Statement < Node
4
- attr_reader :statement
5
-
6
- def initialize(statement)
7
- if statement.key?(:nothing)
8
- @statement = ::Code::Node::Nothing.new
9
- elsif statement.key?(:boolean)
10
- @statement = ::Code::Node::Boolean.new(statement[:boolean])
11
- elsif statement.key?(:number)
12
- @statement = ::Code::Node::Number.new(statement[:number])
13
- elsif statement.key?(:string)
14
- @statement = ::Code::Node::String.new(statement[:string])
15
- elsif statement.key?(:call)
16
- @statement = ::Code::Node::Call.new(statement[:call])
17
- elsif statement.key?(:name)
18
- @statement = ::Code::Node::Name.new(statement[:name])
19
- elsif statement.key?(:list)
20
- @statement = ::Code::Node::List.new(statement[:list])
21
- elsif statement.key?(:dictionnary)
22
- @statement = ::Code::Node::Dictionnary.new(statement[:dictionnary])
23
- elsif statement.key?(:negation)
24
- @statement = ::Code::Node::Negation.new(statement[:negation])
25
- elsif statement.key?(:power)
26
- @statement = ::Code::Node::Power.new(statement[:power])
27
- elsif statement.key?(:unary_minus)
28
- @statement = ::Code::Node::UnaryMinus.new(statement[:unary_minus])
29
- elsif statement.key?(:multiplication)
30
- @statement = ::Code::Node::Operation.new(statement[:multiplication])
31
- elsif statement.key?(:addition)
32
- @statement = ::Code::Node::Operation.new(statement[:addition])
33
- elsif statement.key?(:shift)
34
- @statement = ::Code::Node::Operation.new(statement[:shift])
35
- elsif statement.key?(:bitwise_and)
36
- @statement = ::Code::Node::Operation.new(statement[:bitwise_and])
37
- elsif statement.key?(:bitwise_or)
38
- @statement = ::Code::Node::Operation.new(statement[:bitwise_or])
39
- elsif statement.key?(:greater_than)
40
- @statement = ::Code::Node::Operation.new(statement[:greater_than])
41
- elsif statement.key?(:equality)
42
- @statement = ::Code::Node::Operation.new(statement[:equality])
43
- elsif statement.key?(:and_operator)
44
- @statement = ::Code::Node::Operation.new(statement[:and_operator])
45
- elsif statement.key?(:or_operator)
46
- @statement = ::Code::Node::Operation.new(statement[:or_operator])
47
- elsif statement.key?(:range)
48
- @statement = ::Code::Node::Range.new(statement[:range])
49
- elsif statement.key?(:ternary)
50
- @statement = ::Code::Node::Ternary.new(statement[:ternary])
51
- elsif statement.key?(:rescue)
52
- @statement = ::Code::Node::Rescue.new(statement[:rescue])
53
- elsif statement.key?(:equal)
54
- @statement = ::Code::Node::Equal.new(statement[:equal])
55
- elsif statement.key?(:defined)
56
- @statement = ::Code::Node::Defined.new(statement[:defined])
57
- elsif statement.key?(:not_keyword)
58
- @statement = ::Code::Node::NotKeyword.new(statement[:not_keyword])
59
- elsif statement.key?(:or_keyword)
60
- @statement = ::Code::Node::OrKeyword.new(statement[:or_keyword])
61
- elsif statement.key?(:if_modifier)
62
- @statement = ::Code::Node::IfModifier.new(statement[:if_modifier])
63
- elsif statement.key?(:if)
64
- @statement = ::Code::Node::If.new(statement[:if])
65
- elsif statement.key?(:while)
66
- @statement = ::Code::Node::While.new(statement[:while])
67
- elsif statement.key?(:group)
68
- @statement = ::Code::Node::Group.new(statement[:group])
69
- elsif statement.key?(:function)
70
- @statement = ::Code::Node::Function.new(statement[:function])
71
- else
72
- raise NotImplementedError.new(statement.inspect)
4
+ def initialize(parsed)
5
+ if parsed.key?(:nothing)
6
+ @statement = Node::Nothing.new(parsed.delete(:nothing))
7
+ elsif parsed.key?(:boolean)
8
+ @statement = Node::Boolean.new(parsed.delete(:boolean))
9
+ elsif parsed.key?(:group)
10
+ @statement = Node::Code.new(parsed.delete(:group))
11
+ elsif parsed.key?(:call)
12
+ @statement = Node::Call.new(parsed.delete(:call))
13
+ elsif parsed.key?(:number)
14
+ @statement = Node::Number.new(parsed.delete(:number))
15
+ elsif parsed.key?(:string)
16
+ @statement = Node::String.new(parsed.delete(:string))
17
+ elsif parsed.key?(:list)
18
+ @statement = Node::List.new(parsed.delete(:list))
19
+ elsif parsed.key?(:dictionnary)
20
+ @statement = Node::Dictionnary.new(parsed.delete(:dictionnary))
21
+ elsif parsed.key?(:chained_call)
22
+ @statement = Node::ChainedCall.new(parsed.delete(:chained_call))
23
+ elsif parsed.key?(:operation)
24
+ @statement = Node::Operation.new(parsed.delete(:operation))
25
+ elsif parsed.key?(:equal)
26
+ @statement = Node::Equal.new(parsed.delete(:equal))
27
+ elsif parsed.key?(:function)
28
+ @statement = Node::Function.new(parsed.delete(:function))
29
+ elsif parsed.key?(:negation)
30
+ @statement = Node::Negation.new(parsed.delete(:negation))
31
+ elsif parsed.key?(:power)
32
+ @statement = Node::Power.new(parsed.delete(:power))
33
+ elsif parsed.key?(:unary_minus)
34
+ @statement = Node::UnaryMinus.new(parsed.delete(:unary_minus))
35
+ elsif parsed.key?(:ternary)
36
+ @statement = Node::Ternary.new(parsed.delete(:ternary))
37
+ elsif parsed.key?(:rescue)
38
+ @statement = Node::Rescue.new(parsed.delete(:rescue))
39
+ elsif parsed.key?(:not)
40
+ @statement = Node::Not.new(parsed.delete(:not))
41
+ elsif parsed.key?(:if_modifier)
42
+ @statement = Node::IfModifier.new(parsed.delete(:if_modifier))
43
+ elsif parsed.key?(:if)
44
+ @statement = Node::If.new(parsed.delete(:if))
45
+ elsif parsed.key?(:while)
46
+ @statement = Node::While.new(parsed.delete(:while))
47
+ elsif parsed.key?(:splat)
48
+ @statement = Node::Splat.new(parsed.delete(:splat))
73
49
  end
50
+
51
+ super(parsed)
74
52
  end
75
53
 
76
54
  def evaluate(**args)
@@ -1,21 +1,52 @@
1
1
  class Code
2
2
  class Node
3
3
  class String < Node
4
- def initialize(string)
5
- if string.to_s.blank?
6
- @string = []
7
- elsif string.is_a?(Array)
8
- @string = string.map do |component|
9
- ::Code::Node::StringComponent.new(component)
4
+ class Part < Node
5
+ class Code < Node
6
+ def initialize(parsed)
7
+ @code = Node::Code.new(parsed)
10
8
  end
11
- else
12
- @string = [::Code::Node::StringCharacters.new(string)]
9
+
10
+ def evaluate(**args)
11
+ @code.evaluate(**args)
12
+ end
13
+ end
14
+
15
+ class Text < Node
16
+ def initialize(parsed)
17
+ @text = parsed
18
+ end
19
+
20
+ def evaluate(**args)
21
+ ::Code::Object::String.new(@text)
22
+ end
23
+ end
24
+
25
+ def initialize(parsed)
26
+ if parsed.key?(:text)
27
+ @part = Node::String::Part::Text.new(parsed.delete(:text))
28
+ elsif parsed.key?(:code)
29
+ @part = Node::String::Part::Code.new(parsed.delete(:code))
30
+ end
31
+
32
+ super(parsed)
33
+ end
34
+
35
+ def evaluate(**args)
36
+ @part.evaluate(**args)
13
37
  end
14
38
  end
15
39
 
40
+ def initialize(parsed)
41
+ parsed = [] if parsed == ""
42
+
43
+ @parts = parsed.map { |part| Node::String::Part.new(part) }
44
+ end
45
+
16
46
  def evaluate(**args)
17
- string = @string.map { |component| component.evaluate(**args) }.map(&:to_s).join
18
- ::Code::Object::String.new(string)
47
+ ::Code::Object::String.new(
48
+ @parts.map { |part| part.evaluate(**args) }.map(&:to_s).join
49
+ )
19
50
  end
20
51
  end
21
52
  end
@@ -1,19 +1,17 @@
1
1
  class Code
2
2
  class Node
3
3
  class Ternary < Node
4
- def initialize(ternary)
5
- @left = ::Code::Node::Statement.new(ternary.fetch(:left))
6
- @middle = ::Code::Node::Statement.new(ternary.fetch(:middle))
7
-
8
- if ternary.key?(:right)
9
- @right = ::Code::Node::Statement.new(ternary.fetch(:right))
4
+ def initialize(parsed)
5
+ @left = Node::Statement.new(parsed.delete(:left))
6
+ @middle = Node::Statement.new(parsed.delete(:middle))
7
+ if parsed.key?(:right)
8
+ @right = Node::Statement.new(parsed.delete(:right))
10
9
  end
10
+ super(parsed)
11
11
  end
12
12
 
13
13
  def evaluate(**args)
14
- left = @left.evaluate(**args)
15
-
16
- if left.truthy?
14
+ if @left.evaluate(**args).truthy?
17
15
  @middle.evaluate(**args)
18
16
  elsif @right
19
17
  @right.evaluate(**args)
@@ -1,21 +1,14 @@
1
1
  class Code
2
2
  class Node
3
3
  class UnaryMinus < Node
4
- def initialize(unary_minus)
5
- @statement = ::Code::Node::Statement.new(unary_minus)
4
+ def initialize(parsed)
5
+ @operator = parsed.delete(:operator)
6
+ @right = Node::Statement.new(parsed.delete(:right))
7
+ super(parsed)
6
8
  end
7
9
 
8
10
  def evaluate(**args)
9
- object = @statement.evaluate(**args)
10
-
11
- case object
12
- when ::Code::Object::Integer
13
- ::Code::Object::Integer.new(-object.raw)
14
- when ::Code::Object::Decimal
15
- ::Code::Object::Decimal.new(-object.raw)
16
- else
17
- ::Code::Object::Nothing.new
18
- end
11
+ @right.evaluate(**args).call(operator: @operator, arguments: [], **args)
19
12
  end
20
13
  end
21
14
  end
@@ -1,42 +1,35 @@
1
1
  class Code
2
2
  class Node
3
3
  class While < Node
4
- WHILE_KEYWORD = :while
5
- UNTIL_KEYWORD = :until
6
-
7
- def initialize(while_parsed)
8
- @operator = while_parsed.fetch(:operator)
9
- @statement = ::Code::Node::Statement.new(while_parsed.fetch(:statement))
10
- @body = ::Code::Node::Code.new(while_parsed.fetch(:body))
4
+ WHILE_KEYWORD = "while"
5
+ UNTIL_KEYWORD = "until"
6
+
7
+ def initialize(parsed)
8
+ @operator = parsed.delete(:operator)
9
+ @statement = Node::Statement.new(parsed.delete(:statement))
10
+ @body = Node::Code.new(parsed.delete(:body))
11
+ super(parsed)
11
12
  end
12
13
 
13
14
  def evaluate(**args)
14
- if operator == WHILE_KEYWORD
15
- object = ::Code::Object::Nothing.new
15
+ if @operator == WHILE_KEYWORD
16
+ last = ::Code::Object::Nothing.new
16
17
 
17
18
  while @statement.evaluate(**args).truthy?
18
- object = @body.evaluate(**args)
19
+ last = @body.evaluate(**args)
19
20
  end
20
21
 
21
- object
22
- elsif operator == UNTIL_KEYWORD
23
- object = ::Code::Object::Nothing.new
22
+ last
23
+ elsif @operator == UNTIL_KEYWORD
24
+ last = ::Code::Object::Nothing.new
24
25
 
25
- until @statement.evaluate(**args).truthy?
26
- object = @body.evaluate(**args)
27
- end
26
+ last = @body.evaluate(**args) while @statement.evaluate(**args).falsy?
28
27
 
29
- object
28
+ last
30
29
  else
31
- raise NotImplementedError.new(operator.inspect)
30
+ raise NotImplementedError.new(@operator)
32
31
  end
33
32
  end
34
-
35
- private
36
-
37
- def operator
38
- @operator.to_sym
39
- end
40
33
  end
41
34
  end
42
35
  end
data/lib/code/node.rb CHANGED
@@ -1,14 +1,13 @@
1
1
  class Code
2
2
  class Node
3
- private
3
+ def initialize(parsed)
4
+ if parsed.any?
5
+ raise NotImplementedError.new(self.class.name + ": " + parsed.inspect)
6
+ end
7
+ end
4
8
 
5
- def simple_call(object, operator = nil, value = nil, **args)
6
- object.call(
7
- operator: operator && ::Code::Object::String.new(operator.to_s),
8
- arguments: [value && ::Code::Object::Argument.new(value)].compact,
9
- context: args.fetch(:context),
10
- io: args.fetch(:io),
11
- )
9
+ def evaluate(**args)
10
+ raise NotImplementedError.new(self.class.name + "#evaluate")
12
11
  end
13
12
  end
14
13
  end
@@ -1,20 +1,11 @@
1
1
  class Code
2
2
  class Object
3
- class Argument < ::Code::Object
4
- attr_reader :value, :name, :splat, :keyword_splat, :block
3
+ class Argument
4
+ attr_reader :value, :name
5
5
 
6
- def initialize(
7
- value,
8
- name: nil,
9
- splat: false,
10
- keyword_splat: false,
11
- block: false
12
- )
6
+ def initialize(value, name: nil)
13
7
  @value = value
14
8
  @name = name
15
- @splat = !!splat
16
- @keyword_splat = !!keyword_splat
17
- @block = !!block
18
9
  end
19
10
 
20
11
  def regular?