code-ruby 0.5.6 → 0.6.1

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 -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
@@ -1,63 +1,90 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Code
2
4
  class Object
3
5
  class Function < ::Code::Object
6
+ attr_reader :parameters, :body
7
+
4
8
  def initialize(parameters:, body:)
5
9
  @parameters = parameters
6
10
  @body = body
7
11
  end
8
12
 
13
+ def self.name
14
+ "Function"
15
+ end
16
+
9
17
  def call(**args)
10
18
  operator = args.fetch(:operator, nil)
11
19
  arguments = args.fetch(:arguments, [])
12
20
  globals = multi_fetch(args, *::Code::GLOBALS)
13
21
 
14
- if operator.nil? || operator == "call"
15
- call_function(args: arguments, globals: globals)
22
+ case operator.to_s
23
+ when "", "call"
24
+ sig(args) { signature_for_call }
25
+ code_call(*arguments, **globals)
16
26
  else
17
27
  super
18
28
  end
19
29
  end
20
30
 
21
- def to_s
22
- ""
23
- end
24
-
25
- def inspect
26
- "function"
27
- end
28
-
29
- private
30
-
31
- attr_reader :parameters, :body
32
-
33
- def call_function(args:, globals:)
34
- new_context = deep_dup(globals[:context])
31
+ def code_call(*arguments, **globals)
32
+ context = Context.new({}, parent: globals[:context])
35
33
 
36
34
  parameters.each.with_index do |parameter, index|
37
35
  if parameter.regular?
38
36
  if parameter.regular_splat?
39
- new_context[parameter.name] = ::Code::Object::List.new(
40
- args.select(&:regular?).map(&:value)
37
+ context.code_set(
38
+ parameter.name,
39
+ List.new(
40
+ arguments.select(&:regular?).map(&:value)
41
+ )
41
42
  )
42
43
  elsif parameter.keyword_splat?
43
- new_context[parameter.name] = ::Code::Object::Dictionnary.new(
44
- args.select(&:keyword?).map(&:name_value).to_h
44
+ context.code_set(
45
+ parameter.name,
46
+ Dictionary.new(
47
+ arguments.select(&:keyword?).map(&:name_value).to_h
48
+ )
45
49
  )
46
50
  else
47
- arg = args[index]&.value
48
- arg = parameter.evaluate(**globals) if arg.nil?
49
- new_context[parameter.name] = arg
51
+ argument = arguments[index]&.value
52
+ argument = parameter.evaluate(**globals) if argument.nil?
53
+ context.code_set(parameter.name, argument)
50
54
  end
51
55
  elsif parameter.keyword?
52
- arg = args.detect { |arg| arg.name == parameter.name }&.value
53
- arg = parameter.evaluate(**globals) if arg.nil?
54
- new_context[parameter.name] = arg
56
+ argument = arguments.detect { |argument| argument.name == parameter.name }&.value
57
+ argument = parameter.evaluate(**globals) if argument.nil?
58
+ context.code_set(parameter.name, argument)
55
59
  else
56
60
  raise NotImplementedError
57
61
  end
58
62
  end
59
63
 
60
- body.evaluate(**globals, context: new_context)
64
+ body.evaluate(**globals, context:)
65
+ end
66
+
67
+ def inspect
68
+ "function"
69
+ end
70
+
71
+ def signature_for_call
72
+ parameters.inject([]) do |signature, parameter|
73
+ if parameter.keyword?
74
+ if signature.last.is_a?(::Hash)
75
+ signature.last[parameter.name] = Object
76
+ signature
77
+ else
78
+ signature + [{ parameter.name => Object }]
79
+ end
80
+ else
81
+ signature + [Object]
82
+ end
83
+ end + [Object.repeat]
84
+ end
85
+
86
+ def to_s
87
+ ""
61
88
  end
62
89
  end
63
90
  end
@@ -1,35 +1,81 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Code
2
4
  class Object
3
5
  class Global < ::Code::Object
6
+ def self.name
7
+ "Global"
8
+ end
9
+
4
10
  def call(**args)
5
11
  operator = args.fetch(:operator, nil)
6
12
  arguments = args.fetch(:arguments, [])
7
- context = args.fetch(:context)
8
13
  io = args.fetch(:io)
9
- globals = multi_fetch(args, *::Code::GLOBALS)
14
+ context = args.fetch(:context)
15
+ multi_fetch(args, *GLOBALS)
10
16
  value = arguments.first&.value
11
17
 
12
- if operator == "print"
13
- io.print(*arguments.map(&:value))
14
- ::Code::Object::Nothing.new
15
- elsif operator == "puts"
16
- io.puts(*arguments.map(&:value))
17
- ::Code::Object::Nothing.new
18
- elsif operator == "context"
19
- sig(arguments) { ::Code::Object::String }
20
- context[value] || ::Code::Object::Nothing.new
21
- elsif operator == "evaluate"
22
- sig(arguments) { ::Code::Object::String }
23
- Code.evaluate(value.raw)
18
+ case operator.to_s
19
+ when "Boolean"
20
+ sig(args) { Object.maybe }
21
+ value ? value.code_to_boolean : Class.new(Boolean)
22
+ when "Class"
23
+ sig(args) { Object.maybe }
24
+ value ? value.code_to_class : Class.new(Class)
25
+ when "Decimal"
26
+ sig(args) { Object.maybe }
27
+ value ? value.code_to_decimal : Class.new(Decimal)
28
+ when "Dictionary"
29
+ sig(args) { Object.maybe }
30
+ value ? value.code_to_dictionnary : Class.new(Dictionary)
31
+ when "Function"
32
+ sig(args) { Object.maybe }
33
+ value ? value.code_to_function : Class.new(Function)
34
+ when "Integer"
35
+ sig(args) { Object.maybe }
36
+ value ? value.code_to_integer : Class.new(Integer)
37
+ when "List"
38
+ sig(args) { Object.maybe }
39
+ value ? value.code_to_list : Class.new(List)
40
+ when "Nothing"
41
+ sig(args) { Object.maybe }
42
+ value ? value.code_to_nothing : Class.new(Nothing)
43
+ when "Number"
44
+ sig(args) { Object.maybe }
45
+ value ? value.code_to_number : Class.new(Number)
46
+ when "Object"
47
+ sig(args) { Object.maybe }
48
+ value ? value.code_to_object : Class.new(Object)
49
+ when "Range"
50
+ sig(args) { Object.maybe }
51
+ value ? value.code_to_range : Class.new(Range)
52
+ when "String"
53
+ sig(args) { Object.maybe }
54
+ value ? value.code_to_string : Class.new(String)
55
+ when "context"
56
+ sig(args) { String.maybe }
57
+ value ? context.code_get(value) || Nothing.new : context
58
+ when "evaluate"
59
+ sig(args) { Object }
60
+ Code.evaluate(value.to_s)
61
+ when "p"
62
+ sig(args) { Object.repeat }
63
+ io.puts(*arguments.map(&:value).map(&:inspect)) || Nothing.new
64
+ when "print"
65
+ sig(args) { Object.repeat }
66
+ io.print(*arguments.map(&:value)) || Nothing.new
67
+ when "puts"
68
+ sig(args) { Object.repeat }
69
+ io.puts(*arguments.map(&:value)) || Nothing.new
24
70
  else
25
- result = context[operator]
71
+ context = context.lookup!(operator)
72
+ result = context.code_fetch(operator)
26
73
 
27
- if result && result.is_a?(::Code::Object::Function)
74
+ if result.is_a?(Function)
28
75
  result.call(**args.merge(operator: nil))
29
- elsif result
30
- result
31
76
  else
32
- raise ::Code::Error::Undefined.new("#{operator} is not defined")
77
+ sig(args)
78
+ result
33
79
  end
34
80
  end
35
81
  end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Code
4
+ class Object
5
+ class IdentifierList < List
6
+ def self.name
7
+ "IdentifierList"
8
+ end
9
+
10
+ def call(**args)
11
+ operator = args.fetch(:operator, nil)
12
+ arguments = args.fetch(:arguments, [])
13
+ context = args.fetch(:context)
14
+ value = arguments.first&.value
15
+
16
+ case operator.to_s
17
+ when /=$/
18
+ sig(args) { Object }
19
+
20
+ context = context.lookup!(raw.first)
21
+
22
+ context =
23
+ raw[..-2].reduce(context) do |context, identifier|
24
+ context.code_fetch(identifier)
25
+ end
26
+
27
+ context.code_set(
28
+ raw.last,
29
+ if operator == "="
30
+ value
31
+ else
32
+ context.fetch(raw.last).call(
33
+ **args,
34
+ operator: operator[..-2],
35
+ arguments: [Argument.new(value)]
36
+ )
37
+ end
38
+ )
39
+
40
+ context.code_fetch(raw.last)
41
+ else
42
+ super
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end