language-ruby 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.
- checksums.yaml +7 -0
- data/.editorconfig +9 -0
- data/.github/workflows/rspec.yml +14 -0
- data/.gitignore +2 -0
- data/.prettierrc +3 -0
- data/.rspec +1 -0
- data/CHANGELOG.md +55 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +48 -0
- data/LICENSE +7 -0
- data/README.md +103 -0
- data/TODO +17 -0
- data/bin/code +76 -0
- data/bin/format +3 -0
- data/bin/template +85 -0
- data/bin/test +17 -0
- data/code-ruby.gemspec +17 -0
- data/docs/class.code +9 -0
- data/docs/euler/1.template +10 -0
- data/docs/euler/2.template +16 -0
- data/docs/euler/3.template +16 -0
- data/docs/euler/4.template +10 -0
- data/docs/euler/5.template +13 -0
- data/docs/fibonnaci.template +14 -0
- data/docs/meetup.code +12 -0
- data/docs/precedence.template +36 -0
- data/docs/rain.code +22 -0
- data/docs/slack.code +17 -0
- data/docs/stripe.code +7 -0
- data/docs/twitter.code +9 -0
- data/language-ruby.gemspec +18 -0
- data/lib/code/error.rb +18 -0
- data/lib/code/node/base_10.rb +29 -0
- data/lib/code/node/base_16.rb +13 -0
- data/lib/code/node/base_2.rb +13 -0
- data/lib/code/node/base_8.rb +13 -0
- data/lib/code/node/boolean.rb +22 -0
- data/lib/code/node/call.rb +47 -0
- data/lib/code/node/call_argument.rb +21 -0
- data/lib/code/node/chained_call.rb +23 -0
- data/lib/code/node/code.rb +20 -0
- data/lib/code/node/decimal.rb +26 -0
- data/lib/code/node/dictionnary.rb +33 -0
- data/lib/code/node/equal.rb +34 -0
- data/lib/code/node/function.rb +20 -0
- data/lib/code/node/function_parameter.rb +31 -0
- data/lib/code/node/if.rb +59 -0
- data/lib/code/node/if_modifier.rb +47 -0
- data/lib/code/node/list.rb +16 -0
- data/lib/code/node/negation.rb +15 -0
- data/lib/code/node/not.rb +15 -0
- data/lib/code/node/nothing.rb +12 -0
- data/lib/code/node/number.rb +25 -0
- data/lib/code/node/operation.rb +38 -0
- data/lib/code/node/power.rb +20 -0
- data/lib/code/node/rescue.rb +17 -0
- data/lib/code/node/splat.rb +15 -0
- data/lib/code/node/statement.rb +59 -0
- data/lib/code/node/string.rb +53 -0
- data/lib/code/node/ternary.rb +24 -0
- data/lib/code/node/unary_minus.rb +15 -0
- data/lib/code/node/while.rb +35 -0
- data/lib/code/node.rb +13 -0
- data/lib/code/object/argument.rb +32 -0
- data/lib/code/object/boolean.rb +27 -0
- data/lib/code/object/decimal.rb +162 -0
- data/lib/code/object/dictionnary.rb +96 -0
- data/lib/code/object/function.rb +64 -0
- data/lib/code/object/global.rb +42 -0
- data/lib/code/object/integer.rb +221 -0
- data/lib/code/object/list.rb +200 -0
- data/lib/code/object/nothing.rb +23 -0
- data/lib/code/object/number.rb +6 -0
- data/lib/code/object/range.rb +146 -0
- data/lib/code/object/ruby_function.rb +31 -0
- data/lib/code/object/string.rb +88 -0
- data/lib/code/object.rb +197 -0
- data/lib/code/parser/addition.rb +21 -0
- data/lib/code/parser/and_operator.rb +17 -0
- data/lib/code/parser/bitwise_and.rb +17 -0
- data/lib/code/parser/bitwise_or.rb +21 -0
- data/lib/code/parser/boolean.rb +17 -0
- data/lib/code/parser/call.rb +122 -0
- data/lib/code/parser/chained_call.rb +47 -0
- data/lib/code/parser/class.rb +45 -0
- data/lib/code/parser/code.rb +25 -0
- data/lib/code/parser/dictionnary.rb +67 -0
- data/lib/code/parser/equal.rb +94 -0
- data/lib/code/parser/equality.rb +35 -0
- data/lib/code/parser/equality_lower.rb +9 -0
- data/lib/code/parser/function.rb +85 -0
- data/lib/code/parser/greater.rb +25 -0
- data/lib/code/parser/group.rb +22 -0
- data/lib/code/parser/if.rb +63 -0
- data/lib/code/parser/if_modifier.rb +55 -0
- data/lib/code/parser/list.rb +42 -0
- data/lib/code/parser/multiplication.rb +25 -0
- data/lib/code/parser/name.rb +101 -0
- data/lib/code/parser/negation.rb +30 -0
- data/lib/code/parser/not_keyword.rb +23 -0
- data/lib/code/parser/nothing.rb +22 -0
- data/lib/code/parser/number.rb +154 -0
- data/lib/code/parser/operation.rb +35 -0
- data/lib/code/parser/or_keyword.rb +21 -0
- data/lib/code/parser/or_operator.rb +17 -0
- data/lib/code/parser/power.rb +43 -0
- data/lib/code/parser/range.rb +17 -0
- data/lib/code/parser/rescue.rb +39 -0
- data/lib/code/parser/shift.rb +21 -0
- data/lib/code/parser/splat.rb +31 -0
- data/lib/code/parser/statement.rb +9 -0
- data/lib/code/parser/string.rb +78 -0
- data/lib/code/parser/ternary.rb +46 -0
- data/lib/code/parser/unary_minus.rb +31 -0
- data/lib/code/parser/while.rb +36 -0
- data/lib/code/parser/whitespace.rb +49 -0
- data/lib/code/parser.rb +19 -0
- data/lib/code/ruby.rb +162 -0
- data/lib/code-ruby.rb +10 -0
- data/lib/code.rb +47 -0
- data/lib/language/atom.rb +343 -0
- data/lib/language/output.rb +130 -0
- data/lib/language/parser/absent/present.rb +8 -0
- data/lib/language/parser/absent.rb +6 -0
- data/lib/language/parser/end_of_input.rb +6 -0
- data/lib/language/parser/interuption.rb +38 -0
- data/lib/language/parser/not_end_of_input.rb +6 -0
- data/lib/language/parser/str/not_found.rb +16 -0
- data/lib/language/parser/str.rb +6 -0
- data/lib/language/parser.rb +53 -0
- data/lib/language-ruby.rb +10 -0
- data/lib/language.rb +80 -0
- data/lib/template/node/code_part.rb +13 -0
- data/lib/template/node/part.rb +19 -0
- data/lib/template/node/template.rb +15 -0
- data/lib/template/node/text_part.rb +13 -0
- data/lib/template/node.rb +4 -0
- data/lib/template/parser/template.rb +39 -0
- data/lib/template/parser.rb +19 -0
- data/lib/template/version.rb +3 -0
- data/lib/template-ruby.rb +10 -0
- data/lib/template.rb +50 -0
- data/spec/code/addition_spec.rb +13 -0
- data/spec/code/and_operator_spec.rb +13 -0
- data/spec/code/bitwise_and_spec.rb +13 -0
- data/spec/code/bitwise_or_spec.rb +13 -0
- data/spec/code/boolean_spec.rb +13 -0
- data/spec/code/call_spec.rb +21 -0
- data/spec/code/chained_call_spec.rb +16 -0
- data/spec/code/dictionnary_spec.rb +17 -0
- data/spec/code/equal_spec.rb +26 -0
- data/spec/code/equality_spec.rb +13 -0
- data/spec/code/function_spec.rb +18 -0
- data/spec/code/greater_spec.rb +18 -0
- data/spec/code/group_spec.rb +12 -0
- data/spec/code/if_modifier_spec.rb +20 -0
- data/spec/code/if_spec.rb +25 -0
- data/spec/code/list_spec.rb +17 -0
- data/spec/code/multiplication_spec.rb +18 -0
- data/spec/code/negation_spec.rb +20 -0
- data/spec/code/not_keyword_spec.rb +13 -0
- data/spec/code/nothing_spec.rb +17 -0
- data/spec/code/number_spec.rb +22 -0
- data/spec/code/or_keyword_spec.rb +17 -0
- data/spec/code/or_operator_spec.rb +16 -0
- data/spec/code/parser/boolean_spec.rb +16 -0
- data/spec/code/parser/call_spec.rb +26 -0
- data/spec/code/parser/chained_call.rb +17 -0
- data/spec/code/parser/dictionnary_spec.rb +18 -0
- data/spec/code/parser/function_spec.rb +16 -0
- data/spec/code/parser/group_spec.rb +18 -0
- data/spec/code/parser/list_spec.rb +18 -0
- data/spec/code/parser/number_spec.rb +12 -0
- data/spec/code/parser/string_spec.rb +21 -0
- data/spec/code/parser_spec.rb +23 -0
- data/spec/code/power_spec.rb +13 -0
- data/spec/code/range_spec.rb +16 -0
- data/spec/code/rescue_spec.rb +13 -0
- data/spec/code/shift_spec.rb +13 -0
- data/spec/code/splat_spec.rb +13 -0
- data/spec/code/string_spec.rb +25 -0
- data/spec/code/ternary_spec.rb +18 -0
- data/spec/code/unary_minus_spec.rb +13 -0
- data/spec/code/while_spec.rb +18 -0
- data/spec/spec_helper.rb +6 -0
- data/template-ruby.gemspec +19 -0
- metadata +284 -0
data/lib/code/object.rb
ADDED
@@ -0,0 +1,197 @@
|
|
1
|
+
class Code
|
2
|
+
class Object
|
3
|
+
include Comparable
|
4
|
+
|
5
|
+
def call(**args)
|
6
|
+
operator = args.fetch(:operator, nil)
|
7
|
+
arguments = args.fetch(:arguments, [])
|
8
|
+
value = arguments.first&.value
|
9
|
+
|
10
|
+
if operator == "=="
|
11
|
+
sig(arguments) { ::Code::Object }
|
12
|
+
equal(value)
|
13
|
+
elsif operator == "==="
|
14
|
+
sig(arguments) { ::Code::Object }
|
15
|
+
strict_equal(value)
|
16
|
+
elsif operator == "!="
|
17
|
+
sig(arguments) { ::Code::Object }
|
18
|
+
different(value)
|
19
|
+
elsif operator == "<=>"
|
20
|
+
sig(arguments) { ::Code::Object }
|
21
|
+
compare(value)
|
22
|
+
elsif operator == "&&" || operator == "and"
|
23
|
+
sig(arguments) { ::Code::Object }
|
24
|
+
and_operator(value)
|
25
|
+
elsif operator == "||" || operator == "or"
|
26
|
+
sig(arguments) { ::Code::Object }
|
27
|
+
or_operator(value)
|
28
|
+
elsif operator == "!" || operator == "not"
|
29
|
+
sig(arguments)
|
30
|
+
exclamation_point
|
31
|
+
elsif operator == "+"
|
32
|
+
sig(arguments)
|
33
|
+
self
|
34
|
+
elsif operator == ".."
|
35
|
+
sig(arguments) { ::Code::Object }
|
36
|
+
inclusive_range(value)
|
37
|
+
elsif operator == "..."
|
38
|
+
sig(arguments) { ::Code::Object }
|
39
|
+
exclusive_range(value)
|
40
|
+
elsif operator == "to_string"
|
41
|
+
sig(arguments)
|
42
|
+
to_string
|
43
|
+
else
|
44
|
+
raise(
|
45
|
+
Code::Error::Undefined.new("#{operator} not defined on #{inspect}")
|
46
|
+
)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def truthy?
|
51
|
+
true
|
52
|
+
end
|
53
|
+
|
54
|
+
def falsy?
|
55
|
+
!truthy?
|
56
|
+
end
|
57
|
+
|
58
|
+
def <=>(other)
|
59
|
+
if respond_to?(:raw)
|
60
|
+
other.respond_to?(:raw) ? raw <=> other.raw : raw <=> other
|
61
|
+
else
|
62
|
+
other <=> self
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def ==(other)
|
67
|
+
if respond_to?(:raw)
|
68
|
+
other.respond_to?(:raw) ? raw == other.raw : raw == other
|
69
|
+
else
|
70
|
+
other == self
|
71
|
+
end
|
72
|
+
end
|
73
|
+
alias_method :eql?, :==
|
74
|
+
|
75
|
+
def hash
|
76
|
+
if respond_to?(:raw)
|
77
|
+
[self.class, raw].hash
|
78
|
+
else
|
79
|
+
raise NotImplementedError.new(self.class.name)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def to_s
|
84
|
+
raise NotImplementedError.new(self.class.name)
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
def multi_fetch(hash, *keys)
|
90
|
+
keys.map { |key| [key, hash.fetch(key)] }.to_h
|
91
|
+
end
|
92
|
+
|
93
|
+
def deep_dup(object)
|
94
|
+
if object.is_a?(Array)
|
95
|
+
object.map { |element| deep_dup(o) }
|
96
|
+
elsif object.is_a?(Hash)
|
97
|
+
object.map { |key, value| [deep_dup(key), deep_dup(value)] }.to_h
|
98
|
+
elsif object.is_a?(::Code::Object::List)
|
99
|
+
::Code::Object::List.new(object.raw.map { |element| deep_dup(o) })
|
100
|
+
elsif object.is_a?(::Code::Object::Dictionnary)
|
101
|
+
::Code::Object::Dictionnary.new(
|
102
|
+
object.raw.map { |key, value| [deep_dup(key), deep_dup(value)] }.to_h
|
103
|
+
)
|
104
|
+
else
|
105
|
+
object.dup
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def sig(actual_arguments, &block)
|
110
|
+
if block
|
111
|
+
expected_arguments = block.call
|
112
|
+
expected_arguments = [
|
113
|
+
expected_arguments
|
114
|
+
] unless expected_arguments.is_a?(Array)
|
115
|
+
else
|
116
|
+
expected_arguments = []
|
117
|
+
end
|
118
|
+
|
119
|
+
if actual_arguments.size != expected_arguments.size
|
120
|
+
raise(
|
121
|
+
::Code::Error::ArgumentError.new(
|
122
|
+
"Expected #{expected_arguments.size} arguments, " \
|
123
|
+
"got #{actual_arguments.size} arguments"
|
124
|
+
)
|
125
|
+
)
|
126
|
+
end
|
127
|
+
|
128
|
+
expected_arguments.each.with_index do |expected_argument, index|
|
129
|
+
actual_argument = actual_arguments[index].value
|
130
|
+
|
131
|
+
if expected_argument.is_a?(Array)
|
132
|
+
if expected_argument.none? { |expected_arg|
|
133
|
+
actual_argument.is_a?(expected_arg)
|
134
|
+
}
|
135
|
+
raise(
|
136
|
+
::Code::Error::TypeError.new(
|
137
|
+
"Expected #{expected_argument}, got #{actual_argument.class}"
|
138
|
+
)
|
139
|
+
)
|
140
|
+
end
|
141
|
+
else
|
142
|
+
if !actual_argument.is_a?(expected_argument)
|
143
|
+
raise(
|
144
|
+
::Code::Error::TypeError.new(
|
145
|
+
"Expected #{expected_argument}, got #{actual_argument.class}"
|
146
|
+
)
|
147
|
+
)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def equal(other)
|
154
|
+
::Code::Object::Boolean.new(self == other)
|
155
|
+
end
|
156
|
+
|
157
|
+
def strict_equal(other)
|
158
|
+
::Code::Object::Boolean.new(self === other)
|
159
|
+
end
|
160
|
+
|
161
|
+
def different(other)
|
162
|
+
::Code::Object::Boolean.new(self != other)
|
163
|
+
end
|
164
|
+
|
165
|
+
def compare(other)
|
166
|
+
::Code::Object::Integer.new(self <=> other)
|
167
|
+
end
|
168
|
+
|
169
|
+
def and_operator(other)
|
170
|
+
truthy? ? other : self
|
171
|
+
end
|
172
|
+
|
173
|
+
def or_operator(other)
|
174
|
+
truthy? ? self : other
|
175
|
+
end
|
176
|
+
|
177
|
+
def to_string
|
178
|
+
::Code::Object::String.new(to_s)
|
179
|
+
end
|
180
|
+
|
181
|
+
def inclusive_range(value)
|
182
|
+
::Code::Object::Range.new(self, value, exclude_end: false)
|
183
|
+
end
|
184
|
+
|
185
|
+
def exclusive_range(value)
|
186
|
+
::Code::Object::Range.new(self, value, exclude_end: true)
|
187
|
+
end
|
188
|
+
|
189
|
+
def exclamation_point
|
190
|
+
if truthy?
|
191
|
+
::Code::Object::Boolean.new(false)
|
192
|
+
else
|
193
|
+
::Code::Object::Boolean.new(true)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class Code
|
2
|
+
class Parser
|
3
|
+
class Boolean < Language
|
4
|
+
def true_keyword
|
5
|
+
str("true")
|
6
|
+
end
|
7
|
+
|
8
|
+
def false_keyword
|
9
|
+
str("false")
|
10
|
+
end
|
11
|
+
|
12
|
+
def root
|
13
|
+
(true_keyword | false_keyword).aka(:boolean) | ::Code::Parser::Nothing
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
class Code
|
2
|
+
class Parser
|
3
|
+
class Call < Language
|
4
|
+
def name
|
5
|
+
::Code::Parser::Name
|
6
|
+
end
|
7
|
+
|
8
|
+
def whitespace
|
9
|
+
::Code::Parser::Whitespace
|
10
|
+
end
|
11
|
+
|
12
|
+
def whitespace?
|
13
|
+
whitespace.maybe
|
14
|
+
end
|
15
|
+
|
16
|
+
def code
|
17
|
+
::Code::Parser::Code
|
18
|
+
end
|
19
|
+
|
20
|
+
def code_present
|
21
|
+
::Code::Parser::Code.new.present
|
22
|
+
end
|
23
|
+
|
24
|
+
def colon
|
25
|
+
str(":")
|
26
|
+
end
|
27
|
+
|
28
|
+
def comma
|
29
|
+
str(",")
|
30
|
+
end
|
31
|
+
|
32
|
+
def pipe
|
33
|
+
str("|")
|
34
|
+
end
|
35
|
+
|
36
|
+
def equal
|
37
|
+
str("=")
|
38
|
+
end
|
39
|
+
|
40
|
+
def opening_curly_bracket
|
41
|
+
str("{")
|
42
|
+
end
|
43
|
+
|
44
|
+
def closing_curly_bracket
|
45
|
+
str("}")
|
46
|
+
end
|
47
|
+
|
48
|
+
def opening_parenthesis
|
49
|
+
str("(")
|
50
|
+
end
|
51
|
+
|
52
|
+
def closing_parenthesis
|
53
|
+
str(")")
|
54
|
+
end
|
55
|
+
|
56
|
+
def do_keyword
|
57
|
+
str("do")
|
58
|
+
end
|
59
|
+
|
60
|
+
def end_keyword
|
61
|
+
str("end")
|
62
|
+
end
|
63
|
+
|
64
|
+
def keyword_argument
|
65
|
+
name.aka(:name) << colon << code_present.aka(:value)
|
66
|
+
end
|
67
|
+
|
68
|
+
def regular_argument
|
69
|
+
code_present.aka(:value)
|
70
|
+
end
|
71
|
+
|
72
|
+
def argument
|
73
|
+
keyword_argument | regular_argument
|
74
|
+
end
|
75
|
+
|
76
|
+
def arguments
|
77
|
+
opening_parenthesis.ignore << whitespace? << argument.repeat(0, 1) <<
|
78
|
+
(comma << whitespace? << argument << whitespace?).repeat <<
|
79
|
+
whitespace? << closing_parenthesis.ignore.maybe
|
80
|
+
end
|
81
|
+
|
82
|
+
def keyword_parameter
|
83
|
+
name.aka(:name) << whitespace? << colon.aka(:keyword) <<
|
84
|
+
code_present.aka(:default).maybe
|
85
|
+
end
|
86
|
+
|
87
|
+
def regular_parameter
|
88
|
+
name.aka(:name) << whitespace? <<
|
89
|
+
(equal << whitespace? << code_present.aka(:default)).maybe
|
90
|
+
end
|
91
|
+
|
92
|
+
def parameter
|
93
|
+
keyword_parameter | regular_parameter
|
94
|
+
end
|
95
|
+
|
96
|
+
def parameters
|
97
|
+
pipe.ignore << whitespace? << parameter.repeat(0, 1) <<
|
98
|
+
(whitespace? << comma << whitespace? << parameter).repeat <<
|
99
|
+
whitespace? << pipe.ignore.maybe
|
100
|
+
end
|
101
|
+
|
102
|
+
def block
|
103
|
+
(
|
104
|
+
do_keyword << whitespace? << parameters.aka(:parameters).maybe <<
|
105
|
+
code.aka(:body) << end_keyword.maybe
|
106
|
+
) |
|
107
|
+
(
|
108
|
+
opening_curly_bracket << whitespace? <<
|
109
|
+
parameters.aka(:parameters).maybe << code.aka(:body) <<
|
110
|
+
closing_curly_bracket.maybe
|
111
|
+
)
|
112
|
+
end
|
113
|
+
|
114
|
+
def root
|
115
|
+
(
|
116
|
+
name.aka(:name) << (whitespace? << arguments.aka(:arguments)).maybe <<
|
117
|
+
(whitespace? << block.aka(:block)).maybe
|
118
|
+
).aka(:call)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
class Code
|
2
|
+
class Parser
|
3
|
+
class ChainedCall < Operation
|
4
|
+
def statement
|
5
|
+
::Code::Parser::Dictionnary
|
6
|
+
end
|
7
|
+
|
8
|
+
def whitespace
|
9
|
+
::Code::Parser::Whitespace
|
10
|
+
end
|
11
|
+
|
12
|
+
def whitespace?
|
13
|
+
whitespace.maybe
|
14
|
+
end
|
15
|
+
|
16
|
+
def dot
|
17
|
+
str(".")
|
18
|
+
end
|
19
|
+
|
20
|
+
def colon
|
21
|
+
str(":")
|
22
|
+
end
|
23
|
+
|
24
|
+
def operator
|
25
|
+
dot | (colon << colon)
|
26
|
+
end
|
27
|
+
|
28
|
+
def root
|
29
|
+
(
|
30
|
+
statement.aka(:first) <<
|
31
|
+
(whitespace? << operator << whitespace? << statement)
|
32
|
+
.repeat(1)
|
33
|
+
.aka(:others)
|
34
|
+
.maybe
|
35
|
+
)
|
36
|
+
.aka(:chained_call)
|
37
|
+
.then do |output|
|
38
|
+
if output[:chained_call][:others]
|
39
|
+
output
|
40
|
+
else
|
41
|
+
output[:chained_call][:first]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class Code
|
2
|
+
class Parser
|
3
|
+
class Class < Language
|
4
|
+
def statement
|
5
|
+
::Code::Parser::While
|
6
|
+
end
|
7
|
+
|
8
|
+
def name
|
9
|
+
::Code::Parser::Name
|
10
|
+
end
|
11
|
+
|
12
|
+
def code
|
13
|
+
::Code::Parser::Code
|
14
|
+
end
|
15
|
+
|
16
|
+
def whitespace
|
17
|
+
::Code::Parser::Whitespace
|
18
|
+
end
|
19
|
+
|
20
|
+
def whitespace?
|
21
|
+
whitespace.maybe
|
22
|
+
end
|
23
|
+
|
24
|
+
def class_keyword
|
25
|
+
str("class")
|
26
|
+
end
|
27
|
+
|
28
|
+
def end_keyword
|
29
|
+
str("end")
|
30
|
+
end
|
31
|
+
|
32
|
+
def lesser
|
33
|
+
str("<")
|
34
|
+
end
|
35
|
+
|
36
|
+
def root
|
37
|
+
(
|
38
|
+
class_keyword << whitespace? << name.aka(:name) <<
|
39
|
+
(whitespace? << lesser << name.aka(:superclass)).maybe <<
|
40
|
+
code.aka(:body) << end_keyword.maybe
|
41
|
+
).aka(:class) | statement
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class Code
|
2
|
+
class Parser
|
3
|
+
class Code < Language
|
4
|
+
def whitespace
|
5
|
+
::Code::Parser::Whitespace
|
6
|
+
end
|
7
|
+
|
8
|
+
def whitespace?(&block)
|
9
|
+
whitespace.maybe(&block)
|
10
|
+
end
|
11
|
+
|
12
|
+
def statement
|
13
|
+
::Code::Parser::Statement
|
14
|
+
end
|
15
|
+
|
16
|
+
def present
|
17
|
+
(whitespace? << statement << whitespace?).repeat(1)
|
18
|
+
end
|
19
|
+
|
20
|
+
def root
|
21
|
+
present | whitespace?.then { [] }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
class Code
|
2
|
+
class Parser
|
3
|
+
class Dictionnary < Language
|
4
|
+
def code
|
5
|
+
::Code::Parser::Code.new.present
|
6
|
+
end
|
7
|
+
|
8
|
+
def statement
|
9
|
+
::Code::Parser::Statement
|
10
|
+
end
|
11
|
+
|
12
|
+
def name
|
13
|
+
::Code::Parser::Name
|
14
|
+
end
|
15
|
+
|
16
|
+
def whitespace
|
17
|
+
::Code::Parser::Whitespace
|
18
|
+
end
|
19
|
+
|
20
|
+
def whitespace?
|
21
|
+
whitespace.maybe
|
22
|
+
end
|
23
|
+
|
24
|
+
def opening_curly_bracket
|
25
|
+
str("{")
|
26
|
+
end
|
27
|
+
|
28
|
+
def closing_curly_bracket
|
29
|
+
str("}")
|
30
|
+
end
|
31
|
+
|
32
|
+
def comma
|
33
|
+
str(",")
|
34
|
+
end
|
35
|
+
|
36
|
+
def colon
|
37
|
+
str(":")
|
38
|
+
end
|
39
|
+
|
40
|
+
def equal
|
41
|
+
str("=")
|
42
|
+
end
|
43
|
+
|
44
|
+
def greater
|
45
|
+
str(">")
|
46
|
+
end
|
47
|
+
|
48
|
+
def key_value
|
49
|
+
(name.aka(:name) << colon << code.aka(:value)) |
|
50
|
+
(statement.aka(:statement) << colon << code.aka(:value)) |
|
51
|
+
(
|
52
|
+
statement.aka(:statement) << whitespace? << equal << greater <<
|
53
|
+
code.aka(:value)
|
54
|
+
)
|
55
|
+
end
|
56
|
+
|
57
|
+
def root
|
58
|
+
(
|
59
|
+
opening_curly_bracket.ignore << whitespace? <<
|
60
|
+
key_value.repeat(0, 1) <<
|
61
|
+
(whitespace? << comma << whitespace? << key_value).repeat <<
|
62
|
+
(whitespace? << closing_curly_bracket.ignore).maybe
|
63
|
+
).aka(:dictionnary) | ::Code::Parser::List
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
class Code
|
2
|
+
class Parser
|
3
|
+
class Equal < Language
|
4
|
+
def statement
|
5
|
+
::Code::Parser::Rescue
|
6
|
+
end
|
7
|
+
|
8
|
+
def name
|
9
|
+
::Code::Parser::Name
|
10
|
+
end
|
11
|
+
|
12
|
+
def equal_class
|
13
|
+
::Code::Parser::Equal
|
14
|
+
end
|
15
|
+
|
16
|
+
def whitespace
|
17
|
+
::Code::Parser::Whitespace
|
18
|
+
end
|
19
|
+
|
20
|
+
def whitespace?
|
21
|
+
whitespace.maybe
|
22
|
+
end
|
23
|
+
|
24
|
+
def equal
|
25
|
+
str("=")
|
26
|
+
end
|
27
|
+
|
28
|
+
def plus
|
29
|
+
str("+")
|
30
|
+
end
|
31
|
+
|
32
|
+
def minus
|
33
|
+
str("-")
|
34
|
+
end
|
35
|
+
|
36
|
+
def asterisk
|
37
|
+
str("*")
|
38
|
+
end
|
39
|
+
|
40
|
+
def slash
|
41
|
+
str("/")
|
42
|
+
end
|
43
|
+
|
44
|
+
def percent
|
45
|
+
str("%")
|
46
|
+
end
|
47
|
+
|
48
|
+
def greater
|
49
|
+
str(">")
|
50
|
+
end
|
51
|
+
|
52
|
+
def lesser
|
53
|
+
str("<")
|
54
|
+
end
|
55
|
+
|
56
|
+
def ampersand
|
57
|
+
str("&")
|
58
|
+
end
|
59
|
+
|
60
|
+
def pipe
|
61
|
+
str("|")
|
62
|
+
end
|
63
|
+
|
64
|
+
def caret
|
65
|
+
str("^")
|
66
|
+
end
|
67
|
+
|
68
|
+
def dot
|
69
|
+
str(".")
|
70
|
+
end
|
71
|
+
|
72
|
+
def operator
|
73
|
+
equal.ignore | (plus << equal.ignore) | (minus << equal.ignore) |
|
74
|
+
(asterisk << equal.ignore) | (slash << equal.ignore) |
|
75
|
+
(percent << equal.ignore) | (greater << greater << equal.ignore) |
|
76
|
+
(lesser << lesser << equal.ignore) | (ampersand << equal.ignore) |
|
77
|
+
(pipe << equal.ignore) | (caret << equal.ignore) |
|
78
|
+
(pipe << pipe << equal.ignore) |
|
79
|
+
(ampersand << ampersand << equal.ignore)
|
80
|
+
end
|
81
|
+
|
82
|
+
def names
|
83
|
+
name << (dot << name).repeat
|
84
|
+
end
|
85
|
+
|
86
|
+
def root
|
87
|
+
(
|
88
|
+
names.aka(:left) << whitespace? << operator.aka(:operator) <<
|
89
|
+
whitespace? << equal_class.aka(:right)
|
90
|
+
).aka(:equal) | statement
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|