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
@@ -10,56 +10,65 @@ class Code
10
10
  def call(**args)
11
11
  operator = args.fetch(:operator, nil)
12
12
  arguments = args.fetch(:arguments, [])
13
- context = args.fetch(:context)
14
- io = args.fetch(:io)
13
+ globals = multi_fetch(args, *::Code::GLOBALS)
14
+ value = arguments.first&.value
15
15
 
16
16
  if operator == "any?"
17
- any?(arguments, context: context, io: io)
17
+ sig(arguments) { ::Code::Object::Function }
18
+ any?(value, **globals)
18
19
  elsif operator == "none?"
19
- none?(arguments, context: context, io: io)
20
+ sig(arguments) { ::Code::Object::Function }
21
+ none?(value, **globals)
20
22
  elsif operator == "detect"
21
- detect(arguments, context: context, io: io)
23
+ sig(arguments) { ::Code::Object::Function }
24
+ detect(value, **globals)
22
25
  elsif operator == "reduce"
23
- reduce(arguments, context: context, io: io)
26
+ sig(arguments) { ::Code::Object::Function }
27
+ reduce(value, **globals)
24
28
  elsif operator == "each"
25
- each(arguments, context: context, io: io)
29
+ sig(arguments) { ::Code::Object::Function }
30
+ each(value, **globals)
26
31
  elsif operator == "select"
27
- select(arguments, context: context, io: io)
32
+ sig(arguments) { ::Code::Object::Function }
33
+ select(value, **globals)
28
34
  elsif operator == "map"
29
- map(arguments, context: context, io: io)
35
+ sig(arguments) { ::Code::Object::Function }
36
+ map(value, **globals)
37
+ elsif operator == "max_by"
38
+ sig(arguments) { ::Code::Object::Function }
39
+ max_by(value, **globals)
30
40
  elsif operator == "max"
31
- max(arguments)
41
+ sig(arguments)
42
+ max
32
43
  elsif operator == "flatten"
33
- flatten(arguments)
44
+ sig(arguments)
45
+ flatten
34
46
  elsif operator == "reverse"
35
- reverse(arguments)
47
+ sig(arguments)
48
+ reverse
36
49
  elsif operator == "first"
37
- first(arguments)
50
+ sig(arguments)
51
+ first
38
52
  elsif operator == "last"
39
- last(arguments)
40
- elsif operator == "max_by"
41
- max_by(arguments, context: context, io: io)
53
+ sig(arguments)
54
+ last
42
55
  elsif operator == "<<"
43
- append(arguments)
56
+ sig(arguments) { ::Code::Object }
57
+ append(value)
44
58
  else
45
59
  super
46
60
  end
47
61
  end
48
62
 
49
- def <<(element)
50
- raw << element
51
- end
52
-
53
- def flatten(arguments)
54
- sig(arguments)
63
+ def flatten
55
64
  ::Code::Object::List.new(
56
65
  raw.reduce([]) do |acc, element|
57
66
  if element.is_a?(::Code::Object::List)
58
- acc + element.flatten(arguments).raw
67
+ acc + element.flatten.raw
59
68
  else
60
69
  acc + [element]
61
70
  end
62
- end,
71
+ end
63
72
  )
64
73
  end
65
74
 
@@ -67,6 +76,11 @@ class Code
67
76
  ::Code::Object::List.new(raw.deep_dup)
68
77
  end
69
78
 
79
+ def <<(other)
80
+ raw << other
81
+ self
82
+ end
83
+
70
84
  def to_s
71
85
  "[#{raw.map(&:inspect).join(", ")}]"
72
86
  end
@@ -77,144 +91,109 @@ class Code
77
91
 
78
92
  private
79
93
 
80
- def any?(arguments, context:, io:)
81
- sig(arguments, ::Code::Object::Function)
82
- argument = arguments.first
94
+ def any?(argument, **globals)
83
95
  ::Code::Object::Boolean.new(
84
96
  raw.any? do |element|
85
- argument
86
- .value
87
- .call(
88
- arguments: [::Code::Object::Argument.new(element)],
89
- context: context,
90
- io: io,
91
- )
92
- .truthy?
93
- end,
97
+ argument.call(
98
+ arguments: [::Code::Object::Argument.new(element)],
99
+ **globals
100
+ ).truthy?
101
+ end
94
102
  )
95
103
  end
96
104
 
97
- def none?(arguments, context:, io:)
98
- sig(arguments, ::Code::Object::Function)
99
- argument = arguments.first
105
+ def none?(argument, **globals)
100
106
  ::Code::Object::Boolean.new(
101
107
  raw.none? do |element|
102
- argument
103
- .value
104
- .call(
105
- arguments: [::Code::Object::Argument.new(element)],
106
- context: context,
107
- io: io,
108
- )
109
- .truthy?
110
- end,
108
+ argument.call(
109
+ arguments: [::Code::Object::Argument.new(element)],
110
+ **globals
111
+ ).truthy?
112
+ end
111
113
  )
112
114
  end
113
115
 
114
- def max_by(arguments, context:, io:)
115
- sig(arguments, ::Code::Object::Function)
116
- argument = arguments.first.value
116
+ def max_by(argument, **globals)
117
117
  raw.max_by do |element|
118
118
  argument.call(
119
119
  arguments: [::Code::Object::Argument.new(element)],
120
- context: context,
121
- io: io,
120
+ **globals
122
121
  )
123
122
  end || ::Code::Object::Nothing.new
124
123
  end
125
124
 
126
- def detect(arguments, context:, io:)
127
- sig(arguments, ::Code::Object::Function)
128
- argument = arguments.first.value
125
+ def detect(argument, **globals)
129
126
  raw.detect do |element|
130
127
  argument.call(
131
128
  arguments: [::Code::Object::Argument.new(element)],
132
- context: context,
133
- io: io,
129
+ **globals
134
130
  ).truthy?
135
131
  end || ::Code::Object::Nothing.new
136
132
  end
137
133
 
138
- def reduce(arguments, context:, io:)
139
- sig(arguments, ::Code::Object::Function)
140
- argument = arguments.first.value
134
+ def reduce(argument, **globals)
141
135
  raw.reduce do |acc, element|
142
136
  argument.call(
143
137
  arguments: [
144
138
  ::Code::Object::Argument.new(acc),
145
- ::Code::Object::Argument.new(element),
139
+ ::Code::Object::Argument.new(element)
146
140
  ],
147
- context: context,
148
- io: io,
141
+ **globals
149
142
  )
150
143
  end || ::Code::Object::Nothing.new
151
144
  end
152
145
 
153
- def each(arguments, context:, io:)
154
- sig(arguments, ::Code::Object::Function)
155
- argument = arguments.first.value
146
+ def each(argument, **globals)
156
147
  raw.each do |element|
157
148
  argument.call(
158
149
  arguments: [::Code::Object::Argument.new(element)],
159
- context: context,
160
- io: io,
150
+ **globals
161
151
  )
162
152
  end
163
153
  self
164
154
  end
165
155
 
166
- def select(arguments, context:, io:)
167
- sig(arguments, ::Code::Object::Function)
168
- argument = arguments.first.value
156
+ def select(argument, **globals)
169
157
  ::Code::Object::List.new(
170
158
  raw.select do |element|
171
159
  argument.call(
172
160
  arguments: [::Code::Object::Argument.new(element)],
173
- context: context,
174
- io: io,
161
+ **globals
175
162
  ).truthy?
176
- end,
163
+ end
177
164
  )
178
165
  end
179
166
 
180
- def map(arguments, context:, io:)
181
- sig(arguments, ::Code::Object::Function)
182
- argument = arguments.first.value
167
+ def map(argument, **globals)
183
168
  ::Code::Object::List.new(
184
169
  raw.map do |element|
185
170
  argument.call(
186
171
  arguments: [::Code::Object::Argument.new(element)],
187
- context: context,
188
- io: io,
172
+ **globals
189
173
  )
190
- end,
174
+ end
191
175
  )
192
176
  end
193
177
 
194
- def append(arguments)
195
- sig(arguments, ::Code::Object)
196
- raw << arguments.first.value
178
+ def append(other)
179
+ raw << other
197
180
  self
198
181
  end
199
182
 
200
- def first(arguments)
201
- sig(arguments)
202
- raw.first
183
+ def first
184
+ raw.first || ::Code::Object::Nothing.new
203
185
  end
204
186
 
205
- def max(arguments)
206
- sig(arguments)
187
+ def max
207
188
  raw.max || ::Code::Object::Nothing.new
208
189
  end
209
190
 
210
- def reverse(arguments)
211
- sig(arguments)
191
+ def reverse
212
192
  ::Code::Object::List.new(raw.reverse)
213
193
  end
214
194
 
215
- def last(arguments)
216
- sig(arguments)
217
- raw.last
195
+ def last
196
+ raw.last || ::Code::Object::Nothing.new
218
197
  end
219
198
  end
220
199
  end
@@ -13,27 +13,36 @@ class Code
13
13
  def call(**args)
14
14
  operator = args.fetch(:operator, nil)
15
15
  arguments = args.fetch(:arguments, [])
16
- context = args.fetch(:context)
17
- io = args.fetch(:io)
16
+ globals = multi_fetch(args, *::Code::GLOBALS)
17
+ value = arguments.first&.value
18
18
 
19
19
  if operator == "any?"
20
- any?(arguments, context: context, io: io)
20
+ sig(arguments) { ::Code::Object::Function }
21
+ any?(value, **globals)
21
22
  elsif operator == "all?"
22
- all?(arguments, context: context, io: io)
23
+ sig(arguments) { ::Code::Object::Function }
24
+ all?(value, **globals)
23
25
  elsif operator == "each"
24
- each(arguments, context: context, io: io)
26
+ sig(arguments) { ::Code::Object::Function }
27
+ each(value, **globals)
25
28
  elsif operator == "select"
26
- select(arguments, context: context, io: io)
29
+ sig(arguments) { ::Code::Object::Function }
30
+ select(value, **globals)
27
31
  elsif operator == "map"
28
- map(arguments, context: context, io: io)
32
+ sig(arguments) { ::Code::Object::Function }
33
+ map(value, **globals)
29
34
  elsif operator == "step"
30
- step(arguments)
35
+ sig(arguments) { ::Code::Object::Number }
36
+ step(value)
31
37
  elsif operator == "to_list"
32
- to_list(arguments)
38
+ sig(arguments)
39
+ to_list
33
40
  elsif operator == "first"
34
- first(arguments)
41
+ sig(arguments)
42
+ first
35
43
  elsif operator == "last"
36
- last(arguments)
44
+ sig(arguments)
45
+ last
37
46
  else
38
47
  super
39
48
  end
@@ -49,79 +58,61 @@ class Code
49
58
 
50
59
  private
51
60
 
52
- def any?(arguments, context:, io:)
53
- sig(arguments, ::Code::Object::Function)
54
- argument = arguments.first.value
61
+ def any?(argument, **globals)
55
62
  ::Code::Object::Boolean.new(
56
63
  raw.any? do |element|
57
64
  argument.call(
58
65
  arguments: [::Code::Object::Argument.new(element)],
59
- context: context,
60
- io: io,
66
+ **globals
61
67
  ).truthy?
62
- end,
68
+ end
63
69
  )
64
70
  end
65
71
 
66
- def all?(arguments, context:, io:)
67
- sig(arguments, ::Code::Object::Function)
68
- argument = arguments.first.value
72
+ def all?(argument, **globals)
69
73
  ::Code::Object::Boolean.new(
70
74
  raw.all? do |element|
71
75
  argument.call(
72
76
  arguments: [::Code::Object::Argument.new(element)],
73
- context: context,
74
- io: io,
77
+ **globals
75
78
  ).truthy?
76
- end,
79
+ end
77
80
  )
78
81
  end
79
82
 
80
- def each(arguments, context:, io:)
81
- sig(arguments, ::Code::Object::Function)
82
- argument = arguments.first.value
83
+ def each(argument, **globals)
83
84
  raw.each do |element|
84
85
  argument.call(
85
86
  arguments: [::Code::Object::Argument.new(element)],
86
- context: context,
87
- io: io,
87
+ **globals
88
88
  )
89
89
  end
90
90
  self
91
91
  end
92
92
 
93
- def select(arguments, context:, io:)
94
- sig(arguments, ::Code::Object::Function)
95
- argument = arguments.first.value
93
+ def select(argument, **globals)
96
94
  ::Code::Object::List.new(
97
95
  raw.select do |element|
98
96
  argument.call(
99
97
  arguments: [::Code::Object::Argument.new(element)],
100
- context: context,
101
- io: io,
98
+ **globals
102
99
  ).truthy?
103
- end,
100
+ end
104
101
  )
105
102
  end
106
103
 
107
- def map(arguments, context:, io:)
108
- sig(arguments, ::Code::Object::Function)
109
- argument = arguments.first.value
104
+ def map(argument, **globals)
110
105
  ::Code::Object::List.new(
111
106
  raw.map do |element|
112
107
  argument.call(
113
108
  arguments: [::Code::Object::Argument.new(element)],
114
- context: context,
115
- io: io,
109
+ **globals
116
110
  )
117
- end,
111
+ end
118
112
  )
119
113
  end
120
114
 
121
- def step(arguments)
122
- sig(arguments, ::Code::Object::Number)
123
- argument = arguments.first.value
124
-
115
+ def step(argument)
125
116
  list = ::Code::Object::List.new
126
117
  element = @left
127
118
  list << element
@@ -139,18 +130,15 @@ class Code
139
130
  list
140
131
  end
141
132
 
142
- def to_list(arguments)
143
- sig(arguments)
133
+ def to_list
144
134
  ::Code::Object::List.new(raw.to_a)
145
135
  end
146
136
 
147
- def first(arguments)
148
- sig(arguments)
137
+ def first
149
138
  raw.first
150
139
  end
151
140
 
152
- def last(arguments)
153
- sig(arguments)
141
+ def last
154
142
  raw.last
155
143
  end
156
144
  end
@@ -0,0 +1,31 @@
1
+ class Code
2
+ class Object
3
+ class RubyFunction < ::Code::Object::Function
4
+ attr_reader :raw
5
+
6
+ def initialize(raw)
7
+ @raw = raw
8
+ end
9
+
10
+ private
11
+
12
+ def call_function(args:, globals:)
13
+ regular_arguments =
14
+ args
15
+ .select(&:regular?)
16
+ .map(&:value)
17
+ .map { |argument| ::Code::Ruby.from_code(argument) }
18
+
19
+ keyword_arguments =
20
+ args
21
+ .select(&:keyword?)
22
+ .map do |argument|
23
+ [argument.name.to_sym, ::Code::Ruby.from_code(argument.value)]
24
+ end
25
+ .to_h
26
+
27
+ ::Code::Ruby.to_code(raw.call(*regular_arguments, **keyword_arguments))
28
+ end
29
+ end
30
+ end
31
+ end
@@ -10,15 +10,21 @@ class Code
10
10
  def call(**args)
11
11
  operator = args.fetch(:operator, nil)
12
12
  arguments = args.fetch(:arguments, [])
13
+ globals = multi_fetch(args, *::Code::GLOBALS)
14
+ value = arguments.first&.value
13
15
 
14
- if operator == "to_function"
15
- to_function(arguments)
16
+ if operator == "&" || operator == "to_function"
17
+ sig(arguments)
18
+ to_function(**globals)
16
19
  elsif operator == "+"
17
- plus(arguments)
20
+ sig(arguments) { ::Code::Object }
21
+ plus(value)
18
22
  elsif operator == "*"
19
- multiplication(arguments)
23
+ sig(arguments) { ::Code::Object::Number }
24
+ multiplication(value)
20
25
  elsif operator == "reverse"
21
- reverse(arguments)
26
+ sig(arguments)
27
+ reverse
22
28
  else
23
29
  super
24
30
  end
@@ -42,25 +48,39 @@ class Code
42
48
 
43
49
  private
44
50
 
45
- def to_function(arguments)
46
- sig(arguments)
47
- Code.evaluate("(_) => { _.#{raw} }")
51
+ def to_function(**globals)
52
+ ::Code::Node::Code.new(
53
+ [
54
+ {
55
+ function: {
56
+ parameters: [{ name: "_" }],
57
+ body: [
58
+ {
59
+ chained_call: {
60
+ first: {
61
+ call: {
62
+ name: "_"
63
+ }
64
+ },
65
+ others: [{ call: { name: raw } }]
66
+ }
67
+ }
68
+ ]
69
+ }
70
+ }
71
+ ]
72
+ ).evaluate(**globals)
48
73
  end
49
74
 
50
- def plus(arguments)
51
- sig(arguments, ::Code::Object)
52
- other = arguments.first.value
75
+ def plus(other)
53
76
  ::Code::Object::String.new(raw + other.to_s)
54
77
  end
55
78
 
56
- def multiplication(arguments)
57
- sig(arguments, ::Code::Object::Number)
58
- other = arguments.first.value
79
+ def multiplication(other)
59
80
  ::Code::Object::String.new(raw * other.raw)
60
81
  end
61
82
 
62
- def reverse(arguments)
63
- sig(arguments)
83
+ def reverse
64
84
  ::Code::Object::String.new(raw.reverse)
65
85
  end
66
86
  end