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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/lib/liquidscript.rb +1 -1
  3. data/lib/liquidscript/cli.rb +1 -1
  4. data/lib/liquidscript/compiler/base.rb +7 -0
  5. data/lib/liquidscript/compiler/base/blank.rb +7 -0
  6. data/lib/liquidscript/compiler/icr/classes.rb +46 -30
  7. data/lib/liquidscript/compiler/icr/directives.rb +42 -4
  8. data/lib/liquidscript/compiler/icr/expressions.rb +40 -6
  9. data/lib/liquidscript/compiler/icr/functions.rb +7 -11
  10. data/lib/liquidscript/compiler/icr/groups.rb +2 -1
  11. data/lib/liquidscript/compiler/icr/helpers.rb +8 -0
  12. data/lib/liquidscript/compiler/icr/literals.rb +9 -4
  13. data/lib/liquidscript/errors.rb +9 -8
  14. data/lib/liquidscript/generator/javascript/exceptions.rb +5 -1
  15. data/lib/liquidscript/generator/javascript/literals.rb +33 -1
  16. data/lib/liquidscript/generator/javascript/metas.rb +14 -1
  17. data/lib/liquidscript/generator/javascript/objects.rb +3 -0
  18. data/lib/liquidscript/icr/code.rb +43 -2
  19. data/lib/liquidscript/icr/context.rb +163 -85
  20. data/lib/liquidscript/icr/representable.rb +1 -1
  21. data/lib/liquidscript/icr/set.rb +43 -81
  22. data/lib/liquidscript/icr/variable.rb +17 -0
  23. data/lib/liquidscript/scanner/base.rb +11 -1
  24. data/lib/liquidscript/scanner/base/lexer.rb +3 -2
  25. data/lib/liquidscript/scanner/liquidscript/main.rb +36 -34
  26. data/lib/liquidscript/version.rb +1 -1
  27. data/spec/fixtures/class.compile.yml +0 -2
  28. data/spec/fixtures/function.generate.yml +14 -1
  29. data/spec/fixtures/literals.generate.yml +3 -1
  30. data/spec/liquidscript/compiler/icr_spec.rb +1 -1
  31. data/spec/liquidscript/icr/context_spec.rb +2 -2
  32. data/spec/liquidscript/icr/set_spec.rb +4 -4
  33. data/vendor/assets/javascripts/liquidscript.js +103 -0
  34. data/vendor/assets/javascripts/liquidscript.liq +29 -0
  35. data/vendor/assets/javascripts/promise.liq +67 -0
  36. metadata +7 -4
@@ -9,7 +9,7 @@ module Liquidscript
9
9
  extend Forwardable
10
10
  include Comparable
11
11
 
12
- def_delegators :to_a, :to_s, :inspect, :[], :each, :'<=>'
12
+ def_delegators :to_a, :to_s, :inspect, :[], :each, :'<=>', :length
13
13
 
14
14
 
15
15
  def to_ary
@@ -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
- @metadata = {}
20
- @code = []
21
- @contexts = []
22
- @action = :exec
14
+ @context = nil
15
+ super :exec
23
16
  end
24
17
 
25
18
  #
26
19
  def context
27
- contexts.last || @metadata.fetch(:parent).context
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 contexts
31
- @contexts
32
+ def parent
33
+ @metadata[:parent]
32
34
  end
33
35
 
34
36
  #
35
- def context=(new_context)
36
- contexts << new_context
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
- @code << Code.new(action, arguments)
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
- @code << part
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
- @code
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(:number) { |m| emit :number, m }
106
- on(:string) { |m| emit :sstring, m }
107
- on(:keywords) { |m| emit :keyword, m }
108
- on(:actions) { |m| emit :action, m }
109
- on(:binops) { |m| emit :binop, m }
110
- on(:preunops) { |m| emit :preunop, m }
111
- on(:unops) { |m| emit :unop, m }
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(".") { emit :prop }
128
- on(",") { emit :comma }
129
- on("-") { emit :minus }
130
- on("+") { emit :plus }
131
- on("\n") { line! }
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
 
@@ -1,5 +1,5 @@
1
1
  module Liquidscript
2
2
 
3
3
  # The current version of liquidscript.
4
- VERSION = "0.11.0.rc1".freeze
4
+ VERSION = "0.11.0".freeze
5
5
  end
@@ -30,11 +30,9 @@ compiled:
30
30
  - []
31
31
  - - :_arguments
32
32
  - []
33
- - - :test
34
33
  - - :class
35
34
  - - :identifier
36
35
  - AnotherClass
37
36
  - - :_variable
38
37
  - :SomeClass
39
38
  - []
40
- - []
@@ -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;
@@ -114,7 +114,7 @@ describe Compiler::ICR do
114
114
  [:_context, []], [:function,
115
115
  [:exec,
116
116
  [:_context, [:test]],
117
- [:_arguments, [[:identifier, "test"]]],
117
+ [:_arguments, [[[:identifier, "test"], nil]]],
118
118
  [:number, "2"]
119
119
  ]
120
120
  ]])
@@ -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.parents << parent
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! :hello => "world"
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, [:_hello, "world"]] }
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! :hello => "world"
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, [:_hello, "world"], "test"] }
46
+ specify { expect(subject.to_a).to eq [:exec, [:_arguments, "world"], "test"] }
47
47
 
48
48
  end
49
49
  end