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
data/lib/liquidscript/icr/set.rb
CHANGED
@@ -7,33 +7,50 @@ module Liquidscript
|
|
7
7
|
# etc.
|
8
8
|
class Set < Code
|
9
9
|
|
10
|
-
# The metadata that is applied to the set.
|
11
|
-
#
|
12
|
-
# @return [Hash]
|
13
|
-
attr_reader :metadata
|
14
|
-
|
15
10
|
include Representable
|
16
11
|
|
17
12
|
# Initialize the set.
|
18
13
|
def initialize
|
19
|
-
@
|
20
|
-
|
21
|
-
@contexts = []
|
22
|
-
@action = :exec
|
14
|
+
@context = nil
|
15
|
+
super :exec
|
23
16
|
end
|
24
17
|
|
25
18
|
#
|
26
19
|
def context
|
27
|
-
|
20
|
+
@context || @metadata.fetch(:parent).context
|
21
|
+
end
|
22
|
+
|
23
|
+
def parent=(parent)
|
24
|
+
@metadata[:parent] = parent
|
25
|
+
if @context
|
26
|
+
@context.parent = parent.context
|
27
|
+
end
|
28
|
+
|
29
|
+
parent
|
28
30
|
end
|
29
31
|
|
30
|
-
def
|
31
|
-
@
|
32
|
+
def parent
|
33
|
+
@metadata[:parent]
|
32
34
|
end
|
33
35
|
|
34
36
|
#
|
35
|
-
def context=(
|
36
|
-
|
37
|
+
def context=(context)
|
38
|
+
@context = context
|
39
|
+
end
|
40
|
+
|
41
|
+
# Turns the code into an array, containing the
|
42
|
+
# action and the arguments. Note that changing
|
43
|
+
# this array will not change the code.
|
44
|
+
#
|
45
|
+
# @return [Array]
|
46
|
+
def to_a
|
47
|
+
part = [@action]
|
48
|
+
part << [:_context, context] if @context
|
49
|
+
part.concat(@metadata.to_a.select { |(k, v)|
|
50
|
+
[:arguments, :heredocs, :herenum].include?(k)
|
51
|
+
}.map { |(k, v)| [:"_#{k}", v] })
|
52
|
+
part.concat(@arguments)
|
53
|
+
part
|
37
54
|
end
|
38
55
|
|
39
56
|
# Adds a code to the code list. This is just a
|
@@ -43,12 +60,12 @@ module Liquidscript
|
|
43
60
|
# the action.
|
44
61
|
# @param arguments the arguments for the code.
|
45
62
|
def add(action, *arguments)
|
46
|
-
|
63
|
+
self << Code.new(action, arguments)
|
47
64
|
end
|
48
65
|
|
49
66
|
def <<(*v)
|
50
67
|
v.select { |p| p }.each do |part|
|
51
|
-
@
|
68
|
+
@arguments << part
|
52
69
|
end
|
53
70
|
end
|
54
71
|
|
@@ -62,7 +79,7 @@ module Liquidscript
|
|
62
79
|
#
|
63
80
|
# @return [Array<Symbol>]
|
64
81
|
def locals
|
65
|
-
variables - parameters
|
82
|
+
variables - parameters - hidden
|
66
83
|
end
|
67
84
|
|
68
85
|
# A list of components (or arguments) that are
|
@@ -75,6 +92,14 @@ module Liquidscript
|
|
75
92
|
context.parameters.map(&:name)
|
76
93
|
end
|
77
94
|
|
95
|
+
# A list of hidden variables in the current
|
96
|
+
# context.
|
97
|
+
#
|
98
|
+
# @return [Array<Symbol>]
|
99
|
+
def hidden
|
100
|
+
context.hidden.map(&:name)
|
101
|
+
end
|
102
|
+
|
78
103
|
# A list of _all_ variables in the current
|
79
104
|
# scope.
|
80
105
|
#
|
@@ -83,74 +108,11 @@ module Liquidscript
|
|
83
108
|
context.variables.keys - context.allowed_variables
|
84
109
|
end
|
85
110
|
|
86
|
-
# Turns the set into an array. Includes the
|
87
|
-
# metadata information and the actual internal
|
88
|
-
# array.
|
89
|
-
# Note that this is _not_ the array used in
|
90
|
-
# {#method_missing} - that actually operates on
|
91
|
-
# the internal array.
|
92
|
-
#
|
93
|
-
# @return [Array]
|
94
|
-
def to_a
|
95
|
-
part = [@action]
|
96
|
-
part << [:_context, context] if contexts.any?
|
97
|
-
part.concat(@metadata.to_a.map { |(m, i)| [:"_#{m}", i] })
|
98
|
-
part.concat(@code)
|
99
|
-
part
|
100
|
-
end
|
101
|
-
|
102
111
|
# Outputs the codes in this set.
|
103
112
|
#
|
104
113
|
# @return [Array<Code>]
|
105
114
|
def codes
|
106
|
-
@
|
107
|
-
end
|
108
|
-
|
109
|
-
# Access either the metadata or the codes. If
|
110
|
-
# the accessor is a Symbol, it access the metadata;
|
111
|
-
# if it the accessor is a Numeric, it access the
|
112
|
-
# codes.
|
113
|
-
#
|
114
|
-
# @param key [Symbol, Numeric] the key.
|
115
|
-
# @return [Object]
|
116
|
-
def [](key)
|
117
|
-
if key.is_a? Numeric
|
118
|
-
@code[key]
|
119
|
-
else
|
120
|
-
@metadata[key]
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
# Sets something from the metadata. Unlike the
|
125
|
-
# accessor, it does not distinguish between
|
126
|
-
# Numeric and Symbol keys.
|
127
|
-
#
|
128
|
-
# @param key [Object] the key.
|
129
|
-
# @param value [Object] the value.
|
130
|
-
# @return [Object]
|
131
|
-
def []=(key, value)
|
132
|
-
@metadata[key] = value
|
133
|
-
end
|
134
|
-
|
135
|
-
# Tells ruby that we respond to some methods.
|
136
|
-
# Passes the method name to the internal
|
137
|
-
# array, asking if it responds to it.
|
138
|
-
#
|
139
|
-
# @param method [Symbol] the method to check.
|
140
|
-
# @param include_private [Boolean] whether or not
|
141
|
-
# to include private methods.
|
142
|
-
# @return [Boolean] whether or not we respond
|
143
|
-
# to that method.
|
144
|
-
def respond_to_missing?(method, include_private = false)
|
145
|
-
@code.respond_to?(method, include_private)
|
146
|
-
end
|
147
|
-
|
148
|
-
# For methods that we don't respond to, send
|
149
|
-
# them to the interal array.
|
150
|
-
#
|
151
|
-
# @return [Object]
|
152
|
-
def method_missing(method, *args, &block)
|
153
|
-
@code.public_send(method, *args, &block)
|
115
|
+
@arguments
|
154
116
|
end
|
155
117
|
|
156
118
|
end
|
@@ -50,6 +50,23 @@ module Liquidscript
|
|
50
50
|
self
|
51
51
|
end
|
52
52
|
|
53
|
+
# Marks this variable as hidden. This variable does not show
|
54
|
+
# up as a parameter nor a class variable.
|
55
|
+
#
|
56
|
+
# @return [self]
|
57
|
+
def hidden!
|
58
|
+
@hidden = true
|
59
|
+
self
|
60
|
+
end
|
61
|
+
|
62
|
+
# WHether or not this variable is hidden.
|
63
|
+
#
|
64
|
+
# @see {#hidden!}
|
65
|
+
# @return [Boolean]
|
66
|
+
def hidden?
|
67
|
+
@hidden
|
68
|
+
end
|
69
|
+
|
53
70
|
# Whether or not the variable is an argument to a function.
|
54
71
|
#
|
55
72
|
# @see {#parameter!}
|
@@ -17,12 +17,22 @@ module Liquidscript
|
|
17
17
|
|
18
18
|
attr_accessor :metadata
|
19
19
|
|
20
|
-
def initialize(source)
|
20
|
+
def initialize(source, file = nil)
|
21
21
|
@source = source
|
22
22
|
@scanner = StringScanner.new(@source)
|
23
23
|
@tokens = []
|
24
24
|
@_scan = nil
|
25
25
|
@metadata = {}
|
26
|
+
|
27
|
+
if !file and source.respond_to?(:to_path)
|
28
|
+
file = source.to_path
|
29
|
+
end
|
30
|
+
|
31
|
+
@metadata[:file] = file || "<none>"
|
32
|
+
end
|
33
|
+
|
34
|
+
def file
|
35
|
+
@metadata[:file]
|
26
36
|
end
|
27
37
|
|
28
38
|
def contexts
|
@@ -40,10 +40,11 @@ module Liquidscript
|
|
40
40
|
out
|
41
41
|
end
|
42
42
|
|
43
|
-
def error(scanner = @scanner, context = @context
|
43
|
+
def error(scanner = @scanner, context = @context,
|
44
|
+
file = @metadata[:file])
|
44
45
|
raise SyntaxError, "Unexpected " +
|
45
46
|
"#{scanner.matched}#{scanner.peek(2)}".inspect +
|
46
|
-
" (line: #{line}, column: #{column})"
|
47
|
+
" (line: #{line}, column: #{column}, file: #{file})"
|
47
48
|
end
|
48
49
|
|
49
50
|
private
|
@@ -90,45 +90,47 @@ module Liquidscript
|
|
90
90
|
|
91
91
|
set :identifier, %r{[A-Za-z_$]([A-Za-z0-9_$-]*[A-Za-z0-9_$])?}
|
92
92
|
|
93
|
-
on("class") { emit :class
|
94
|
-
on("module") { emit :module
|
95
|
-
on("if") { emit :if
|
96
|
-
on("unless") { emit :unless
|
97
|
-
on("elsif") { emit :elsif
|
98
|
-
on("else") { emit :else
|
99
|
-
on("for") { emit :for
|
100
|
-
on("while") { emit :while
|
101
|
-
on("try") { emit :try
|
102
|
-
on("catch") { emit :catch
|
103
|
-
on("finally") { emit :finally
|
104
|
-
on("return") { emit :return
|
105
|
-
on(
|
106
|
-
on(:
|
107
|
-
on(:
|
108
|
-
on(:
|
109
|
-
on(:
|
110
|
-
on(:
|
111
|
-
on(:
|
93
|
+
on("class") { emit :class }
|
94
|
+
on("module") { emit :module }
|
95
|
+
on("if") { emit :if }
|
96
|
+
on("unless") { emit :unless }
|
97
|
+
on("elsif") { emit :elsif }
|
98
|
+
on("else") { emit :else }
|
99
|
+
on("for") { emit :for }
|
100
|
+
on("while") { emit :while }
|
101
|
+
on("try") { emit :try }
|
102
|
+
on("catch") { emit :catch }
|
103
|
+
on("finally") { emit :finally }
|
104
|
+
on("return") { emit :return }
|
105
|
+
on("nil") { emit :keyword, "null" }
|
106
|
+
on(:number) { |m| emit :number, m }
|
107
|
+
on(:string) { |m| emit :sstring, m }
|
108
|
+
on(:keywords) { |m| emit :keyword, m }
|
109
|
+
on(:actions) { |m| emit :action, m }
|
110
|
+
on(:binops) { |m| emit :binop, m }
|
111
|
+
on(:preunops) { |m| emit :preunop, m }
|
112
|
+
on(:unops) { |m| emit :unop, m }
|
112
113
|
on(%r{<<([A-Z]+)}, :heredoc)
|
113
114
|
on(%r{<<-([A-Z]+)}, :iheredoc)
|
114
115
|
on(%r{r/((?:.|\/)*)/([gimy]*)}, :regex)
|
115
116
|
on(%r{"} => :istring)
|
116
117
|
on("///" => :block_regex)
|
117
|
-
on("->") { emit :arrow
|
118
|
-
on("=") { emit :equal
|
119
|
-
on("{") { emit :lbrace
|
120
|
-
on("(") { emit :lparen
|
121
|
-
on("[") { emit :lbrack
|
122
|
-
on("}") { emit :rbrace
|
123
|
-
on(")") { emit :rparen
|
124
|
-
on("]") { emit :rbrack
|
125
|
-
on(":") { emit :colon
|
126
|
-
on("..") { emit :range
|
127
|
-
on("
|
128
|
-
on("
|
129
|
-
on("
|
130
|
-
on("
|
131
|
-
on("
|
118
|
+
on("->") { emit :arrow }
|
119
|
+
on("=") { emit :equal }
|
120
|
+
on("{") { emit :lbrace }
|
121
|
+
on("(") { emit :lparen }
|
122
|
+
on("[") { emit :lbrack }
|
123
|
+
on("}") { emit :rbrace }
|
124
|
+
on(")") { emit :rparen }
|
125
|
+
on("]") { emit :rbrack }
|
126
|
+
on(":") { emit :colon }
|
127
|
+
on("..") { emit :range }
|
128
|
+
on("...") { emit :erange }
|
129
|
+
on(".") { emit :prop }
|
130
|
+
on(",") { emit :comma }
|
131
|
+
on("-") { emit :minus }
|
132
|
+
on("+") { emit :plus }
|
133
|
+
on("\n") { line! }
|
132
134
|
on(:identifier, :identifier)
|
133
135
|
on(%r{!\[\s*([A-Za-z]+)\s*(.*?)\s*\]\n}, :directive)
|
134
136
|
|
data/lib/liquidscript/version.rb
CHANGED
@@ -6,8 +6,12 @@ data: |
|
|
6
6
|
test = 0..console
|
7
7
|
}
|
8
8
|
|
9
|
+
another_function = (a, b = a, c...)-> {
|
10
|
+
console.log()
|
11
|
+
}
|
12
|
+
|
9
13
|
compiled: |
|
10
|
-
var some_function;
|
14
|
+
var some_function, another_function;
|
11
15
|
console = 2;
|
12
16
|
|
13
17
|
some_function = function() {
|
@@ -26,3 +30,12 @@ compiled: |
|
|
26
30
|
return t === undefined ? out : out.reverse();
|
27
31
|
})(0, console);
|
28
32
|
};
|
33
|
+
|
34
|
+
another_function = function(a, b) {
|
35
|
+
if(b == null) {
|
36
|
+
b = a;
|
37
|
+
}
|
38
|
+
c = [].slice.call(arguments, 2);
|
39
|
+
|
40
|
+
return console.log();
|
41
|
+
};
|
@@ -3,6 +3,7 @@ data: |
|
|
3
3
|
test = [1, 2]
|
4
4
|
range = 0x1..0x9
|
5
5
|
range2 = 10..1
|
6
|
+
range3 = 10...1
|
6
7
|
regex = r/^\/test/
|
7
8
|
block = ///
|
8
9
|
^test # comment
|
@@ -10,11 +11,12 @@ data: |
|
|
10
11
|
regex == block
|
11
12
|
|
12
13
|
compiled: |
|
13
|
-
var object, test, range, range2, regex, block;
|
14
|
+
var object, test, range, range2, range3, regex, block;
|
14
15
|
object = { "hello": "world" };
|
15
16
|
test = [1, 2];
|
16
17
|
range = [0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9];
|
17
18
|
range2 = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1];
|
19
|
+
range3 = [9, 8, 7, 6, 5, 4, 3, 2, 1];
|
18
20
|
regex = /^\/test/;
|
19
21
|
block = /^test/;
|
20
22
|
regex === block;
|
@@ -18,13 +18,13 @@ describe ICR::Context do
|
|
18
18
|
|
19
19
|
let(:parent) do
|
20
20
|
parent = double("parent")
|
21
|
-
expect(parent).to receive(:get).once.with(:foo).and_return(:test)
|
21
|
+
expect(parent).to receive(:get).once.with(:foo, {}).and_return(:test)
|
22
22
|
parent
|
23
23
|
end
|
24
24
|
|
25
25
|
subject do
|
26
26
|
context = ICR::Context.new
|
27
|
-
context.
|
27
|
+
context.parent = parent
|
28
28
|
context
|
29
29
|
end
|
30
30
|
|
@@ -13,12 +13,12 @@ describe ICR::Set do
|
|
13
13
|
context "with metadata" do
|
14
14
|
subject do
|
15
15
|
set = ICR::Set.new
|
16
|
-
set.metadata.merge! :
|
16
|
+
set.metadata.merge! :arguments => "world"
|
17
17
|
set
|
18
18
|
end
|
19
19
|
|
20
20
|
specify { expect(subject.to_a).to have(2).items }
|
21
|
-
specify { expect(subject.to_a).to eq [:exec, [:
|
21
|
+
specify { expect(subject.to_a).to eq [:exec, [:_arguments, "world"]] }
|
22
22
|
|
23
23
|
end
|
24
24
|
|
@@ -37,13 +37,13 @@ describe ICR::Set do
|
|
37
37
|
context "with both" do
|
38
38
|
subject do
|
39
39
|
set = ICR::Set.new
|
40
|
-
set.metadata.merge! :
|
40
|
+
set.metadata.merge! :arguments => "world"
|
41
41
|
set << "test"
|
42
42
|
set
|
43
43
|
end
|
44
44
|
|
45
45
|
specify { expect(subject.to_a).to have(3).items }
|
46
|
-
specify { expect(subject.to_a).to eq [:exec, [:
|
46
|
+
specify { expect(subject.to_a).to eq [:exec, [:_arguments, "world"], "test"] }
|
47
47
|
|
48
48
|
end
|
49
49
|
end
|