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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +8 -8
- data/code-ruby.gemspec +0 -3
- data/lib/code/error.rb +3 -0
- data/lib/code/node/call.rb +1 -0
- data/lib/code/node/chained_call.rb +4 -2
- data/lib/code/node/list.rb +2 -3
- data/lib/code/node/name.rb +7 -34
- data/lib/code/node/statement.rb +1 -1
- data/lib/code/node/string.rb +9 -4
- data/lib/code/node/string_component.rb +6 -6
- data/lib/code/node.rb +2 -2
- data/lib/code/object/argument.rb +1 -1
- data/lib/code/object/decimal.rb +99 -27
- data/lib/code/object/dictionnary.rb +29 -13
- data/lib/code/object/function.rb +11 -9
- data/lib/code/object/global.rb +37 -0
- data/lib/code/object/integer.rb +99 -35
- data/lib/code/object/list.rb +62 -89
- data/lib/code/object/range.rb +33 -46
- data/lib/code/object/ruby_function.rb +25 -0
- data/lib/code/object/string.rb +25 -15
- data/lib/code/object.rb +51 -49
- data/lib/code/parser/function.rb +3 -1
- data/lib/code/parser/if.rb +1 -1
- data/lib/code/parser/string.rb +8 -8
- data/lib/code/ruby.rb +161 -0
- data/lib/code-ruby.rb +6 -0
- data/lib/code.rb +20 -6
- data/lib/template/version.rb +1 -1
- data/lib/template-ruby.rb +6 -0
- data/lib/template.rb +24 -9
- data/spec/code/parser/string_spec.rb +1 -1
- data/spec/code_spec.rb +63 -1
- data/spec/template_spec.rb +25 -6
- data/template-ruby.gemspec +0 -3
- metadata +5 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f269ce2ed25933bd413596e077a7f37fdd8b2914d4f2a40c49ae040a3d80eaa2
|
4
|
+
data.tar.gz: ca1870d839bd4ad4d46546b7320c39469fbe8f37425fb3ba0457f9584a6e4907
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e00e5e53b5bd74c402f7e6ea3b32d05ecf06faab892a52cf6b28e4c7c926821f33e7e7fea098b0d7350f58e20c548797bd297c5b6ff2743bbc04a7f8778b92a7
|
7
|
+
data.tar.gz: 4120703ce09203e412baa280f2dae7ea19d51beec10c08f393d8d362e7a294a3a9e21c6ed125768d88fc619f0908d252ce3bd67e2f5fe067e0c320b08a764659
|
data/CHANGELOG.md
CHANGED
@@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
7
|
|
8
|
+
## 0.4.0 / 2022-10-21
|
9
|
+
|
10
|
+
- Rewrite of how functions are called internally (no more `public_send`)
|
11
|
+
- Call ruby functions from template/code
|
12
|
+
|
8
13
|
## 0.3.1 / 2022-10-13
|
9
14
|
|
10
15
|
- Fix Zeitwerk auto-loading issue
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
code-ruby (0.
|
4
|
+
code-ruby (0.3.1)
|
5
5
|
activesupport (~> 7)
|
6
6
|
parslet (~> 2)
|
7
7
|
zeitwerk (~> 2.6)
|
8
|
-
template-ruby (0.
|
8
|
+
template-ruby (0.3.1)
|
9
9
|
activesupport (~> 7)
|
10
10
|
parslet (~> 2)
|
11
11
|
zeitwerk (~> 2.6)
|
@@ -13,7 +13,7 @@ PATH
|
|
13
13
|
GEM
|
14
14
|
remote: https://rubygems.org/
|
15
15
|
specs:
|
16
|
-
activesupport (7.0.
|
16
|
+
activesupport (7.0.4)
|
17
17
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
18
18
|
i18n (>= 1.6, < 2)
|
19
19
|
minitest (>= 5.1)
|
@@ -39,13 +39,13 @@ GEM
|
|
39
39
|
rspec-mocks (~> 3.11.0)
|
40
40
|
rspec-core (3.11.0)
|
41
41
|
rspec-support (~> 3.11.0)
|
42
|
-
rspec-expectations (3.11.
|
42
|
+
rspec-expectations (3.11.1)
|
43
43
|
diff-lcs (>= 1.2.0, < 2.0)
|
44
44
|
rspec-support (~> 3.11.0)
|
45
45
|
rspec-mocks (3.11.1)
|
46
46
|
diff-lcs (>= 1.2.0, < 2.0)
|
47
47
|
rspec-support (~> 3.11.0)
|
48
|
-
rspec-support (3.11.
|
48
|
+
rspec-support (3.11.1)
|
49
49
|
syntax_tree (3.5.0)
|
50
50
|
prettier_print
|
51
51
|
syntax_tree-haml (1.3.1)
|
@@ -60,15 +60,15 @@ GEM
|
|
60
60
|
tilt (2.0.11)
|
61
61
|
tzinfo (2.0.5)
|
62
62
|
concurrent-ruby (~> 1.0)
|
63
|
-
zeitwerk (2.6.
|
63
|
+
zeitwerk (2.6.1)
|
64
64
|
|
65
65
|
PLATFORMS
|
66
66
|
arm64-darwin-21
|
67
67
|
|
68
68
|
DEPENDENCIES
|
69
69
|
code-ruby!
|
70
|
-
prettier
|
71
|
-
rspec
|
70
|
+
prettier
|
71
|
+
rspec
|
72
72
|
template-ruby!
|
73
73
|
|
74
74
|
BUNDLED WITH
|
data/code-ruby.gemspec
CHANGED
data/lib/code/error.rb
CHANGED
data/lib/code/node/call.rb
CHANGED
@@ -16,7 +16,9 @@ class Code
|
|
16
16
|
arguments =
|
17
17
|
@arguments.map do |argument|
|
18
18
|
::Code::Object::Argument.new(
|
19
|
-
argument.evaluate(
|
19
|
+
argument.evaluate(
|
20
|
+
**args.merge(object: ::Code::Object::Global.new),
|
21
|
+
),
|
20
22
|
name: argument.name,
|
21
23
|
splat: argument.splat?,
|
22
24
|
keyword_splat: argument.keyword_splat?,
|
@@ -26,7 +28,7 @@ class Code
|
|
26
28
|
|
27
29
|
if @block
|
28
30
|
arguments << ::Code::Object::Argument.new(
|
29
|
-
@block.evaluate(**args.merge(object:
|
31
|
+
@block.evaluate(**args.merge(object: ::Code::Object::Global.new)),
|
30
32
|
block: true,
|
31
33
|
)
|
32
34
|
end
|
data/lib/code/node/list.rb
CHANGED
data/lib/code/node/name.rb
CHANGED
@@ -8,41 +8,14 @@ class Code
|
|
8
8
|
def evaluate(**args)
|
9
9
|
context = args.fetch(:context)
|
10
10
|
arguments = args.fetch(:arguments, [])
|
11
|
-
object = args.fetch(:object
|
12
|
-
|
11
|
+
object = args.fetch(:object)
|
12
|
+
globals = args.multi_fetch(*::Code::GLOBALS)
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
io: io,
|
20
|
-
)
|
21
|
-
elsif context.key?(name)
|
22
|
-
object = context[name]
|
23
|
-
|
24
|
-
if object.is_a?(::Code::Object::Function)
|
25
|
-
object.call(
|
26
|
-
context: context,
|
27
|
-
operator: nil,
|
28
|
-
arguments: arguments,
|
29
|
-
io: io,
|
30
|
-
)
|
31
|
-
else
|
32
|
-
object
|
33
|
-
end
|
34
|
-
elsif name == "puts"
|
35
|
-
arguments.each { |argument| io.puts argument.value }
|
36
|
-
::Code::Object::Nothing.new
|
37
|
-
elsif name == "print"
|
38
|
-
arguments.each { |argument| io.print argument.value }
|
39
|
-
::Code::Object::Nothing.new
|
40
|
-
elsif name == "context"
|
41
|
-
return ::Code::Object::Nothing.new if arguments.size != 1
|
42
|
-
context[arguments.first&.value] || ::Code::Object::Nothing.new
|
43
|
-
else
|
44
|
-
raise ::Code::Error::Undefined.new("#{name} undefined")
|
45
|
-
end
|
14
|
+
object.call(
|
15
|
+
operator: name,
|
16
|
+
arguments: arguments,
|
17
|
+
**globals
|
18
|
+
)
|
46
19
|
end
|
47
20
|
|
48
21
|
private
|
data/lib/code/node/statement.rb
CHANGED
data/lib/code/node/string.rb
CHANGED
@@ -5,16 +5,21 @@ class Code
|
|
5
5
|
if string.to_s.blank?
|
6
6
|
@string = []
|
7
7
|
elsif string.is_a?(Array)
|
8
|
-
@string =
|
9
|
-
|
10
|
-
|
8
|
+
@string =
|
9
|
+
string.map do |component|
|
10
|
+
::Code::Node::StringComponent.new(component)
|
11
|
+
end
|
11
12
|
else
|
12
13
|
@string = [::Code::Node::StringCharacters.new(string)]
|
13
14
|
end
|
14
15
|
end
|
15
16
|
|
16
17
|
def evaluate(**args)
|
17
|
-
string =
|
18
|
+
string =
|
19
|
+
@string
|
20
|
+
.map { |component| component.evaluate(**args) }
|
21
|
+
.map(&:to_s)
|
22
|
+
.join
|
18
23
|
::Code::Object::String.new(string)
|
19
24
|
end
|
20
25
|
end
|
@@ -3,13 +3,13 @@ class Code
|
|
3
3
|
class StringComponent < Node
|
4
4
|
def initialize(component)
|
5
5
|
if component.key?(:characters)
|
6
|
-
@component =
|
7
|
-
component.fetch(:characters)
|
8
|
-
)
|
6
|
+
@component =
|
7
|
+
::Code::Node::StringCharacters.new(component.fetch(:characters))
|
9
8
|
elsif component.key?(:interpolation)
|
10
|
-
@component =
|
11
|
-
|
12
|
-
|
9
|
+
@component =
|
10
|
+
::Code::Node::StringInterpolation.new(
|
11
|
+
component.fetch(:interpolation),
|
12
|
+
)
|
13
13
|
else
|
14
14
|
raise NotImplementedError.new(component.inspect)
|
15
15
|
end
|
data/lib/code/node.rb
CHANGED
@@ -3,11 +3,11 @@ class Code
|
|
3
3
|
private
|
4
4
|
|
5
5
|
def simple_call(object, operator = nil, value = nil, **args)
|
6
|
+
args = args.multi_fetch(*::Code::GLOBALS)
|
6
7
|
object.call(
|
7
8
|
operator: operator && ::Code::Object::String.new(operator.to_s),
|
8
9
|
arguments: [value && ::Code::Object::Argument.new(value)].compact,
|
9
|
-
|
10
|
-
io: args.fetch(:io),
|
10
|
+
**args
|
11
11
|
)
|
12
12
|
end
|
13
13
|
end
|
data/lib/code/object/argument.rb
CHANGED
data/lib/code/object/decimal.rb
CHANGED
@@ -19,14 +19,51 @@ class Code
|
|
19
19
|
operator = args.fetch(:operator, nil)
|
20
20
|
arguments = args.fetch(:arguments, [])
|
21
21
|
|
22
|
-
if
|
23
|
-
|
24
|
-
|
25
|
-
comparaison(operator.to_sym, arguments)
|
26
|
-
elsif %w[<< >> & | ^].detect { |o| operator == o }
|
27
|
-
integer_operation(operator.to_sym, arguments)
|
22
|
+
if operator == "%"
|
23
|
+
sig(arguments, ::Code::Object::Number)
|
24
|
+
modulo(arguments.first.value)
|
28
25
|
elsif operator == "+"
|
29
|
-
|
26
|
+
sig(arguments, ::Code::Object)
|
27
|
+
plus(arguments.first.value)
|
28
|
+
elsif operator == "-"
|
29
|
+
sig(arguments, ::Code::Object::Number)
|
30
|
+
minus(arguments.first.value)
|
31
|
+
elsif operator == "/"
|
32
|
+
sig(arguments, ::Code::Object::Number)
|
33
|
+
division(arguments.first.value)
|
34
|
+
elsif operator == "*"
|
35
|
+
sig(arguments, ::Code::Object::Number)
|
36
|
+
multiplication(arguments.first.value)
|
37
|
+
elsif operator == "**"
|
38
|
+
sig(arguments, ::Code::Object::Number)
|
39
|
+
power(arguments.first.value)
|
40
|
+
elsif operator == "<"
|
41
|
+
sig(arguments, ::Code::Object::Number)
|
42
|
+
inferior(arguments.first.value)
|
43
|
+
elsif operator == "<="
|
44
|
+
sig(arguments, ::Code::Object::Number)
|
45
|
+
inferior_or_equal(arguments.first.value)
|
46
|
+
elsif operator == ">"
|
47
|
+
sig(arguments, ::Code::Object::Number)
|
48
|
+
superior(arguments.first.value)
|
49
|
+
elsif operator == ">="
|
50
|
+
sig(arguments, ::Code::Object::Number)
|
51
|
+
superior_or_equal(arguments.first.value)
|
52
|
+
elsif operator == "<<"
|
53
|
+
sig(arguments, ::Code::Object::Number)
|
54
|
+
left_shift(arguments.first.value)
|
55
|
+
elsif operator == ">>"
|
56
|
+
sig(arguments, ::Code::Object::Number)
|
57
|
+
right_shift(arguments.first.value)
|
58
|
+
elsif operator == "&"
|
59
|
+
sig(arguments, ::Code::Object::Number)
|
60
|
+
bitwise_and(arguments.first.value)
|
61
|
+
elsif operator == "|"
|
62
|
+
sig(arguments, ::Code::Object::Number)
|
63
|
+
bitwise_or(arguments.first.value)
|
64
|
+
elsif operator == "^"
|
65
|
+
sig(arguments, ::Code::Object::Number)
|
66
|
+
bitwise_xor(arguments.first.value)
|
30
67
|
else
|
31
68
|
super
|
32
69
|
end
|
@@ -42,34 +79,69 @@ class Code
|
|
42
79
|
|
43
80
|
private
|
44
81
|
|
45
|
-
def
|
46
|
-
|
47
|
-
other = arguments.first.value
|
48
|
-
::Code::Object::Decimal.new(raw.public_send(operator, other.raw))
|
82
|
+
def modulo(other)
|
83
|
+
::Code::Object::Decimal.new(raw % other.raw)
|
49
84
|
end
|
50
85
|
|
51
|
-
def
|
52
|
-
sig(arguments, ::Code::Object::Number)
|
53
|
-
other = arguments.first.value
|
54
|
-
::Code::Object::Integer.new(raw.to_i.public_send(operator, other.raw.to_i))
|
55
|
-
end
|
56
|
-
|
57
|
-
def comparaison(operator, arguments)
|
58
|
-
sig(arguments, ::Code::Object::Number)
|
59
|
-
other = arguments.first.value
|
60
|
-
::Code::Object::Boolean.new(raw.public_send(operator, other.raw))
|
61
|
-
end
|
62
|
-
|
63
|
-
def plus(arguments)
|
64
|
-
sig(arguments, ::Code::Object)
|
65
|
-
other = arguments.first.value
|
66
|
-
|
86
|
+
def plus(other)
|
67
87
|
if other.is_a?(::Code::Object::Number)
|
68
88
|
::Code::Object::Decimal.new(raw + other.raw)
|
69
89
|
else
|
70
90
|
::Code::Object::String.new(to_s + other.to_s)
|
71
91
|
end
|
72
92
|
end
|
93
|
+
|
94
|
+
def minus(other)
|
95
|
+
::Code::Object::Decimal.new(raw - other.raw)
|
96
|
+
end
|
97
|
+
|
98
|
+
def division(other)
|
99
|
+
::Code::Object::Decimal.new(raw / other.raw)
|
100
|
+
end
|
101
|
+
|
102
|
+
def multiplication(other)
|
103
|
+
::Code::Object::Decimal.new(raw * other.raw)
|
104
|
+
end
|
105
|
+
|
106
|
+
def power(other)
|
107
|
+
::Code::Object::Decimal.new(raw**other.raw)
|
108
|
+
end
|
109
|
+
|
110
|
+
def inferior(other)
|
111
|
+
::Code::Object::Boolean.new(raw < other.raw)
|
112
|
+
end
|
113
|
+
|
114
|
+
def inferior_or_equal(other)
|
115
|
+
::Code::Object::Boolean.new(raw <= other.raw)
|
116
|
+
end
|
117
|
+
|
118
|
+
def superior(other)
|
119
|
+
::Code::Object::Boolean.new(raw > other.raw)
|
120
|
+
end
|
121
|
+
|
122
|
+
def superior_or_equal(other)
|
123
|
+
::Code::Object::Boolean.new(raw >= other.raw)
|
124
|
+
end
|
125
|
+
|
126
|
+
def left_shift(other)
|
127
|
+
::Code::Object::Integer.new(raw.to_i << other.raw.to_i)
|
128
|
+
end
|
129
|
+
|
130
|
+
def right_shift(other)
|
131
|
+
::Code::Object::Integer.new(raw.to_i >> other.raw.to_i)
|
132
|
+
end
|
133
|
+
|
134
|
+
def bitwise_and(other)
|
135
|
+
::Code::Object::Integer.new(raw.to_i & other.raw.to_i)
|
136
|
+
end
|
137
|
+
|
138
|
+
def bitwise_or(other)
|
139
|
+
::Code::Object::Integer.new(raw.to_i | other.raw.to_i)
|
140
|
+
end
|
141
|
+
|
142
|
+
def bitwise_xor(other)
|
143
|
+
::Code::Object::Integer.new(raw.to_i ^ other.raw.to_i)
|
144
|
+
end
|
73
145
|
end
|
74
146
|
end
|
75
147
|
end
|
@@ -10,20 +10,35 @@ class Code
|
|
10
10
|
def call(**args)
|
11
11
|
operator = args.fetch(:operator, nil)
|
12
12
|
arguments = args.fetch(:arguments, [])
|
13
|
-
|
14
|
-
io = args.fetch(:io)
|
13
|
+
globals = args.multi_fetch(*::Code::GLOBALS)
|
15
14
|
|
16
15
|
if operator == "values"
|
17
|
-
|
16
|
+
sig(arguments)
|
17
|
+
values
|
18
|
+
elsif operator == "keys"
|
19
|
+
sig(arguments)
|
20
|
+
keys
|
18
21
|
elsif operator == "each"
|
19
|
-
|
22
|
+
sig(arguments, ::Code::Object::Function)
|
23
|
+
each(arguments.first.value, **globals)
|
20
24
|
elsif key?(operator)
|
21
|
-
fetch(operator)
|
25
|
+
result = fetch(operator)
|
26
|
+
|
27
|
+
if result.is_a?(::Code::Object::Function)
|
28
|
+
result.call(**args.merge(operator: nil))
|
29
|
+
else
|
30
|
+
sig(arguments)
|
31
|
+
result
|
32
|
+
end
|
22
33
|
else
|
23
34
|
super
|
24
35
|
end
|
25
36
|
end
|
26
37
|
|
38
|
+
def merge(other)
|
39
|
+
::Code::Object::Dictionnary.new(raw.merge(other.raw))
|
40
|
+
end
|
41
|
+
|
27
42
|
def fetch(key)
|
28
43
|
raw.fetch(key)
|
29
44
|
end
|
@@ -54,24 +69,25 @@ class Code
|
|
54
69
|
|
55
70
|
private
|
56
71
|
|
57
|
-
def
|
58
|
-
|
72
|
+
def keys
|
73
|
+
::Code::Object::List.new(raw.keys)
|
74
|
+
end
|
75
|
+
|
76
|
+
def values
|
59
77
|
::Code::Object::List.new(raw.values)
|
60
78
|
end
|
61
79
|
|
62
|
-
def each(
|
63
|
-
sig(arguments, ::Code::Object::Function)
|
64
|
-
argument = arguments.first.value
|
80
|
+
def each(argument, **globals)
|
65
81
|
raw.each do |key, value|
|
66
82
|
argument.call(
|
67
83
|
arguments: [
|
68
84
|
::Code::Object::Argument.new(key),
|
69
|
-
::Code::Object::Argument.new(value)
|
85
|
+
::Code::Object::Argument.new(value),
|
70
86
|
],
|
71
|
-
|
72
|
-
io: io,
|
87
|
+
**globals,
|
73
88
|
)
|
74
89
|
end
|
90
|
+
|
75
91
|
self
|
76
92
|
end
|
77
93
|
end
|
data/lib/code/object/function.rb
CHANGED
@@ -9,11 +9,10 @@ class Code
|
|
9
9
|
def call(**args)
|
10
10
|
operator = args.fetch(:operator, nil)
|
11
11
|
arguments = args.fetch(:arguments, [])
|
12
|
-
|
13
|
-
io = args.fetch(:io)
|
12
|
+
globals = args.multi_fetch(*::Code::GLOBALS)
|
14
13
|
|
15
|
-
if operator.nil?
|
16
|
-
call_function(args: arguments,
|
14
|
+
if operator.nil? || operator == "call"
|
15
|
+
call_function(args: arguments, globals: globals)
|
17
16
|
else
|
18
17
|
super
|
19
18
|
end
|
@@ -31,8 +30,8 @@ class Code
|
|
31
30
|
|
32
31
|
attr_reader :arguments, :body
|
33
32
|
|
34
|
-
def call_function(args:,
|
35
|
-
new_context = context.deep_dup
|
33
|
+
def call_function(args:, globals:)
|
34
|
+
new_context = globals[:context].deep_dup
|
36
35
|
|
37
36
|
arguments.each.with_index do |argument, index|
|
38
37
|
if argument.regular?
|
@@ -46,19 +45,22 @@ class Code
|
|
46
45
|
)
|
47
46
|
else
|
48
47
|
arg = args[index]&.value
|
49
|
-
arg = argument.evaluate(
|
48
|
+
arg = argument.evaluate(**globals) if arg.nil?
|
50
49
|
new_context[argument.name] = arg
|
51
50
|
end
|
52
51
|
elsif argument.keyword?
|
53
52
|
arg = args.detect { |arg| arg.name == argument.name }&.value
|
54
|
-
arg = argument.evaluate(
|
53
|
+
arg = argument.evaluate(**globals) if arg.nil?
|
55
54
|
new_context[argument.name] = arg
|
56
55
|
else
|
57
56
|
raise NotImplementedError
|
58
57
|
end
|
59
58
|
end
|
60
59
|
|
61
|
-
body.evaluate(
|
60
|
+
body.evaluate(
|
61
|
+
**globals,
|
62
|
+
context: new_context,
|
63
|
+
)
|
62
64
|
end
|
63
65
|
end
|
64
66
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
class Code
|
2
|
+
class Object
|
3
|
+
class Global < ::Code::Object
|
4
|
+
def call(**args)
|
5
|
+
operator = args.fetch(:operator, nil)
|
6
|
+
arguments = args.fetch(:arguments, [])
|
7
|
+
context = args.fetch(:context)
|
8
|
+
io = args.fetch(:io)
|
9
|
+
globals = args.multi_fetch(*::Code::GLOBALS)
|
10
|
+
|
11
|
+
if operator == "print"
|
12
|
+
io.print(*arguments.map(&:value))
|
13
|
+
::Code::Object::Nothing.new
|
14
|
+
elsif operator == "puts"
|
15
|
+
io.puts(*arguments.map(&:value))
|
16
|
+
::Code::Object::Nothing.new
|
17
|
+
elsif operator == "context"
|
18
|
+
sig(arguments, ::Code::Object::String)
|
19
|
+
context[arguments.first.value] || ::Code::Object::Nothing.new
|
20
|
+
elsif operator == "eval"
|
21
|
+
sig(arguments, ::Code::Object::String)
|
22
|
+
Code.evaluate(arguments.first.value.raw)
|
23
|
+
else
|
24
|
+
result = context[operator]
|
25
|
+
|
26
|
+
if result && result.is_a?(::Code::Object::Function)
|
27
|
+
result.call(**args.merge(operator: nil))
|
28
|
+
elsif result
|
29
|
+
result
|
30
|
+
else
|
31
|
+
raise ::Code::Error::Undefined.new("#{operator} is not defined")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|