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