antlers 0.7.0 → 0.8.1
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 +4 -4
- data/lib/factories/node_factory.rb +9 -0
- data/lib/interfaces/lexeme.rb +13 -0
- data/lib/lexemes/for_lexeme.rb +28 -0
- data/lib/lexemes/form_lexeme.rb +25 -0
- data/lib/lexemes/if_lexeme.rb +22 -0
- data/lib/lexemes/prop_lexeme.rb +43 -0
- data/lib/lexemes/slot_lexeme.rb +26 -0
- data/lib/lexemes/yield_lexeme.rb +18 -0
- data/lib/lexer.rb +29 -93
- data/lib/nodes/if_node.rb +31 -0
- data/lib/nodes/prop_node.rb +3 -2
- data/lib/nodes/var_node.rb +7 -2
- data/lib/parser.rb +6 -0
- data/lib/version.rb +1 -1
- metadata +9 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8d3bcf6e14ade37294793b87b3ab3ab152e519f8c081a130644b0d28d489b63b
|
|
4
|
+
data.tar.gz: d9886a3044fb8654b37f111a9536ba7dfef4945c26fb08112e400ab14e76d8e7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a4179e613ca96ea49fdbc7d991a627a45640182ae5aaa5f01dc935396586ba8b583df469113c26c7a139308956bc18980cdbd04877c73a9b7cd14617682dd2d3
|
|
7
|
+
data.tar.gz: 698769c0d6bfd0e9872c5022f72555290acff3888615f44061ed10847af8f97af58477c35059678c2e02a2bdafc16d3f06ff514ab80aa539abc2de7cbfeda6bd
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative '../nodes/if_node'
|
|
3
4
|
require_relative '../nodes/for_node'
|
|
4
5
|
require_relative '../nodes/form_node'
|
|
5
6
|
require_relative '../nodes/prop_node'
|
|
@@ -13,6 +14,10 @@ module Antlers
|
|
|
13
14
|
@namespace = namespace
|
|
14
15
|
end
|
|
15
16
|
|
|
17
|
+
def if_node(segment:)
|
|
18
|
+
IfNode.new(name: segment[:if_def], value: segment[:if_def])
|
|
19
|
+
end
|
|
20
|
+
|
|
16
21
|
def for_node(segment:)
|
|
17
22
|
value, key, items = segment.values_at(:for_def, :key, :in)
|
|
18
23
|
ForNode.new(name: value, key:, value:, items:)
|
|
@@ -37,6 +42,10 @@ module Antlers
|
|
|
37
42
|
VarNode.new(value: segment[:var])
|
|
38
43
|
end
|
|
39
44
|
|
|
45
|
+
def raw_var_node(segment:)
|
|
46
|
+
VarNode.new(value: segment[:raw_var], raw: true)
|
|
47
|
+
end
|
|
48
|
+
|
|
40
49
|
def yield_node(segment:)
|
|
41
50
|
YieldNode.new(name: segment[:slot])
|
|
42
51
|
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../interfaces/lexeme'
|
|
4
|
+
|
|
5
|
+
module Antlers
|
|
6
|
+
module ForLexeme
|
|
7
|
+
include Lexeme
|
|
8
|
+
extend self
|
|
9
|
+
|
|
10
|
+
KEYWORDS = ['for:', 'in:', ':for'].freeze
|
|
11
|
+
|
|
12
|
+
def match?(keywords:, **)
|
|
13
|
+
KEYWORDS.include?(keywords.keys.first)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def lexeme(keywords:, **)
|
|
17
|
+
if keywords['for:']
|
|
18
|
+
*key, value = keywords['for:'].split(',').map(&:strip)
|
|
19
|
+
for_def = { for_def: value, in: keywords['in:'] }
|
|
20
|
+
for_def[:key] = key.first unless key.empty?
|
|
21
|
+
return for_def
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# TODO: Keep track of which for loop we're in to allow nested for loops.
|
|
25
|
+
{ for_end: 'level_1' }
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../interfaces/lexeme'
|
|
4
|
+
|
|
5
|
+
module Antlers
|
|
6
|
+
module FormLexeme
|
|
7
|
+
include Lexeme
|
|
8
|
+
extend self
|
|
9
|
+
|
|
10
|
+
KEYWORDS = ['form:', ':form'].freeze
|
|
11
|
+
|
|
12
|
+
def match?(keywords:, **)
|
|
13
|
+
KEYWORDS.include?(keywords.keys.first)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def lexeme(keywords:, **)
|
|
17
|
+
if keywords.key?('form:')
|
|
18
|
+
action = keywords['form:'] ? keywords['form:'][1...-1] : nil
|
|
19
|
+
return { form_def: action }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
{ form_end: 'level_1' }
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../interfaces/lexeme'
|
|
4
|
+
|
|
5
|
+
module Antlers
|
|
6
|
+
module IfLexeme
|
|
7
|
+
include Lexeme
|
|
8
|
+
extend self
|
|
9
|
+
|
|
10
|
+
KEYWORDS = ['if:', ':if'].freeze
|
|
11
|
+
|
|
12
|
+
def match?(keywords:, **)
|
|
13
|
+
KEYWORDS.include?(keywords.keys.first)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def lexeme(keywords:, **)
|
|
17
|
+
return { if_def: keywords['if:'] } if keywords.key?('if:')
|
|
18
|
+
|
|
19
|
+
{ if_end: 'level_1' }
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../interfaces/lexeme'
|
|
4
|
+
|
|
5
|
+
module Antlers
|
|
6
|
+
module PropLexeme
|
|
7
|
+
include Lexeme
|
|
8
|
+
extend self
|
|
9
|
+
|
|
10
|
+
def match?(name:, **)
|
|
11
|
+
name && [*'A'..'Z'].include?(name[0]) && !(name.start_with?(':') || name.end_with?(':'))
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def lexeme(name:, props:, **)
|
|
15
|
+
prop = { prop: name }
|
|
16
|
+
prop[:props] = props(props) unless props.empty?
|
|
17
|
+
prop
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def props(props)
|
|
23
|
+
odd_props = props.join(' ').split(/(=)|\s/)
|
|
24
|
+
|
|
25
|
+
return {} unless odd_props.any?
|
|
26
|
+
|
|
27
|
+
props = {}
|
|
28
|
+
until odd_props.empty?
|
|
29
|
+
prop = odd_props.shift
|
|
30
|
+
value = nil
|
|
31
|
+
|
|
32
|
+
if odd_props.first == '='
|
|
33
|
+
odd_props.shift
|
|
34
|
+
value = odd_props.shift
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
props[prop.to_sym] = value
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
props
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../interfaces/lexeme'
|
|
4
|
+
|
|
5
|
+
module Antlers
|
|
6
|
+
module SlotLexeme
|
|
7
|
+
include Lexeme
|
|
8
|
+
extend self
|
|
9
|
+
|
|
10
|
+
KEYWORDS = ['slot:', ':slot'].freeze
|
|
11
|
+
|
|
12
|
+
def match?(name:, **)
|
|
13
|
+
name && (name.start_with?(':') || name.end_with?(':'))
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def lexeme(name:, props:, **)
|
|
17
|
+
if name.end_with?(':')
|
|
18
|
+
slot_def = { slot_def: name.delete_suffix(':') }
|
|
19
|
+
slot_def[:props] = props(props) unless props.empty?
|
|
20
|
+
return slot_def
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
{ slot_end: name.delete_prefix(':') }
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../interfaces/lexeme'
|
|
4
|
+
|
|
5
|
+
module Antlers
|
|
6
|
+
module YieldLexeme
|
|
7
|
+
include Lexeme
|
|
8
|
+
extend self
|
|
9
|
+
|
|
10
|
+
def match?(keywords:, **)
|
|
11
|
+
keywords.keys.include?(':slot')
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def lexeme(**)
|
|
15
|
+
{ slot: :default }
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
data/lib/lexer.rb
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative 'lexemes/for_lexeme'
|
|
4
|
+
require_relative 'lexemes/form_lexeme'
|
|
5
|
+
require_relative 'lexemes/if_lexeme'
|
|
6
|
+
require_relative 'lexemes/prop_lexeme'
|
|
7
|
+
require_relative 'lexemes/slot_lexeme'
|
|
8
|
+
require_relative 'lexemes/yield_lexeme'
|
|
3
9
|
require_relative 'support/queries'
|
|
4
10
|
|
|
5
11
|
module Antlers
|
|
@@ -7,13 +13,20 @@ module Antlers
|
|
|
7
13
|
|
|
8
14
|
class LexerParseError < StandardError; end
|
|
9
15
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
16
|
+
LEXEMES = [
|
|
17
|
+
# FormLexeme must be ordered before ForLexeme for regex to work.
|
|
18
|
+
Antlers::FormLexeme,
|
|
19
|
+
Antlers::ForLexeme,
|
|
20
|
+
Antlers::IfLexeme,
|
|
21
|
+
Antlers::PropLexeme,
|
|
22
|
+
Antlers::SlotLexeme,
|
|
23
|
+
Antlers::YieldLexeme,
|
|
24
|
+
]
|
|
13
25
|
|
|
26
|
+
class Lexer
|
|
14
27
|
def initialize
|
|
15
28
|
@delimiters = ['<{', '}>', '{', '}']
|
|
16
|
-
@keywords =
|
|
29
|
+
@keywords = LEXEMES.flat_map { |lexeme| lexeme.const_get(:KEYWORDS) }
|
|
17
30
|
@cursor = 0
|
|
18
31
|
end
|
|
19
32
|
|
|
@@ -44,21 +57,19 @@ module Antlers
|
|
|
44
57
|
|
|
45
58
|
def antlers_segment(segments:)
|
|
46
59
|
next_segment = segments[@cursor + 1]
|
|
47
|
-
return nil unless next_segment && (segments[@cursor] == '<{' ||
|
|
60
|
+
return nil unless next_segment && (segments[@cursor] == '<{' || brackets?(segments:))
|
|
48
61
|
|
|
49
62
|
next_segment
|
|
50
63
|
end
|
|
51
64
|
|
|
52
65
|
def antlers_lexeme(antlers_segment:, segments:)
|
|
53
|
-
return var(antlers_segment:) if
|
|
66
|
+
return var(antlers_segment:) if brackets?(segments:)
|
|
54
67
|
|
|
55
68
|
name, props, keywords = parse_segment(antlers_segment:)
|
|
56
69
|
|
|
57
|
-
|
|
58
|
-
return
|
|
59
|
-
return
|
|
60
|
-
return for_loop(keywords:) if for_loop?(keywords:)
|
|
61
|
-
return form(keywords:) if form?(keywords:)
|
|
70
|
+
lexeme = LEXEMES.find { it.match?(name:, keywords:) }
|
|
71
|
+
return lexeme.lexeme(name:, props:, keywords:) if lexeme
|
|
72
|
+
return var(antlers_segment:, raw: true) if deerheads?(segments:)
|
|
62
73
|
|
|
63
74
|
raise LexerParseError, "Unrecognised syntax: '#{antlers_segment}'"
|
|
64
75
|
end
|
|
@@ -87,98 +98,23 @@ module Antlers
|
|
|
87
98
|
|
|
88
99
|
# TODO: Refactor every constant, match and result method into its own class. Loop through every class and return the first match.
|
|
89
100
|
|
|
90
|
-
def
|
|
101
|
+
def brackets?(segments:)
|
|
91
102
|
first, _, last = segments[@cursor..@cursor + 3].map(&:strip)
|
|
92
103
|
first == '{' && last == '}'
|
|
93
104
|
end
|
|
94
105
|
|
|
95
|
-
def
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
def form?(keywords:)
|
|
100
|
-
FORM_KEYWORDS.include?(keywords.keys.first)
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
def slot?(name)
|
|
104
|
-
name && (name.start_with?(':') || name.end_with?(':'))
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
def slot_yield?(keywords:)
|
|
108
|
-
keywords.keys.include?(':slot')
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
def prop?(name)
|
|
112
|
-
name && [*'A'..'Z'].include?(name[0])
|
|
106
|
+
def deerheads?(segments:)
|
|
107
|
+
first, _, last = segments[@cursor..@cursor + 3].map(&:strip)
|
|
108
|
+
first == '<{' && last == '}>'
|
|
113
109
|
end
|
|
114
110
|
|
|
115
|
-
def var(antlers_segment:)
|
|
111
|
+
def var(antlers_segment:, raw: false)
|
|
116
112
|
# String is already interpolated or not depending on user input on the template layer, now we store it without those template quotes.
|
|
117
113
|
antlers_segment = antlers_segment[1..-2] if Queries.user_defined_string?(antlers_segment)
|
|
118
114
|
|
|
119
|
-
{
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
def for_loop(keywords:)
|
|
123
|
-
if keywords['for:']
|
|
124
|
-
*key, value = keywords['for:'].split(',').map(&:strip)
|
|
125
|
-
for_def = { for_def: value, in: keywords['in:'] }
|
|
126
|
-
for_def[:key] = key.first unless key.empty?
|
|
127
|
-
return for_def
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
# TODO: Keep track of which for loop we're in to allow nested for loops.
|
|
131
|
-
{ for_end: 'level_1' }
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
def form(keywords:)
|
|
135
|
-
if keywords.key?('form:')
|
|
136
|
-
action = keywords['form:'] ? keywords['form:'][1...-1] : nil
|
|
137
|
-
return { form_def: action }
|
|
138
|
-
end
|
|
115
|
+
return { raw_var: antlers_segment } if raw
|
|
139
116
|
|
|
140
|
-
{
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
def slot(name:, props:)
|
|
144
|
-
if name.end_with?(':')
|
|
145
|
-
slot_def = { slot_def: name.delete_suffix(':') }
|
|
146
|
-
slot_def[:props] = props(props) unless props.empty?
|
|
147
|
-
return slot_def
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
{ slot_end: name.delete_prefix(':') }
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
def slot_yield
|
|
154
|
-
{ slot: :default }
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
def prop(name:, props:)
|
|
158
|
-
prop = { prop: name }
|
|
159
|
-
prop[:props] = props(props) unless props.empty?
|
|
160
|
-
prop
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
def props(props)
|
|
164
|
-
odd_props = props.join(' ').split(/(=)|\s/)
|
|
165
|
-
|
|
166
|
-
return {} unless odd_props.any?
|
|
167
|
-
|
|
168
|
-
props = {}
|
|
169
|
-
until odd_props.empty?
|
|
170
|
-
prop = odd_props.shift
|
|
171
|
-
value = nil
|
|
172
|
-
|
|
173
|
-
if odd_props.first == '='
|
|
174
|
-
odd_props.shift
|
|
175
|
-
value = odd_props.shift
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
props[prop.to_sym] = value
|
|
179
|
-
end
|
|
180
|
-
|
|
181
|
-
props
|
|
117
|
+
{ var: antlers_segment }
|
|
182
118
|
end
|
|
183
119
|
end
|
|
184
120
|
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../interfaces/branch_node'
|
|
4
|
+
require_relative '../modules/props'
|
|
5
|
+
require_relative '../modules/variables'
|
|
6
|
+
|
|
7
|
+
module Antlers
|
|
8
|
+
class IfNode < BranchNode
|
|
9
|
+
include Props
|
|
10
|
+
include Variables
|
|
11
|
+
|
|
12
|
+
def initialize(name:, value:, props: [], children: [])
|
|
13
|
+
super(name:, props:, children:)
|
|
14
|
+
|
|
15
|
+
@value = value
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def render(current_binding: nil, parent_binding: nil, slot_node: nil)
|
|
19
|
+
output = ''.dup
|
|
20
|
+
|
|
21
|
+
if evaluate(name: @value, current_binding:)
|
|
22
|
+
@children.each do |child|
|
|
23
|
+
# Antlers nodes respond to "render", whereas HTML is stored as a string and output as is.
|
|
24
|
+
output += (child.respond_to?(:render) ? child.render(current_binding:, parent_binding:, slot_node:) : child) || ''
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
output
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
data/lib/nodes/prop_node.rb
CHANGED
|
@@ -23,8 +23,8 @@ module Antlers
|
|
|
23
23
|
# TODO: Get LowLoad to load constants defined in "<{ MyNode }>" syntax so that we can resolve namespace/params on class load.
|
|
24
24
|
klass = class_constant(namespace: @namespace&.split('::') || [], name: @name)
|
|
25
25
|
class_proxy = Lowkey[klass.to_s].first[klass.to_s]
|
|
26
|
-
instance = create_instance(class_proxy:, klass:, event:)
|
|
27
26
|
|
|
27
|
+
instance = create_instance(class_proxy:, klass:, event:, props:)
|
|
28
28
|
return instance.render_template(event:, parent_binding:, props:) if klass.template
|
|
29
29
|
|
|
30
30
|
render_args(class_proxy:, instance:, event:, props:)
|
|
@@ -32,9 +32,10 @@ module Antlers
|
|
|
32
32
|
|
|
33
33
|
private
|
|
34
34
|
|
|
35
|
-
def create_instance(class_proxy:, klass:, event:)
|
|
35
|
+
def create_instance(class_proxy:, klass:, event:, props:)
|
|
36
36
|
initialize_params = class_proxy.instance_methods[:initialize]&.tagged_params(:keyword)&.map(&:name) || []
|
|
37
37
|
return klass.new(event:, **props) if initialize_params.include?(:event) && initialize_params.count > 1
|
|
38
|
+
return klass.new(**props) if initialize_params.count > 1
|
|
38
39
|
return klass.new(event:) if initialize_params.include?(:event)
|
|
39
40
|
|
|
40
41
|
klass.new
|
data/lib/nodes/var_node.rb
CHANGED
|
@@ -11,14 +11,19 @@ module Antlers
|
|
|
11
11
|
|
|
12
12
|
attr_reader :value
|
|
13
13
|
|
|
14
|
-
def initialize(value:, name: :var)
|
|
14
|
+
def initialize(value:, name: :var, raw: false)
|
|
15
15
|
super(name:)
|
|
16
16
|
|
|
17
17
|
@value = value
|
|
18
|
+
@raw = raw
|
|
18
19
|
end
|
|
19
20
|
|
|
20
21
|
def render(current_binding: nil, parent_binding: nil, slot_node: nil)
|
|
21
|
-
|
|
22
|
+
result = evaluate(name: @value, current_binding:) || fallback(@value)
|
|
23
|
+
|
|
24
|
+
return result if @raw
|
|
25
|
+
|
|
26
|
+
ERB::Util.html_escape(result)
|
|
22
27
|
end
|
|
23
28
|
end
|
|
24
29
|
end
|
data/lib/parser.rb
CHANGED
|
@@ -21,6 +21,8 @@ module Antlers
|
|
|
21
21
|
node.children << segment
|
|
22
22
|
elsif segment[:var]
|
|
23
23
|
node.children << @factory.var_node(segment:)
|
|
24
|
+
elsif segment[:raw_var]
|
|
25
|
+
node.children << @factory.raw_var_node(segment:)
|
|
24
26
|
elsif segment[:prop]
|
|
25
27
|
node.children << @factory.prop_node(segment:)
|
|
26
28
|
elsif segment[:slot]
|
|
@@ -29,6 +31,10 @@ module Antlers
|
|
|
29
31
|
slot_node = @factory.slot_node(segment:)
|
|
30
32
|
node.children << slot_node
|
|
31
33
|
sub_branch(node: slot_node, sequence:, end_key: :slot_end, end_name: slot_node.name)
|
|
34
|
+
elsif segment[:if_def]
|
|
35
|
+
if_node = @factory.if_node(segment:)
|
|
36
|
+
node.children << if_node
|
|
37
|
+
sub_branch(node: if_node, sequence:, end_key: :if_end, end_name: 'level_1')
|
|
32
38
|
elsif segment[:for_def]
|
|
33
39
|
for_node = @factory.for_node(segment:)
|
|
34
40
|
node.children << for_node
|
data/lib/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: antlers
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.8.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- maedi
|
|
@@ -64,12 +64,20 @@ files:
|
|
|
64
64
|
- lib/interfaces/antler_node.rb
|
|
65
65
|
- lib/interfaces/branch_node.rb
|
|
66
66
|
- lib/interfaces/leaf_node.rb
|
|
67
|
+
- lib/interfaces/lexeme.rb
|
|
68
|
+
- lib/lexemes/for_lexeme.rb
|
|
69
|
+
- lib/lexemes/form_lexeme.rb
|
|
70
|
+
- lib/lexemes/if_lexeme.rb
|
|
71
|
+
- lib/lexemes/prop_lexeme.rb
|
|
72
|
+
- lib/lexemes/slot_lexeme.rb
|
|
73
|
+
- lib/lexemes/yield_lexeme.rb
|
|
67
74
|
- lib/lexer.rb
|
|
68
75
|
- lib/modules/namespace.rb
|
|
69
76
|
- lib/modules/props.rb
|
|
70
77
|
- lib/modules/variables.rb
|
|
71
78
|
- lib/nodes/for_node.rb
|
|
72
79
|
- lib/nodes/form_node.rb
|
|
80
|
+
- lib/nodes/if_node.rb
|
|
73
81
|
- lib/nodes/prop_node.rb
|
|
74
82
|
- lib/nodes/root_node.rb
|
|
75
83
|
- lib/nodes/slot_node.rb
|