liquidscript 0.11.0.rc1 → 0.11.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 +4 -4
- data/lib/liquidscript.rb +1 -1
- data/lib/liquidscript/cli.rb +1 -1
- data/lib/liquidscript/compiler/base.rb +7 -0
- data/lib/liquidscript/compiler/base/blank.rb +7 -0
- data/lib/liquidscript/compiler/icr/classes.rb +46 -30
- data/lib/liquidscript/compiler/icr/directives.rb +42 -4
- data/lib/liquidscript/compiler/icr/expressions.rb +40 -6
- data/lib/liquidscript/compiler/icr/functions.rb +7 -11
- data/lib/liquidscript/compiler/icr/groups.rb +2 -1
- data/lib/liquidscript/compiler/icr/helpers.rb +8 -0
- data/lib/liquidscript/compiler/icr/literals.rb +9 -4
- data/lib/liquidscript/errors.rb +9 -8
- data/lib/liquidscript/generator/javascript/exceptions.rb +5 -1
- data/lib/liquidscript/generator/javascript/literals.rb +33 -1
- data/lib/liquidscript/generator/javascript/metas.rb +14 -1
- data/lib/liquidscript/generator/javascript/objects.rb +3 -0
- data/lib/liquidscript/icr/code.rb +43 -2
- data/lib/liquidscript/icr/context.rb +163 -85
- data/lib/liquidscript/icr/representable.rb +1 -1
- data/lib/liquidscript/icr/set.rb +43 -81
- data/lib/liquidscript/icr/variable.rb +17 -0
- data/lib/liquidscript/scanner/base.rb +11 -1
- data/lib/liquidscript/scanner/base/lexer.rb +3 -2
- data/lib/liquidscript/scanner/liquidscript/main.rb +36 -34
- data/lib/liquidscript/version.rb +1 -1
- data/spec/fixtures/class.compile.yml +0 -2
- data/spec/fixtures/function.generate.yml +14 -1
- data/spec/fixtures/literals.generate.yml +3 -1
- data/spec/liquidscript/compiler/icr_spec.rb +1 -1
- data/spec/liquidscript/icr/context_spec.rb +2 -2
- data/spec/liquidscript/icr/set_spec.rb +4 -4
- data/vendor/assets/javascripts/liquidscript.js +103 -0
- data/vendor/assets/javascripts/liquidscript.liq +29 -0
- data/vendor/assets/javascripts/promise.liq +67 -0
- metadata +7 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6c88d468f4ac01f88dc94196315f2b19f107eaa4
|
4
|
+
data.tar.gz: e7a78f612a4563d8e61f9700e24e6fb032e85d37
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7fe74221dd6cffe7c26eaaa42a6c5f7fb9133624016fd983cdf03d0e5ebeb95790c4ef7ab552a61a1ab9ddd7c8946c2d96c18994516abf48ec249bc8d22a69fd
|
7
|
+
data.tar.gz: e223f22fca8701f39dcb1b55ce1e8328ce35f749406033a0e907d8c4c5dc6b8e2c5d143d2750ee192fc0ed63d85d76491c6dca54cb76d3872bbf70a3592c3ead
|
data/lib/liquidscript.rb
CHANGED
data/lib/liquidscript/cli.rb
CHANGED
@@ -47,6 +47,13 @@ module Liquidscript
|
|
47
47
|
end
|
48
48
|
|
49
49
|
top
|
50
|
+
|
51
|
+
rescue CompileError => e
|
52
|
+
token = peek
|
53
|
+
part = "#{File.expand_path(@scanner.metadata[:file])}" +
|
54
|
+
":#{token.line}:#{token.column}: " +
|
55
|
+
"before #{token.type.to_s.upcase}"
|
56
|
+
raise e, e.message, [part, *e.backtrace]
|
50
57
|
end
|
51
58
|
|
52
59
|
# Checks to see if the given input compiles.
|
@@ -4,42 +4,50 @@ module Liquidscript
|
|
4
4
|
module Classes
|
5
5
|
|
6
6
|
def compile_class
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
7
|
+
delegate_if_class do
|
8
|
+
shift :class
|
9
|
+
name = shift :identifier
|
10
|
+
inherit = nil
|
11
|
+
existed = check(name)
|
12
|
+
set(name)
|
13
|
+
# Inheritance ftw!
|
14
|
+
if peek?(:colon)
|
15
|
+
shift :colon
|
16
|
+
inherit = shift :identifier
|
17
|
+
inherit = ref(inherit)
|
18
|
+
end
|
19
|
+
|
20
|
+
@classes[name.value] =
|
21
|
+
expressions = Liquidscript::ICR::Set.new
|
22
|
+
expressions.context =
|
23
|
+
Liquidscript::ICR::Context.new.tap(&:class!)
|
24
|
+
expressions.parent = if inherit
|
25
|
+
@classes[inherit.name.to_s].tap { |t| t.parent = top }
|
26
|
+
else
|
27
|
+
top
|
28
|
+
end
|
29
|
+
|
30
|
+
@set << expressions
|
31
|
+
body = _compile_class_body(false)
|
32
|
+
expressions.context.force_defined!
|
33
|
+
out = code(:class, name, inherit, body)
|
34
|
+
@set.pop
|
35
|
+
out[:existed] = existed
|
36
|
+
out
|
16
37
|
end
|
17
|
-
|
18
|
-
new_context = Liquidscript::ICR::Context.new
|
19
|
-
new_context.parents << top.context
|
20
|
-
new_context.class!
|
21
|
-
@classes[name.value] = new_context
|
22
|
-
|
23
|
-
new_context.parents << @classes[inherit.name.to_s] if inherit
|
24
|
-
|
25
|
-
top.context = new_context
|
26
|
-
body = _compile_class_body(false)
|
27
|
-
|
28
|
-
new_context.undefined.each do |f|
|
29
|
-
raise f[1]
|
30
|
-
end
|
31
|
-
|
32
|
-
code :class, name, inherit, body, top.contexts.pop
|
33
38
|
end
|
34
39
|
|
35
40
|
def compile_module
|
36
41
|
m = shift :module
|
37
42
|
if peek? :identifier
|
38
|
-
name
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
+
name = shift :identifier
|
44
|
+
existed = check(name)
|
45
|
+
set(name)
|
46
|
+
body = _compile_class_body(true)
|
47
|
+
|
48
|
+
out = code :module, name, body
|
49
|
+
out[:existed] = existed
|
50
|
+
out
|
43
51
|
else
|
44
52
|
value_expect _new_token(m, :identifier)
|
45
53
|
end
|
@@ -86,6 +94,14 @@ module Liquidscript
|
|
86
94
|
shift :colon
|
87
95
|
item
|
88
96
|
end
|
97
|
+
|
98
|
+
def delegate_if_class
|
99
|
+
if top.context.class?
|
100
|
+
top.context.delegate(&Proc.new)
|
101
|
+
else
|
102
|
+
yield
|
103
|
+
end
|
104
|
+
end
|
89
105
|
end
|
90
106
|
end
|
91
107
|
end
|
@@ -40,7 +40,7 @@ module Liquidscript
|
|
40
40
|
|
41
41
|
def directive_allow(*args)
|
42
42
|
args.each do |a|
|
43
|
-
top.context.
|
43
|
+
top.context.set(a.value.intern).hidden!
|
44
44
|
end
|
45
45
|
|
46
46
|
nil
|
@@ -48,18 +48,56 @@ module Liquidscript
|
|
48
48
|
|
49
49
|
def directive_cvar(*args)
|
50
50
|
args.each do |a|
|
51
|
-
top.context.set(a.value.intern, :class => true).
|
51
|
+
top.context.set(a.value.intern, :class => true).hidden!
|
52
52
|
end
|
53
53
|
|
54
54
|
nil
|
55
55
|
end
|
56
56
|
|
57
|
+
def directive_todo(comment)
|
58
|
+
$stderr.puts "TODO (file: #{@scanner.file}): #{comment[1]}"
|
59
|
+
nil
|
60
|
+
end
|
61
|
+
|
62
|
+
def directive_include(file)
|
63
|
+
file_name = file[1]
|
64
|
+
path = include_paths.find do |part|
|
65
|
+
File.file?(File.join(part, file_name))
|
66
|
+
end
|
67
|
+
|
68
|
+
raise LoadError,
|
69
|
+
"cannot load such file -- #{file}" unless path
|
70
|
+
|
71
|
+
full_path = File.join(path, file_name)
|
72
|
+
f = File.open(full_path)
|
73
|
+
scanner = Scanner::Liquidscript.new(f.read, full_path)
|
74
|
+
compiler = Compiler::ICR.new(scanner)
|
75
|
+
compiler.top.parent = top
|
76
|
+
compiler.top.context.delegate!
|
77
|
+
compiler.compile
|
78
|
+
end
|
79
|
+
|
80
|
+
def directive_include_path(*paths)
|
81
|
+
include_paths.push(*paths.map(&:value))
|
82
|
+
nil
|
83
|
+
end
|
84
|
+
|
57
85
|
def directive_strict
|
58
86
|
top.metadata[:strict] = true
|
59
87
|
|
60
88
|
nil
|
61
89
|
end
|
62
90
|
|
91
|
+
private
|
92
|
+
|
93
|
+
def include_paths
|
94
|
+
@_include_paths ||= [
|
95
|
+
".",
|
96
|
+
File.expand_path("../", @scanner.metadata[:file]),
|
97
|
+
*ENV.fetch("LIQUID_PATHS", "").split(':')
|
98
|
+
]
|
99
|
+
end
|
100
|
+
|
63
101
|
end
|
64
102
|
|
65
103
|
def self.included(receiver)
|
@@ -67,8 +105,8 @@ module Liquidscript
|
|
67
105
|
receiver.send :include, InstanceMethods
|
68
106
|
|
69
107
|
InstanceMethods.instance_methods.each do |m|
|
70
|
-
if m.to_s =~ /\A_?directive_([A-Za-z0-9]+)\z/
|
71
|
-
receiver.define_directive($1, m)
|
108
|
+
if m.to_s =~ /\A_?directive_([A-Za-z0-9\_]+)\z/
|
109
|
+
receiver.define_directive($1.gsub(/\_[a-z]/) { |m| m[1].upcase }, m)
|
72
110
|
end
|
73
111
|
end
|
74
112
|
end
|
@@ -121,20 +121,29 @@ module Liquidscript
|
|
121
121
|
:command => command,
|
122
122
|
:arguments => arguments }
|
123
123
|
|
124
|
-
@in_directive = old
|
125
124
|
|
126
|
-
if
|
125
|
+
out = if old
|
127
126
|
directive
|
128
127
|
else
|
129
128
|
handle_directive(directive)
|
130
129
|
end
|
130
|
+
|
131
|
+
@in_directive = old
|
132
|
+
out
|
131
133
|
end
|
132
134
|
|
133
135
|
def _compile_lparen_method
|
134
136
|
ident = shift :identifier
|
135
137
|
|
138
|
+
if peek?(:equal)
|
139
|
+
shift(:equal)
|
140
|
+
v = compile_vexpression
|
141
|
+
else
|
142
|
+
v = nil
|
143
|
+
end
|
144
|
+
|
136
145
|
if peek?(:comma, :rparen)
|
137
|
-
_compile_lparen_method_final(ident)
|
146
|
+
_compile_lparen_method_final([ident, v])
|
138
147
|
else
|
139
148
|
out = value_expect(ref(ident))
|
140
149
|
shift :rparen
|
@@ -145,12 +154,15 @@ module Liquidscript
|
|
145
154
|
|
146
155
|
def _compile_lparen_method_final(ident = nil)
|
147
156
|
components = [ident].compact
|
157
|
+
_build_set
|
158
|
+
set(ident[0]) if ident
|
148
159
|
|
149
|
-
while peek?(:comma)
|
150
|
-
|
151
|
-
components << shift(:identifier)
|
160
|
+
while peek?(:comma)
|
161
|
+
components << _compile_lparen_argument
|
152
162
|
end
|
153
163
|
|
164
|
+
@set.pop
|
165
|
+
|
154
166
|
shift :rparen
|
155
167
|
compile_function_with_parameters(components)
|
156
168
|
end
|
@@ -161,6 +173,28 @@ module Liquidscript
|
|
161
173
|
code :expression, out
|
162
174
|
end
|
163
175
|
|
176
|
+
def _compile_lparen_argument
|
177
|
+
shift(:comma)
|
178
|
+
|
179
|
+
ident = shift(:identifier)
|
180
|
+
set(ident)
|
181
|
+
|
182
|
+
erange = action do |_|
|
183
|
+
if top[:etc]
|
184
|
+
raise CompileError,
|
185
|
+
"A drain argument has already been specified!"
|
186
|
+
end
|
187
|
+
|
188
|
+
top[:etc] = ident
|
189
|
+
:etc
|
190
|
+
end
|
191
|
+
|
192
|
+
value = expect :equal => action { |_| compile_vexpression },
|
193
|
+
:erange => erange, :_ => action { nil }
|
194
|
+
|
195
|
+
[ident, value]
|
196
|
+
end
|
197
|
+
|
164
198
|
end
|
165
199
|
end
|
166
200
|
end
|
@@ -40,15 +40,7 @@ module Liquidscript
|
|
40
40
|
shift :arrow
|
41
41
|
|
42
42
|
expressions = _build_set(parameters)
|
43
|
-
|
44
|
-
if peek?(:lbrace)
|
45
|
-
shift :lbrace
|
46
|
-
collect_compiles(:rbrace) do
|
47
|
-
expressions << compile_expression
|
48
|
-
end
|
49
|
-
else
|
50
|
-
expressions << compile_expression
|
51
|
-
end
|
43
|
+
expressions.push(*_compile_block)
|
52
44
|
|
53
45
|
code :function, @set.pop
|
54
46
|
end
|
@@ -58,12 +50,16 @@ module Liquidscript
|
|
58
50
|
def _build_set(parameters = [])
|
59
51
|
expressions = Liquidscript::ICR::Set.new
|
60
52
|
expressions.context = Liquidscript::ICR::Context.new
|
61
|
-
expressions.context.
|
53
|
+
expressions.context.parent = top.context
|
62
54
|
expressions[:arguments] = parameters
|
63
55
|
@set << expressions
|
64
56
|
|
65
57
|
parameters.each do |parameter|
|
66
|
-
|
58
|
+
if parameter[1] == :etc
|
59
|
+
set(parameter[0]).hidden!
|
60
|
+
else
|
61
|
+
set(parameter[0]).parameter!
|
62
|
+
end
|
67
63
|
end
|
68
64
|
|
69
65
|
expressions
|
@@ -11,6 +11,13 @@ module Liquidscript
|
|
11
11
|
top.context.set(literal.value.intern)
|
12
12
|
end
|
13
13
|
|
14
|
+
def check(literal)
|
15
|
+
top.context.get(literal.value.intern,
|
16
|
+
:dry_run => true)
|
17
|
+
rescue InvalidReferenceError
|
18
|
+
false
|
19
|
+
end
|
20
|
+
|
14
21
|
def code(type, *args)
|
15
22
|
Liquidscript::ICR::Code.new type, *args
|
16
23
|
end
|
@@ -31,6 +38,7 @@ module Liquidscript
|
|
31
38
|
:prop => action { compile_property(v) },
|
32
39
|
:lbrack => action { compile_access(v) },
|
33
40
|
:range => action { |_| compile_range(v) },
|
41
|
+
:erange => action { |_| compile_erange(v) },
|
34
42
|
[:binop,
|
35
43
|
:minus,
|
36
44
|
:plus] => action { compile_binop(v) },
|
@@ -6,13 +6,14 @@ module Liquidscript
|
|
6
6
|
def compile_number
|
7
7
|
n = shift(:number)
|
8
8
|
|
9
|
-
if peek?(:range)
|
10
|
-
shift(:range)
|
9
|
+
if peek?(:range, :erange)
|
10
|
+
range = shift(:range, :erange)
|
11
11
|
|
12
12
|
if peek?(:number)
|
13
|
-
|
13
|
+
type = :"n#{range.type}"
|
14
|
+
code(type, n.value, shift(:number).value)
|
14
15
|
else
|
15
|
-
|
16
|
+
send(:"compile_#{range.type}", code(:number, n.value))
|
16
17
|
end
|
17
18
|
else
|
18
19
|
code :number, n.value
|
@@ -27,6 +28,10 @@ module Liquidscript
|
|
27
28
|
code :range, subject, compile_vexpression
|
28
29
|
end
|
29
30
|
|
31
|
+
def compile_erange(subject)
|
32
|
+
code :erange, subject, compile_vexpression
|
33
|
+
end
|
34
|
+
|
30
35
|
def compile_while
|
31
36
|
shift :while
|
32
37
|
shift :lparen
|
data/lib/liquidscript/errors.rb
CHANGED
@@ -26,7 +26,7 @@ module Liquidscript
|
|
26
26
|
class UnexpectedError < CompileError
|
27
27
|
def initialize(expected, got)
|
28
28
|
@expected = expected
|
29
|
-
@got
|
29
|
+
@got = got
|
30
30
|
|
31
31
|
super build_error_message
|
32
32
|
end
|
@@ -34,24 +34,25 @@ module Liquidscript
|
|
34
34
|
private
|
35
35
|
|
36
36
|
def build_error_message
|
37
|
-
str = "Expected one of %{expected}, got %{type}(%{value})"
|
37
|
+
str = "Expected one of %{expected}, got %{type}(%{value}) "
|
38
38
|
hash = {
|
39
|
-
:expected => @expected.map { |e| e
|
39
|
+
:expected => @expected.map { |e| ns(e) }.join(', ')
|
40
40
|
}
|
41
41
|
|
42
42
|
if @got.is_a? Symbol
|
43
|
-
hash[:type] = @got
|
43
|
+
hash[:type] = ns(@got)
|
44
44
|
hash[:value] = ""
|
45
45
|
else
|
46
|
-
|
47
|
-
hash.merge! :type => @got.type.to_s.upcase,
|
48
|
-
:line => @got.line,
|
49
|
-
:column => @got.column,
|
46
|
+
hash.merge! :type => ns(@got.type),
|
50
47
|
:value => @got.value
|
51
48
|
end
|
52
49
|
|
53
50
|
sprintf(str, hash)
|
54
51
|
end
|
52
|
+
|
53
|
+
def ns(sym)
|
54
|
+
sym.to_s.upcase
|
55
|
+
end
|
55
56
|
end
|
56
57
|
|
57
58
|
class InvalidCodeError < GeneratorError
|