code-ruby 0.5.6 → 0.6.1

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.
Files changed (218) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -3
  3. data/Gemfile.lock +11 -21
  4. data/README.md +2 -102
  5. data/bin/code +34 -16
  6. data/code-ruby.gemspec +5 -3
  7. data/lib/code/error.rb +16 -5
  8. data/lib/code/node/base_10.rb +4 -2
  9. data/lib/code/node/base_16.rb +3 -1
  10. data/lib/code/node/base_2.rb +3 -1
  11. data/lib/code/node/base_8.rb +3 -1
  12. data/lib/code/node/boolean.rb +4 -2
  13. data/lib/code/node/call.rb +35 -12
  14. data/lib/code/node/call_argument.rb +16 -5
  15. data/lib/code/node/code.rb +5 -4
  16. data/lib/code/node/decimal.rb +2 -0
  17. data/lib/code/node/{dictionnary.rb → dictionary.rb} +14 -5
  18. data/lib/code/node/function.rb +7 -4
  19. data/lib/code/node/function_parameter.rb +3 -1
  20. data/lib/code/node/if.rb +5 -3
  21. data/lib/code/node/left_operation.rb +63 -0
  22. data/lib/code/node/list.rb +2 -0
  23. data/lib/code/node/negation.rb +2 -0
  24. data/lib/code/node/not.rb +2 -0
  25. data/lib/code/node/nothing.rb +3 -1
  26. data/lib/code/node/number.rb +2 -0
  27. data/lib/code/node/right_operation.rb +70 -0
  28. data/lib/code/node/splat.rb +2 -0
  29. data/lib/code/node/square_bracket.rb +37 -0
  30. data/lib/code/node/statement.rb +13 -5
  31. data/lib/code/node/string.rb +3 -1
  32. data/lib/code/node/ternary.rb +5 -3
  33. data/lib/code/node/unary_minus.rb +2 -0
  34. data/lib/code/node/while.rb +6 -4
  35. data/lib/code/node.rb +11 -5
  36. data/lib/code/object/argument.rb +13 -7
  37. data/lib/code/object/boolean.rb +43 -5
  38. data/lib/code/object/class.rb +17 -0
  39. data/lib/code/object/context.rb +36 -0
  40. data/lib/code/object/decimal.rb +252 -100
  41. data/lib/code/object/dictionary.rb +641 -0
  42. data/lib/code/object/function.rb +54 -27
  43. data/lib/code/object/global.rb +65 -19
  44. data/lib/code/object/identifier_list.rb +47 -0
  45. data/lib/code/object/integer.rb +320 -137
  46. data/lib/code/object/list.rb +140 -138
  47. data/lib/code/object/nothing.rb +10 -4
  48. data/lib/code/object/number.rb +6 -1
  49. data/lib/code/object/range.rb +85 -88
  50. data/lib/code/object/ruby_function.rb +11 -6
  51. data/lib/code/object/string.rb +51 -48
  52. data/lib/code/object.rb +117 -139
  53. data/lib/code/parser/addition.rb +4 -2
  54. data/lib/code/parser/and_operator.rb +4 -2
  55. data/lib/code/parser/bitwise_and.rb +4 -2
  56. data/lib/code/parser/bitwise_or.rb +4 -2
  57. data/lib/code/parser/boolean.rb +3 -1
  58. data/lib/code/parser/call.rb +17 -11
  59. data/lib/code/parser/chained_call.rb +10 -22
  60. data/lib/code/parser/class.rb +9 -6
  61. data/lib/code/parser/code.rb +6 -4
  62. data/lib/code/parser/{dictionnary.rb → dictionary.rb} +16 -13
  63. data/lib/code/parser/equal.rb +9 -36
  64. data/lib/code/parser/equality.rb +4 -2
  65. data/lib/code/parser/function.rb +24 -9
  66. data/lib/code/parser/greater.rb +6 -3
  67. data/lib/code/parser/group.rb +4 -2
  68. data/lib/code/parser/if.rb +6 -4
  69. data/lib/code/parser/if_modifier.rb +5 -25
  70. data/lib/code/parser/left_operation.rb +40 -0
  71. data/lib/code/parser/list.rb +6 -5
  72. data/lib/code/parser/multiplication.rb +4 -2
  73. data/lib/code/parser/name.rb +19 -4
  74. data/lib/code/parser/negation.rb +4 -2
  75. data/lib/code/parser/not_keyword.rb +5 -3
  76. data/lib/code/parser/nothing.rb +3 -10
  77. data/lib/code/parser/number.rb +4 -2
  78. data/lib/code/parser/or_keyword.rb +4 -2
  79. data/lib/code/parser/or_operator.rb +4 -2
  80. data/lib/code/parser/power.rb +4 -28
  81. data/lib/code/parser/range.rb +4 -2
  82. data/lib/code/parser/rescue.rb +6 -26
  83. data/lib/code/parser/right_operation.rb +40 -0
  84. data/lib/code/parser/shift.rb +4 -2
  85. data/lib/code/parser/splat.rb +5 -3
  86. data/lib/code/parser/square_bracket.rb +48 -0
  87. data/lib/code/parser/statement.rb +3 -1
  88. data/lib/code/parser/string.rb +12 -10
  89. data/lib/code/parser/ternary.rb +10 -11
  90. data/lib/code/parser/unary_minus.rb +5 -3
  91. data/lib/code/parser/while.rb +5 -3
  92. data/lib/code/parser/whitespace.rb +2 -0
  93. data/lib/code/parser.rb +10 -3
  94. data/lib/code/ruby.rb +4 -2
  95. data/lib/code/type/hash.rb +38 -0
  96. data/lib/code/type/maybe.rb +29 -0
  97. data/lib/code/type/or.rb +38 -0
  98. data/lib/code/type/repeat.rb +38 -0
  99. data/lib/code/type/sig.rb +130 -0
  100. data/lib/code/type.rb +25 -0
  101. data/lib/code/version.rb +3 -0
  102. data/lib/code-ruby.rb +1 -2
  103. data/lib/code.rb +15 -16
  104. data/spec/code/node/call_spec.rb +39 -0
  105. data/spec/code/object/boolean_spec.rb +18 -0
  106. data/spec/code/object/decimal_spec.rb +51 -0
  107. data/spec/code/object/dictionary_spec.rb +98 -0
  108. data/spec/code/object/function_spec.rb +42 -0
  109. data/spec/code/object/integer_spec.rb +43 -0
  110. data/spec/code/object/nothing_spec.rb +14 -0
  111. data/spec/code/object/range_spec.rb +23 -0
  112. data/spec/code/parser/boolean_spec.rb +5 -10
  113. data/spec/code/parser/chained_call.rb +4 -5
  114. data/spec/code/parser/{dictionnary_spec.rb → dictionary_spec.rb} +5 -6
  115. data/spec/code/parser/function_spec.rb +4 -5
  116. data/spec/code/parser/group_spec.rb +5 -12
  117. data/spec/code/parser/if_modifier_spec.rb +18 -0
  118. data/spec/code/parser/list_spec.rb +4 -5
  119. data/spec/code/parser/number_spec.rb +4 -5
  120. data/spec/code/parser/string_spec.rb +4 -5
  121. data/spec/code/parser_spec.rb +22 -16
  122. data/spec/code/type_spec.rb +21 -0
  123. data/spec/code_spec.rb +171 -0
  124. data/spec/spec_helper.rb +1 -6
  125. metadata +63 -136
  126. data/.cherry.js +0 -21
  127. data/.editorconfig +0 -9
  128. data/.github/workflows/rspec.yml +0 -14
  129. data/.gitignore +0 -2
  130. data/.prettierrc +0 -3
  131. data/.tool-versions +0 -1
  132. data/CHANGELOG.md +0 -55
  133. data/LICENSE +0 -7
  134. data/TODO +0 -17
  135. data/bin/format +0 -3
  136. data/bin/publish +0 -19
  137. data/bin/template +0 -85
  138. data/bin/test +0 -17
  139. data/docs/class.code +0 -9
  140. data/docs/euler/1.template +0 -10
  141. data/docs/euler/2.template +0 -16
  142. data/docs/euler/3.template +0 -16
  143. data/docs/euler/4.template +0 -10
  144. data/docs/euler/5.template +0 -13
  145. data/docs/fibonnaci.template +0 -14
  146. data/docs/meetup.code +0 -12
  147. data/docs/precedence.template +0 -36
  148. data/docs/rain.code +0 -22
  149. data/docs/slack.code +0 -17
  150. data/docs/stripe.code +0 -7
  151. data/docs/twitter.code +0 -9
  152. data/language-ruby.gemspec +0 -17
  153. data/lib/code/node/chained_call.rb +0 -23
  154. data/lib/code/node/equal.rb +0 -34
  155. data/lib/code/node/if_modifier.rb +0 -47
  156. data/lib/code/node/operation.rb +0 -38
  157. data/lib/code/node/power.rb +0 -20
  158. data/lib/code/node/rescue.rb +0 -17
  159. data/lib/code/object/dictionnary.rb +0 -96
  160. data/lib/code/parser/equality_lower.rb +0 -9
  161. data/lib/code/parser/operation.rb +0 -35
  162. data/lib/language/atom.rb +0 -342
  163. data/lib/language/output.rb +0 -130
  164. data/lib/language/parser/absent/present.rb +0 -8
  165. data/lib/language/parser/absent.rb +0 -6
  166. data/lib/language/parser/end_of_input.rb +0 -6
  167. data/lib/language/parser/interuption.rb +0 -38
  168. data/lib/language/parser/not_end_of_input.rb +0 -6
  169. data/lib/language/parser/str/not_found.rb +0 -16
  170. data/lib/language/parser/str.rb +0 -6
  171. data/lib/language/parser.rb +0 -53
  172. data/lib/language-ruby.rb +0 -10
  173. data/lib/language.rb +0 -80
  174. data/lib/template/node/code_part.rb +0 -13
  175. data/lib/template/node/part.rb +0 -19
  176. data/lib/template/node/template.rb +0 -15
  177. data/lib/template/node/text_part.rb +0 -13
  178. data/lib/template/node.rb +0 -4
  179. data/lib/template/parser/template.rb +0 -39
  180. data/lib/template/parser.rb +0 -19
  181. data/lib/template/version.rb +0 -3
  182. data/lib/template-ruby.rb +0 -10
  183. data/lib/template.rb +0 -50
  184. data/spec/code/addition_spec.rb +0 -13
  185. data/spec/code/and_operator_spec.rb +0 -13
  186. data/spec/code/bitwise_and_spec.rb +0 -13
  187. data/spec/code/bitwise_or_spec.rb +0 -13
  188. data/spec/code/boolean_spec.rb +0 -13
  189. data/spec/code/call_spec.rb +0 -21
  190. data/spec/code/chained_call_spec.rb +0 -16
  191. data/spec/code/code_spec.rb +0 -29
  192. data/spec/code/dictionnary_spec.rb +0 -17
  193. data/spec/code/equal_spec.rb +0 -26
  194. data/spec/code/equality_spec.rb +0 -13
  195. data/spec/code/function_spec.rb +0 -18
  196. data/spec/code/greater_spec.rb +0 -18
  197. data/spec/code/group_spec.rb +0 -12
  198. data/spec/code/if_modifier_spec.rb +0 -20
  199. data/spec/code/if_spec.rb +0 -25
  200. data/spec/code/list_spec.rb +0 -19
  201. data/spec/code/multiplication_spec.rb +0 -18
  202. data/spec/code/negation_spec.rb +0 -20
  203. data/spec/code/not_keyword_spec.rb +0 -13
  204. data/spec/code/nothing_spec.rb +0 -17
  205. data/spec/code/number_spec.rb +0 -22
  206. data/spec/code/or_keyword_spec.rb +0 -17
  207. data/spec/code/or_operator_spec.rb +0 -16
  208. data/spec/code/parser/call_spec.rb +0 -26
  209. data/spec/code/power_spec.rb +0 -13
  210. data/spec/code/range_spec.rb +0 -16
  211. data/spec/code/rescue_spec.rb +0 -13
  212. data/spec/code/shift_spec.rb +0 -13
  213. data/spec/code/splat_spec.rb +0 -13
  214. data/spec/code/string_spec.rb +0 -27
  215. data/spec/code/ternary_spec.rb +0 -18
  216. data/spec/code/unary_minus_spec.rb +0 -13
  217. data/spec/code/while_spec.rb +0 -18
  218. data/template-ruby.gemspec +0 -19
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Code
4
+ class Node
5
+ class LeftOperation < Node
6
+ class Operator < Node
7
+ DOT = "."
8
+ COLON_COLON = "::"
9
+
10
+ attr_reader :operator, :statement
11
+
12
+ def initialize(parsed)
13
+ @operator = parsed.delete(:operator)
14
+ @statement = Statement.new(parsed.delete(:statement))
15
+ end
16
+
17
+ def call?
18
+ operator == DOT || operator == COLON_COLON
19
+ end
20
+ end
21
+
22
+ def initialize(parsed)
23
+ @first = Statement.new(parsed.delete(:first))
24
+ @others =
25
+ parsed.delete(:others).map { |operator| Operator.new(operator) }
26
+
27
+ super(parsed)
28
+ end
29
+
30
+ def evaluate(**args)
31
+ first = @first.evaluate(**args)
32
+
33
+ @others.reduce(first) do |left, right|
34
+ if right.call?
35
+ right.statement.evaluate(**args, object: left)
36
+ else
37
+ statement = right.statement.evaluate(**args)
38
+
39
+ left.call(
40
+ **args,
41
+ operator: right.operator,
42
+ arguments: [::Code::Object::Argument.new(statement)]
43
+ )
44
+ end
45
+ end
46
+ end
47
+
48
+ def resolve(**args)
49
+ first = @first.resolve(**args)
50
+
51
+ list = Object::IdentifierList.new([first])
52
+
53
+ @others.each do |other|
54
+ list.code_append(
55
+ other.statement.resolve(**args, object: list.code_last)
56
+ )
57
+ end
58
+
59
+ list
60
+ end
61
+ end
62
+ end
63
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Code
2
4
  class Node
3
5
  class List < Node
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Code
2
4
  class Node
3
5
  class Negation < Node
data/lib/code/node/not.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Code
2
4
  class Node
3
5
  class Not < Node
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Code
2
4
  class Node
3
5
  class Nothing < Node
4
6
  def initialize(parsed)
5
7
  end
6
8
 
7
- def evaluate(**args)
9
+ def evaluate(**_args)
8
10
  ::Code::Object::Nothing.new
9
11
  end
10
12
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Code
2
4
  class Node
3
5
  class Number < Node
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Code
4
+ class Node
5
+ class RightOperation < Node
6
+ EQUAL = "="
7
+
8
+ def initialize(parsed)
9
+ @left = Statement.new(parsed.delete(:left))
10
+ @operator = parsed.delete(:operator)
11
+ @right = Statement.new(parsed.delete(:right))
12
+
13
+ super(parsed)
14
+ end
15
+
16
+ def evaluate(**args)
17
+ case @operator
18
+ when "if"
19
+ if @right.evaluate(**args).truthy?
20
+ @left.evaluate(**args)
21
+ else
22
+ Object::Nothing.new
23
+ end
24
+ when "unless"
25
+ if @right.evaluate(**args).truthy?
26
+ Object::Nothing.new
27
+ else
28
+ @left.evaluate(**args)
29
+ end
30
+ when "while"
31
+ left = Object::Nothing.new
32
+
33
+ left = @left.evaluate(**args) while @right.evaluate(**args).truthy?
34
+
35
+ left
36
+ when "until"
37
+ left = Object::Nothing.new
38
+
39
+ left = @left.evaluate(**args) while @right.evaluate(**args).falsy?
40
+
41
+ left
42
+ when "rescue"
43
+ begin
44
+ @left.evaluate(**args)
45
+ rescue Error
46
+ @right.evaluate(**args)
47
+ end
48
+ when /=$/
49
+ right = @right.evaluate(**args)
50
+ left = @left.resolve(**args)
51
+
52
+ left.call(
53
+ operator: @operator,
54
+ arguments: [Object::Argument.new(right)],
55
+ **args
56
+ )
57
+ else
58
+ right = @right.evaluate(**args)
59
+ left = @left.evaluate(**args)
60
+
61
+ left.call(
62
+ operator: @operator,
63
+ arguments: [Object::Argument.new(right)],
64
+ **args
65
+ )
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Code
2
4
  class Node
3
5
  class Splat < Node
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Code
4
+ class Node
5
+ class SquareBracket < Node
6
+ def initialize(parsed)
7
+ @left = Node::Statement.new(parsed.delete(:left))
8
+ @statements =
9
+ parsed
10
+ .delete(:statements)
11
+ .map { |statement| Node::Statement.new(statement) }
12
+
13
+ super(parsed)
14
+ end
15
+
16
+ def evaluate(**args)
17
+ left = @left.evaluate(**args)
18
+
19
+ @statements.reduce(left) do |object, statement|
20
+ object.code_fetch(statement.evaluate(**args))
21
+ end
22
+ end
23
+
24
+ def resolve(**args)
25
+ left = @left.resolve(**args)
26
+
27
+ list = Object::IdentifierList.new([left])
28
+
29
+ @statements.each do |statement|
30
+ list.code_append(statement.evaluate(**args))
31
+ end
32
+
33
+ list
34
+ end
35
+ end
36
+ end
37
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Code
2
4
  class Node
3
5
  class Statement < Node
@@ -17,13 +19,13 @@ class Code
17
19
  elsif parsed.key?(:list)
18
20
  @statement = Node::List.new(parsed.delete(:list))
19
21
  elsif parsed.key?(:dictionnary)
20
- @statement = Node::Dictionnary.new(parsed.delete(:dictionnary))
22
+ @statement = Node::Dictionary.new(parsed.delete(:dictionnary))
21
23
  elsif parsed.key?(:chained_call)
22
24
  @statement = Node::ChainedCall.new(parsed.delete(:chained_call))
23
- elsif parsed.key?(:operation)
24
- @statement = Node::Operation.new(parsed.delete(:operation))
25
- elsif parsed.key?(:equal)
26
- @statement = Node::Equal.new(parsed.delete(:equal))
25
+ elsif parsed.key?(:left_operation)
26
+ @statement = Node::LeftOperation.new(parsed.delete(:left_operation))
27
+ elsif parsed.key?(:right_operation)
28
+ @statement = Node::RightOperation.new(parsed.delete(:right_operation))
27
29
  elsif parsed.key?(:function)
28
30
  @statement = Node::Function.new(parsed.delete(:function))
29
31
  elsif parsed.key?(:negation)
@@ -46,6 +48,8 @@ class Code
46
48
  @statement = Node::While.new(parsed.delete(:while))
47
49
  elsif parsed.key?(:splat)
48
50
  @statement = Node::Splat.new(parsed.delete(:splat))
51
+ elsif parsed.key?(:square_bracket)
52
+ @statement = Node::SquareBracket.new(parsed.delete(:square_bracket))
49
53
  end
50
54
 
51
55
  super(parsed)
@@ -54,6 +58,10 @@ class Code
54
58
  def evaluate(**args)
55
59
  @statement.evaluate(**args)
56
60
  end
61
+
62
+ def resolve(**args)
63
+ @statement.resolve(**args)
64
+ end
57
65
  end
58
66
  end
59
67
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Code
2
4
  class Node
3
5
  class String < Node
@@ -17,7 +19,7 @@ class Code
17
19
  @text = parsed
18
20
  end
19
21
 
20
- def evaluate(**args)
22
+ def evaluate(**_args)
21
23
  ::Code::Object::String.new(@text)
22
24
  end
23
25
  end
@@ -1,12 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Code
2
4
  class Node
3
5
  class Ternary < Node
4
6
  def initialize(parsed)
5
7
  @left = Node::Statement.new(parsed.delete(:left))
6
8
  @middle = Node::Statement.new(parsed.delete(:middle))
7
- if parsed.key?(:right)
8
- @right = Node::Statement.new(parsed.delete(:right))
9
- end
9
+ @right = Node::Statement.new(parsed.delete(:right)) if parsed.key?(
10
+ :right
11
+ )
10
12
  super(parsed)
11
13
  end
12
14
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Code
2
4
  class Node
3
5
  class UnaryMinus < Node
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Code
2
4
  class Node
3
5
  class While < Node
@@ -15,9 +17,9 @@ class Code
15
17
  if @operator == WHILE_KEYWORD
16
18
  last = ::Code::Object::Nothing.new
17
19
 
18
- while @statement.evaluate(**args).truthy?
19
- last = @body.evaluate(**args)
20
- end
20
+ last = @body.evaluate(**args) while @statement.evaluate(
21
+ **args
22
+ ).truthy?
21
23
 
22
24
  last
23
25
  elsif @operator == UNTIL_KEYWORD
@@ -27,7 +29,7 @@ class Code
27
29
 
28
30
  last
29
31
  else
30
- raise NotImplementedError.new(@operator)
32
+ raise NotImplementedError, @operator
31
33
  end
32
34
  end
33
35
  end
data/lib/code/node.rb CHANGED
@@ -1,13 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Code
2
4
  class Node
3
5
  def initialize(parsed)
4
- if parsed.any?
5
- raise NotImplementedError.new(self.class.name + ": " + parsed.inspect)
6
- end
6
+ return unless parsed.any?
7
+
8
+ raise NotImplementedError, "#{self.class.name}: #{parsed.inspect}"
9
+ end
10
+
11
+ def evaluate(**_args)
12
+ raise NotImplementedError, "#{self.class.name}#evaluate"
7
13
  end
8
14
 
9
- def evaluate(**args)
10
- raise NotImplementedError.new(self.class.name + "#evaluate")
15
+ def resolve(...)
16
+ evaluate(...)
11
17
  end
12
18
  end
13
19
  end
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Code
2
4
  class Object
3
- class Argument
5
+ class Argument < Object
4
6
  attr_reader :value, :name
5
7
 
6
8
  def initialize(value, name: nil)
@@ -8,8 +10,12 @@ class Code
8
10
  @name = name
9
11
  end
10
12
 
11
- def regular?
12
- !name
13
+ def self.name
14
+ "Argument"
15
+ end
16
+
17
+ def inspect
18
+ to_s
13
19
  end
14
20
 
15
21
  def keyword?
@@ -20,12 +26,12 @@ class Code
20
26
  [name, value]
21
27
  end
22
28
 
23
- def to_s
24
- "<Argument #{value.inspect}>"
29
+ def regular?
30
+ !name
25
31
  end
26
32
 
27
- def inspect
28
- to_s
33
+ def to_s
34
+ "<Argument #{value.inspect}>"
29
35
  end
30
36
  end
31
37
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Code
2
4
  class Object
3
5
  class Boolean < ::Code::Object
@@ -7,20 +9,56 @@ class Code
7
9
  @raw = raw
8
10
  end
9
11
 
10
- def truthy?
11
- raw
12
+ def self.name
13
+ "Boolean"
14
+ end
15
+
16
+ def call(**args)
17
+ operator = args.fetch(:operator, nil)
18
+ arguments = args.fetch(:arguments, [])
19
+ value = arguments.first&.value
20
+
21
+ case operator.to_s
22
+ when "&", "bitwise_and"
23
+ sig(args) { Boolean }
24
+ code_bitwise_and(value)
25
+ when "^", "bitwise_xor"
26
+ sig(args) { Boolean }
27
+ code_bitwise_xor(value)
28
+ when "|", "bitwise_or"
29
+ sig(args) { Boolean }
30
+ code_bitwise_or(value)
31
+ else
32
+ super
33
+ end
34
+ end
35
+
36
+ def code_bitwise_and(value)
37
+ Boolean.new(raw & value.raw)
38
+ end
39
+
40
+ def code_bitwise_or(value)
41
+ Boolean.new(raw | value.raw)
42
+ end
43
+
44
+ def code_bitwise_xor(value)
45
+ Boolean.new(raw ^ value.raw)
46
+ end
47
+
48
+ def inspect
49
+ to_s
12
50
  end
13
51
 
14
52
  def succ
15
- ::Code::Object::Boolean.new(!raw)
53
+ Boolean.new(!raw)
16
54
  end
17
55
 
18
56
  def to_s
19
57
  raw.to_s
20
58
  end
21
59
 
22
- def inspect
23
- to_s
60
+ def truthy?
61
+ raw
24
62
  end
25
63
  end
26
64
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Code
4
+ class Object
5
+ class Class < Object
6
+ attr_reader :raw
7
+
8
+ def initialize(raw)
9
+ @raw = raw
10
+ end
11
+
12
+ def self.name
13
+ "Class"
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Code
4
+ class Object
5
+ class Context < Dictionary
6
+ attr_reader :parent
7
+
8
+ def initialize(raw = {}, parent: nil)
9
+ @raw = raw
10
+ @parent = parent
11
+ end
12
+
13
+ def self.name
14
+ "Context"
15
+ end
16
+
17
+ def lookup!(identifier)
18
+ if code_has_key?(identifier).truthy?
19
+ self
20
+ elsif parent?
21
+ parent.lookup!(identifier)
22
+ else
23
+ raise Code::Error::Undefined, "#{identifier} is not defined"
24
+ end
25
+ end
26
+
27
+ def merge(other)
28
+ Context.new(raw.merge(other.raw), parent: parent || other.parent)
29
+ end
30
+
31
+ def parent?
32
+ !!parent
33
+ end
34
+ end
35
+ end
36
+ end