liquidscript 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +0 -1
  3. data/Guardfile +0 -4
  4. data/Rakefile +2 -2
  5. data/lib/liquidscript/compiler/icr/expressions.rb +2 -1
  6. data/lib/liquidscript/compiler/icr/literals.rb +17 -3
  7. data/lib/liquidscript/generator/javascript/literals.rb +18 -2
  8. data/lib/liquidscript/scanner.rb +3 -31
  9. data/lib/liquidscript/scanner/base.rb +84 -0
  10. data/lib/liquidscript/scanner/base/builder.rb +38 -0
  11. data/lib/liquidscript/scanner/base/context.rb +83 -0
  12. data/lib/liquidscript/scanner/base/dsl.rb +27 -0
  13. data/lib/liquidscript/scanner/base/lexer.rb +80 -0
  14. data/lib/liquidscript/scanner/liquidscript.rb +128 -0
  15. data/lib/liquidscript/scanner/token.rb +2 -6
  16. data/lib/liquidscript/template.rb +0 -1
  17. data/lib/liquidscript/version.rb +1 -1
  18. data/spec/fixtures/complex.generate.yml +1 -0
  19. data/spec/fixtures/main.compile.yml +1 -1
  20. data/spec/fixtures/string.compile.yml +15 -0
  21. data/spec/fixtures/string.generate.yml +3 -1
  22. data/spec/{lib/liquidscript → liquidscript}/buffer_spec.rb +0 -0
  23. data/spec/{lib/liquidscript → liquidscript}/compiler/icr_spec.rb +0 -0
  24. data/spec/{lib/liquidscript → liquidscript}/generator/javascript_spec.rb +7 -2
  25. data/spec/{lib/liquidscript → liquidscript}/icr/code_spec.rb +0 -0
  26. data/spec/{lib/liquidscript → liquidscript}/icr/context_spec.rb +0 -0
  27. data/spec/{lib/liquidscript → liquidscript}/icr/set_spec.rb +0 -0
  28. data/spec/{lib/liquidscript → liquidscript}/scanner/lexer_spec.rb +13 -15
  29. data/spec/{lib/liquidscript → liquidscript}/scanner/token_spec.rb +0 -0
  30. data/spec/{lib/liquidscript → liquidscript}/scanner_spec.rb +2 -2
  31. data/spec/spec_helper.rb +1 -0
  32. data/spec/support/helpers/lexer_helper.rb +1 -1
  33. data/spec/support/matchers/compile.rb +1 -1
  34. data/spec/support/matchers/generate.rb +2 -2
  35. metadata +28 -22
  36. data/lib/liquidscript/scanner/lexer.rb +0 -805
  37. data/lib/liquidscript/scanner/lexer.rl +0 -118
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 93358b89fa051538828ed587aaa478796f993676
4
- data.tar.gz: bf64eeb97bbdf9cb43150bf94b3d49d79bbba043
3
+ metadata.gz: 6e5b9fbac30bdea16bbd07de8b99ca913d320b6c
4
+ data.tar.gz: 888ba150e7957d376b2d1582b8ddd7d12a1d8ecc
5
5
  SHA512:
6
- metadata.gz: e91ab8b884aa60ed0d52d12f793f0f0b0f0cb13d3fbd060ae9d0345a56ef693dd99560fb280a8d68ea28f63fdf14f4f6b0106fbd34bbf3b039dd4456d2705b92
7
- data.tar.gz: 5bf5238837a656e9926809656fd90b3d96d768c6c589fd15886085852ec2e3fbc4e8963502ead086483a15cd0dea5f29bbdd0d5328d21c5e3eac2643bb9acba4
6
+ metadata.gz: c8d20ebc1d0dbdcf8398304d8e2a7e4a6e67eec0468189f42ee8f08e449151b2f9d3799e73ef9b4d9be25e7b4b083c0c625e3e2379c5d69c0bb5604c8eeaaf4c
7
+ data.tar.gz: e989b3f6b374a81c8e55b282570ecb6b6969a7250611addd042c6a8ce10bbb165be7cde3dbc1e43ca9c40276245236363e07dc7ca2c976f7e36a3df92ab996e9
data/.travis.yml CHANGED
@@ -4,5 +4,4 @@ rvm:
4
4
  - 1.9.3
5
5
  - jruby-19mode
6
6
  - rbx
7
- before_script: bundle exec rake ls:ragel
8
7
  script: bundle exec rspec -f d spec
data/Guardfile CHANGED
@@ -1,7 +1,3 @@
1
- guard :rake, :task => "ls:ragel" do
2
- watch("lib/liquidscript/scanner/lexer.rl")
3
- end
4
-
5
1
  guard :rspec do
6
2
  watch(%r{^spec/.+_spec\.rb})
7
3
  watch(%r{^lib/(.+)\.rb}) { |m| "spec/lib/#{m[1]}_spec.rb" }
data/Rakefile CHANGED
@@ -9,8 +9,8 @@ namespace :ls do
9
9
  sh "ragel -R #{t.source}"
10
10
  end
11
11
 
12
- desc "Builds the ragel parser."
13
- task :ragel => ["lib/liquidscript/scanner/lexer.rb"]
12
+ #desc "Builds the ragel parser."
13
+ #task :ragel => ["lib/liquidscript/scanner/lexer.rb"]
14
14
 
15
15
  desc "Opens up a pry session."
16
16
  task :pry => [:ragel] do
@@ -16,10 +16,11 @@ module Liquidscript
16
16
  # @return [ICR::Code]
17
17
  def compile_vexpression
18
18
  out = expect :number, :identifier,
19
- :dstring, :lparen,
19
+ :istring, :lparen,
20
20
  :sstring, :operator,
21
21
  :keyword, :unop,
22
22
  :newline,
23
+ :istring_begin,
23
24
  :lbrack => :object,
24
25
  :lbrace => :array,
25
26
  :arrow => :function
@@ -18,12 +18,26 @@ module Liquidscript
18
18
  :_ => default
19
19
  end
20
20
 
21
- def compile_dstring
22
- code :dstring, pop.value[1..-2]
21
+ def compile_istring_begin
22
+ start = shift :istring_begin
23
+ contents = [start]
24
+
25
+ loop do
26
+ contents << compile_vexpression
27
+ contents << shift(:istring)
28
+ peek?(:istring_begin)
29
+ end
30
+
31
+
32
+ code :interop, *contents
33
+ end
34
+
35
+ def compile_istring
36
+ code :istring, shift(:istring).value
23
37
  end
24
38
 
25
39
  def compile_sstring
26
- code :sstring, pop.value[1..-1]
40
+ code :sstring, shift(:sstring).value[1..-1]
27
41
  end
28
42
 
29
43
  def compile_operator
@@ -17,11 +17,27 @@ module Liquidscript
17
17
  "#{code.first}"
18
18
  end
19
19
 
20
- def generate_dstring(code)
21
-
20
+ def generate_istring(code)
22
21
  "\"#{code.first.gsub("\n", "\\n")}\""
23
22
  end
24
23
 
24
+ def generate_interop(code)
25
+ content = code[1..-1]
26
+ buf = buffer
27
+ buf.set_join! ','
28
+
29
+ content.each do |part|
30
+ case part.type
31
+ when :istring_begin, :istring
32
+ buf << "\"#{part.value}\""
33
+ else
34
+ buf << "#{replace(part)}"
35
+ end
36
+ end
37
+
38
+ "[#{buf}].join('')"
39
+ end
40
+
25
41
  def generate_sstring(code)
26
42
 
27
43
  "'#{code.first.gsub(/'/, "\\'")}'"
@@ -1,40 +1,12 @@
1
1
  require "liquidscript/scanner/token"
2
- require "liquidscript/scanner/lexer"
2
+ require "liquidscript/scanner/base"
3
+ require "liquidscript/scanner/liquidscript"
3
4
 
4
5
  module Liquidscript
5
6
 
6
7
  # @todo Stream scanning.
7
8
  # um...
8
- class Scanner
9
-
10
- include Enumerable
11
-
12
- def initialize(source)
13
- @tokenizer = Lexer.new
14
- @source = source
15
- end
16
-
17
- def each
18
- e = buffer.each
19
-
20
- if block_given?
21
- e.each(&Proc.new)
22
- else
23
- e
24
- end
25
- end
26
-
27
- def inspect
28
- "#<#{self.class.to_s}:#{'0x%08x' % self.object_id}>"
29
- end
30
-
31
- private
32
-
33
- def buffer
34
- @_parts ||= begin
35
- @tokenizer.perform(@source)
36
- end
37
- end
9
+ module Scanner
38
10
 
39
11
  end
40
12
  end
@@ -0,0 +1,84 @@
1
+ require 'set'
2
+ require 'strscan'
3
+ require 'liquidscript/scanner/base/builder'
4
+ require 'liquidscript/scanner/base/context'
5
+ require 'liquidscript/scanner/base/dsl'
6
+ require 'liquidscript/scanner/base/lexer'
7
+
8
+ module Liquidscript
9
+ module Scanner
10
+ # TODO: documentation
11
+ class Base
12
+
13
+ EXIT = Object.new.freeze
14
+
15
+ include Lexer
16
+ include Enumerable
17
+
18
+ class << self
19
+
20
+ def contexts
21
+ @_contexts ||= Set.new
22
+ end
23
+
24
+ attr_accessor :default
25
+
26
+ end
27
+
28
+ def initialize(source)
29
+ @source = source
30
+ @scanner = StringScanner.new(@source)
31
+ @tokens = []
32
+ @_scan = nil
33
+ end
34
+
35
+ def contexts
36
+ self.class.contexts
37
+ end
38
+
39
+ def default_context
40
+ self.class.default
41
+ end
42
+
43
+ def scan
44
+ lex default_context
45
+ self
46
+ end
47
+
48
+ def each
49
+ e = buffer.each
50
+
51
+ if block_given?
52
+ e.each(&Proc.new)
53
+ else
54
+ e
55
+ end
56
+ end
57
+
58
+ def line
59
+ "(unknown)"
60
+ end
61
+
62
+ def column
63
+ "(unkown)"
64
+ end
65
+
66
+ def emit(token_name, body = nil)
67
+ @tokens << Token.new(token_name, body, line, column)
68
+ end
69
+
70
+ def inspect
71
+ "#<#{self.class}:#{'0x%08x' % object_id}>"
72
+ end
73
+
74
+ private
75
+
76
+ def buffer
77
+ @_scan ||= begin
78
+ scan
79
+ @tokens
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,38 @@
1
+ require 'set'
2
+
3
+ module Liquidscript
4
+ module Scanner
5
+ class Base
6
+ class Builder
7
+
8
+ EMPTY_VALUE = Object.new
9
+
10
+ attr_reader :contexts
11
+
12
+ def default_context(value = EMPTY_VALUE)
13
+ if value.equal? EMPTY_VALUE
14
+ @default_context
15
+ else
16
+ @default_context = value
17
+ end
18
+ end
19
+
20
+ def contexts
21
+ @contexts ||= Set.new
22
+ end
23
+
24
+ def context(name)
25
+ context = Context.new(name)
26
+ context.instance_exec(&Proc.new)
27
+ contexts << context
28
+ end
29
+
30
+ def reset!
31
+ @default_context = nil
32
+ @contexts = nil
33
+ self
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,83 @@
1
+ module Liquidscript
2
+ module Scanner
3
+ class Base
4
+ class Context
5
+
6
+ attr_reader :name
7
+
8
+ def initialize(name)
9
+ @name = name
10
+ @matches = {}
11
+ @temps = {}
12
+ end
13
+
14
+ def find_matcher(with)
15
+ best_match = [0, nil, nil]
16
+ @matches.each do |k, v|
17
+ if with.match?(k) && with.matched_size > best_match[0]
18
+ best_match = [with.matched_size, k, v]
19
+ end
20
+ end
21
+
22
+ best_match[1..-1]
23
+ end
24
+
25
+ def exit
26
+ EXIT
27
+ end
28
+
29
+ def init
30
+ if block_given?
31
+ @init = Proc.new
32
+ else
33
+ @init || proc {}
34
+ end
35
+ end
36
+
37
+ def set(key, matcher)
38
+ @temps[key] = matcher
39
+ end
40
+
41
+ def get(key)
42
+ normalize_matcher @temps[key]
43
+ end
44
+
45
+ def on(matcher)
46
+ key = nil
47
+ value = nil
48
+
49
+ if block_given?
50
+ key = normalize_matcher matcher
51
+ value = Proc.new
52
+ else
53
+ key = normalize_matcher matcher.keys.first
54
+ value = matcher.values.first
55
+ end
56
+
57
+ @matches[key] = value
58
+ end
59
+
60
+ private
61
+
62
+ def normalize_matcher(matcher)
63
+ case matcher
64
+ when :_
65
+ /./m
66
+ when String
67
+ Regexp.new(Regexp.escape(matcher))
68
+ when Symbol
69
+ normalize_matcher(@temps[matcher])
70
+ when Array
71
+ union = matcher.map { |m|
72
+ Regexp.escape(m.to_s)
73
+ }.join('|')
74
+ Regexp.new "(#{union})"
75
+ else
76
+ matcher
77
+ end
78
+ end
79
+
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,27 @@
1
+ module Liquidscript
2
+ module Scanner
3
+ class Base
4
+ module DSL
5
+
6
+ module ClassMethods
7
+
8
+ def define
9
+ builder.instance_exec(&Proc.new)
10
+ contexts.merge builder.contexts
11
+ self.default = builder.default_context
12
+ builder.reset!
13
+ end
14
+
15
+ def builder
16
+ @_builder ||= Builder.new
17
+ end
18
+
19
+ end
20
+
21
+ def self.included(base)
22
+ base.extend ClassMethods
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,80 @@
1
+ module Liquidscript
2
+ module Scanner
3
+ class Base
4
+ module Lexer
5
+
6
+ def perform_with_context(context, scanner = @scanner)
7
+ key, value = context.find_matcher(scanner)
8
+
9
+ if value.nil? && scanner.rest?
10
+ error scanner
11
+ end
12
+
13
+ normalize_action key, value, scanner if scanner.rest?
14
+ end
15
+
16
+ def lex(argument)
17
+ context, body =
18
+ if argument.is_a?(Hash)
19
+ argument.to_a.first
20
+ else
21
+ argument
22
+ end
23
+
24
+ scanner = if body
25
+ StringScanner.new(body)
26
+ else
27
+ @scanner
28
+ end
29
+ out = []
30
+
31
+ context = find_context(context)
32
+ instance_exec &context.init
33
+
34
+ while scanner.rest? && out.last != EXIT
35
+ out << perform_with_context(context, scanner)
36
+ end
37
+
38
+ out
39
+ end
40
+
41
+ def error(scanner = @scanner)
42
+ raise SyntaxError, "Unexpected #{scanner.peek(2).inspect}" \
43
+ " (line: #{line}, column: #{column})"
44
+ end
45
+
46
+ private
47
+
48
+ def find_context(name)
49
+ context = contexts.dup.keep_if { |c|
50
+ c.name == name
51
+ }.to_a.first
52
+
53
+ if context.nil?
54
+ raise NoContextError.new(name)
55
+ end
56
+
57
+ context
58
+ end
59
+
60
+ def exit
61
+ EXIT
62
+ end
63
+
64
+ def normalize_action(key, value, scanner)
65
+ body = scanner.scan(key)
66
+
67
+ case value
68
+ when Proc
69
+ instance_exec(*body.match(key), &value)
70
+ when Symbol
71
+ lex value
72
+ when EXIT
73
+ EXIT
74
+ end
75
+ end
76
+
77
+ end
78
+ end
79
+ end
80
+ end