language-ruby 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 (187) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +9 -0
  3. data/.github/workflows/rspec.yml +14 -0
  4. data/.gitignore +2 -0
  5. data/.prettierrc +3 -0
  6. data/.rspec +1 -0
  7. data/CHANGELOG.md +55 -0
  8. data/Gemfile +8 -0
  9. data/Gemfile.lock +48 -0
  10. data/LICENSE +7 -0
  11. data/README.md +103 -0
  12. data/TODO +17 -0
  13. data/bin/code +76 -0
  14. data/bin/format +3 -0
  15. data/bin/template +85 -0
  16. data/bin/test +17 -0
  17. data/code-ruby.gemspec +17 -0
  18. data/docs/class.code +9 -0
  19. data/docs/euler/1.template +10 -0
  20. data/docs/euler/2.template +16 -0
  21. data/docs/euler/3.template +16 -0
  22. data/docs/euler/4.template +10 -0
  23. data/docs/euler/5.template +13 -0
  24. data/docs/fibonnaci.template +14 -0
  25. data/docs/meetup.code +12 -0
  26. data/docs/precedence.template +36 -0
  27. data/docs/rain.code +22 -0
  28. data/docs/slack.code +17 -0
  29. data/docs/stripe.code +7 -0
  30. data/docs/twitter.code +9 -0
  31. data/language-ruby.gemspec +18 -0
  32. data/lib/code/error.rb +18 -0
  33. data/lib/code/node/base_10.rb +29 -0
  34. data/lib/code/node/base_16.rb +13 -0
  35. data/lib/code/node/base_2.rb +13 -0
  36. data/lib/code/node/base_8.rb +13 -0
  37. data/lib/code/node/boolean.rb +22 -0
  38. data/lib/code/node/call.rb +47 -0
  39. data/lib/code/node/call_argument.rb +21 -0
  40. data/lib/code/node/chained_call.rb +23 -0
  41. data/lib/code/node/code.rb +20 -0
  42. data/lib/code/node/decimal.rb +26 -0
  43. data/lib/code/node/dictionnary.rb +33 -0
  44. data/lib/code/node/equal.rb +34 -0
  45. data/lib/code/node/function.rb +20 -0
  46. data/lib/code/node/function_parameter.rb +31 -0
  47. data/lib/code/node/if.rb +59 -0
  48. data/lib/code/node/if_modifier.rb +47 -0
  49. data/lib/code/node/list.rb +16 -0
  50. data/lib/code/node/negation.rb +15 -0
  51. data/lib/code/node/not.rb +15 -0
  52. data/lib/code/node/nothing.rb +12 -0
  53. data/lib/code/node/number.rb +25 -0
  54. data/lib/code/node/operation.rb +38 -0
  55. data/lib/code/node/power.rb +20 -0
  56. data/lib/code/node/rescue.rb +17 -0
  57. data/lib/code/node/splat.rb +15 -0
  58. data/lib/code/node/statement.rb +59 -0
  59. data/lib/code/node/string.rb +53 -0
  60. data/lib/code/node/ternary.rb +24 -0
  61. data/lib/code/node/unary_minus.rb +15 -0
  62. data/lib/code/node/while.rb +35 -0
  63. data/lib/code/node.rb +13 -0
  64. data/lib/code/object/argument.rb +32 -0
  65. data/lib/code/object/boolean.rb +27 -0
  66. data/lib/code/object/decimal.rb +162 -0
  67. data/lib/code/object/dictionnary.rb +96 -0
  68. data/lib/code/object/function.rb +64 -0
  69. data/lib/code/object/global.rb +42 -0
  70. data/lib/code/object/integer.rb +221 -0
  71. data/lib/code/object/list.rb +200 -0
  72. data/lib/code/object/nothing.rb +23 -0
  73. data/lib/code/object/number.rb +6 -0
  74. data/lib/code/object/range.rb +146 -0
  75. data/lib/code/object/ruby_function.rb +31 -0
  76. data/lib/code/object/string.rb +88 -0
  77. data/lib/code/object.rb +197 -0
  78. data/lib/code/parser/addition.rb +21 -0
  79. data/lib/code/parser/and_operator.rb +17 -0
  80. data/lib/code/parser/bitwise_and.rb +17 -0
  81. data/lib/code/parser/bitwise_or.rb +21 -0
  82. data/lib/code/parser/boolean.rb +17 -0
  83. data/lib/code/parser/call.rb +122 -0
  84. data/lib/code/parser/chained_call.rb +47 -0
  85. data/lib/code/parser/class.rb +45 -0
  86. data/lib/code/parser/code.rb +25 -0
  87. data/lib/code/parser/dictionnary.rb +67 -0
  88. data/lib/code/parser/equal.rb +94 -0
  89. data/lib/code/parser/equality.rb +35 -0
  90. data/lib/code/parser/equality_lower.rb +9 -0
  91. data/lib/code/parser/function.rb +85 -0
  92. data/lib/code/parser/greater.rb +25 -0
  93. data/lib/code/parser/group.rb +22 -0
  94. data/lib/code/parser/if.rb +63 -0
  95. data/lib/code/parser/if_modifier.rb +55 -0
  96. data/lib/code/parser/list.rb +42 -0
  97. data/lib/code/parser/multiplication.rb +25 -0
  98. data/lib/code/parser/name.rb +101 -0
  99. data/lib/code/parser/negation.rb +30 -0
  100. data/lib/code/parser/not_keyword.rb +23 -0
  101. data/lib/code/parser/nothing.rb +22 -0
  102. data/lib/code/parser/number.rb +154 -0
  103. data/lib/code/parser/operation.rb +35 -0
  104. data/lib/code/parser/or_keyword.rb +21 -0
  105. data/lib/code/parser/or_operator.rb +17 -0
  106. data/lib/code/parser/power.rb +43 -0
  107. data/lib/code/parser/range.rb +17 -0
  108. data/lib/code/parser/rescue.rb +39 -0
  109. data/lib/code/parser/shift.rb +21 -0
  110. data/lib/code/parser/splat.rb +31 -0
  111. data/lib/code/parser/statement.rb +9 -0
  112. data/lib/code/parser/string.rb +78 -0
  113. data/lib/code/parser/ternary.rb +46 -0
  114. data/lib/code/parser/unary_minus.rb +31 -0
  115. data/lib/code/parser/while.rb +36 -0
  116. data/lib/code/parser/whitespace.rb +49 -0
  117. data/lib/code/parser.rb +19 -0
  118. data/lib/code/ruby.rb +162 -0
  119. data/lib/code-ruby.rb +10 -0
  120. data/lib/code.rb +47 -0
  121. data/lib/language/atom.rb +343 -0
  122. data/lib/language/output.rb +130 -0
  123. data/lib/language/parser/absent/present.rb +8 -0
  124. data/lib/language/parser/absent.rb +6 -0
  125. data/lib/language/parser/end_of_input.rb +6 -0
  126. data/lib/language/parser/interuption.rb +38 -0
  127. data/lib/language/parser/not_end_of_input.rb +6 -0
  128. data/lib/language/parser/str/not_found.rb +16 -0
  129. data/lib/language/parser/str.rb +6 -0
  130. data/lib/language/parser.rb +53 -0
  131. data/lib/language-ruby.rb +10 -0
  132. data/lib/language.rb +80 -0
  133. data/lib/template/node/code_part.rb +13 -0
  134. data/lib/template/node/part.rb +19 -0
  135. data/lib/template/node/template.rb +15 -0
  136. data/lib/template/node/text_part.rb +13 -0
  137. data/lib/template/node.rb +4 -0
  138. data/lib/template/parser/template.rb +39 -0
  139. data/lib/template/parser.rb +19 -0
  140. data/lib/template/version.rb +3 -0
  141. data/lib/template-ruby.rb +10 -0
  142. data/lib/template.rb +50 -0
  143. data/spec/code/addition_spec.rb +13 -0
  144. data/spec/code/and_operator_spec.rb +13 -0
  145. data/spec/code/bitwise_and_spec.rb +13 -0
  146. data/spec/code/bitwise_or_spec.rb +13 -0
  147. data/spec/code/boolean_spec.rb +13 -0
  148. data/spec/code/call_spec.rb +21 -0
  149. data/spec/code/chained_call_spec.rb +16 -0
  150. data/spec/code/dictionnary_spec.rb +17 -0
  151. data/spec/code/equal_spec.rb +26 -0
  152. data/spec/code/equality_spec.rb +13 -0
  153. data/spec/code/function_spec.rb +18 -0
  154. data/spec/code/greater_spec.rb +18 -0
  155. data/spec/code/group_spec.rb +12 -0
  156. data/spec/code/if_modifier_spec.rb +20 -0
  157. data/spec/code/if_spec.rb +25 -0
  158. data/spec/code/list_spec.rb +17 -0
  159. data/spec/code/multiplication_spec.rb +18 -0
  160. data/spec/code/negation_spec.rb +20 -0
  161. data/spec/code/not_keyword_spec.rb +13 -0
  162. data/spec/code/nothing_spec.rb +17 -0
  163. data/spec/code/number_spec.rb +22 -0
  164. data/spec/code/or_keyword_spec.rb +17 -0
  165. data/spec/code/or_operator_spec.rb +16 -0
  166. data/spec/code/parser/boolean_spec.rb +16 -0
  167. data/spec/code/parser/call_spec.rb +26 -0
  168. data/spec/code/parser/chained_call.rb +17 -0
  169. data/spec/code/parser/dictionnary_spec.rb +18 -0
  170. data/spec/code/parser/function_spec.rb +16 -0
  171. data/spec/code/parser/group_spec.rb +18 -0
  172. data/spec/code/parser/list_spec.rb +18 -0
  173. data/spec/code/parser/number_spec.rb +12 -0
  174. data/spec/code/parser/string_spec.rb +21 -0
  175. data/spec/code/parser_spec.rb +23 -0
  176. data/spec/code/power_spec.rb +13 -0
  177. data/spec/code/range_spec.rb +16 -0
  178. data/spec/code/rescue_spec.rb +13 -0
  179. data/spec/code/shift_spec.rb +13 -0
  180. data/spec/code/splat_spec.rb +13 -0
  181. data/spec/code/string_spec.rb +25 -0
  182. data/spec/code/ternary_spec.rb +18 -0
  183. data/spec/code/unary_minus_spec.rb +13 -0
  184. data/spec/code/while_spec.rb +18 -0
  185. data/spec/spec_helper.rb +6 -0
  186. data/template-ruby.gemspec +19 -0
  187. metadata +284 -0
@@ -0,0 +1,221 @@
1
+ class Code
2
+ class Object
3
+ class Integer < ::Code::Object::Number
4
+ attr_reader :raw
5
+
6
+ def initialize(whole, exponent: nil)
7
+ @raw = whole.to_i
8
+
9
+ if exponent
10
+ if exponent.is_a?(::Code::Object::Number)
11
+ @raw = @raw * 10**exponent.raw
12
+ else
13
+ raise ::Code::Error::TypeError.new("exponent is not a number")
14
+ end
15
+ end
16
+ end
17
+
18
+ def call(**args)
19
+ operator = args.fetch(:operator, nil)
20
+ arguments = args.fetch(:arguments, [])
21
+ globals = multi_fetch(args, *::Code::GLOBALS)
22
+ value = arguments.first&.value
23
+
24
+ if operator == "even?"
25
+ sig(arguments)
26
+ even?
27
+ elsif operator == "odd?"
28
+ sig(arguments)
29
+ odd?
30
+ elsif operator == "times"
31
+ sig(arguments) { ::Code::Object::Function }
32
+ times(value, **globals)
33
+ elsif operator == "*"
34
+ sig(arguments) { [[::Code::Object::Number, ::Code::Object::String]] }
35
+ multiplication(value)
36
+ elsif operator == "/"
37
+ sig(arguments) { ::Code::Object::Number }
38
+ division(value)
39
+ elsif operator == "+"
40
+ if value
41
+ sig(arguments) { ::Code::Object }
42
+ plus(value)
43
+ else
44
+ sig(arguments)
45
+ self
46
+ end
47
+ elsif operator == "%"
48
+ sig(arguments) { ::Code::Object::Number }
49
+ modulo(value)
50
+ elsif operator == "-"
51
+ if value
52
+ sig(arguments) { ::Code::Object::Number }
53
+ minus(value)
54
+ else
55
+ sig(arguments)
56
+ unary_minus
57
+ end
58
+ elsif operator == "**"
59
+ sig(arguments) { ::Code::Object::Number }
60
+ power(value)
61
+ elsif operator == "<"
62
+ sig(arguments) { ::Code::Object::Number }
63
+ inferior(value)
64
+ elsif operator == "<="
65
+ sig(arguments) { ::Code::Object::Number }
66
+ inferior_or_equal(value)
67
+ elsif operator == ">"
68
+ sig(arguments) { ::Code::Object::Number }
69
+ superior(value)
70
+ elsif operator == ">="
71
+ sig(arguments) { ::Code::Object::Number }
72
+ superior_or_equal(value)
73
+ elsif operator == "<<"
74
+ sig(arguments) { ::Code::Object::Number }
75
+ left_shift(value)
76
+ elsif operator == ">>"
77
+ sig(arguments) { ::Code::Object::Number }
78
+ right_shift(value)
79
+ elsif operator == "&"
80
+ sig(arguments) { ::Code::Object::Number }
81
+ bitwise_and(value)
82
+ elsif operator == "|"
83
+ sig(arguments) { ::Code::Object::Number }
84
+ bitwise_or(value)
85
+ elsif operator == "^"
86
+ sig(arguments) { ::Code::Object::Number }
87
+ bitwise_xor(value)
88
+ else
89
+ super
90
+ end
91
+ end
92
+
93
+ def succ
94
+ ::Code::Object::Integer.new(raw + 1)
95
+ end
96
+
97
+ def +(other)
98
+ ::Code::Object::Integer.new(raw + other.raw)
99
+ end
100
+
101
+ def to_s
102
+ raw.to_s
103
+ end
104
+
105
+ def inspect
106
+ to_s
107
+ end
108
+
109
+ private
110
+
111
+ def even?
112
+ ::Code::Object::Boolean.new(raw.even?)
113
+ end
114
+
115
+ def odd?
116
+ ::Code::Object::Boolean.new(raw.odd?)
117
+ end
118
+
119
+ def multiplication(other)
120
+ if other.is_a?(::Code::Object::Integer)
121
+ ::Code::Object::Integer.new(raw * other.raw)
122
+ elsif other.is_a?(::Code::Object::Decimal)
123
+ ::Code::Object::Decimal.new(raw * other.raw)
124
+ else
125
+ ::Code::Object::String.new(other.raw * raw)
126
+ end
127
+ end
128
+
129
+ def plus(other)
130
+ if other.is_a?(::Code::Object::Integer)
131
+ ::Code::Object::Integer.new(raw + other.raw)
132
+ elsif other.is_a?(::Code::Object::Decimal)
133
+ ::Code::Object::Decimal.new(raw + other.raw)
134
+ else
135
+ ::Code::Object::String.new(to_s + other.to_s)
136
+ end
137
+ end
138
+
139
+ def division(other)
140
+ ::Code::Object::Decimal.new(BigDecimal(raw) / other.raw)
141
+ end
142
+
143
+ def modulo(other)
144
+ if other.is_a?(::Code::Object::Integer)
145
+ ::Code::Object::Integer.new(raw % other.raw)
146
+ else
147
+ ::Code::Object::Decimal.new(raw % other.raw)
148
+ end
149
+ end
150
+
151
+ def minus(other)
152
+ if other.is_a?(::Code::Object::Integer)
153
+ ::Code::Object::Integer.new(raw - other.raw)
154
+ else
155
+ ::Code::Object::Decimal.new(raw - other.raw)
156
+ end
157
+ end
158
+
159
+ def unary_minus
160
+ ::Code::Object::Integer.new(-raw)
161
+ end
162
+
163
+ def power(other)
164
+ if other.is_a?(::Code::Object::Integer)
165
+ ::Code::Object::Integer.new(raw**other.raw)
166
+ else
167
+ ::Code::Object::Decimal.new(raw**other.raw)
168
+ end
169
+ end
170
+
171
+ def inferior(other)
172
+ ::Code::Object::Boolean.new(raw < other.raw)
173
+ end
174
+
175
+ def inferior_or_equal(other)
176
+ ::Code::Object::Boolean.new(raw <= other.raw)
177
+ end
178
+
179
+ def superior(other)
180
+ ::Code::Object::Boolean.new(raw > other.raw)
181
+ end
182
+
183
+ def superior_or_equal(other)
184
+ ::Code::Object::Boolean.new(raw >= other.raw)
185
+ end
186
+
187
+ def left_shift(other)
188
+ ::Code::Object::Integer.new(raw << other.raw.to_i)
189
+ end
190
+
191
+ def right_shift(other)
192
+ ::Code::Object::Integer.new(raw >> other.raw.to_i)
193
+ end
194
+
195
+ def bitwise_and(other)
196
+ ::Code::Object::Integer.new(raw & other.raw.to_i)
197
+ end
198
+
199
+ def bitwise_or(other)
200
+ ::Code::Object::Integer.new(raw | other.raw.to_i)
201
+ end
202
+
203
+ def bitwise_xor(other)
204
+ ::Code::Object::Integer.new(raw ^ other.raw.to_i)
205
+ end
206
+
207
+ def times(argument, **globals)
208
+ raw.times do |element|
209
+ argument.call(
210
+ arguments: [
211
+ ::Code::Object::Argument.new(::Code::Object::Integer.new(element))
212
+ ],
213
+ **globals
214
+ )
215
+ end
216
+
217
+ self
218
+ end
219
+ end
220
+ end
221
+ end
@@ -0,0 +1,200 @@
1
+ class Code
2
+ class Object
3
+ class List < ::Code::Object
4
+ attr_reader :raw
5
+
6
+ def initialize(raw = [])
7
+ @raw = raw
8
+ end
9
+
10
+ def call(**args)
11
+ operator = args.fetch(:operator, nil)
12
+ arguments = args.fetch(:arguments, [])
13
+ globals = multi_fetch(args, *::Code::GLOBALS)
14
+ value = arguments.first&.value
15
+
16
+ if operator == "any?"
17
+ sig(arguments) { ::Code::Object::Function }
18
+ any?(value, **globals)
19
+ elsif operator == "none?"
20
+ sig(arguments) { ::Code::Object::Function }
21
+ none?(value, **globals)
22
+ elsif operator == "detect"
23
+ sig(arguments) { ::Code::Object::Function }
24
+ detect(value, **globals)
25
+ elsif operator == "reduce"
26
+ sig(arguments) { ::Code::Object::Function }
27
+ reduce(value, **globals)
28
+ elsif operator == "each"
29
+ sig(arguments) { ::Code::Object::Function }
30
+ each(value, **globals)
31
+ elsif operator == "select"
32
+ sig(arguments) { ::Code::Object::Function }
33
+ select(value, **globals)
34
+ elsif operator == "map"
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)
40
+ elsif operator == "max"
41
+ sig(arguments)
42
+ max
43
+ elsif operator == "flatten"
44
+ sig(arguments)
45
+ flatten
46
+ elsif operator == "reverse"
47
+ sig(arguments)
48
+ reverse
49
+ elsif operator == "first"
50
+ sig(arguments)
51
+ first
52
+ elsif operator == "last"
53
+ sig(arguments)
54
+ last
55
+ elsif operator == "<<"
56
+ sig(arguments) { ::Code::Object }
57
+ append(value)
58
+ else
59
+ super
60
+ end
61
+ end
62
+
63
+ def flatten
64
+ ::Code::Object::List.new(
65
+ raw.reduce([]) do |acc, element|
66
+ if element.is_a?(::Code::Object::List)
67
+ acc + element.flatten.raw
68
+ else
69
+ acc + [element]
70
+ end
71
+ end
72
+ )
73
+ end
74
+
75
+ def deep_dup
76
+ ::Code::Object::List.new(raw.deep_dup)
77
+ end
78
+
79
+ def <<(other)
80
+ raw << other
81
+ self
82
+ end
83
+
84
+ def to_s
85
+ "[#{raw.map(&:inspect).join(", ")}]"
86
+ end
87
+
88
+ def inspect
89
+ to_s
90
+ end
91
+
92
+ private
93
+
94
+ def any?(argument, **globals)
95
+ ::Code::Object::Boolean.new(
96
+ raw.any? do |element|
97
+ argument.call(
98
+ arguments: [::Code::Object::Argument.new(element)],
99
+ **globals
100
+ ).truthy?
101
+ end
102
+ )
103
+ end
104
+
105
+ def none?(argument, **globals)
106
+ ::Code::Object::Boolean.new(
107
+ raw.none? do |element|
108
+ argument.call(
109
+ arguments: [::Code::Object::Argument.new(element)],
110
+ **globals
111
+ ).truthy?
112
+ end
113
+ )
114
+ end
115
+
116
+ def max_by(argument, **globals)
117
+ raw.max_by do |element|
118
+ argument.call(
119
+ arguments: [::Code::Object::Argument.new(element)],
120
+ **globals
121
+ )
122
+ end || ::Code::Object::Nothing.new
123
+ end
124
+
125
+ def detect(argument, **globals)
126
+ raw.detect do |element|
127
+ argument.call(
128
+ arguments: [::Code::Object::Argument.new(element)],
129
+ **globals
130
+ ).truthy?
131
+ end || ::Code::Object::Nothing.new
132
+ end
133
+
134
+ def reduce(argument, **globals)
135
+ raw.reduce do |acc, element|
136
+ argument.call(
137
+ arguments: [
138
+ ::Code::Object::Argument.new(acc),
139
+ ::Code::Object::Argument.new(element)
140
+ ],
141
+ **globals
142
+ )
143
+ end || ::Code::Object::Nothing.new
144
+ end
145
+
146
+ def each(argument, **globals)
147
+ raw.each do |element|
148
+ argument.call(
149
+ arguments: [::Code::Object::Argument.new(element)],
150
+ **globals
151
+ )
152
+ end
153
+ self
154
+ end
155
+
156
+ def select(argument, **globals)
157
+ ::Code::Object::List.new(
158
+ raw.select do |element|
159
+ argument.call(
160
+ arguments: [::Code::Object::Argument.new(element)],
161
+ **globals
162
+ ).truthy?
163
+ end
164
+ )
165
+ end
166
+
167
+ def map(argument, **globals)
168
+ ::Code::Object::List.new(
169
+ raw.map do |element|
170
+ argument.call(
171
+ arguments: [::Code::Object::Argument.new(element)],
172
+ **globals
173
+ )
174
+ end
175
+ )
176
+ end
177
+
178
+ def append(other)
179
+ raw << other
180
+ self
181
+ end
182
+
183
+ def first
184
+ raw.first || ::Code::Object::Nothing.new
185
+ end
186
+
187
+ def max
188
+ raw.max || ::Code::Object::Nothing.new
189
+ end
190
+
191
+ def reverse
192
+ ::Code::Object::List.new(raw.reverse)
193
+ end
194
+
195
+ def last
196
+ raw.last || ::Code::Object::Nothing.new
197
+ end
198
+ end
199
+ end
200
+ end
@@ -0,0 +1,23 @@
1
+ class Code
2
+ class Object
3
+ class Nothing < ::Code::Object
4
+ attr_reader :raw
5
+
6
+ def initialize
7
+ @raw = nil
8
+ end
9
+
10
+ def truthy?
11
+ false
12
+ end
13
+
14
+ def to_s
15
+ ""
16
+ end
17
+
18
+ def inspect
19
+ "nothing"
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,6 @@
1
+ class Code
2
+ class Object
3
+ class Number < ::Code::Object
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,146 @@
1
+ class Code
2
+ class Object
3
+ class Range < ::Code::Object
4
+ attr_reader :raw
5
+
6
+ def initialize(left, right, exclude_end: false)
7
+ @left = left
8
+ @right = right
9
+ @exclude_end = exclude_end
10
+ @raw = ::Range.new(left, right, exclude_end)
11
+ end
12
+
13
+ def call(**args)
14
+ operator = args.fetch(:operator, nil)
15
+ arguments = args.fetch(:arguments, [])
16
+ globals = multi_fetch(args, *::Code::GLOBALS)
17
+ value = arguments.first&.value
18
+
19
+ if operator == "any?"
20
+ sig(arguments) { ::Code::Object::Function }
21
+ any?(value, **globals)
22
+ elsif operator == "all?"
23
+ sig(arguments) { ::Code::Object::Function }
24
+ all?(value, **globals)
25
+ elsif operator == "each"
26
+ sig(arguments) { ::Code::Object::Function }
27
+ each(value, **globals)
28
+ elsif operator == "select"
29
+ sig(arguments) { ::Code::Object::Function }
30
+ select(value, **globals)
31
+ elsif operator == "map"
32
+ sig(arguments) { ::Code::Object::Function }
33
+ map(value, **globals)
34
+ elsif operator == "step"
35
+ sig(arguments) { ::Code::Object::Number }
36
+ step(value)
37
+ elsif operator == "to_list"
38
+ sig(arguments)
39
+ to_list
40
+ elsif operator == "first"
41
+ sig(arguments)
42
+ first
43
+ elsif operator == "last"
44
+ sig(arguments)
45
+ last
46
+ else
47
+ super
48
+ end
49
+ end
50
+
51
+ def to_s
52
+ raw.to_s
53
+ end
54
+
55
+ def inspect
56
+ to_s
57
+ end
58
+
59
+ private
60
+
61
+ def any?(argument, **globals)
62
+ ::Code::Object::Boolean.new(
63
+ raw.any? do |element|
64
+ argument.call(
65
+ arguments: [::Code::Object::Argument.new(element)],
66
+ **globals
67
+ ).truthy?
68
+ end
69
+ )
70
+ end
71
+
72
+ def all?(argument, **globals)
73
+ ::Code::Object::Boolean.new(
74
+ raw.all? do |element|
75
+ argument.call(
76
+ arguments: [::Code::Object::Argument.new(element)],
77
+ **globals
78
+ ).truthy?
79
+ end
80
+ )
81
+ end
82
+
83
+ def each(argument, **globals)
84
+ raw.each do |element|
85
+ argument.call(
86
+ arguments: [::Code::Object::Argument.new(element)],
87
+ **globals
88
+ )
89
+ end
90
+ self
91
+ end
92
+
93
+ def select(argument, **globals)
94
+ ::Code::Object::List.new(
95
+ raw.select do |element|
96
+ argument.call(
97
+ arguments: [::Code::Object::Argument.new(element)],
98
+ **globals
99
+ ).truthy?
100
+ end
101
+ )
102
+ end
103
+
104
+ def map(argument, **globals)
105
+ ::Code::Object::List.new(
106
+ raw.map do |element|
107
+ argument.call(
108
+ arguments: [::Code::Object::Argument.new(element)],
109
+ **globals
110
+ )
111
+ end
112
+ )
113
+ end
114
+
115
+ def step(argument)
116
+ list = ::Code::Object::List.new
117
+ element = @left
118
+ list << element
119
+
120
+ if @exlucde_end
121
+ while (element = element + argument) < @right
122
+ list << element
123
+ end
124
+ else
125
+ while (element = element + argument) <= @right
126
+ list << element
127
+ end
128
+ end
129
+
130
+ list
131
+ end
132
+
133
+ def to_list
134
+ ::Code::Object::List.new(raw.to_a)
135
+ end
136
+
137
+ def first
138
+ raw.first
139
+ end
140
+
141
+ def last
142
+ raw.last
143
+ end
144
+ end
145
+ end
146
+ 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
@@ -0,0 +1,88 @@
1
+ class Code
2
+ class Object
3
+ class String < ::Code::Object
4
+ attr_reader :raw
5
+
6
+ def initialize(string)
7
+ @raw = string
8
+ end
9
+
10
+ def call(**args)
11
+ operator = args.fetch(:operator, nil)
12
+ arguments = args.fetch(:arguments, [])
13
+ globals = multi_fetch(args, *::Code::GLOBALS)
14
+ value = arguments.first&.value
15
+
16
+ if operator == "&" || operator == "to_function"
17
+ sig(arguments)
18
+ to_function(**globals)
19
+ elsif operator == "+"
20
+ sig(arguments) { ::Code::Object }
21
+ plus(value)
22
+ elsif operator == "*"
23
+ sig(arguments) { ::Code::Object::Number }
24
+ multiplication(value)
25
+ elsif operator == "reverse"
26
+ sig(arguments)
27
+ reverse
28
+ else
29
+ super
30
+ end
31
+ end
32
+
33
+ def succ
34
+ ::Code::Object::String.new(raw.succ)
35
+ end
36
+
37
+ def to_sym
38
+ raw.to_sym
39
+ end
40
+
41
+ def to_s
42
+ raw
43
+ end
44
+
45
+ def inspect
46
+ raw.inspect
47
+ end
48
+
49
+ private
50
+
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)
73
+ end
74
+
75
+ def plus(other)
76
+ ::Code::Object::String.new(raw + other.to_s)
77
+ end
78
+
79
+ def multiplication(other)
80
+ ::Code::Object::String.new(raw * other.raw)
81
+ end
82
+
83
+ def reverse
84
+ ::Code::Object::String.new(raw.reverse)
85
+ end
86
+ end
87
+ end
88
+ end