code-ruby 0.4.0 → 0.5.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 (204) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/Gemfile +2 -1
  4. data/Gemfile.lock +27 -54
  5. data/TODO +17 -0
  6. data/bin/code +56 -31
  7. data/bin/format +3 -0
  8. data/bin/template +62 -20
  9. data/bin/test +17 -0
  10. data/code-ruby.gemspec +1 -3
  11. data/docs/class.code +9 -0
  12. data/docs/euler/1.template +1 -5
  13. data/docs/euler/5.template +0 -1
  14. data/docs/meetup.code +12 -0
  15. data/docs/precedence.template +6 -39
  16. data/docs/rain.code +22 -0
  17. data/docs/slack.code +17 -0
  18. data/docs/stripe.code +7 -0
  19. data/docs/twitter.code +9 -0
  20. data/language-ruby.gemspec +18 -0
  21. data/lib/code/node/base_10.rb +29 -0
  22. data/lib/code/node/base_16.rb +13 -0
  23. data/lib/code/node/base_2.rb +13 -0
  24. data/lib/code/node/base_8.rb +13 -0
  25. data/lib/code/node/boolean.rb +7 -7
  26. data/lib/code/node/call.rb +32 -38
  27. data/lib/code/node/call_argument.rb +11 -27
  28. data/lib/code/node/chained_call.rb +10 -27
  29. data/lib/code/node/code.rb +4 -6
  30. data/lib/code/node/decimal.rb +26 -0
  31. data/lib/code/node/dictionnary.rb +20 -9
  32. data/lib/code/node/equal.rb +18 -20
  33. data/lib/code/node/function.rb +10 -7
  34. data/lib/code/node/function_parameter.rb +31 -0
  35. data/lib/code/node/if.rb +36 -32
  36. data/lib/code/node/if_modifier.rb +35 -36
  37. data/lib/code/node/list.rb +6 -8
  38. data/lib/code/node/negation.rb +5 -23
  39. data/lib/code/node/not.rb +15 -0
  40. data/lib/code/node/nothing.rb +1 -1
  41. data/lib/code/node/number.rb +14 -12
  42. data/lib/code/node/operation.rb +21 -16
  43. data/lib/code/node/power.rb +10 -6
  44. data/lib/code/node/rescue.rb +4 -3
  45. data/lib/code/node/splat.rb +15 -0
  46. data/lib/code/node/statement.rb +48 -70
  47. data/lib/code/node/string.rb +42 -16
  48. data/lib/code/node/ternary.rb +7 -9
  49. data/lib/code/node/unary_minus.rb +5 -12
  50. data/lib/code/node/while.rb +17 -24
  51. data/lib/code/node.rb +7 -8
  52. data/lib/code/object/argument.rb +2 -11
  53. data/lib/code/object/decimal.rb +45 -30
  54. data/lib/code/object/dictionnary.rb +6 -5
  55. data/lib/code/object/function.rb +20 -23
  56. data/lib/code/object/global.rb +11 -6
  57. data/lib/code/object/integer.rb +73 -30
  58. data/lib/code/object/list.rb +40 -34
  59. data/lib/code/object/range.rb +18 -17
  60. data/lib/code/object/ruby_function.rb +12 -6
  61. data/lib/code/object/string.rb +22 -12
  62. data/lib/code/object.rb +82 -24
  63. data/lib/code/parser/addition.rb +12 -20
  64. data/lib/code/parser/and_operator.rb +9 -20
  65. data/lib/code/parser/bitwise_and.rb +9 -20
  66. data/lib/code/parser/bitwise_or.rb +12 -20
  67. data/lib/code/parser/boolean.rb +10 -7
  68. data/lib/code/parser/call.rb +92 -60
  69. data/lib/code/parser/chained_call.rb +47 -0
  70. data/lib/code/parser/class.rb +45 -0
  71. data/lib/code/parser/code.rb +17 -10
  72. data/lib/code/parser/dictionnary.rb +56 -30
  73. data/lib/code/parser/equal.rb +87 -35
  74. data/lib/code/parser/equality.rb +23 -24
  75. data/lib/code/parser/equality_lower.rb +9 -0
  76. data/lib/code/parser/function.rb +67 -42
  77. data/lib/code/parser/greater.rb +25 -0
  78. data/lib/code/parser/group.rb +13 -8
  79. data/lib/code/parser/if.rb +51 -21
  80. data/lib/code/parser/if_modifier.rb +43 -16
  81. data/lib/code/parser/list.rb +32 -19
  82. data/lib/code/parser/multiplication.rb +15 -20
  83. data/lib/code/parser/name.rb +96 -84
  84. data/lib/code/parser/negation.rb +20 -9
  85. data/lib/code/parser/not_keyword.rb +14 -12
  86. data/lib/code/parser/nothing.rb +13 -8
  87. data/lib/code/parser/number.rb +124 -68
  88. data/lib/code/parser/operation.rb +35 -0
  89. data/lib/code/parser/or_keyword.rb +12 -20
  90. data/lib/code/parser/or_operator.rb +9 -20
  91. data/lib/code/parser/power.rb +32 -14
  92. data/lib/code/parser/range.rb +9 -17
  93. data/lib/code/parser/rescue.rb +29 -13
  94. data/lib/code/parser/shift.rb +11 -21
  95. data/lib/code/parser/splat.rb +31 -0
  96. data/lib/code/parser/statement.rb +4 -3
  97. data/lib/code/parser/string.rb +53 -62
  98. data/lib/code/parser/ternary.rb +36 -15
  99. data/lib/code/parser/unary_minus.rb +23 -5
  100. data/lib/code/parser/while.rb +26 -15
  101. data/lib/code/parser/whitespace.rb +49 -0
  102. data/lib/code/parser.rb +15 -0
  103. data/lib/code/ruby.rb +13 -12
  104. data/lib/code-ruby.rb +2 -11
  105. data/lib/code.rb +16 -13
  106. data/lib/language/atom.rb +343 -0
  107. data/lib/language/output.rb +130 -0
  108. data/lib/language/parser/absent/present.rb +8 -0
  109. data/lib/language/parser/absent.rb +6 -0
  110. data/lib/language/parser/end_of_input.rb +6 -0
  111. data/lib/language/parser/interuption.rb +38 -0
  112. data/lib/language/parser/not_end_of_input.rb +6 -0
  113. data/lib/language/parser/str/not_found.rb +16 -0
  114. data/lib/language/parser/str.rb +6 -0
  115. data/lib/language/parser.rb +53 -0
  116. data/lib/language-ruby.rb +10 -0
  117. data/lib/language.rb +80 -0
  118. data/lib/template/node/code_part.rb +1 -1
  119. data/lib/template/node/part.rb +1 -1
  120. data/lib/template/node/template.rb +1 -1
  121. data/lib/template/node/text_part.rb +1 -1
  122. data/lib/template/node.rb +1 -1
  123. data/lib/template/parser/template.rb +26 -17
  124. data/lib/template/parser.rb +15 -0
  125. data/lib/template/version.rb +1 -1
  126. data/lib/template-ruby.rb +2 -11
  127. data/lib/template.rb +6 -11
  128. data/spec/code/addition_spec.rb +13 -0
  129. data/spec/code/and_operator_spec.rb +13 -0
  130. data/spec/code/bitwise_and_spec.rb +13 -0
  131. data/spec/code/bitwise_or_spec.rb +13 -0
  132. data/spec/code/boolean_spec.rb +13 -0
  133. data/spec/code/call_spec.rb +21 -0
  134. data/spec/code/chained_call_spec.rb +16 -0
  135. data/spec/code/dictionnary_spec.rb +17 -0
  136. data/spec/code/equal_spec.rb +26 -0
  137. data/spec/code/equality_spec.rb +13 -0
  138. data/spec/code/function_spec.rb +18 -0
  139. data/spec/code/greater_spec.rb +18 -0
  140. data/spec/code/group_spec.rb +12 -0
  141. data/spec/code/if_modifier_spec.rb +20 -0
  142. data/spec/code/if_spec.rb +25 -0
  143. data/spec/code/list_spec.rb +17 -0
  144. data/spec/code/multiplication_spec.rb +18 -0
  145. data/spec/code/negation_spec.rb +20 -0
  146. data/spec/code/not_keyword_spec.rb +13 -0
  147. data/spec/code/nothing_spec.rb +17 -0
  148. data/spec/code/number_spec.rb +22 -0
  149. data/spec/code/or_keyword_spec.rb +17 -0
  150. data/spec/code/or_operator_spec.rb +16 -0
  151. data/spec/code/parser/boolean_spec.rb +5 -7
  152. data/spec/code/parser/call_spec.rb +16 -56
  153. data/spec/code/parser/chained_call.rb +17 -0
  154. data/spec/code/parser/dictionnary_spec.rb +8 -9
  155. data/spec/code/parser/function_spec.rb +5 -21
  156. data/spec/code/parser/group_spec.rb +18 -0
  157. data/spec/code/parser/list_spec.rb +9 -20
  158. data/spec/code/parser/number_spec.rb +4 -109
  159. data/spec/code/parser/string_spec.rb +9 -17
  160. data/spec/code/parser_spec.rb +23 -0
  161. data/spec/code/power_spec.rb +13 -0
  162. data/spec/code/range_spec.rb +16 -0
  163. data/spec/code/rescue_spec.rb +13 -0
  164. data/spec/code/shift_spec.rb +13 -0
  165. data/spec/code/splat_spec.rb +13 -0
  166. data/spec/code/string_spec.rb +25 -0
  167. data/spec/code/ternary_spec.rb +18 -0
  168. data/spec/code/unary_minus_spec.rb +13 -0
  169. data/spec/code/while_spec.rb +18 -0
  170. data/spec/spec_helper.rb +4 -1
  171. data/template-ruby.gemspec +2 -4
  172. metadata +110 -71
  173. data/lib/code/node/base_10_decimal.rb +0 -32
  174. data/lib/code/node/base_10_integer.rb +0 -32
  175. data/lib/code/node/base_10_number.rb +0 -19
  176. data/lib/code/node/base_16_number.rb +0 -19
  177. data/lib/code/node/base_2_number.rb +0 -19
  178. data/lib/code/node/base_8_number.rb +0 -19
  179. data/lib/code/node/block.rb +0 -17
  180. data/lib/code/node/defined.rb +0 -19
  181. data/lib/code/node/dictionnary_key_value.rb +0 -23
  182. data/lib/code/node/function_argument.rb +0 -45
  183. data/lib/code/node/group.rb +0 -13
  184. data/lib/code/node/keyword_call_argument.rb +0 -30
  185. data/lib/code/node/keyword_function_argument.rb +0 -33
  186. data/lib/code/node/name.rb +0 -28
  187. data/lib/code/node/not_keyword.rb +0 -13
  188. data/lib/code/node/or_keyword.rb +0 -34
  189. data/lib/code/node/range.rb +0 -31
  190. data/lib/code/node/regular_call_argument.rb +0 -34
  191. data/lib/code/node/regular_function_argument.rb +0 -36
  192. data/lib/code/node/string_characters.rb +0 -13
  193. data/lib/code/node/string_component.rb +0 -23
  194. data/lib/code/node/string_interpolation.rb +0 -13
  195. data/lib/code/parser/defined.rb +0 -20
  196. data/lib/code/parser/greater_than.rb +0 -33
  197. data/spec/call_spec.rb +0 -22
  198. data/spec/code/error/type_error_spec.rb +0 -63
  199. data/spec/code/parser/name_spec.rb +0 -15
  200. data/spec/code/parser/nothing_spec.rb +0 -19
  201. data/spec/code_spec.rb +0 -182
  202. data/spec/function_spec.rb +0 -26
  203. data/spec/template/parser/template_spec.rb +0 -19
  204. data/spec/template_spec.rb +0 -52
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f269ce2ed25933bd413596e077a7f37fdd8b2914d4f2a40c49ae040a3d80eaa2
4
- data.tar.gz: ca1870d839bd4ad4d46546b7320c39469fbe8f37425fb3ba0457f9584a6e4907
3
+ metadata.gz: 0d3eab372ae2a63a19a9c6df1a8628d5dd27892de2c1976f067cf85e74b417a1
4
+ data.tar.gz: 9b0a7f5d97a9a076b711e7bf8872722d46a2906f98e988f9b661a150a5dcec00
5
5
  SHA512:
6
- metadata.gz: e00e5e53b5bd74c402f7e6ea3b32d05ecf06faab892a52cf6b28e4c7c926821f33e7e7fea098b0d7350f58e20c548797bd297c5b6ff2743bbc04a7f8778b92a7
7
- data.tar.gz: 4120703ce09203e412baa280f2dae7ea19d51beec10c08f393d8d362e7a294a3a9e21c6ed125768d88fc619f0908d252ce3bd67e2f5fe067e0c320b08a764659
6
+ metadata.gz: 72c41b22eaec2f7e43d7f9dd8355b2a797da3fc91fc82621328e2e0bad8fbe7edac71a2a2271559b09f9871cd4f8d20560ff92cdbc4f8d7cddc9882c15e32cff
7
+ data.tar.gz: 36e9c2247fa179763e091499d2c4315e45bb302308e7460ac4b9fca3513bfad0ae7bfe4fbf95ea2071295b3d892874bc5b26248a2f19762c3a3d6e66a0f48812
data/.gitignore CHANGED
@@ -1,2 +1,2 @@
1
1
  *.gem
2
- examples.txt
2
+ tmp/
data/Gemfile CHANGED
@@ -3,5 +3,6 @@ source "https://rubygems.org"
3
3
  gemspec name: "template-ruby"
4
4
  gemspec name: "code-ruby"
5
5
 
6
- gem "prettier"
7
6
  gem "rspec"
7
+ gem "syntax_tree", github: "dorianmariefr/syntax_tree"
8
+ gem "ruby-prof"
data/Gemfile.lock CHANGED
@@ -1,74 +1,47 @@
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
+
1
8
  PATH
2
9
  remote: .
3
10
  specs:
4
- code-ruby (0.3.1)
5
- activesupport (~> 7)
6
- parslet (~> 2)
7
- zeitwerk (~> 2.6)
8
- template-ruby (0.3.1)
9
- activesupport (~> 7)
10
- parslet (~> 2)
11
- zeitwerk (~> 2.6)
11
+ code-ruby (0.4.0)
12
+ zeitwerk (~> 2)
13
+ template-ruby (0.4.0)
14
+ zeitwerk (~> 2)
12
15
 
13
16
  GEM
14
17
  remote: https://rubygems.org/
15
18
  specs:
16
- activesupport (7.0.4)
17
- concurrent-ruby (~> 1.0, >= 1.0.2)
18
- i18n (>= 1.6, < 2)
19
- minitest (>= 5.1)
20
- tzinfo (~> 2.0)
21
- concurrent-ruby (1.1.10)
22
19
  diff-lcs (1.5.0)
23
- haml (5.2.2)
24
- temple (>= 0.8.0)
25
- tilt
26
- i18n (1.12.0)
27
- concurrent-ruby (~> 1.0)
28
- minitest (5.16.3)
29
- parslet (2.0.0)
30
- prettier (3.2.0)
31
- syntax_tree (>= 2.7.1)
32
- syntax_tree-haml (>= 1.1.0)
33
- syntax_tree-rbs (>= 0.2.0)
34
- prettier_print (0.1.0)
35
- rbs (2.6.0)
36
- rspec (3.11.0)
37
- rspec-core (~> 3.11.0)
38
- rspec-expectations (~> 3.11.0)
39
- rspec-mocks (~> 3.11.0)
40
- rspec-core (3.11.0)
41
- rspec-support (~> 3.11.0)
42
- rspec-expectations (3.11.1)
20
+ prettier_print (1.1.0)
21
+ rspec (3.12.0)
22
+ rspec-core (~> 3.12.0)
23
+ rspec-expectations (~> 3.12.0)
24
+ rspec-mocks (~> 3.12.0)
25
+ rspec-core (3.12.0)
26
+ rspec-support (~> 3.12.0)
27
+ rspec-expectations (3.12.0)
43
28
  diff-lcs (>= 1.2.0, < 2.0)
44
- rspec-support (~> 3.11.0)
45
- rspec-mocks (3.11.1)
29
+ rspec-support (~> 3.12.0)
30
+ rspec-mocks (3.12.0)
46
31
  diff-lcs (>= 1.2.0, < 2.0)
47
- rspec-support (~> 3.11.0)
48
- rspec-support (3.11.1)
49
- syntax_tree (3.5.0)
50
- prettier_print
51
- syntax_tree-haml (1.3.1)
52
- haml (>= 5.2)
53
- prettier_print
54
- syntax_tree (>= 2.0.1)
55
- syntax_tree-rbs (0.5.0)
56
- prettier_print
57
- rbs
58
- syntax_tree (>= 2.0.1)
59
- temple (0.8.2)
60
- tilt (2.0.11)
61
- tzinfo (2.0.5)
62
- concurrent-ruby (~> 1.0)
63
- zeitwerk (2.6.1)
32
+ rspec-support (~> 3.12.0)
33
+ rspec-support (3.12.0)
34
+ ruby-prof (1.4.3)
35
+ zeitwerk (2.6.6)
64
36
 
65
37
  PLATFORMS
66
38
  arm64-darwin-21
67
39
 
68
40
  DEPENDENCIES
69
41
  code-ruby!
70
- prettier
71
42
  rspec
43
+ ruby-prof
44
+ syntax_tree!
72
45
  template-ruby!
73
46
 
74
47
  BUNDLED WITH
data/TODO ADDED
@@ -0,0 +1,17 @@
1
+ - Class
2
+ - Function parameters regular splat *args
3
+ - Function parameters keyword splat **kargs
4
+ - Function parameters block &block
5
+ - Block parameters regular splat *args
6
+ - Block parameters keyword splat **kargs
7
+ - Block parameters block &block
8
+ - Dictionnary regular splat { *args }
9
+ - Dictionnary keyword splat { **kargs }
10
+ - Dictionnary block { &block }
11
+ - Dictionnary expand name { user } and { user: }
12
+ - Rescue with exception name, rescue Code::Undefined
13
+ - Rescue with exception catched, rescue => e
14
+ - begin end
15
+ - begin rescue end
16
+ - begin rescue ensure end
17
+ - begin rescue else end
data/bin/code CHANGED
@@ -3,49 +3,74 @@
3
3
  require "optparse"
4
4
  require_relative "../lib/template-ruby"
5
5
 
6
- options = { timeout: 0 }
7
-
8
- OptionParser.new do |opts|
9
- opts.banner = "Usage: bin/code [options]"
10
-
11
- opts.on(
12
- "-i INPUT",
13
- "--input=INPUT",
14
- "Input in the code language (String or File)"
15
- ) do |input|
16
- if File.exists?(input)
17
- input = File.read(input)
6
+ options = { timeout: 0, profile: false }
7
+
8
+ OptionParser
9
+ .new do |opts|
10
+ opts.banner = "Usage: bin/code [options]"
11
+
12
+ opts.on(
13
+ "-i INPUT",
14
+ "--input=INPUT",
15
+ "Input in the code language (String or File)"
16
+ ) do |input|
17
+ input = File.read(input) if File.exists?(input)
18
+
19
+ options[:input] = input
18
20
  end
19
21
 
20
- options[:input] = input
21
- end
22
+ opts.on(
23
+ "-c CONTEXT",
24
+ "--context=CONTEXT",
25
+ "Context in the code language (String or File)"
26
+ ) do |context|
27
+ context = File.read(context) if File.exists?(context)
22
28
 
23
- opts.on(
24
- "-c CONTEXT",
25
- "--context=CONTEXT",
26
- "Context in the code language (String or File)"
27
- ) do |context|
28
- if File.exists?(context)
29
- context = File.read(context)
29
+ options[:context] = context
30
30
  end
31
31
 
32
- options[:context] = context
33
- end
32
+ opts.on("-p", "--parse", "Get parser results for input") do |parse|
33
+ options[:parse] = parse
34
+ end
34
35
 
35
- opts.on("-p", "--parse", "Get parser results for input") do |parse|
36
- options[:parse] = parse
37
- end
36
+ opts.on(
37
+ "-t TIMEOUT",
38
+ "--timeout=TIMEOUT",
39
+ "Set timeout in seconds"
40
+ ) { |timeout| options[:timeout] = timeout.to_f }
38
41
 
39
- opts.on("-t TIMEOUT", "--timeout=TIMEOUT", "Set timeout in seconds") do |timeout|
40
- options[:timeout] = timeout.to_f
42
+ opts.on(
43
+ "--profile",
44
+ "Profile Ruby code"
45
+ ) do |timeout|
46
+ require "ruby-prof"
47
+ options[:profile] = true
48
+ end
41
49
  end
42
- end.parse!
50
+ .parse!
43
51
 
44
52
  input = options.fetch(:input, "")
45
53
  context = options.fetch(:context, "")
46
54
 
55
+ if options[:profile]
56
+ RubyProf.start
57
+ end
58
+
47
59
  if options[:parse]
48
- pp ::Code::Parser::Code.new.parse(input)
60
+ pp ::Code::Parser.parse(input).to_raw
49
61
  else
50
- print Code.evaluate(input, context, io: $stdout, timeout: options[:timeout]).to_s
62
+ print(
63
+ Code.evaluate(
64
+ input,
65
+ context,
66
+ io: $stdout,
67
+ timeout: options[:timeout]
68
+ ).to_s
69
+ )
70
+ end
71
+
72
+ if options[:profile]
73
+ result = RubyProf.stop
74
+ printer = RubyProf::FlatPrinter.new(result)
75
+ printer.print($stdout)
51
76
  end
data/bin/format ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env fish
2
+
3
+ stree write Gemfile lib/**/*.rb spec/**/*.rb bin/code-parser
data/bin/template CHANGED
@@ -3,41 +3,83 @@
3
3
  require "optparse"
4
4
  require_relative "../lib/template-ruby"
5
5
 
6
- options = { timeout: 0 }
6
+ options = { timeout: 0, profile: false, profiler: "text" }
7
7
 
8
- OptionParser.new do |opts|
9
- opts.banner = "Usage: template [options]"
8
+ OptionParser
9
+ .new do |opts|
10
+ opts.banner = "Usage: template [options]"
10
11
 
11
- opts.on("-i INPUT", "--input=INPUT", "Input in the template language (String or File)") do |input|
12
- if File.exists?(input)
13
- input = File.read(input)
12
+ opts.on(
13
+ "-i INPUT",
14
+ "--input=INPUT",
15
+ "Input in the template language (String or File)"
16
+ ) do |input|
17
+ input = File.read(input) if File.exists?(input)
18
+
19
+ options[:input] = input
14
20
  end
15
21
 
16
- options[:input] = input
17
- end
22
+ opts.on(
23
+ "-c CONTEXT",
24
+ "--context=CONTEXT",
25
+ "Context in the code language (String or File)"
26
+ ) do |context|
27
+ context = File.read(context) if File.exists?(context)
18
28
 
19
- opts.on("-c CONTEXT", "--context=CONTEXT", "Context in the code language (String or File)") do |context|
20
- if File.exists?(context)
21
- context = File.read(context)
29
+ options[:context] = context
22
30
  end
23
31
 
24
- options[:context] = context
25
- end
32
+ opts.on("-p", "--parse", "Get parser results for input") do |parse|
33
+ options[:parse] = parse
34
+ end
26
35
 
27
- opts.on("-p", "--parse", "Get parser results for input") do |parse|
28
- options[:parse] = parse
29
- end
36
+ opts.on(
37
+ "-t TIMEOUT",
38
+ "--timeout=TIMEOUT",
39
+ "Set timeout in seconds"
40
+ ) { |timeout| options[:timeout] = timeout.to_f }
41
+
42
+ opts.on(
43
+ "--profile",
44
+ "Profile Ruby code"
45
+ ) do |timeout|
46
+ require "ruby-prof"
47
+ options[:profile] = true
48
+ end
30
49
 
31
- opts.on("-t TIMEOUT", "--timeout=TIMEOUT", "Set timeout in seconds") do |timeout|
32
- options[:timeout] = timeout.to_f
50
+ opts.on(
51
+ "--profiler TYPE",
52
+ "Profiler output type (text (default) or html)"
53
+ ) do |profiler|
54
+ require "ruby-prof"
55
+ options[:profile] = true
56
+ options[:profiler] = profiler
57
+ end
33
58
  end
34
- end.parse!
59
+ .parse!
35
60
 
36
61
  input = options.fetch(:input, "")
37
62
  context = options.fetch(:context, "")
38
63
 
64
+ if options[:profile]
65
+ RubyProf.start
66
+ end
67
+
39
68
  if options[:parse]
40
- pp ::Template::Parser::Template.new.parse(input)
69
+ pp ::Template::Parser.parse(input).to_raw
41
70
  else
42
71
  Template.render(input, context, io: $stdout, timeout: options[:timeout])
43
72
  end
73
+
74
+ if options[:profile]
75
+ result = RubyProf.stop
76
+ if options[:profiler] == "text"
77
+ printer = RubyProf::FlatPrinter.new(result)
78
+ printer.print($stdout)
79
+ elsif options[:profiler] == "html"
80
+ printer = RubyProf::GraphHtmlPrinter.new(result)
81
+ printer.print($stdout)
82
+ else
83
+ abort "#{options[:profiler]} not recognized"
84
+ end
85
+ end
data/bin/test ADDED
@@ -0,0 +1,17 @@
1
+ #!/bin/bash
2
+
3
+ set -e
4
+
5
+ rspec
6
+
7
+ for f in docs/**/*.template
8
+ do
9
+ echo $f
10
+ bin/template -i $f -p > /dev/null
11
+ done
12
+
13
+ for f in docs/*.code
14
+ do
15
+ echo $f
16
+ bin/code -i $f -p > /dev/null
17
+ done
data/code-ruby.gemspec CHANGED
@@ -13,7 +13,5 @@ Gem::Specification.new do |s|
13
13
  s.homepage = "https://github.com/dorianmariefr/template-ruby"
14
14
  s.license = "MIT"
15
15
 
16
- s.add_dependency "activesupport", "~> 7"
17
- s.add_dependency "parslet", "~> 2"
18
- s.add_dependency "zeitwerk", "~> 2.6"
16
+ s.add_dependency "zeitwerk", "~> 2"
19
17
  end
data/docs/class.code ADDED
@@ -0,0 +1,9 @@
1
+ class ApiClient
2
+ get = (url) => {
3
+ fetch(url)
4
+ }
5
+ end
6
+
7
+ class Twitter < ApiClient
8
+ self.base_url = "https://api.twitter.com"
9
+ end
@@ -1,14 +1,10 @@
1
1
  {
2
2
  sum = 0
3
3
 
4
- i = 1
5
-
6
- while i < 1000
4
+ 1000.times do |i|
7
5
  if i % 3 == 0 or i % 5 == 0
8
6
  sum += i
9
7
  end
10
-
11
- i += 1
12
8
  end
13
9
 
14
10
  sum
@@ -11,4 +11,3 @@
11
11
  i % j == 0
12
12
  end
13
13
  end
14
- }
data/docs/meetup.code ADDED
@@ -0,0 +1,12 @@
1
+ url = fetch(:url) { "https://www.meetup.com/parisrb" }
2
+ response = HTTP.get(url)
3
+ times = response.css(".groupHome-eventsList-upcomingEvents time")
4
+ times = times.map(&:datetime).map { |time| Time.from_epoch(time.to_integer) }
5
+
6
+ times.each do |time|
7
+ if (1.day.from_now...(1.day.from_now + 1.hour)).include?(time)
8
+ Sms.send("Event in one day {url}")
9
+ elsif (2.hours.from_now...(1.hour.from_now)).include(time)
10
+ Sms.send("Event in two hours {url}")
11
+ end
12
+ end
@@ -1,69 +1,36 @@
1
1
  - Code
2
- - {a = "Go" a += "od" a}
3
2
  - Statement
4
- - {a = "Good"}
5
3
  - Equality
6
- - {1 == 1 ? "Good"}
4
+ - Splat
5
+ - Class
7
6
  - While
8
- - {a = 0
9
- while a < 10 a += 1 "Good" end}
10
7
  - If
11
- - {if true "Good" end}
12
8
  - IfModifier
13
- - {"Good" if true}
14
9
  - OrKeyword
15
- - {false or "Good"}
16
10
  - NotKeyword
17
- - {not false and "Good"}
18
11
  - Equal
19
- - {a = "Good"}
20
12
  - Rescue
21
- - {0 > "String" rescue "Good"}
22
13
  - Ternary
23
- - {nothing ? "Bad" : "Good"}
24
- - Defined
25
- - {a = 1 "Good" if defined?(a)}
26
14
  - Range
27
- - {("Good".."Bad").first}
28
15
  - OrOperator
29
- - {false || "Good"}
30
16
  - AndOperator
31
- - {"Bad" && "Good"}
32
- - GreaterThan
33
- - {2 > 1 ? "Good"}
17
+ - EqualityLower
18
+ - Greater
34
19
  - BitwiseOr
35
- - {2 | 1 == 3 ? "Good"}
36
20
  - BitwiseAnd
37
- - {2 & 1 == 0 ? "Good"}
38
21
  - Shift
39
- - {1 << 1 == 2 ? "Good"}
40
22
  - Addition
41
- - {1 + 1 == 2 ? "Good"}
42
23
  - Multiplication
43
- - {1 * 2 == 2 ? "Good"}
44
24
  - UnaryMinus
45
- - {-1 == 1 - 2 ? "Good"}
46
25
  - Power
47
- - {2 ** 2 == 4 ? "Good"}
48
26
  - Negation
49
- - {!false ? "Good"}
50
27
  - Function
51
- - {good = () => { "Good" } good}
52
- - Call
53
- - {["Good"].first}
28
+ - ChainedCall
54
29
  - Dictionnary
55
- - {{a: "Good"}.a}
56
30
  - List
57
- - {["Good", "Bad"].first}
58
31
  - String
59
- - {"Good"}
60
32
  - Number
61
- - {1 == 1 ? "Good"}
62
33
  - Boolean
63
- - {true ? "Good"}
64
34
  - Nothing
65
- - {nothing ? "Bad" : "Good"}
66
35
  - Group
67
- - {(a = 0 a += 1 a) == 1 ? "Good"}
68
- - Name
69
- - {a = "Good" a}
36
+ - Call
data/docs/rain.code ADDED
@@ -0,0 +1,22 @@
1
+ paris = { latitude: 48.8566, longitude: 2.4022 }
2
+ latitude = fetch(:latitude) { paris.latitude }
3
+ longitude = fetch(:longitude) { paris.longitude }
4
+ duration = fetch(:duration) { 1.hour }
5
+ hour = duration.from_now.hour
6
+
7
+ response =
8
+ HTTP.get(
9
+ "https://api.open-meteo.com/v1/forecast",
10
+ parameters: {
11
+ latitude: latitude,
12
+ longitude: longitude,
13
+ hourly: :precipitation
14
+ }
15
+ )
16
+
17
+ precipitation = response.hourly.precipitation[hour]
18
+ precipitation = (precipitation * 100).to_integer
19
+
20
+ if precipitation > 0
21
+ Sms.send("There will be {precipitation}% of precipitation in the next hour")
22
+ end
data/docs/slack.code ADDED
@@ -0,0 +1,17 @@
1
+ Slack.send("Who is leading the syncs?", channel: "#team-template")
2
+
3
+ Twitter.send("What do you want to do this week?")
4
+
5
+ Discord.send("Who will be the game master this week?")
6
+
7
+ Email.send(
8
+ subject: "What did you do last week?",
9
+ from: "dorian@thoughtbot.com",
10
+ reply_to: "rob@thoughtbot.com"
11
+ )
12
+
13
+ Email.send(
14
+ subject: "What do you want to do this week?",
15
+ from: "dorian@thoughtbot.com",
16
+ reply_to: "rob@thoughtbot.com"
17
+ )
data/docs/stripe.code ADDED
@@ -0,0 +1,7 @@
1
+ event = Stripe::Webhook.event
2
+
3
+ if event.type == "payment_intent.succeeded"
4
+ payment_intent = event.data.object
5
+ amount = Money.format(payment_intent.amount, payment_intent.currency)
6
+ Sms.send("You got paid {amount}")
7
+ end
data/docs/twitter.code ADDED
@@ -0,0 +1,9 @@
1
+ twitter_username = fetch(:twitter_username) { "dorianmariefr" }
2
+
3
+ Twitter
4
+ .search("to:{twitter_username}", type: :recent)
5
+ .each do |tweet|
6
+ next if Storage.exists?(tweet.id)
7
+ Storage.create!(tweet.id)
8
+ Sms.send("New mention: {tweet.user.screen_name}: {tweet.text}")
9
+ end
@@ -0,0 +1,18 @@
1
+ require_relative "lib/template/version"
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "language-ruby"
5
+ s.version = ::Template::Version
6
+ s.summary = "A Parsing Expression Grammar (PEG)"
7
+ s.description =
8
+ 'A Parsing Expression Grammar (PEG) for making parsers'
9
+ s.authors = ["Dorian Marié"]
10
+ s.email = "dorian@dorianmarie.fr"
11
+ s.files = `git ls-files`.split($/)
12
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
13
+ s.require_paths = ["lib"]
14
+ s.homepage = "https://github.com/dorianmariefr/template-ruby"
15
+ s.license = "MIT"
16
+
17
+ s.add_dependency "zeitwerk", "~> 2"
18
+ end
@@ -0,0 +1,29 @@
1
+ class Code
2
+ class Node
3
+ class Base10 < Node
4
+ def initialize(parsed)
5
+ @whole = parsed.delete(:whole)
6
+
7
+ if parsed.key?(:exponent)
8
+ @exponent = Node::Statement.new(parsed.delete(:exponent))
9
+ end
10
+
11
+ super(parsed)
12
+ end
13
+
14
+ def evaluate(**args)
15
+ if @exponent
16
+ exponent = @exponent.evaluate(**args)
17
+
18
+ if exponent.is_a?(::Code::Object::Integer)
19
+ ::Code::Object::Integer.new(@whole.to_i, exponent: exponent)
20
+ else
21
+ ::Code::Object::Decimal.new(@whole, exponent: exponent)
22
+ end
23
+ else
24
+ ::Code::Object::Integer.new(@whole.to_i)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,13 @@
1
+ class Code
2
+ class Node
3
+ class Base16 < Node
4
+ def initialize(parsed)
5
+ @base_16 = parsed
6
+ end
7
+
8
+ def evaluate(**args)
9
+ ::Code::Object::Integer.new(@base_16.to_i(16))
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ class Code
2
+ class Node
3
+ class Base2 < Node
4
+ def initialize(parsed)
5
+ @base_2 = parsed
6
+ end
7
+
8
+ def evaluate(**args)
9
+ ::Code::Object::Integer.new(@base_2.to_i(2))
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ class Code
2
+ class Node
3
+ class Base8 < Node
4
+ def initialize(parsed)
5
+ @base_8 = parsed
6
+ end
7
+
8
+ def evaluate(**args)
9
+ ::Code::Object::Integer.new(@base_8.to_i(8))
10
+ end
11
+ end
12
+ end
13
+ end