liquidscript 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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,40 @@
1
+ require "liquidscript/scanner/token"
2
+ require "liquidscript/scanner/lexer"
3
+
4
+ module Liquidscript
5
+
6
+ # @todo Stream scanning.
7
+ # 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
38
+
39
+ end
40
+ end
@@ -0,0 +1,106 @@
1
+ %%{
2
+
3
+ machine lexer;
4
+
5
+ variable data @data;
6
+ variable p @p;
7
+ variable pe @pe;
8
+ variable eof @eof;
9
+ access @;
10
+
11
+ number_integer = '-'? [0-9][1-9]*;
12
+ number_frac = '.' [0-9]+;
13
+ number_e = ('e' | 'E') ('+' | '-' | '');
14
+ number_exp = number_e [0-9]+;
15
+ number = number_integer number_frac? number_exp?;
16
+
17
+ string_double = '"' ( any -- '"' | '\\"' )* '"';
18
+ identifier = [A-Za-z_$][A-Za-z0-9_$]*;
19
+ string_single = "'" [A-Za-z0-9_$\-]+;
20
+
21
+ main := |*
22
+ number => { emit :number };
23
+ string_double => { emit :dstring };
24
+ string_single => { emit :sstring };
25
+ 'class' => { emit :class };
26
+ 'module' => { emit :module };
27
+ 'new' => { emit :keyword };
28
+ 'return' => { emit :keyword };
29
+ identifier => { emit :identifier };
30
+ '->' => { emit :arrow };
31
+ '=' => { emit :equal };
32
+ '{' => { emit :lbrack };
33
+ '(' => { emit :lparen };
34
+ '[' => { emit :lbrace };
35
+ '}' => { emit :rbrack };
36
+ ')' => { emit :rparen };
37
+ ']' => { emit :rbrace };
38
+ ':' => { emit :colon };
39
+ '.' => { emit :prop };
40
+ ',' => { emit :comma };
41
+ '\n' => { line.call };
42
+ space => { };
43
+ any => { error };
44
+ *|;
45
+ }%%
46
+
47
+ module Liquidscript
48
+ class Scanner
49
+
50
+ # A lexer, built from ragel.
51
+ #
52
+ # @private
53
+ class Lexer
54
+
55
+ attr_reader :tokens
56
+
57
+ def initialize
58
+ %% write data;
59
+ # %% # fix
60
+ @tokens = []
61
+ clean!
62
+ end
63
+
64
+ def clean!
65
+ @p = nil
66
+ @pe = nil
67
+ @te = nil
68
+ @ts = nil
69
+ @act = nil
70
+ @eof = nil
71
+ @top = nil
72
+ @line = { :start => 0, :num => 0 }
73
+ @data = nil
74
+ @stack = nil
75
+ end
76
+
77
+ def emit(type)
78
+ @tokens << Token.new(type, @data[@ts..(@te - 1)],
79
+ @line[:num], @ts - @line[:start])
80
+ end
81
+
82
+ def error
83
+ raise SyntaxError, "Unexpected #{@data[@ts..(@te-1)].pack('c*')}"
84
+ end
85
+
86
+ def perform(data)
87
+ @data = data.unpack("c*") if data.is_a? String
88
+ @eof = data.length
89
+
90
+ @tokens = []
91
+
92
+ line = proc do
93
+ @line[:start] = @ts
94
+ @line[:num] += 1
95
+ end
96
+
97
+ %% write init;
98
+ %% write exec;
99
+
100
+ clean!
101
+
102
+ @tokens
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,37 @@
1
+ require "liquidscript/icr/representable"
2
+
3
+ module Liquidscript
4
+ class Scanner
5
+ class Token
6
+
7
+ attr_accessor :type
8
+ attr_accessor :value
9
+ attr_reader :line
10
+ attr_reader :column
11
+
12
+ include Enumerable
13
+ include ICR::Representable
14
+
15
+ def initialize(type, value, line, column)
16
+ @type = type
17
+ @line = line
18
+ @column = column
19
+ @value = begin
20
+ value.pack("c*")
21
+ rescue NoMethodError, TypeError
22
+ value
23
+ end
24
+ end
25
+
26
+ def to_a
27
+ [@type, @value]
28
+ end
29
+
30
+ def type?(type)
31
+ @type == type
32
+ end
33
+
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,16 @@
1
+ module Liquidscript
2
+ class Template
3
+
4
+ def initialize(data)
5
+ @data = data
6
+ end
7
+
8
+ def render
9
+ @_render ||= begin
10
+ compiler = Compiler::ICR.new(Scanner.new(@data))
11
+ compiler.compile
12
+ Generator::Javascript.new(compiler).generate
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,5 @@
1
+ module Liquidscript
2
+
3
+ # The current version of liquidscript.
4
+ VERSION = "0.0.1".freeze
5
+ end
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'liquidscript/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "liquidscript"
8
+ spec.version = Liquidscript::VERSION
9
+ spec.authors = ["Jeremy Rodi"]
10
+ spec.email = ["redjazz96@gmail.com"]
11
+ spec.summary = %q{A javascript-based language that compiles to javascript.}
12
+ spec.description = %q{A javascript-based language that compiles to javascript.}
13
+ spec.homepage = "https://github.com/redjazz96/liquidscript"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.5"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
24
+ spec.add_development_dependency "yard"
25
+
26
+ spec.add_dependency "hashie", "~> 2.0"
27
+ end
@@ -0,0 +1,26 @@
1
+ data: |
2
+ module Something {
3
+ class SomeClass {
4
+ test: -> {}
5
+ }
6
+ }
7
+
8
+ compiled:
9
+ - :exec
10
+ - - :_context
11
+ - - :SomeClass
12
+ - :Something
13
+ - - :module
14
+ - - :identifier
15
+ - Something
16
+ - - - :class
17
+ - - :identifier
18
+ - SomeClass
19
+ - - - - :identifier
20
+ - test
21
+ - - :function
22
+ - - :exec
23
+ - - :_context
24
+ - []
25
+ - - :_arguments
26
+ - []
@@ -0,0 +1,31 @@
1
+ data: |
2
+ module Something {
3
+ class Test {
4
+ wee: -> {
5
+ console.log(2)
6
+ }
7
+
8
+ initialize: -> {
9
+ "this should be init"
10
+ }
11
+ }
12
+ }
13
+
14
+ compiled: |
15
+ var Test, Something;
16
+
17
+ Something = {};
18
+ Test = function Test() {
19
+ if(this.initialize) {
20
+ this.initialize.apply(this, arguments);
21
+ }
22
+ };
23
+
24
+ Test.prototype.wee = function() {
25
+ console.log(2)
26
+ };
27
+
28
+ Test.prototype.initialize = function() {
29
+ "this should be init"
30
+ };
31
+ Something.Test = Test;
@@ -0,0 +1,33 @@
1
+ data: |
2
+ Test = require("some_module/test")
3
+
4
+ module SomeModule {
5
+ class Thing {
6
+ initialize: -> {
7
+ this.test = new Test()
8
+ }
9
+
10
+ do: (thing)-> {
11
+ return this.test.do(thing)
12
+ }
13
+ }
14
+ }
15
+
16
+ compiled: |
17
+ var Test, Thing, SomeModule;
18
+ Test = require("some_module/test");
19
+ SomeModule = {};
20
+ Thing = function Thing() {
21
+ if(this.initialize) {
22
+ this.initialize.apply(this, arguments);
23
+ }
24
+ };
25
+
26
+ Thing.prototype.initialize = function() {
27
+ this.test = new Test();
28
+ };
29
+
30
+ Thing.prototype.do = function(thing) {
31
+ return this.test.do(thing)
32
+ };
33
+ SomeModule.Thing = Thing;
@@ -0,0 +1,20 @@
1
+ data: |
2
+ thing = {
3
+ test: -> {
4
+ "hello"
5
+ }
6
+ }
7
+
8
+ thing.test()
9
+
10
+ compiled: |
11
+ var thing;
12
+
13
+ thing = {
14
+ "test": function() {
15
+ "hello"
16
+ }
17
+ };
18
+
19
+ thing.test()
20
+
@@ -0,0 +1,4 @@
1
+ data: |
2
+ (2)
3
+
4
+ compiled: "(2)"
@@ -0,0 +1,11 @@
1
+ data: |
2
+ console = 2
3
+ some_function = ()-> {
4
+ console = 3
5
+ }
6
+
7
+ compiled: |
8
+ var some_function;
9
+ console = 2;
10
+
11
+ some_function = function() { console = 3; };
@@ -0,0 +1,5 @@
1
+ data: |
2
+ something = 2
3
+ test = something
4
+
5
+ compiled: "var something,test; something = 2; test = something;"
@@ -0,0 +1,8 @@
1
+ data: |
2
+ object = { hello: "world" }
3
+ test = [1, 2]
4
+
5
+ compiled: |
6
+ var object, test;
7
+ object = { "hello": "world" };
8
+ test = [1, 2];
@@ -0,0 +1,32 @@
1
+ data: |
2
+ console = 2
3
+ func = ()-> {
4
+ console.log("hello world")
5
+ }
6
+ compiled:
7
+ - :exec
8
+ - - :_context
9
+ - - :console
10
+ - :func
11
+ - - :set
12
+ - - :_variable
13
+ - :console
14
+ - - :number
15
+ - "2"
16
+ - - :set
17
+ - - :_variable
18
+ - :func
19
+ - - :function
20
+ - - :exec
21
+ - - :_context
22
+ - []
23
+ - - :_arguments
24
+ - []
25
+ - - :call
26
+ - - :property
27
+ - - :_variable
28
+ - :console
29
+ - - :identifier
30
+ - log
31
+ - - :dstring
32
+ - hello world
@@ -0,0 +1,4 @@
1
+ data: |
2
+ something = 2
3
+
4
+ compiled: "var something; something = 2;"
@@ -0,0 +1,6 @@
1
+ data: |
2
+ test = "hello"
3
+ foo = 'world
4
+
5
+ compiled: |
6
+ var test,foo; test = "hello"; foo = 'world';
@@ -0,0 +1,14 @@
1
+ require "spec_helper"
2
+
3
+ describe Liquidscript::Buffer do
4
+
5
+ subject { described_class.new "hello ", "world" }
6
+
7
+ its(:to_s) { should eq "hello world" }
8
+ its(:inspect) { should eq '"hello world"' }
9
+
10
+ it "appends a value" do
11
+ subject.append(", test")
12
+ expect(subject.to_s).to eq "hello world, test"
13
+ end
14
+ end