liquidscript 0.11.0.rc1 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|