code-ruby 0.5.5 → 0.6.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.
Files changed (218) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -4
  3. data/Gemfile.lock +10 -22
  4. data/code-ruby.gemspec +4 -3
  5. data/lib/code/error.rb +16 -5
  6. data/lib/code/node/base_10.rb +4 -2
  7. data/lib/code/node/base_16.rb +3 -1
  8. data/lib/code/node/base_2.rb +3 -1
  9. data/lib/code/node/base_8.rb +3 -1
  10. data/lib/code/node/boolean.rb +4 -2
  11. data/lib/code/node/call.rb +35 -12
  12. data/lib/code/node/call_argument.rb +16 -5
  13. data/lib/code/node/code.rb +5 -4
  14. data/lib/code/node/decimal.rb +2 -0
  15. data/lib/code/node/{dictionnary.rb → dictionary.rb} +14 -5
  16. data/lib/code/node/function.rb +7 -4
  17. data/lib/code/node/function_parameter.rb +3 -1
  18. data/lib/code/node/if.rb +5 -3
  19. data/lib/code/node/left_operation.rb +63 -0
  20. data/lib/code/node/list.rb +2 -0
  21. data/lib/code/node/negation.rb +2 -0
  22. data/lib/code/node/not.rb +2 -0
  23. data/lib/code/node/nothing.rb +3 -1
  24. data/lib/code/node/number.rb +2 -0
  25. data/lib/code/node/right_operation.rb +70 -0
  26. data/lib/code/node/splat.rb +2 -0
  27. data/lib/code/node/square_bracket.rb +37 -0
  28. data/lib/code/node/statement.rb +13 -5
  29. data/lib/code/node/string.rb +3 -1
  30. data/lib/code/node/ternary.rb +5 -3
  31. data/lib/code/node/unary_minus.rb +2 -0
  32. data/lib/code/node/while.rb +6 -4
  33. data/lib/code/node.rb +11 -5
  34. data/lib/code/object/argument.rb +13 -7
  35. data/lib/code/object/boolean.rb +43 -5
  36. data/lib/code/object/class.rb +17 -0
  37. data/lib/code/object/context.rb +36 -0
  38. data/lib/code/object/decimal.rb +252 -100
  39. data/lib/code/object/dictionary.rb +641 -0
  40. data/lib/code/object/function.rb +54 -27
  41. data/lib/code/object/global.rb +65 -19
  42. data/lib/code/object/identifier_list.rb +47 -0
  43. data/lib/code/object/integer.rb +320 -137
  44. data/lib/code/object/list.rb +140 -138
  45. data/lib/code/object/nothing.rb +10 -4
  46. data/lib/code/object/number.rb +6 -1
  47. data/lib/code/object/range.rb +85 -88
  48. data/lib/code/object/ruby_function.rb +11 -6
  49. data/lib/code/object/string.rb +51 -48
  50. data/lib/code/object.rb +117 -139
  51. data/lib/code/parser/addition.rb +4 -2
  52. data/lib/code/parser/and_operator.rb +4 -2
  53. data/lib/code/parser/bitwise_and.rb +4 -2
  54. data/lib/code/parser/bitwise_or.rb +4 -2
  55. data/lib/code/parser/boolean.rb +3 -1
  56. data/lib/code/parser/call.rb +17 -11
  57. data/lib/code/parser/chained_call.rb +10 -22
  58. data/lib/code/parser/class.rb +9 -6
  59. data/lib/code/parser/code.rb +6 -4
  60. data/lib/code/parser/{dictionnary.rb → dictionary.rb} +16 -13
  61. data/lib/code/parser/equal.rb +9 -36
  62. data/lib/code/parser/equality.rb +4 -2
  63. data/lib/code/parser/function.rb +24 -9
  64. data/lib/code/parser/greater.rb +6 -3
  65. data/lib/code/parser/group.rb +4 -2
  66. data/lib/code/parser/if.rb +6 -4
  67. data/lib/code/parser/if_modifier.rb +5 -25
  68. data/lib/code/parser/left_operation.rb +40 -0
  69. data/lib/code/parser/list.rb +6 -5
  70. data/lib/code/parser/multiplication.rb +4 -2
  71. data/lib/code/parser/name.rb +19 -4
  72. data/lib/code/parser/negation.rb +4 -2
  73. data/lib/code/parser/not_keyword.rb +5 -3
  74. data/lib/code/parser/nothing.rb +3 -10
  75. data/lib/code/parser/number.rb +4 -2
  76. data/lib/code/parser/or_keyword.rb +4 -2
  77. data/lib/code/parser/or_operator.rb +4 -2
  78. data/lib/code/parser/power.rb +4 -28
  79. data/lib/code/parser/range.rb +4 -2
  80. data/lib/code/parser/rescue.rb +6 -26
  81. data/lib/code/parser/right_operation.rb +40 -0
  82. data/lib/code/parser/shift.rb +4 -2
  83. data/lib/code/parser/splat.rb +5 -3
  84. data/lib/code/parser/square_bracket.rb +48 -0
  85. data/lib/code/parser/statement.rb +3 -1
  86. data/lib/code/parser/string.rb +12 -10
  87. data/lib/code/parser/ternary.rb +10 -11
  88. data/lib/code/parser/unary_minus.rb +5 -3
  89. data/lib/code/parser/while.rb +5 -3
  90. data/lib/code/parser/whitespace.rb +2 -0
  91. data/lib/code/parser.rb +10 -3
  92. data/lib/code/ruby.rb +4 -2
  93. data/lib/code/type/hash.rb +38 -0
  94. data/lib/code/type/maybe.rb +29 -0
  95. data/lib/code/type/or.rb +38 -0
  96. data/lib/code/type/repeat.rb +38 -0
  97. data/lib/code/type/sig.rb +130 -0
  98. data/lib/code/type.rb +25 -0
  99. data/lib/code/version.rb +3 -0
  100. data/lib/code-ruby.rb +1 -2
  101. data/lib/code.rb +15 -16
  102. data/spec/code/node/call_spec.rb +39 -0
  103. data/spec/code/object/boolean_spec.rb +18 -0
  104. data/spec/code/object/decimal_spec.rb +51 -0
  105. data/spec/code/object/dictionary_spec.rb +98 -0
  106. data/spec/code/object/function_spec.rb +42 -0
  107. data/spec/code/object/integer_spec.rb +43 -0
  108. data/spec/code/object/nothing_spec.rb +14 -0
  109. data/spec/code/object/range_spec.rb +23 -0
  110. data/spec/code/parser/boolean_spec.rb +5 -10
  111. data/spec/code/parser/chained_call.rb +4 -5
  112. data/spec/code/parser/{dictionnary_spec.rb → dictionary_spec.rb} +5 -6
  113. data/spec/code/parser/function_spec.rb +4 -5
  114. data/spec/code/parser/group_spec.rb +5 -12
  115. data/spec/code/parser/if_modifier_spec.rb +18 -0
  116. data/spec/code/parser/list_spec.rb +4 -5
  117. data/spec/code/parser/number_spec.rb +4 -5
  118. data/spec/code/parser/string_spec.rb +4 -5
  119. data/spec/code/parser_spec.rb +22 -16
  120. data/spec/code/type_spec.rb +21 -0
  121. data/spec/code_spec.rb +171 -0
  122. data/spec/spec_helper.rb +1 -6
  123. metadata +61 -137
  124. data/.cherry.js +0 -21
  125. data/.editorconfig +0 -9
  126. data/.github/workflows/rspec.yml +0 -14
  127. data/.gitignore +0 -2
  128. data/.prettierrc +0 -3
  129. data/.tool-versions +0 -1
  130. data/CHANGELOG.md +0 -55
  131. data/LICENSE +0 -7
  132. data/README.md +0 -103
  133. data/TODO +0 -17
  134. data/bin/code +0 -76
  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 -11
  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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f36763f875625586b92b0e923f79a44179b70b090d9673bc5249636795d8db66
4
- data.tar.gz: d95cdb157fb3da9c59b18fc4f84808fe2368390a132e2be8b9e2bc6a20758503
3
+ metadata.gz: 28db53e527baab77e31c69d2ba121f06a91333aa413ac1f82daf5f4f87ba6864
4
+ data.tar.gz: '0963f43654020b71820b21fbcc4ade468fa98d85bd5e5fc628bdf5406037508a'
5
5
  SHA512:
6
- metadata.gz: 1ff082f216e4f73b99ce64174599815862f466d6f2918dc4f653e3f518b6f2be1b5f5e1d38e1da8d2c37d14c05eb917ff3ed59b05e4417116f1ec1abc1cd938d
7
- data.tar.gz: 63bce33e3bbe8db8baf4ea842467f98aafc0470277d15665253cca727d29fcfc1e00b79f4f00b35c734937b15dbb17dbc0144b80ae526dbc5075d1b019249047
6
+ metadata.gz: 61e09ee88f713f2f9dfd3e2f1a6db3ce89ab059170ff9864038e3473d264a36966595b7d354bcc77e3832d8f67620fd44ddf155177e716c0ea841682c64a232b
7
+ data.tar.gz: '0806530251411c030f51f3edd620ab7147b98cdbc1712719db0656c5bc9fa9c17b34b92a416432614c046036a327dcefe514cc78e6b5f5026618f2120f536d68'
data/Gemfile CHANGED
@@ -1,8 +1,5 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- gemspec name: "template-ruby"
4
- gemspec name: "code-ruby"
3
+ gemspec
5
4
 
6
5
  gem "rspec"
7
- gem "syntax_tree", github: "dorianmariefr/syntax_tree"
8
- gem "ruby-prof"
data/Gemfile.lock CHANGED
@@ -1,49 +1,37 @@
1
- GIT
2
- remote: https://github.com/dorianmariefr/syntax_tree.git
3
- revision: f7c9dc36a3d60c90a8d2411f123913b37319dc11
4
- specs:
5
- syntax_tree (5.0.1)
6
- prettier_print (>= 1.1.0)
7
-
8
1
  PATH
9
2
  remote: .
10
3
  specs:
11
- code-ruby (0.5.4)
12
- zeitwerk (~> 2)
13
- template-ruby (0.5.4)
4
+ code-ruby (0.6.0)
5
+ language-ruby (~> 0)
14
6
  zeitwerk (~> 2)
15
7
 
16
8
  GEM
17
9
  remote: https://rubygems.org/
18
10
  specs:
19
11
  diff-lcs (1.5.0)
20
- prettier_print (1.1.0)
12
+ language-ruby (0.6.0)
13
+ zeitwerk (~> 2)
21
14
  rspec (3.12.0)
22
15
  rspec-core (~> 3.12.0)
23
16
  rspec-expectations (~> 3.12.0)
24
17
  rspec-mocks (~> 3.12.0)
25
- rspec-core (3.12.0)
18
+ rspec-core (3.12.2)
26
19
  rspec-support (~> 3.12.0)
27
- rspec-expectations (3.12.0)
20
+ rspec-expectations (3.12.3)
28
21
  diff-lcs (>= 1.2.0, < 2.0)
29
22
  rspec-support (~> 3.12.0)
30
- rspec-mocks (3.12.0)
23
+ rspec-mocks (3.12.6)
31
24
  diff-lcs (>= 1.2.0, < 2.0)
32
25
  rspec-support (~> 3.12.0)
33
- rspec-support (3.12.0)
34
- ruby-prof (1.4.3)
35
- zeitwerk (2.6.6)
26
+ rspec-support (3.12.1)
27
+ zeitwerk (2.6.12)
36
28
 
37
29
  PLATFORMS
38
- arm64-darwin-21
39
30
  arm64-darwin-22
40
31
 
41
32
  DEPENDENCIES
42
33
  code-ruby!
43
34
  rspec
44
- ruby-prof
45
- syntax_tree!
46
- template-ruby!
47
35
 
48
36
  BUNDLED WITH
49
- 2.3.18
37
+ 2.4.22
data/code-ruby.gemspec CHANGED
@@ -1,8 +1,8 @@
1
- require_relative "lib/template/version"
1
+ require_relative "lib/code/version"
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "code-ruby"
5
- s.version = ::Template::Version
5
+ s.version = ::Code::Version
6
6
  s.summary = "A programming language"
7
7
  s.description = 'A programming language, like Code.evaluate("1 + 1") # => 2'
8
8
  s.authors = ["Dorian Marié"]
@@ -10,8 +10,9 @@ Gem::Specification.new do |s|
10
10
  s.files = `git ls-files`.split($/)
11
11
  s.test_files = s.files.grep(%r{^(test|spec|features)/})
12
12
  s.require_paths = ["lib"]
13
- s.homepage = "https://github.com/dorianmariefr/template-ruby"
13
+ s.homepage = "https://github.com/dorianmariefr/code-ruby"
14
14
  s.license = "MIT"
15
15
 
16
16
  s.add_dependency "zeitwerk", "~> 2"
17
+ s.add_dependency "language-ruby", "~> 0"
17
18
  end
data/lib/code/error.rb CHANGED
@@ -1,18 +1,29 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Code
2
4
  class Error < StandardError
3
- class TypeError < ::Code::Error
5
+ class ArityError < Error
6
+ end
7
+
8
+ class TypeError < Error
9
+ end
10
+
11
+ class TypeError < Error
12
+ end
13
+
14
+ class Undefined < Error
4
15
  end
5
16
 
6
- class Undefined < ::Code::Error
17
+ class UndefinedVariable < Error
7
18
  end
8
19
 
9
- class UndefinedVariable < ::Code::Error
20
+ class ArgumentError < Error
10
21
  end
11
22
 
12
- class ArgumentError < ::Code::Error
23
+ class IncompatibleContext < Error
13
24
  end
14
25
 
15
- class IncompatibleContext < ::Code::Error
26
+ class KeyNotFound < Error
16
27
  end
17
28
  end
18
29
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Code
2
4
  class Node
3
5
  class Base10 < Node
@@ -16,9 +18,9 @@ class Code
16
18
  exponent = @exponent.evaluate(**args)
17
19
 
18
20
  if exponent.is_a?(::Code::Object::Integer)
19
- ::Code::Object::Integer.new(@whole.to_i, exponent: exponent)
21
+ ::Code::Object::Integer.new(@whole.to_i, exponent:)
20
22
  else
21
- ::Code::Object::Decimal.new(@whole, exponent: exponent)
23
+ ::Code::Object::Decimal.new(@whole, exponent:)
22
24
  end
23
25
  else
24
26
  ::Code::Object::Integer.new(@whole.to_i)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Code
2
4
  class Node
3
5
  class Base16 < Node
@@ -5,7 +7,7 @@ class Code
5
7
  @base_16 = parsed
6
8
  end
7
9
 
8
- def evaluate(**args)
10
+ def evaluate(**_args)
9
11
  ::Code::Object::Integer.new(@base_16.to_i(16))
10
12
  end
11
13
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Code
2
4
  class Node
3
5
  class Base2 < Node
@@ -5,7 +7,7 @@ class Code
5
7
  @base_2 = parsed
6
8
  end
7
9
 
8
- def evaluate(**args)
10
+ def evaluate(**_args)
9
11
  ::Code::Object::Integer.new(@base_2.to_i(2))
10
12
  end
11
13
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Code
2
4
  class Node
3
5
  class Base8 < Node
@@ -5,7 +7,7 @@ class Code
5
7
  @base_8 = parsed
6
8
  end
7
9
 
8
- def evaluate(**args)
10
+ def evaluate(**_args)
9
11
  ::Code::Object::Integer.new(@base_8.to_i(8))
10
12
  end
11
13
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Code
2
4
  class Node
3
5
  class Boolean < Node
@@ -8,13 +10,13 @@ class Code
8
10
  @boolean = parsed
9
11
  end
10
12
 
11
- def evaluate(**args)
13
+ def evaluate(**_args)
12
14
  if @boolean == TRUE_KEYWORD
13
15
  ::Code::Object::Boolean.new(true)
14
16
  elsif @boolean == FALSE_KEYWORD
15
17
  ::Code::Object::Boolean.new(false)
16
18
  else
17
- raise NotImplementedError.new(@boolean)
19
+ raise NotImplementedError, @boolean
18
20
  end
19
21
  end
20
22
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Code
2
4
  class Node
3
5
  class Call < Node
@@ -6,16 +8,16 @@ class Code
6
8
  @parameters =
7
9
  parsed
8
10
  .delete(:parameters) { [] }
9
- .map { |parameter| Node::FunctionParameter.new(parameter) }
11
+ .map { |parameter| FunctionParameter.new(parameter) }
10
12
 
11
- @body = Node::Code.new(parsed.delete(:body))
13
+ @body = Code.new(parsed.delete(:body))
12
14
 
13
15
  super(parsed)
14
16
  end
15
17
 
16
- def evaluate(**args)
17
- ::Code::Object::Argument.new(
18
- ::Code::Object::Function.new(parameters: @parameters, body: @body)
18
+ def evaluate(**_args)
19
+ Object::Argument.new(
20
+ Object::Function.new(parameters: @parameters, body: @body)
19
21
  )
20
22
  end
21
23
  end
@@ -25,22 +27,43 @@ class Code
25
27
  @arguments =
26
28
  parsed
27
29
  .delete(:arguments) { [] }
28
- .map { |argument| Node::CallArgument.new(argument) }
30
+ .map { |argument| CallArgument.new(argument) }
29
31
 
30
- if parsed.key?(:block)
31
- @block = Node::Call::Block.new(parsed.delete(:block))
32
- end
32
+ @block = Call::Block.new(parsed.delete(:block)) if parsed.key?(:block)
33
33
 
34
34
  super(parsed)
35
35
  end
36
36
 
37
37
  def evaluate(**args)
38
- arguments = @arguments.map { |argument| argument.evaluate(**args) }
38
+ arguments = []
39
+
40
+ @arguments.each do |argument|
41
+ if argument.keyword?
42
+ if arguments.last&.value.is_a?(Object::Dictionary)
43
+ arguments.last.value[argument.name] = argument.evaluate(
44
+ **args
45
+ ).value
46
+ else
47
+ arguments << Object::Argument.new(
48
+ Object::Dictionary.new(
49
+ { argument.name => argument.evaluate(**args).value }
50
+ )
51
+ )
52
+ end
53
+ else
54
+ arguments << argument.evaluate(**args)
55
+ end
56
+ end
57
+
39
58
  arguments << @block.evaluate(**args) if @block
40
59
 
41
- name = ::Code::Object::String.new(@name)
60
+ name = Object::String.new(@name)
61
+
62
+ args.fetch(:object).call(operator: name, arguments:, **args)
63
+ end
42
64
 
43
- args.fetch(:object).call(operator: name, arguments: arguments, **args)
65
+ def resolve(**_args)
66
+ Object::String.new(@name)
44
67
  end
45
68
  end
46
69
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Code
2
4
  class Node
3
5
  class CallArgument < Node
@@ -8,14 +10,23 @@ class Code
8
10
 
9
11
  def evaluate(**args)
10
12
  if @name
11
- ::Code::Object::Argument.new(
12
- @value.evaluate(**args),
13
- name: ::Code::Object::String.new(@name)
14
- )
13
+ Object::Argument.new(@value.evaluate(**args), name:)
15
14
  else
16
- ::Code::Object::Argument.new(@value.evaluate(**args))
15
+ Object::Argument.new(@value.evaluate(**args))
17
16
  end
18
17
  end
18
+
19
+ def keyword?
20
+ !!@name
21
+ end
22
+
23
+ def regular?
24
+ !keyword?
25
+ end
26
+
27
+ def name
28
+ Object::String.new(@name)
29
+ end
19
30
  end
20
31
  end
21
32
  end
@@ -1,16 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Code
2
4
  class Node
3
5
  class Code < Node
4
6
  def initialize(parsed)
5
- @statements = parsed.map { |statement| Node::Statement.new(statement) }
7
+ @statements = parsed.map { |statement| Statement.new(statement) }
6
8
  end
7
9
 
8
10
  def evaluate(**args)
9
- last = ::Code::Object::Nothing.new
11
+ last = Object::Nothing.new
10
12
 
11
13
  @statements.each do |statement|
12
- last =
13
- statement.evaluate(**args.merge(object: ::Code::Object::Global.new))
14
+ last = statement.evaluate(**args.merge(object: Object::Global.new))
14
15
  end
15
16
 
16
17
  last
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Code
2
4
  class Node
3
5
  class Decimal < Node
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Code
2
4
  class Node
3
- class Dictionnary < Node
5
+ class Dictionary < Node
4
6
  class KeyValue < Node
5
7
  def initialize(parsed)
6
8
  if parsed.key?(:statement)
@@ -9,22 +11,29 @@ class Code
9
11
  @key = Node::String.new([{ text: parsed.delete(:name) }])
10
12
  end
11
13
 
12
- @value = Node::Code.new(parsed.delete(:value))
14
+ @value = Node::Code.new(parsed.delete(:value)) if parsed[:value]
13
15
  end
14
16
 
15
17
  def evaluate(**args)
16
- [@key.evaluate(**args), @value.evaluate(**args)]
18
+ key = @key.evaluate(**args)
19
+
20
+ if @value
21
+ value = @value.evaluate(**args)
22
+ [key, value]
23
+ else
24
+ [key, key]
25
+ end
17
26
  end
18
27
  end
19
28
 
20
29
  def initialize(parsed)
21
30
  parsed = [] if parsed == ""
22
31
  @key_values =
23
- parsed.map { |key_value| Node::Dictionnary::KeyValue.new(key_value) }
32
+ parsed.map { |key_value| Node::Dictionary::KeyValue.new(key_value) }
24
33
  end
25
34
 
26
35
  def evaluate(**args)
27
- ::Code::Object::Dictionnary.new(
36
+ ::Code::Object::Dictionary.new(
28
37
  @key_values.map { |key_value| key_value.evaluate(**args) }.to_h
29
38
  )
30
39
  end
@@ -1,18 +1,21 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Code
2
4
  class Node
3
5
  class Function < Node
4
6
  def initialize(parsed)
7
+ @parameters = parsed.delete(:parameters) { [] }
8
+ @parameters = [] if @parameters.empty?
9
+
5
10
  @parameters =
6
- parsed
7
- .delete(:parameters) { [] }
8
- .map { |parameter| Node::FunctionParameter.new(parameter) }
11
+ @parameters.map { |parameter| Node::FunctionParameter.new(parameter) }
9
12
 
10
13
  @body = Node::Code.new(parsed.delete(:body))
11
14
 
12
15
  super(parsed)
13
16
  end
14
17
 
15
- def evaluate(**args)
18
+ def evaluate(**_args)
16
19
  ::Code::Object::Function.new(parameters: @parameters, body: @body)
17
20
  end
18
21
  end
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Code
2
4
  class Node
3
5
  class FunctionParameter < Node
4
6
  def initialize(parsed)
5
7
  @name = parsed.delete(:name)
6
- @keyword = !!parsed.delete(:keyword)
8
+ @keyword = !parsed.delete(:keyword).nil?
7
9
  super(parsed)
8
10
  end
9
11
 
data/lib/code/node/if.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Code
2
4
  class Node
3
5
  class If < Node
@@ -13,9 +15,9 @@ class Code
13
15
  @operator = parsed.delete(:operator)
14
16
  @body = Node::Code.new(parsed.delete(:body))
15
17
 
16
- if parsed.key?(:statement)
17
- @statement = Node::Statement.new(parsed.delete(:statement))
18
- end
18
+ return unless parsed.key?(:statement)
19
+
20
+ @statement = Node::Statement.new(parsed.delete(:statement))
19
21
  end
20
22
  end
21
23
 
@@ -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