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