liquidscript 0.0.1

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 (72) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +8 -0
  5. data/Gemfile +11 -0
  6. data/Guardfile +9 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +59 -0
  9. data/Rakefile +25 -0
  10. data/lib/liquidscript.rb +11 -0
  11. data/lib/liquidscript/buffer.rb +34 -0
  12. data/lib/liquidscript/compiler.rb +9 -0
  13. data/lib/liquidscript/compiler/base.rb +101 -0
  14. data/lib/liquidscript/compiler/base/action.rb +39 -0
  15. data/lib/liquidscript/compiler/base/blank.rb +24 -0
  16. data/lib/liquidscript/compiler/base/callable.rb +51 -0
  17. data/lib/liquidscript/compiler/base/helpers.rb +207 -0
  18. data/lib/liquidscript/compiler/icr.rb +40 -0
  19. data/lib/liquidscript/compiler/icr/classes.rb +59 -0
  20. data/lib/liquidscript/compiler/icr/expressions.rb +94 -0
  21. data/lib/liquidscript/compiler/icr/functions.rb +42 -0
  22. data/lib/liquidscript/compiler/icr/helpers.rb +20 -0
  23. data/lib/liquidscript/compiler/icr/literals.rb +106 -0
  24. data/lib/liquidscript/errors.rb +51 -0
  25. data/lib/liquidscript/generator.rb +11 -0
  26. data/lib/liquidscript/generator/base.rb +25 -0
  27. data/lib/liquidscript/generator/base/dsl.rb +19 -0
  28. data/lib/liquidscript/generator/base/replacements.rb +33 -0
  29. data/lib/liquidscript/generator/context.rb +7 -0
  30. data/lib/liquidscript/generator/javascript.rb +37 -0
  31. data/lib/liquidscript/generator/javascript/literals.rb +63 -0
  32. data/lib/liquidscript/generator/javascript/metas.rb +41 -0
  33. data/lib/liquidscript/generator/javascript/objects.rb +137 -0
  34. data/lib/liquidscript/icr.rb +18 -0
  35. data/lib/liquidscript/icr/code.rb +68 -0
  36. data/lib/liquidscript/icr/context.rb +94 -0
  37. data/lib/liquidscript/icr/representable.rb +39 -0
  38. data/lib/liquidscript/icr/set.rb +147 -0
  39. data/lib/liquidscript/icr/sexp.rb +41 -0
  40. data/lib/liquidscript/icr/variable.rb +68 -0
  41. data/lib/liquidscript/scanner.rb +40 -0
  42. data/lib/liquidscript/scanner/lexer.rl +106 -0
  43. data/lib/liquidscript/scanner/token.rb +37 -0
  44. data/lib/liquidscript/template.rb +16 -0
  45. data/lib/liquidscript/version.rb +5 -0
  46. data/liquidscript.gemspec +27 -0
  47. data/spec/fixtures/class.compile.yml +26 -0
  48. data/spec/fixtures/class.generate.yml +31 -0
  49. data/spec/fixtures/combination.generate.yml +33 -0
  50. data/spec/fixtures/complex.generate.yml +20 -0
  51. data/spec/fixtures/expression.generate.yml +4 -0
  52. data/spec/fixtures/function.generate.yml +11 -0
  53. data/spec/fixtures/get.generate.yml +5 -0
  54. data/spec/fixtures/literals.generate.yml +8 -0
  55. data/spec/fixtures/main.compile.yml +32 -0
  56. data/spec/fixtures/set.generate.yml +4 -0
  57. data/spec/fixtures/string.generate.yml +6 -0
  58. data/spec/lib/liquidscript/buffer_spec.rb +14 -0
  59. data/spec/lib/liquidscript/compiler/icr_spec.rb +139 -0
  60. data/spec/lib/liquidscript/generator/javascript_spec.rb +15 -0
  61. data/spec/lib/liquidscript/icr/code_spec.rb +0 -0
  62. data/spec/lib/liquidscript/icr/context_spec.rb +36 -0
  63. data/spec/lib/liquidscript/icr/set_spec.rb +59 -0
  64. data/spec/lib/liquidscript/scanner/lexer_spec.rb +58 -0
  65. data/spec/lib/liquidscript/scanner/token_spec.rb +0 -0
  66. data/spec/lib/liquidscript/scanner_spec.rb +21 -0
  67. data/spec/spec_helper.rb +30 -0
  68. data/spec/support/helpers/lexer_helper.rb +5 -0
  69. data/spec/support/matchers/be_token.rb +9 -0
  70. data/spec/support/matchers/compile.rb +41 -0
  71. data/spec/support/matchers/generate.rb +46 -0
  72. metadata +210 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d8099fbffde0b4c86f743c1eeb2f7945876bda79
4
+ data.tar.gz: 61440eea14db6d81cff6245c03916e58092f310e
5
+ SHA512:
6
+ metadata.gz: d58710b0697834bfa1501061adc3d9d0492206d71c24d8886a769e451dadff2e41bdcc527d8629fb4522ff92cb2a9e423ee96eb1559d7fc5370c04a3bbfd3262
7
+ data.tar.gz: 9552101c9846bde2f34eebedcf1e4dcd1fa4da268c3e563331e2872ad0d9d5d21ea82296c79044265cdc0f01023fb3333542c99ed52d312cb30e9b40fed3afa9
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ lib/liquidscript/scanner/lexer.rb
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ -f d
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.0
4
+ - 1.9.3
5
+ - jruby-19mode
6
+ - rbx
7
+ before_script: bundle exec rake ls:ragel
8
+ script: bundle exec rspec -f d spec
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in liquidscript.gemspec
4
+ gemspec
5
+
6
+ gem 'pry'
7
+ gem 'guard'
8
+ gem 'guard-rspec'
9
+ gem 'guard-rake'
10
+ gem 'coveralls', require: false
11
+ gem 'rb-readline'
@@ -0,0 +1,9 @@
1
+ guard :rake, :task => "ls:ragel" do
2
+ watch("lib/liquidscript/scanner/lexer.rl")
3
+ end
4
+
5
+ guard :rspec do
6
+ watch(%r{^spec/.+_spec\.rb})
7
+ watch(%r{^lib/(.+)\.rb}) { |m| "spec/lib/#{m[1]}_spec.rb" }
8
+ watch('spec/spec_helper.rb') { "spec" }
9
+ end
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Jeremy Rodi
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,59 @@
1
+ # Liquidscript
2
+
3
+ [![Build Status](https://travis-ci.org/redjazz96/liquidscript.png?branch=master)](https://travis-ci.org/redjazz96/liquidscript) [![Coverage Status](https://coveralls.io/repos/redjazz96/liquidscript/badge.png?branch=master)](https://coveralls.io/r/redjazz96/liquidscript?branch=master) [![Code Climate](https://codeclimate.com/github/redjazz96/liquidscript.png)](https://codeclimate.com/github/redjazz96/liquidscript)
4
+
5
+ A javascript-based language that compiles to javascript.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'liquidscript'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install liquidscript
20
+
21
+ ## Usage
22
+
23
+ To use liquidscript:
24
+
25
+ ```
26
+ TODO: usage example
27
+ ```
28
+
29
+ The language of liquidscript:
30
+
31
+ ```coffeescript
32
+ # This is an object.
33
+
34
+ {
35
+ test: "hello",
36
+
37
+ # Note here that a single-quoted string does not have an ending
38
+ # delimiter. This is on purpose.
39
+ foo: 'bar # ' # syntax highlighting fix
40
+ }
41
+ ```
42
+
43
+ ```coffeescript
44
+ # This is a function
45
+
46
+ func = ()-> {
47
+ console.log("hello world")
48
+ }
49
+
50
+ func()
51
+ ```
52
+
53
+ ## Contributing
54
+
55
+ 1. Fork it ( http://github.com/redjazz96/liquidscript/fork )
56
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
57
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
58
+ 4. Push to the branch (`git push origin my-new-feature`)
59
+ 5. Create new Pull Request
@@ -0,0 +1,25 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+
5
+ RSpec::Core::RakeTask.new('spec')
6
+
7
+ namespace :ls do
8
+ rule '.rb' => ['.rl'] do |t|
9
+ sh "ragel -R #{t.source}"
10
+ end
11
+
12
+ desc "Builds the ragel parser."
13
+ task :ragel => ["lib/liquidscript/scanner/lexer.rb"]
14
+
15
+ desc "Opens up a pry session."
16
+ task :pry => [:ragel] do
17
+ require "pry"
18
+ require File.expand_path("../lib/liquidscript", __FILE__)
19
+ Pry.start
20
+ end
21
+
22
+ task :clean do
23
+ File.unlink("lib/liquidscript/scanner/lexer.rb")
24
+ end
25
+ end
@@ -0,0 +1,11 @@
1
+ require "forwardable"
2
+ require "liquidscript/icr"
3
+ require "liquidscript/errors"
4
+ require "liquidscript/version"
5
+ require "liquidscript/scanner"
6
+ require "liquidscript/compiler"
7
+ require "liquidscript/generator"
8
+
9
+ module Liquidscript
10
+ # Your code goes here...
11
+ end
@@ -0,0 +1,34 @@
1
+ module Liquidscript
2
+ class Buffer
3
+
4
+ def initialize(*args)
5
+ @_buf = args
6
+ @_cache = nil
7
+ @_join = ''
8
+ end
9
+
10
+ def append(*a)
11
+ @_cache = nil
12
+ @_buf.push(*a)
13
+ self
14
+ end
15
+
16
+ def set_join!(to)
17
+ @_join = to
18
+ end
19
+
20
+ alias_method :<<, :append
21
+ alias_method :push, :append
22
+
23
+ def to_s
24
+ @_cache ||= begin
25
+ @_buf.join @_join
26
+ end
27
+ end
28
+
29
+ def inspect
30
+ to_s.inspect
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,9 @@
1
+ require "liquidscript/buffer"
2
+ require "liquidscript/compiler/base"
3
+ require "liquidscript/compiler/icr"
4
+
5
+ module Liquidscript
6
+ module Compiler
7
+
8
+ end
9
+ end
@@ -0,0 +1,101 @@
1
+ require "liquidscript/compiler/base/blank"
2
+ require "liquidscript/compiler/base/action"
3
+ require "liquidscript/compiler/base/helpers"
4
+ require "liquidscript/compiler/base/callable"
5
+
6
+ module Liquidscript
7
+ module Compiler
8
+ class Base
9
+
10
+ include Helpers
11
+ extend Forwardable
12
+
13
+ # Initializes the compiler.
14
+ #
15
+ # @param scanner [Scanner, #each] the scanner. Used to
16
+ # manage the tokens. This could be stubbed out, if
17
+ # the #each function returns an Enumerator, which yields
18
+ # {Scanner::Token}s.
19
+ def initialize(scanner)
20
+ @scanner = scanner.each
21
+ @action = Action.new
22
+ reset!
23
+ end
24
+
25
+ # Returns the top set. If the variable @top isn't set by the
26
+ # inheriting class, then it defaults to the value of an array.
27
+ #
28
+ # @return [Array, #push]
29
+ def top
30
+ @top ||= []
31
+ end
32
+
33
+ # Begins the compiliation. Continues until the iterator raises
34
+ # a `StopIteration` error, and then returns the top set with
35
+ # {#top}.
36
+ #
37
+ # @raise [CompileError] if there's an error compiling.
38
+ # @raise [UnexpectedEndError] if the top {Array} isn't the topmost
39
+ # set.
40
+ # @return [Array] the topmost set.
41
+ def compile
42
+ # We're using this cool property of Base::Blank such that it
43
+ # will return a nil to any method call.
44
+ while !peek.is_a?(Blank) do
45
+ top.push compile_start
46
+ end
47
+
48
+ top
49
+ end
50
+
51
+ # Checks to see if the given input compiles.
52
+ #
53
+ # @see [#compile]
54
+ # @return [Boolean] if it compiles.
55
+ def compile?
56
+ compile
57
+ true
58
+ rescue CompileError
59
+ false
60
+ ensure
61
+ reset!
62
+ end
63
+
64
+ def scanner_nil
65
+ @_blank ||= Blank.new
66
+ end
67
+
68
+ # Pops the next argument off of the scanner. If the call
69
+ # raises a {StopIteration} error, it returns the value of
70
+ # {#scanner_nil} instead.
71
+ #
72
+ # @return [#type?, Blank]
73
+ def pop
74
+ @scanner.next
75
+ rescue StopIteration
76
+ scanner_nil
77
+ end
78
+
79
+ # Peeks at the next argument on the scanner. If the call
80
+ # raises a {StopIteration} error, it returns the value of
81
+ # {#scanner_nil} instead.
82
+ #
83
+ # @return [#type, Blank]
84
+ def peek
85
+ @scanner.peek
86
+ rescue StopIteration
87
+ scanner_nil
88
+ end
89
+
90
+ # Resets the state of the compiler.
91
+ #
92
+ # @return [void]
93
+ def reset!
94
+ @scanner.rewind
95
+ end
96
+
97
+ alias_method :rewind, :reset!
98
+
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,39 @@
1
+ module Liquidscript
2
+ module Compiler
3
+ class Base
4
+
5
+ # Used to construct blocks that are used with {#expect}. It's
6
+ # primarily syntaxic sugar, and DRYness.
7
+ class Action
8
+
9
+ # Returns a block that returns true, and takes no arguments.
10
+ # This is for {#expect}, when you don't want the token to be
11
+ # shifted, and you don't want the loop to end (if applicable).
12
+ #
13
+ # @return [Proc]
14
+ def nothing
15
+ @_nothing ||= proc { true }
16
+ end
17
+
18
+ # Returns a block that returns the first argument given to it.
19
+ # This is for {#expect}, when you want to shift the token, and
20
+ # you don't want the loop to end (if applicable). Also used
21
+ # internally for {Helpers#shift}.
22
+ #
23
+ # @return [Proc]
24
+ def shift
25
+ @_shift ||= proc { |_| _ }
26
+ end
27
+
28
+ # Returns a block that returns false, and takes one argument.
29
+ # This is for {#expect}, when you want to shift the token, and
30
+ # you want the loop to end (if applicable).
31
+ #
32
+ # @return [Proc]
33
+ def end_loop
34
+ @_end_loop ||= proc { |_| false }
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,24 @@
1
+ module Liquidscript
2
+ module Compiler
3
+ class Base
4
+
5
+ # Responds to all methods with `nil`.
6
+ class Blank
7
+
8
+ # Respond to all methods, with `nil`.
9
+ #
10
+ # @return [nil]
11
+ def method_missing(*_, &block)
12
+ nil
13
+ end
14
+
15
+ # Tells Ruby that we respond to all methods.
16
+ #
17
+ # @return [true]
18
+ def respond_to_missing?(_, __)
19
+ true
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,51 @@
1
+ module Liquidscript
2
+ module Compiler
3
+ class Base
4
+ class Callable
5
+
6
+ # Initialize the callable.
7
+ #
8
+ # @param bind [Object] the object that holds the method (if
9
+ # this represents a method call).
10
+ # @param block [Symbol, Block] if it's a Symbol, it represents
11
+ # a method on bind; otherwise, it's a pure block.
12
+ def initialize(bind, block)
13
+ @bind = bind
14
+ @block = if block.is_a? Symbol
15
+ :"compile_#{block}"
16
+ else
17
+ block
18
+ end
19
+ end
20
+
21
+ # Calls the thing that this represents. If this represents a
22
+ # method call, it calls the method with the given arguments;
23
+ # otherwise, it calls {#call} on the block.
24
+ #
25
+ # @param args [Object] passed to the call.
26
+ # @return [Object] the result of the call.
27
+ def call(*args)
28
+ if @block.is_a? Symbol
29
+ @bind.public_send(@block, *args)
30
+ elsif @block.respond_to?(:call)
31
+ @block.call(*args)
32
+ end
33
+ end
34
+
35
+ # How many arguments the call can take. If this represents a
36
+ # block that has tricks enabled, then this isn't an issue; if
37
+ # it's a method call, however, it becomes important.
38
+ #
39
+ # @return [Numeric] the number of arguments it can take.
40
+ def arity
41
+ if @block.is_a? Symbol
42
+ @bind.method(@block).arity
43
+ else
44
+ @block.arity
45
+ end
46
+ end
47
+
48
+ end
49
+ end
50
+ end
51
+ end