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
@@ -1,29 +1,21 @@
1
1
  class Code
2
2
  class Parser
3
- class OrKeyword < Parslet::Parser
4
- rule(:not_keyword) { ::Code::Parser::NotKeyword.new }
5
-
6
- rule(:or_keyword) { str("or") }
7
- rule(:and_keyword) { str("and") }
8
-
9
- rule(:operator) { or_keyword | and_keyword }
3
+ class OrKeyword < Operation
4
+ def statement
5
+ ::Code::Parser::NotKeyword
6
+ end
10
7
 
11
- rule(:space) { str(" ") }
12
- rule(:newline) { str("\n") }
13
- rule(:whitespace) { (space | newline).repeat(1) }
14
- rule(:whitespace?) { whitespace.maybe }
8
+ def or_keyword
9
+ str("or")
10
+ end
15
11
 
16
- rule(:or_rule) do
17
- (
18
- not_keyword.as(:first) >>
19
- (
20
- whitespace? >> operator.as(:operator) >> whitespace? >>
21
- not_keyword.as(:statement)
22
- ).repeat(1).as(:rest)
23
- ).as(:or_keyword) | not_keyword
12
+ def and_keyword
13
+ str("and")
24
14
  end
25
15
 
26
- root(:or_rule)
16
+ def operator
17
+ or_keyword | and_keyword
18
+ end
27
19
  end
28
20
  end
29
21
  end
@@ -1,28 +1,17 @@
1
1
  class Code
2
2
  class Parser
3
- class OrOperator < Parslet::Parser
4
- rule(:and_operator) { ::Code::Parser::AndOperator.new }
5
-
6
- rule(:pipe) { str("|") }
7
-
8
- rule(:operator) { pipe >> pipe }
9
-
10
- rule(:space) { str(" ") }
11
- rule(:newline) { str("\n") }
12
- rule(:whitespace) { (space | newline).repeat(1) }
13
- rule(:whitespace?) { whitespace.maybe }
3
+ class OrOperator < Operation
4
+ def statement
5
+ ::Code::Parser::AndOperator
6
+ end
14
7
 
15
- rule(:or_operator) do
16
- (
17
- and_operator.as(:first) >>
18
- (
19
- whitespace? >> operator.as(:operator) >> whitespace? >>
20
- and_operator.as(:statement)
21
- ).repeat(1).as(:rest)
22
- ).as(:or_operator) | and_operator
8
+ def pipe
9
+ str("|")
23
10
  end
24
11
 
25
- root(:or_operator)
12
+ def operator
13
+ pipe << pipe
14
+ end
26
15
  end
27
16
  end
28
17
  end
@@ -1,25 +1,43 @@
1
1
  class Code
2
2
  class Parser
3
- class Power < Parslet::Parser
4
- rule(:negation) { ::Code::Parser::Negation.new }
3
+ class Power < Language
4
+ def power
5
+ ::Code::Parser::Power
6
+ end
5
7
 
6
- rule(:asterisk) { str("*") }
8
+ def statement
9
+ ::Code::Parser::Negation
10
+ end
7
11
 
8
- rule(:operator) { asterisk >> asterisk }
12
+ def whitespace
13
+ ::Code::Parser::Whitespace
14
+ end
9
15
 
10
- rule(:space) { str(" ") }
11
- rule(:newline) { str("\n") }
12
- rule(:whitespace) { (space | newline).repeat(1) }
13
- rule(:whitespace?) { whitespace.maybe }
16
+ def whitespace?
17
+ whitespace.maybe
18
+ end
14
19
 
15
- rule(:power) do
16
- (
17
- negation.as(:left) >> whitespace? >> operator >> whitespace? >>
18
- power.as(:right)
19
- ).as(:power) | negation
20
+ def asterisk
21
+ str("*")
20
22
  end
21
23
 
22
- root(:power)
24
+ def operator
25
+ asterisk << asterisk
26
+ end
27
+
28
+ def root
29
+ (
30
+ statement.aka(:left) <<
31
+ (
32
+ whitespace? << operator.aka(:operator) << whitespace? <<
33
+ power.aka(:right)
34
+ ).maybe
35
+ )
36
+ .aka(:power)
37
+ .then do |output|
38
+ output[:power][:right] ? output : output[:power][:left]
39
+ end
40
+ end
23
41
  end
24
42
  end
25
43
  end
@@ -1,25 +1,17 @@
1
1
  class Code
2
2
  class Parser
3
- class Range < Parslet::Parser
4
- rule(:or_operator) { ::Code::Parser::OrOperator.new }
5
-
6
- rule(:dot) { str(".") }
7
-
8
- rule(:operator) { dot >> dot >> dot | dot >> dot }
9
-
10
- rule(:space) { str(" ") }
11
- rule(:newline) { str("\n") }
12
- rule(:whitespace) { (space | newline).repeat(1) }
13
- rule(:whitespace?) { whitespace.maybe }
3
+ class Range < Operation
4
+ def statement
5
+ ::Code::Parser::OrOperator
6
+ end
14
7
 
15
- rule(:range) do
16
- (
17
- or_operator.as(:left) >> whitespace? >> operator.as(:operator) >>
18
- whitespace? >> range.as(:right)
19
- ).as(:range) | or_operator
8
+ def dot
9
+ str(".")
20
10
  end
21
11
 
22
- root(:range)
12
+ def operator
13
+ (dot << dot << dot) | (dot << dot)
14
+ end
23
15
  end
24
16
  end
25
17
  end
@@ -1,23 +1,39 @@
1
1
  class Code
2
2
  class Parser
3
- class Rescue < Parslet::Parser
4
- rule(:ternary) { ::Code::Parser::Ternary.new }
3
+ class Rescue < Language
4
+ def statement
5
+ ::Code::Parser::Ternary
6
+ end
5
7
 
6
- rule(:rescue_keyword) { str("rescue") }
8
+ def rescue_class
9
+ ::Code::Parser::Rescue
10
+ end
7
11
 
8
- rule(:space) { str(" ") }
9
- rule(:newline) { str("\n") }
10
- rule(:whitespace) { (space | newline).repeat(1) }
11
- rule(:whitespace?) { whitespace.maybe }
12
+ def whitespace
13
+ ::Code::Parser::Whitespace
14
+ end
12
15
 
13
- rule(:rescue) do
14
- (
15
- ternary.as(:left) >> whitespace? >> rescue_keyword >> whitespace? >>
16
- ternary.as(:right)
17
- ).as(:rescue) | ternary
16
+ def whitespace?
17
+ whitespace.maybe
18
18
  end
19
19
 
20
- root(:rescue)
20
+ def rescue_keyword
21
+ str("rescue")
22
+ end
23
+
24
+ def root
25
+ (
26
+ statement.aka(:left) <<
27
+ (
28
+ whitespace? << rescue_keyword << whitespace? <<
29
+ rescue_class.aka(:right)
30
+ ).maybe
31
+ )
32
+ .aka(:rescue)
33
+ .then do |output|
34
+ output[:rescue][:right] ? output : output[:rescue][:left]
35
+ end
36
+ end
21
37
  end
22
38
  end
23
39
  end
@@ -1,31 +1,21 @@
1
1
  class Code
2
2
  class Parser
3
- class Shift < Parslet::Parser
4
- rule(:addition) { ::Code::Parser::Addition.new }
5
-
6
- rule(:right_caret) { str(">") }
7
- rule(:left_caret) { str("<") }
8
-
9
- rule(:operator) do
10
- (left_caret >> left_caret) | (right_caret >> right_caret)
3
+ class Shift < Operation
4
+ def statement
5
+ ::Code::Parser::Addition
11
6
  end
12
7
 
13
- rule(:space) { str(" ") }
14
- rule(:newline) { str("\n") }
15
- rule(:whitespace) { (space | newline).repeat(1) }
16
- rule(:whitespace?) { whitespace.maybe }
8
+ def greater
9
+ str(">")
10
+ end
17
11
 
18
- rule(:shift) do
19
- (
20
- addition.as(:first) >>
21
- (
22
- whitespace? >> operator.as(:operator) >> whitespace? >>
23
- addition.as(:statement)
24
- ).repeat(1).as(:rest)
25
- ).as(:shift) | addition
12
+ def lesser
13
+ str("<")
26
14
  end
27
15
 
28
- root(:shift)
16
+ def operator
17
+ (greater << greater) | (lesser << lesser)
18
+ end
29
19
  end
30
20
  end
31
21
  end
@@ -0,0 +1,31 @@
1
+ class Code
2
+ class Parser
3
+ class Splat < Language
4
+ def statement
5
+ ::Code::Parser::Class
6
+ end
7
+
8
+ def splat
9
+ ::Code::Parser::Splat
10
+ end
11
+
12
+ def whitespace
13
+ ::Code::Parser::Whitespace
14
+ end
15
+
16
+ def whitespace?
17
+ whitespace.maybe
18
+ end
19
+
20
+ def ampersand
21
+ str("&")
22
+ end
23
+
24
+ def root
25
+ (ampersand.aka(:operator) << whitespace? << splat.aka(:right)).aka(
26
+ :splat
27
+ ) | statement
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,8 +1,9 @@
1
1
  class Code
2
2
  class Parser
3
- class Statement < Parslet::Parser
4
- rule(:statement) { ::Code::Parser::Equality.new }
5
- root(:statement)
3
+ class Statement < Language
4
+ def root
5
+ ::Code::Parser::Equality
6
+ end
6
7
  end
7
8
  end
8
9
  end
@@ -1,87 +1,78 @@
1
1
  class Code
2
2
  class Parser
3
- class String < Parslet::Parser
4
- rule(:number) { ::Code::Parser::Number.new }
5
- rule(:name) { ::Code::Parser::Name.new.name }
6
- rule(:code) { ::Code::Parser::Code.new }
3
+ class String < Language
4
+ def code
5
+ ::Code::Parser::Code
6
+ end
7
7
 
8
- rule(:single_quote) { str("'") }
9
- rule(:double_quote) { str('"') }
10
- rule(:backslash) { str("\\") }
11
- rule(:colon) { str(":") }
12
- rule(:opening_curly_bracket) { str("{") }
13
- rule(:closing_curly_bracket) { str("}") }
8
+ def name
9
+ ::Code::Parser::Name
10
+ end
14
11
 
15
- rule(:zero) { str("0") }
16
- rule(:one) { str("1") }
17
- rule(:two) { str("2") }
18
- rule(:three) { str("3") }
19
- rule(:four) { str("4") }
20
- rule(:five) { str("5") }
21
- rule(:six) { str("6") }
22
- rule(:seven) { str("7") }
23
- rule(:eight) { str("8") }
24
- rule(:nine) { str("9") }
25
- rule(:a) { str("a") | str("A") }
26
- rule(:b) { str("b") | str("B") }
27
- rule(:b) { str("b") | str("B") }
28
- rule(:c) { str("c") | str("C") }
29
- rule(:d) { str("d") | str("D") }
30
- rule(:e) { str("e") | str("E") }
31
- rule(:f) { str("f") | str("F") }
32
- rule(:n) { str("n") | str("N") }
33
- rule(:r) { str("r") | str("R") }
34
- rule(:t) { str("t") | str("T") }
35
- rule(:u) { str("u") | str("U") }
12
+ def single_quote
13
+ str("'")
14
+ end
36
15
 
37
- rule(:interpolation) do
38
- opening_curly_bracket >> code >> closing_curly_bracket
16
+ def double_quote
17
+ str('"')
39
18
  end
40
19
 
41
- rule(:base_16_digit) do
42
- zero | one | two | three | four | five | six | seven | eight | nine |
43
- a | b | c | d | e | f
20
+ def backslash
21
+ str("\\")
44
22
  end
45
23
 
46
- rule(:escaped_character) do
47
- (backslash >> u >> base_16_digit.repeat(4, 4)) |
48
- (backslash >> (b | f | n | r | t)) | (backslash.ignore >> any)
24
+ def opening_curly_bracket
25
+ str("{")
49
26
  end
50
27
 
51
- rule(:single_quoted_character) do
52
- escaped_character |
53
- (opening_curly_bracket.absent? >> single_quote.absent? >> any)
28
+ def closing_curly_bracket
29
+ str("}")
54
30
  end
55
31
 
56
- rule(:double_quoted_character) do
57
- escaped_character |
58
- (opening_curly_bracket.absent? >> double_quote.absent? >> any)
32
+ def colon
33
+ str(":")
59
34
  end
60
35
 
61
- rule(:single_quoted_string) do
62
- single_quote.ignore >>
63
- (
64
- interpolation.as(:interpolation) |
65
- single_quoted_character.repeat(1).as(:characters)
66
- ).repeat >> single_quote.ignore
36
+ def code_part
37
+ opening_curly_bracket << code << closing_curly_bracket.maybe
67
38
  end
68
39
 
69
- rule(:double_quoted_string) do
70
- double_quote.ignore >>
71
- (
72
- interpolation.as(:interpolation) |
73
- double_quoted_character.repeat(1).as(:characters)
74
- ).repeat >> double_quote.ignore
40
+ def single_quoted_text_part
41
+ (
42
+ backslash.ignore << opening_curly_bracket |
43
+ backslash.ignore << single_quote |
44
+ single_quote.absent << opening_curly_bracket.absent << any
45
+ ).repeat(1)
75
46
  end
76
47
 
77
- rule(:symbol) { colon.ignore >> name }
48
+ def double_quoted_text_part
49
+ (
50
+ backslash.ignore << opening_curly_bracket |
51
+ backslash.ignore << double_quote |
52
+ double_quote.absent << opening_curly_bracket.absent << any
53
+ ).repeat(1)
54
+ end
78
55
 
79
- rule(:string) do
80
- (single_quoted_string | double_quoted_string | symbol).as(:string) |
81
- number
56
+ def single_quoted_string
57
+ single_quote.ignore <<
58
+ (code_part.aka(:code) | single_quoted_text_part.aka(:text)).repeat <<
59
+ single_quote.ignore.maybe
82
60
  end
83
61
 
84
- root(:string)
62
+ def double_quoted_string
63
+ double_quote.ignore <<
64
+ (code_part.aka(:code) | double_quoted_text_part.aka(:text)).repeat <<
65
+ double_quote.ignore.maybe
66
+ end
67
+
68
+ def symbol
69
+ (colon.ignore << name).aka(:text).repeat(1, 1)
70
+ end
71
+
72
+ def root
73
+ (single_quoted_string | double_quoted_string | symbol).aka(:string) |
74
+ ::Code::Parser::Number
75
+ end
85
76
  end
86
77
  end
87
78
  end
@@ -1,25 +1,46 @@
1
1
  class Code
2
2
  class Parser
3
- class Ternary < Parslet::Parser
4
- rule(:defined) { ::Code::Parser::Defined.new }
3
+ class Ternary < Language
4
+ def statement
5
+ ::Code::Parser::Range
6
+ end
5
7
 
6
- rule(:question_mark) { str("?") }
7
- rule(:colon) { str(":") }
8
+ def ternary
9
+ ::Code::Parser::Ternary
10
+ end
8
11
 
9
- rule(:space) { str(" ") }
10
- rule(:newline) { str("\n") }
11
- rule(:whitespace) { (space | newline).repeat(1) }
12
- rule(:whitespace?) { whitespace.maybe }
12
+ def whitespace
13
+ ::Code::Parser::Whitespace
14
+ end
13
15
 
14
- rule(:ternary) do
15
- (
16
- defined.as(:left) >> whitespace >> question_mark >> whitespace? >>
17
- ternary.as(:middle) >>
18
- (whitespace? >> colon >> whitespace? >> ternary.as(:right)).maybe
19
- ).as(:ternary) | defined
16
+ def whitespace?
17
+ whitespace.maybe
18
+ end
19
+
20
+ def question_mark
21
+ str("?")
22
+ end
23
+
24
+ def colon
25
+ str(":")
20
26
  end
21
27
 
22
- root(:ternary)
28
+ def root
29
+ (
30
+ statement.aka(:left) <<
31
+ (
32
+ whitespace? << question_mark << whitespace? <<
33
+ ternary.aka(:middle) <<
34
+ (
35
+ whitespace? << colon << whitespace? << ternary.aka(:right)
36
+ ).maybe
37
+ ).maybe
38
+ )
39
+ .aka(:ternary)
40
+ .then do |output|
41
+ output[:ternary][:middle] ? output : output[:ternary][:left]
42
+ end
43
+ end
23
44
  end
24
45
  end
25
46
  end
@@ -1,13 +1,31 @@
1
1
  class Code
2
2
  class Parser
3
- class UnaryMinus < Parslet::Parser
4
- rule(:power) { ::Code::Parser::Power.new }
3
+ class UnaryMinus < Language
4
+ def unary_minus
5
+ ::Code::Parser::UnaryMinus
6
+ end
5
7
 
6
- rule(:minus) { str("-") }
8
+ def whitespace
9
+ ::Code::Parser::Whitespace
10
+ end
7
11
 
8
- rule(:unary_minus) { (minus >> unary_minus).as(:unary_minus) | power }
12
+ def whitespace?
13
+ whitespace.maybe
14
+ end
9
15
 
10
- root(:unary_minus)
16
+ def minus
17
+ str("-")
18
+ end
19
+
20
+ def operator
21
+ minus
22
+ end
23
+
24
+ def root
25
+ (operator.aka(:operator) << whitespace? << unary_minus.aka(:right)).aka(
26
+ :unary_minus
27
+ ) | ::Code::Parser::Power
28
+ end
11
29
  end
12
30
  end
13
31
  end
@@ -1,25 +1,36 @@
1
1
  class Code
2
2
  class Parser
3
- class While < Parslet::Parser
4
- rule(:if_rule) { ::Code::Parser::If.new }
5
- rule(:code) { ::Code::Parser::Code.new }
3
+ class While < Language
4
+ def statement
5
+ ::Code::Parser::If
6
+ end
6
7
 
7
- rule(:while_keyword) { str("while") }
8
- rule(:until_keyword) { str("until") }
9
- rule(:end_keyword) { str("end") }
8
+ def whitespace
9
+ ::Code::Parser::Whitespace
10
+ end
10
11
 
11
- rule(:space) { str(" ") }
12
- rule(:newline) { str("\n") }
13
- rule(:whitespace) { (space | newline).repeat(1) }
12
+ def code
13
+ ::Code::Parser::Code
14
+ end
14
15
 
15
- rule(:while_rule) do
16
- (
17
- (while_keyword | until_keyword).as(:operator) >> whitespace >>
18
- if_rule.as(:statement) >> code.as(:body) >> end_keyword
19
- ).as(:while) | if_rule
16
+ def while_keyword
17
+ str("while")
18
+ end
19
+
20
+ def until_keyword
21
+ str("until")
22
+ end
23
+
24
+ def end_keyword
25
+ str("end")
20
26
  end
21
27
 
22
- root(:while_rule)
28
+ def root
29
+ (
30
+ (while_keyword | until_keyword).aka(:operator) << whitespace <<
31
+ statement.aka(:statement) << code.aka(:body) << end_keyword.maybe
32
+ ).aka(:while) | statement
33
+ end
23
34
  end
24
35
  end
25
36
  end
@@ -0,0 +1,49 @@
1
+ class Code
2
+ class Parser
3
+ class Whitespace < Language
4
+ def space
5
+ str(" ")
6
+ end
7
+
8
+ def newline
9
+ str("\n")
10
+ end
11
+
12
+ def hashtag
13
+ str("#")
14
+ end
15
+
16
+ def slash
17
+ str("/")
18
+ end
19
+
20
+ def asterisk
21
+ str("*")
22
+ end
23
+
24
+ def hash_comment
25
+ hashtag << (newline.absent << any).repeat << newline.maybe
26
+ end
27
+
28
+ def double_slash_comment
29
+ slash << slash << (newline.absent << any).repeat << newline.maybe
30
+ end
31
+
32
+ def multi_line_comment
33
+ slash << asterisk << ((asterisk << slash).absent << any).repeat <<
34
+ asterisk.maybe << slash.maybe
35
+ end
36
+
37
+ def without_newline
38
+ (space | multi_line_comment).repeat(1)
39
+ end
40
+
41
+ def root
42
+ (
43
+ space | newline | hash_comment | double_slash_comment |
44
+ multi_line_comment
45
+ ).repeat(1)
46
+ end
47
+ end
48
+ end
49
+ end
data/lib/code/parser.rb CHANGED
@@ -1,4 +1,19 @@
1
1
  class Code
2
2
  class Parser
3
+ def initialize(input)
4
+ @input = input
5
+ end
6
+
7
+ def self.parse(input)
8
+ new(input).parse
9
+ end
10
+
11
+ def parse
12
+ ::Code::Parser::Code.parse(input)
13
+ end
14
+
15
+ private
16
+
17
+ attr_reader :input
3
18
  end
4
19
  end