code-ruby 0.5.6 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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 -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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0ec67f37dc432338ef23418046fd1b4672268351bbce19bc737793df2fef16c8
4
- data.tar.gz: 1e92c9e186f0463109589f843862c01633af3cbcc6d12a6f916b7b40ddd641ed
3
+ metadata.gz: 28db53e527baab77e31c69d2ba121f06a91333aa413ac1f82daf5f4f87ba6864
4
+ data.tar.gz: '0963f43654020b71820b21fbcc4ade468fa98d85bd5e5fc628bdf5406037508a'
5
5
  SHA512:
6
- metadata.gz: 218135cc2e96e8d85609c3efe047d7aa716a3a87380dd60608bb4d2d107b44c86852362dcadeff7b18e35800dbbe172761d457d3bf039c2dae36fb8b3fa1358d
7
- data.tar.gz: c44d215dcb56eb2f2357139e16c3cca8fe4e4ecff825dc62afec8625695c6f2f0634c428605e57461f73debd58c6d72a6a4f2fcb0a680cf76593df4edbd9d5a0
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.6)
12
- zeitwerk (~> 2)
13
- template-ruby (0.5.6)
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