language-ruby 0.5.0

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