template-ruby 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. checksums.yaml +4 -4
  2. data/.editorconfig +9 -0
  3. data/.gitignore +1 -0
  4. data/.prettierrc +3 -0
  5. data/CHANGELOG.md +15 -0
  6. data/Gemfile.lock +1 -1
  7. data/README.md +10 -0
  8. data/bin/template +39 -0
  9. data/docs/euler/1.template +14 -0
  10. data/docs/euler/2.template +16 -0
  11. data/docs/euler/3.template +16 -0
  12. data/docs/euler/4.template +11 -0
  13. data/docs/euler/5.template +14 -0
  14. data/docs/precedence.template +94 -0
  15. data/lib/code/error.rb +15 -0
  16. data/lib/code/node/base_10_decimal.rb +12 -7
  17. data/lib/code/node/base_10_integer.rb +13 -4
  18. data/lib/code/node/base_10_number.rb +3 -3
  19. data/lib/code/node/base_16_number.rb +2 -2
  20. data/lib/code/node/base_2_number.rb +2 -2
  21. data/lib/code/node/base_8_number.rb +2 -2
  22. data/lib/code/node/block.rb +17 -0
  23. data/lib/code/node/boolean.rb +13 -4
  24. data/lib/code/node/call.rb +40 -8
  25. data/lib/code/node/call_argument.rb +37 -0
  26. data/lib/code/node/chained_call.rb +38 -0
  27. data/lib/code/node/code.rb +4 -7
  28. data/lib/code/node/defined.rb +19 -0
  29. data/lib/code/node/dictionnary.rb +11 -7
  30. data/lib/code/node/dictionnary_key_value.rb +3 -3
  31. data/lib/code/node/equal.rb +36 -0
  32. data/lib/code/node/function.rb +17 -0
  33. data/lib/code/node/function_argument.rb +45 -0
  34. data/lib/code/node/group.rb +13 -0
  35. data/lib/code/node/if.rb +55 -0
  36. data/lib/code/node/if_modifier.rb +48 -0
  37. data/lib/code/node/keyword_call_argument.rb +30 -0
  38. data/lib/code/node/keyword_function_argument.rb +33 -0
  39. data/lib/code/node/list.rb +10 -4
  40. data/lib/code/node/name.rb +37 -4
  41. data/lib/code/node/negation.rb +33 -0
  42. data/lib/code/node/not_keyword.rb +13 -0
  43. data/lib/code/node/nothing.rb +2 -2
  44. data/lib/code/node/number.rb +3 -3
  45. data/lib/code/node/operation.rb +33 -0
  46. data/lib/code/node/or_keyword.rb +34 -0
  47. data/lib/code/node/power.rb +16 -0
  48. data/lib/code/node/range.rb +31 -0
  49. data/lib/code/node/regular_call_argument.rb +34 -0
  50. data/lib/code/node/regular_function_argument.rb +36 -0
  51. data/lib/code/node/rescue.rb +16 -0
  52. data/lib/code/node/statement.rb +53 -3
  53. data/lib/code/node/string.rb +2 -2
  54. data/lib/code/node/ternary.rb +26 -0
  55. data/lib/code/node/unary_minus.rb +22 -0
  56. data/lib/code/node/while.rb +42 -0
  57. data/lib/code/node.rb +10 -0
  58. data/lib/code/object/argument.rb +41 -0
  59. data/lib/code/object/boolean.rb +8 -9
  60. data/lib/code/object/decimal.rb +32 -9
  61. data/lib/code/object/dictionnary.rb +33 -10
  62. data/lib/code/object/function.rb +64 -0
  63. data/lib/code/object/integer.rb +94 -7
  64. data/lib/code/object/list.rb +190 -10
  65. data/lib/code/object/nothing.rb +10 -9
  66. data/lib/code/object/number.rb +6 -0
  67. data/lib/code/object/range.rb +158 -0
  68. data/lib/code/object/string.rb +37 -7
  69. data/lib/code/object.rb +129 -2
  70. data/lib/code/parser/addition.rb +29 -0
  71. data/lib/code/parser/and_operator.rb +28 -0
  72. data/lib/code/parser/bitwise_and.rb +28 -0
  73. data/lib/code/parser/bitwise_or.rb +29 -0
  74. data/lib/code/parser/call.rb +77 -3
  75. data/lib/code/parser/defined.rb +20 -0
  76. data/lib/code/parser/equal.rb +42 -0
  77. data/lib/code/parser/equality.rb +36 -0
  78. data/lib/code/parser/function.rb +57 -0
  79. data/lib/code/parser/greater_than.rb +33 -0
  80. data/lib/code/parser/group.rb +17 -0
  81. data/lib/code/parser/if.rb +33 -0
  82. data/lib/code/parser/if_modifier.rb +28 -0
  83. data/lib/code/parser/multiplication.rb +30 -0
  84. data/lib/code/parser/name.rb +44 -4
  85. data/lib/code/parser/negation.rb +19 -0
  86. data/lib/code/parser/not_keyword.rb +21 -0
  87. data/lib/code/parser/nothing.rb +2 -2
  88. data/lib/code/parser/or_keyword.rb +29 -0
  89. data/lib/code/parser/or_operator.rb +28 -0
  90. data/lib/code/parser/power.rb +25 -0
  91. data/lib/code/parser/range.rb +25 -0
  92. data/lib/code/parser/rescue.rb +23 -0
  93. data/lib/code/parser/shift.rb +31 -0
  94. data/lib/code/parser/statement.rb +1 -4
  95. data/lib/code/parser/string.rb +7 -1
  96. data/lib/code/parser/ternary.rb +25 -0
  97. data/lib/code/parser/unary_minus.rb +13 -0
  98. data/lib/code/parser/while.rb +25 -0
  99. data/lib/code.rb +5 -7
  100. data/lib/template/node/code_part.rb +2 -2
  101. data/lib/template/node/part.rb +2 -2
  102. data/lib/template/node/template.rb +4 -2
  103. data/lib/template/node/text_part.rb +1 -1
  104. data/lib/template-ruby.rb +4 -0
  105. data/lib/template.rb +9 -4
  106. data/spec/call_spec.rb +22 -0
  107. data/spec/code/error/type_error_spec.rb +65 -0
  108. data/spec/code/parser/boolean_spec.rb +1 -1
  109. data/spec/code/parser/call_spec.rb +40 -11
  110. data/spec/code/parser/dictionnary_spec.rb +11 -11
  111. data/spec/code/parser/function_spec.rb +32 -0
  112. data/spec/code/parser/list_spec.rb +5 -5
  113. data/spec/code/parser/nothing_spec.rb +1 -1
  114. data/spec/code/parser/number_spec.rb +35 -35
  115. data/spec/code/parser/string_spec.rb +3 -2
  116. data/spec/code_spec.rb +75 -3
  117. data/spec/function_spec.rb +26 -0
  118. data/spec/spec_helper.rb +2 -0
  119. data/spec/template/parser/template_spec.rb +1 -1
  120. data/spec/template_spec.rb +6 -6
  121. data/template-ruby.gemspec +6 -3
  122. metadata +76 -4
@@ -1,6 +1,6 @@
1
1
  class Code
2
2
  class Node
3
- class DictionnaryKeyValue
3
+ class DictionnaryKeyValue < Node
4
4
  def initialize(key_value)
5
5
  @key = key_value.fetch(:key)
6
6
 
@@ -15,8 +15,8 @@ class Code
15
15
  @value = ::Code::Node::Code.new(key_value.fetch(:value))
16
16
  end
17
17
 
18
- def evaluate(context)
19
- [@key.evaluate(context), @value.evaluate(context)]
18
+ def evaluate(**args)
19
+ [@key.evaluate(**args), @value.evaluate(**args)]
20
20
  end
21
21
  end
22
22
  end
@@ -0,0 +1,36 @@
1
+ class Code
2
+ class Node
3
+ class Equal < Node
4
+ def initialize(equal)
5
+ @left = equal.fetch(:left).fetch(:name)
6
+ @operator = equal.fetch(:operator)
7
+ @right = ::Code::Node::Statement.new(equal.fetch(:right))
8
+ end
9
+
10
+ def evaluate(**args)
11
+ right = @right.evaluate(**args)
12
+ context = args.fetch(:context)
13
+
14
+ if operator
15
+ if context[left]
16
+ context[left] = simple_call(context[left], operator, right, **args)
17
+ else
18
+ raise ::Code::Error::UndefinedVariable.new("#{left} is undefined")
19
+ end
20
+ else
21
+ context[left] = right
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def operator
28
+ @operator.to_s[0...-1].to_sym.presence
29
+ end
30
+
31
+ def left
32
+ ::Code::Object::String.new(@left.to_s)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,17 @@
1
+ class Code
2
+ class Node
3
+ class Function < Node
4
+ def initialize(function)
5
+ @body = ::Code::Node::Code.new(function.fetch(:body))
6
+ @arguments = function.fetch(:arguments, [])
7
+ @arguments.map! do |argument|
8
+ ::Code::Node::FunctionArgument.new(argument)
9
+ end
10
+ end
11
+
12
+ def evaluate(**args)
13
+ ::Code::Object::Function.new(arguments: @arguments, body: @body)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,45 @@
1
+ class Code
2
+ class Node
3
+ class FunctionArgument < Node
4
+ def initialize(argument)
5
+ if argument.key?(:regular)
6
+ @argument =
7
+ ::Code::Node::RegularFunctionArgument.new(argument.fetch(:regular))
8
+ elsif argument.key?(:keyword)
9
+ @argument =
10
+ ::Code::Node::KeywordFunctionArgument.new(argument.fetch(:keyword))
11
+ else
12
+ raise NotImplementedError.new(argument.inspect)
13
+ end
14
+ end
15
+
16
+ def evaluate(**args)
17
+ @argument.evaluate(**args)
18
+ end
19
+
20
+ def splat?
21
+ @argument.splat?
22
+ end
23
+
24
+ def keyword_splat?
25
+ @argument.keyword_splat?
26
+ end
27
+
28
+ def name
29
+ @argument.name
30
+ end
31
+
32
+ def block?
33
+ @argument.block?
34
+ end
35
+
36
+ def regular?
37
+ @argument.is_a?(::Code::Node::RegularFunctionArgument)
38
+ end
39
+
40
+ def keyword?
41
+ @argument.is_a?(::Code::Node::KeywordFunctionArgument)
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,13 @@
1
+ class Code
2
+ class Node
3
+ class Group < Node
4
+ def initialize(group)
5
+ @code = ::Code::Node::Code.new(group)
6
+ end
7
+
8
+ def evaluate(**args)
9
+ @code.evaluate(**args)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,55 @@
1
+ class Code
2
+ class Node
3
+ class If < Node
4
+ IF_KEYWORD = "if"
5
+ UNLESS_KEYWORD = "unless"
6
+
7
+ class Else
8
+ def initialize(else_parsed)
9
+ if else_parsed.key?(:operator)
10
+ @operator = else_parsed.fetch(:operator)
11
+ @statement =
12
+ ::Code::Node::Statement.new(else_parsed.fetch(:statement))
13
+ end
14
+
15
+ @body = ::Code::Node::Code.new(else_parsed.fetch(:body))
16
+ end
17
+
18
+ attr_reader :operator, :body, :statement
19
+ end
20
+
21
+ def initialize(if_parsed)
22
+ @if_operator = if_parsed.fetch(:if_operator)
23
+ @if_statement =
24
+ ::Code::Node::Statement.new(if_parsed.fetch(:if_statement))
25
+ @if_body = ::Code::Node::Code.new(if_parsed.fetch(:if_body))
26
+ @elses = if_parsed.fetch(:elses, [])
27
+ @elses.map! { |else_parsed| ::Code::Node::If::Else.new(else_parsed) }
28
+ end
29
+
30
+ def evaluate(**args)
31
+ if_object = @if_statement.evaluate(**args)
32
+
33
+ if @if_operator == IF_KEYWORD && if_object.truthy?
34
+ @if_body.evaluate(**args)
35
+ elsif @if_operator == UNLESS_KEYWORD && if_object.falsy?
36
+ @if_body.evaluate(**args)
37
+ else
38
+ @elses.each do |else_node|
39
+ if else_node.operator == IF_KEYWORD
40
+ else_object = else_node.statement.evaluate(**args)
41
+ return else_node.body.evaluate(**args) if else_object.truthy?
42
+ elsif else_node.operator == UNLESS_KEYWORD
43
+ else_object = else_node.statement.evaluate(**args)
44
+ return else_node.body.evaluate(**args) if else_object.falsy?
45
+ elsif else_node.operator.nil?
46
+ return else_node.body.evaluate(**args)
47
+ end
48
+ end
49
+
50
+ ::Code::Object::Nothing.new
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,48 @@
1
+ class Code
2
+ class Node
3
+ class IfModifier < Node
4
+ IF_KEYWORD = :if
5
+ UNLESS_KEYWORD = :unless
6
+ WHILE_KEYWORD = :while
7
+ UNTIL_KEYWORD = :until
8
+
9
+ def initialize(if_modifier)
10
+ @left = ::Code::Node::Statement.new(if_modifier.fetch(:left))
11
+ @operator = if_modifier.fetch(:operator)
12
+ @right = ::Code::Node::Statement.new(if_modifier.fetch(:right))
13
+ end
14
+
15
+ def evaluate(**args)
16
+ if operator == IF_KEYWORD
17
+ right = @right.evaluate(**args)
18
+
19
+ right.truthy? ? @left.evaluate(**args) : ::Code::Object::Nothing.new
20
+ elsif operator == UNLESS_KEYWORD
21
+ right = @right.evaluate(**args)
22
+
23
+ right.truthy? ? ::Code::Object::Nothing.new : @left.evaluate(**args)
24
+ elsif operator == WHILE_KEYWORD
25
+ left = ::Code::Object::Nothing.new
26
+
27
+ left = @left.evaluate(**args) while @right.evaluate(**args).truthy?
28
+
29
+ left
30
+ elsif operator == UNTIL_KEYWORD
31
+ left = ::Code::Object::Nothing.new
32
+
33
+ left = @left.evaluate(**args) until @right.evaluate(**args).truthy?
34
+
35
+ left
36
+ else
37
+ raise NotImplementedError.new(operator.inspect)
38
+ end
39
+ end
40
+
41
+ private
42
+
43
+ def operator
44
+ @operator.to_sym
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,30 @@
1
+ class Code
2
+ class Node
3
+ class KeywordCallArgument < Node
4
+ def initialize(argument)
5
+ @name = argument.fetch(:name)
6
+ @value = ::Code::Node::Code.new(argument.fetch(:value))
7
+ end
8
+
9
+ def evaluate(**args)
10
+ @value.evaluate(**args)
11
+ end
12
+
13
+ def name
14
+ ::Code::Object::String.new(@name.to_s)
15
+ end
16
+
17
+ def block?
18
+ false
19
+ end
20
+
21
+ def splat?
22
+ false
23
+ end
24
+
25
+ def keyword_splat?
26
+ false
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,33 @@
1
+ class Code
2
+ class Node
3
+ class KeywordFunctionArgument < Node
4
+ def initialize(argument)
5
+ @name = argument.fetch(:name)
6
+
7
+ if argument.key?(:default)
8
+ @default = ::Code::Node::Code.new(argument.fetch(:default))
9
+ end
10
+ end
11
+
12
+ def evaluate(**args)
13
+ @default ? @default.evaluate(**args) : ::Code::Object::Nothing.new
14
+ end
15
+
16
+ def name
17
+ ::Code::Object::String.new(@name.to_s)
18
+ end
19
+
20
+ def splat?
21
+ false
22
+ end
23
+
24
+ def keyword_splat?
25
+ false
26
+ end
27
+
28
+ def block?
29
+ false
30
+ end
31
+ end
32
+ end
33
+ end
@@ -1,12 +1,18 @@
1
1
  class Code
2
2
  class Node
3
- class List
3
+ class List < Node
4
4
  def initialize(codes)
5
- @codes = codes.map { |code| ::Code::Node::Code.new(code[:code]) }
5
+ @codes =
6
+ codes
7
+ .map do |code|
8
+ code.fetch(:code).presence &&
9
+ ::Code::Node::Code.new(code.fetch(:code))
10
+ end
11
+ .compact
6
12
  end
7
13
 
8
- def evaluate(context)
9
- ::Code::Object::List.new(@codes.map { |code| code.evaluate(context) })
14
+ def evaluate(**args)
15
+ ::Code::Object::List.new(@codes.map { |code| code.evaluate(**args) })
10
16
  end
11
17
  end
12
18
  end
@@ -1,17 +1,50 @@
1
1
  class Code
2
2
  class Node
3
- class Name
3
+ class Name < Node
4
4
  def initialize(name)
5
5
  @name = name
6
6
  end
7
7
 
8
- def evaluate(context)
9
- context.fetch(::Code::Object::String.new(name.to_s))
8
+ def evaluate(**args)
9
+ context = args.fetch(:context)
10
+ arguments = args.fetch(:arguments, [])
11
+ object = args.fetch(:object, nil)
12
+ io = args.fetch(:io)
13
+
14
+ if object
15
+ object.call(
16
+ context: context,
17
+ operator: name,
18
+ arguments: arguments,
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
+
37
+ ::Code::Object::Nothing.new
38
+ else
39
+ raise ::Code::Error::Undefined.new("#{name} undefined")
40
+ end
10
41
  end
11
42
 
12
43
  private
13
44
 
14
- attr_reader :name
45
+ def name
46
+ ::Code::Object::String.new(@name.to_s)
47
+ end
15
48
  end
16
49
  end
17
50
  end
@@ -0,0 +1,33 @@
1
+ class Code
2
+ class Node
3
+ class Negation < Node
4
+ EXCLAMATION_POINT = "!"
5
+ PLUS = "+"
6
+
7
+ def initialize(negation)
8
+ @operator = negation.fetch(:operator)
9
+ @statement = ::Code::Node::Statement.new(negation.fetch(:statement))
10
+ end
11
+
12
+ def evaluate(**args)
13
+ object = @statement.evaluate(**args)
14
+
15
+ if operator == EXCLAMATION_POINT
16
+ if object.truthy?
17
+ ::Code::Object::Boolean.new(false)
18
+ else
19
+ ::Code::Object::Boolean.new(true)
20
+ end
21
+ elsif operator == PLUS
22
+ object
23
+ else
24
+ raise NotImplementedError.new(operator)
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ attr_reader :operator
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,13 @@
1
+ class Code
2
+ class Node
3
+ class NotKeyword < Node
4
+ def initialize(not_keyword)
5
+ @statement = ::Code::Node::Statement.new(not_keyword)
6
+ end
7
+
8
+ def evaluate(**args)
9
+ ::Code::Object::Boolean.new(!@statement.evaluate(**args).truthy?)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -1,10 +1,10 @@
1
1
  class Code
2
2
  class Node
3
- class Nothing
3
+ class Nothing < Node
4
4
  def initialize
5
5
  end
6
6
 
7
- def evaluate(_context)
7
+ def evaluate(**args)
8
8
  ::Code::Object::Nothing.new
9
9
  end
10
10
  end
@@ -1,6 +1,6 @@
1
1
  class Code
2
2
  class Node
3
- class Number
3
+ class Number < Node
4
4
  def initialize(number)
5
5
  if number.key?(:base_2)
6
6
  @number = ::Code::Node::Base2Number.new(number[:base_2])
@@ -15,8 +15,8 @@ class Code
15
15
  end
16
16
  end
17
17
 
18
- def evaluate(context)
19
- @number.evaluate(context)
18
+ def evaluate(**args)
19
+ @number.evaluate(**args)
20
20
  end
21
21
  end
22
22
  end
@@ -0,0 +1,33 @@
1
+ class Code
2
+ class Node
3
+ class Operation < Node
4
+ class Operation
5
+ attr_reader :operator, :statement
6
+
7
+ def initialize(operation)
8
+ @operator = operation.fetch(:operator).to_s
9
+ @statement = ::Code::Node::Statement.new(operation.fetch(:statement))
10
+ end
11
+ end
12
+
13
+ def initialize(operation)
14
+ @first = ::Code::Node::Statement.new(operation.fetch(:first))
15
+ @rest = operation.fetch(:rest)
16
+ @rest.map! do |operation|
17
+ ::Code::Node::Operation::Operation.new(operation)
18
+ end
19
+ end
20
+
21
+ def evaluate(**args)
22
+ object = @first.evaluate(**args)
23
+
24
+ @rest.each do |operation|
25
+ other = operation.statement.evaluate(**args)
26
+ object = simple_call(object, operation.operator, other, **args)
27
+ end
28
+
29
+ object
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,34 @@
1
+ class Code
2
+ class Node
3
+ class OrKeyword < Node
4
+ OR_KEYWORD = "or"
5
+ AND_KEYWORD = "and"
6
+
7
+ def initialize(or_keyword)
8
+ @first = ::Code::Node::Statement.new(or_keyword.fetch(:first))
9
+ @rest = or_keyword.fetch(:rest)
10
+ @rest.map! do |operation|
11
+ ::Code::Node::Operation::Operation.new(operation)
12
+ end
13
+ end
14
+
15
+ def evaluate(**args)
16
+ object = @first.evaluate(**args)
17
+
18
+ @rest.each do |operation|
19
+ if operation.operator == OR_KEYWORD
20
+ return object if object.truthy?
21
+ elsif operation.operator == AND_KEYWORD
22
+ return object unless object.truthy?
23
+ else
24
+ raise NotImplementedError.new(operation.operator.inspect)
25
+ end
26
+
27
+ object = operation.statement.evaluate(**args)
28
+ end
29
+
30
+ object
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,16 @@
1
+ class Code
2
+ class Node
3
+ class Power < Node
4
+ def initialize(power)
5
+ @left = ::Code::Node::Statement.new(power.fetch(:left))
6
+ @right = ::Code::Node::Statement.new(power.fetch(:right))
7
+ end
8
+
9
+ def evaluate(**args)
10
+ right = @right.evaluate(**args)
11
+ left = @left.evaluate(**args)
12
+ simple_call(left, :**, right, **args)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,31 @@
1
+ class Code
2
+ class Node
3
+ class Range < Node
4
+ INCLUSIVE_RANGE = ".."
5
+ EXCLUSIVE_RANGE = "..."
6
+
7
+ def initialize(range)
8
+ @left = ::Code::Node::Statement.new(range.fetch(:left))
9
+ @operator = range.fetch(:operator)
10
+ @right = ::Code::Node::Statement.new(range.fetch(:right))
11
+ end
12
+
13
+ def evaluate(**args)
14
+ left = @left.evaluate(**args)
15
+ right = @right.evaluate(**args)
16
+
17
+ if operator == INCLUSIVE_RANGE
18
+ ::Code::Object::Range.new(left, right, exclude_end: false)
19
+ elsif operator == EXCLUSIVE_RANGE
20
+ ::Code::Object::Range.new(left, right, exclude_end: true)
21
+ else
22
+ raise NotImplementedError.new(operator)
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ attr_reader :operator
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,34 @@
1
+ class Code
2
+ class Node
3
+ class RegularCallArgument < Node
4
+ def initialize(argument)
5
+ @splat = argument.key?(:splat)
6
+ @keyword_splat = argument.key?(:keyword_splat)
7
+ @block = argument.key?(:block)
8
+ @value = ::Code::Node::Code.new(argument.fetch(:value))
9
+ end
10
+
11
+ def evaluate(**args)
12
+ object = @value.evaluate(**args)
13
+
14
+ block? ? simple_call(object, :to_function, **args) : object
15
+ end
16
+
17
+ def block?
18
+ @block
19
+ end
20
+
21
+ def splat?
22
+ @splat
23
+ end
24
+
25
+ def keyword_splat?
26
+ @keyword_splat
27
+ end
28
+
29
+ def name
30
+ nil
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,36 @@
1
+ class Code
2
+ class Node
3
+ class RegularFunctionArgument < Node
4
+ def initialize(argument)
5
+ @block = argument.key?(:block)
6
+ @splat = argument.key?(:splat)
7
+ @keyword_splat = argument.key?(:keyword_splat)
8
+ @name = argument.fetch(:name)
9
+
10
+ if argument.key?(:default)
11
+ @default = ::Code::Node::Code.new(argument.fetch(:default))
12
+ end
13
+ end
14
+
15
+ def evaluate(**args)
16
+ @default ? @default.evaluate(**args) : ::Code::Object::Nothing.new
17
+ end
18
+
19
+ def name
20
+ ::Code::Object::String.new(@name.to_s)
21
+ end
22
+
23
+ def splat?
24
+ @splat
25
+ end
26
+
27
+ def keyword_splat?
28
+ @keyword_splat
29
+ end
30
+
31
+ def block?
32
+ @block
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,16 @@
1
+ class Code
2
+ class Node
3
+ class Rescue < Node
4
+ def initialize(power)
5
+ @left = ::Code::Node::Statement.new(power.fetch(:left))
6
+ @right = ::Code::Node::Statement.new(power.fetch(:right))
7
+ end
8
+
9
+ def evaluate(**args)
10
+ @left.evaluate(**args)
11
+ rescue ::Code::Error
12
+ @right.evaluate(**args)
13
+ end
14
+ end
15
+ end
16
+ end