code-ruby 0.3.1 → 0.4.0

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