hotcell 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -1
  3. data/.rspec +1 -0
  4. data/.rvmrc +1 -1
  5. data/.travis.yml +7 -0
  6. data/Gemfile +4 -1
  7. data/README.md +361 -2
  8. data/Rakefile +28 -6
  9. data/ext/lexerc/extconf.rb +3 -0
  10. data/ext/lexerc/lexerc.c +618 -0
  11. data/ext/lexerc/lexerc.h +20 -0
  12. data/ext/lexerc/lexerc.rl +167 -0
  13. data/hotcell.gemspec +8 -7
  14. data/lib/hotcell/commands/case.rb +59 -0
  15. data/lib/hotcell/commands/cycle.rb +38 -0
  16. data/lib/hotcell/commands/for.rb +70 -0
  17. data/lib/hotcell/commands/if.rb +51 -0
  18. data/lib/hotcell/commands/include.rb +21 -0
  19. data/lib/hotcell/commands/scope.rb +13 -0
  20. data/lib/hotcell/commands/unless.rb +23 -0
  21. data/lib/hotcell/commands.rb +13 -0
  22. data/lib/hotcell/config.rb +33 -6
  23. data/lib/hotcell/context.rb +40 -7
  24. data/lib/hotcell/errors.rb +37 -28
  25. data/lib/hotcell/extensions.rb +4 -0
  26. data/lib/hotcell/lexer.rb +19 -635
  27. data/lib/hotcell/lexerr.rb +572 -0
  28. data/lib/hotcell/lexerr.rl +137 -0
  29. data/lib/hotcell/node/assigner.rb +1 -5
  30. data/lib/hotcell/node/block.rb +17 -40
  31. data/lib/hotcell/node/command.rb +29 -22
  32. data/lib/hotcell/node/hasher.rb +1 -1
  33. data/lib/hotcell/node/summoner.rb +2 -6
  34. data/lib/hotcell/node/tag.rb +10 -7
  35. data/lib/hotcell/node.rb +12 -1
  36. data/lib/hotcell/parser.rb +474 -408
  37. data/lib/hotcell/parser.y +175 -117
  38. data/lib/hotcell/resolver.rb +44 -0
  39. data/lib/hotcell/source.rb +35 -0
  40. data/lib/hotcell/template.rb +15 -6
  41. data/lib/hotcell/version.rb +1 -1
  42. data/lib/hotcell.rb +15 -10
  43. data/spec/data/templates/simple.hc +1 -0
  44. data/spec/lib/hotcell/commands/case_spec.rb +39 -0
  45. data/spec/lib/hotcell/commands/cycle_spec.rb +29 -0
  46. data/spec/lib/hotcell/commands/for_spec.rb +65 -0
  47. data/spec/lib/hotcell/commands/if_spec.rb +35 -0
  48. data/spec/lib/hotcell/commands/include_spec.rb +39 -0
  49. data/spec/lib/hotcell/commands/scope_spec.rb +16 -0
  50. data/spec/lib/hotcell/commands/unless_spec.rb +23 -0
  51. data/spec/lib/hotcell/config_spec.rb +35 -10
  52. data/spec/lib/hotcell/context_spec.rb +58 -18
  53. data/spec/lib/hotcell/lexer_spec.rb +37 -28
  54. data/spec/lib/hotcell/node/block_spec.rb +28 -56
  55. data/spec/lib/hotcell/node/command_spec.rb +7 -31
  56. data/spec/lib/hotcell/node/tag_spec.rb +16 -0
  57. data/spec/lib/hotcell/parser_spec.rb +152 -123
  58. data/spec/lib/hotcell/resolver_spec.rb +28 -0
  59. data/spec/lib/hotcell/source_spec.rb +41 -0
  60. data/spec/lib/hotcell/template_spec.rb +47 -4
  61. data/spec/lib/hotcell_spec.rb +2 -1
  62. data/spec/spec_helper.rb +6 -2
  63. metadata +54 -24
  64. data/lib/hotcell/.DS_Store +0 -0
  65. data/lib/hotcell/lexer.rl +0 -299
  66. data/misc/rage.rl +0 -1999
  67. data/misc/unicode2ragel.rb +0 -305
metadata CHANGED
@@ -1,72 +1,81 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hotcell
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
5
- prerelease:
4
+ version: 0.1.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - pyromaniac
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-06-19 00:00:00.000000000 Z
11
+ date: 2013-07-04 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
- name: activesupport
14
+ name: racc
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0'
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - '>='
28
25
  - !ruby/object:Gem::Version
29
26
  version: '0'
30
27
  - !ruby/object:Gem::Dependency
31
- name: racc
28
+ name: activesupport
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - '>='
36
32
  - !ruby/object:Gem::Version
37
33
  version: '0'
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - '>='
44
39
  - !ruby/object:Gem::Version
45
40
  version: '0'
46
41
  description: Sandboxed ruby template processor
47
42
  email:
48
43
  - kinwizard@gmail.com
49
44
  executables: []
50
- extensions: []
45
+ extensions:
46
+ - ext/lexerc/extconf.rb
51
47
  extra_rdoc_files: []
52
48
  files:
53
49
  - .gitignore
54
50
  - .rspec
55
51
  - .rvmrc
52
+ - .travis.yml
56
53
  - Gemfile
57
54
  - Guardfile
58
55
  - LICENSE.txt
59
56
  - README.md
60
57
  - Rakefile
58
+ - ext/lexerc/extconf.rb
59
+ - ext/lexerc/lexerc.c
60
+ - ext/lexerc/lexerc.h
61
+ - ext/lexerc/lexerc.rl
61
62
  - hotcell.gemspec
62
63
  - lib/hotcell.rb
63
- - lib/hotcell/.DS_Store
64
+ - lib/hotcell/commands.rb
65
+ - lib/hotcell/commands/case.rb
66
+ - lib/hotcell/commands/cycle.rb
67
+ - lib/hotcell/commands/for.rb
68
+ - lib/hotcell/commands/if.rb
69
+ - lib/hotcell/commands/include.rb
70
+ - lib/hotcell/commands/scope.rb
71
+ - lib/hotcell/commands/unless.rb
64
72
  - lib/hotcell/config.rb
65
73
  - lib/hotcell/context.rb
66
74
  - lib/hotcell/errors.rb
67
75
  - lib/hotcell/extensions.rb
68
76
  - lib/hotcell/lexer.rb
69
- - lib/hotcell/lexer.rl
77
+ - lib/hotcell/lexerr.rb
78
+ - lib/hotcell/lexerr.rl
70
79
  - lib/hotcell/manipulator.rb
71
80
  - lib/hotcell/node.rb
72
81
  - lib/hotcell/node/arrayer.rb
@@ -81,59 +90,80 @@ files:
81
90
  - lib/hotcell/node/tag.rb
82
91
  - lib/hotcell/parser.rb
83
92
  - lib/hotcell/parser.y
93
+ - lib/hotcell/resolver.rb
84
94
  - lib/hotcell/scope.rb
95
+ - lib/hotcell/source.rb
85
96
  - lib/hotcell/template.rb
86
97
  - lib/hotcell/version.rb
87
- - misc/rage.rl
88
- - misc/unicode2ragel.rb
89
98
  - spec/data/dstrings
90
99
  - spec/data/sstrings
100
+ - spec/data/templates/simple.hc
101
+ - spec/lib/hotcell/commands/case_spec.rb
102
+ - spec/lib/hotcell/commands/cycle_spec.rb
103
+ - spec/lib/hotcell/commands/for_spec.rb
104
+ - spec/lib/hotcell/commands/if_spec.rb
105
+ - spec/lib/hotcell/commands/include_spec.rb
106
+ - spec/lib/hotcell/commands/scope_spec.rb
107
+ - spec/lib/hotcell/commands/unless_spec.rb
91
108
  - spec/lib/hotcell/config_spec.rb
92
109
  - spec/lib/hotcell/context_spec.rb
93
110
  - spec/lib/hotcell/lexer_spec.rb
94
111
  - spec/lib/hotcell/manipulator_spec.rb
95
112
  - spec/lib/hotcell/node/block_spec.rb
96
113
  - spec/lib/hotcell/node/command_spec.rb
114
+ - spec/lib/hotcell/node/tag_spec.rb
97
115
  - spec/lib/hotcell/parser_spec.rb
116
+ - spec/lib/hotcell/resolver_spec.rb
98
117
  - spec/lib/hotcell/scope_spec.rb
118
+ - spec/lib/hotcell/source_spec.rb
99
119
  - spec/lib/hotcell/template_spec.rb
100
120
  - spec/lib/hotcell_spec.rb
101
121
  - spec/spec_helper.rb
102
122
  homepage: ''
103
123
  licenses: []
124
+ metadata: {}
104
125
  post_install_message:
105
126
  rdoc_options: []
106
127
  require_paths:
107
128
  - lib
108
129
  required_ruby_version: !ruby/object:Gem::Requirement
109
- none: false
110
130
  requirements:
111
- - - ! '>='
131
+ - - '>='
112
132
  - !ruby/object:Gem::Version
113
133
  version: '0'
114
134
  required_rubygems_version: !ruby/object:Gem::Requirement
115
- none: false
116
135
  requirements:
117
- - - ! '>='
136
+ - - '>='
118
137
  - !ruby/object:Gem::Version
119
138
  version: '0'
120
139
  requirements: []
121
140
  rubyforge_project:
122
- rubygems_version: 1.8.25
141
+ rubygems_version: 2.0.3
123
142
  signing_key:
124
- specification_version: 3
143
+ specification_version: 4
125
144
  summary: Sandboxed ruby template processor
126
145
  test_files:
127
146
  - spec/data/dstrings
128
147
  - spec/data/sstrings
148
+ - spec/data/templates/simple.hc
149
+ - spec/lib/hotcell/commands/case_spec.rb
150
+ - spec/lib/hotcell/commands/cycle_spec.rb
151
+ - spec/lib/hotcell/commands/for_spec.rb
152
+ - spec/lib/hotcell/commands/if_spec.rb
153
+ - spec/lib/hotcell/commands/include_spec.rb
154
+ - spec/lib/hotcell/commands/scope_spec.rb
155
+ - spec/lib/hotcell/commands/unless_spec.rb
129
156
  - spec/lib/hotcell/config_spec.rb
130
157
  - spec/lib/hotcell/context_spec.rb
131
158
  - spec/lib/hotcell/lexer_spec.rb
132
159
  - spec/lib/hotcell/manipulator_spec.rb
133
160
  - spec/lib/hotcell/node/block_spec.rb
134
161
  - spec/lib/hotcell/node/command_spec.rb
162
+ - spec/lib/hotcell/node/tag_spec.rb
135
163
  - spec/lib/hotcell/parser_spec.rb
164
+ - spec/lib/hotcell/resolver_spec.rb
136
165
  - spec/lib/hotcell/scope_spec.rb
166
+ - spec/lib/hotcell/source_spec.rb
137
167
  - spec/lib/hotcell/template_spec.rb
138
168
  - spec/lib/hotcell_spec.rb
139
169
  - spec/spec_helper.rb
Binary file
data/lib/hotcell/lexer.rl DELETED
@@ -1,299 +0,0 @@
1
- %%{
2
- #%
3
- machine puffer_lexer;
4
-
5
- variable data @data;
6
- variable te @te;
7
- variable ts @ts;
8
-
9
- plus = '+';
10
- minus = '-';
11
- multiply = '*';
12
- power = '**';
13
- divide = '/';
14
- modulo = '%';
15
- arithmetic = plus | minus | multiply | power | divide | modulo;
16
-
17
- and = '&&';
18
- or = '||';
19
- not = '!';
20
- equal = '==';
21
- inequal = '!=';
22
- gt = '>';
23
- gte = '>=';
24
- lt = '<';
25
- lte = '<=';
26
- logic = and | or | not | equal | inequal | gt | gte | lt | lte;
27
-
28
- assign = '=';
29
- comma = ',';
30
- period = '.';
31
- colon = ':';
32
- question = '?';
33
- semicolon = ';';
34
- newline = '\n';
35
- flow = assign | comma | period | colon | question | semicolon | newline;
36
-
37
- array_open = '[';
38
- array_close = ']';
39
- hash_open = '{';
40
- hash_close = '}';
41
- bracket_open = '(';
42
- bracket_close = ')';
43
- structure = array_open | array_close | hash_open | hash_close | bracket_open | bracket_close;
44
-
45
-
46
- escaped_symbol = '\\' any;
47
-
48
- squote = "'";
49
- snon_quote = [^\\'];
50
- sstring = squote (snon_quote | escaped_symbol)* squote @lerr{ raise_unterminated_string };
51
-
52
- dquote = '"';
53
- dnon_quote = [^\\"];
54
- dstring = dquote (dnon_quote | escaped_symbol)* dquote @lerr{ raise_unterminated_string };
55
-
56
- rquote = '/';
57
- rnon_quote = [^\\/];
58
- regexp = rquote @{ regexp_ambiguity { fgoto expression; } }
59
- (rnon_quote | escaped_symbol)* rquote alpha* @lerr{ raise_unterminated_regexp };
60
-
61
-
62
- numeric = digit* ('.' digit+)?;
63
- identifer = (alpha | '_') (alnum | '_')* [?!]?;
64
- operator = arithmetic | logic | flow | structure;
65
- comment = '#' ([^\n}]+ | '}' [^}])*;
66
- blank = [\t\v\f\r ];
67
-
68
- tag_open = '{{' [!\#]?;
69
- tag_close = '}}';
70
- template = [^{]+ | '{';
71
-
72
- template_comment_close = '#}}';
73
- template_comment_body = [^\#]+ | '#';
74
-
75
-
76
- expression := |*
77
- tag_close => { emit_tag; fret; };
78
- operator => { emit_operator };
79
- numeric => { emit_numeric };
80
- identifer => { emit_identifer };
81
- sstring => { emit_sstring };
82
- dstring => { emit_dstring };
83
- regexp => { emit_regexp };
84
- comment => { emit_comment };
85
- blank;
86
- *|;
87
-
88
- template_comment := |*
89
- template_comment_close => { emit_comment; fret; };
90
- template_comment_body => { emit_comment };
91
- *|;
92
-
93
- main := |*
94
- tag_open => { emit_tag_or_comment ->{ fcall expression; }, ->{ fcall template_comment; } };
95
- template => { emit_template };
96
- *|;
97
- }%%
98
- #%
99
-
100
- module Hotcell
101
- class Lexer
102
- OPERATIONS = {
103
- '+' => :PLUS, '-' => :MINUS, '*' => :MULTIPLY, '**' => :POWER, '/' => :DIVIDE, '%' => :MODULO,
104
-
105
- '&&' => :AND, '||' => :OR, '!' => :NOT, '==' => :EQUAL, '!=' => :INEQUAL,
106
- '>' => :GT, '>=' => :GTE, '<' => :LT, '<=' => :LTE,
107
-
108
- '=' => :ASSIGN, ',' => :COMMA, '.' => :PERIOD, ':' => :COLON, '?' => :QUESTION,
109
- ';' => :SEMICOLON
110
- }
111
-
112
- BOPEN = { '[' => :AOPEN, '{' => :HOPEN, '(' => :POPEN }
113
- BCLOSE = { ']' => :ACLOSE, '}' => :HCLOSE, ')' => :PCLOSE }
114
- BRACKETS = BOPEN.merge(BCLOSE)
115
-
116
- OPERATORS = OPERATIONS.merge(BRACKETS).merge("\n" => :NEWLINE)
117
-
118
- CONSTANTS = {
119
- 'nil' => [:NIL, nil], 'null' => [:NIL, nil],
120
- 'false' => [:FALSE, false], 'true' => [:TRUE, true]
121
- }
122
-
123
- SSTRING_ESCAPE_REGEXP = /\\\'|\\\\/
124
- SSTRING_ESCAPE_MAP = { "\\'" => "'", "\\\\" => "\\" }
125
-
126
- DSTRING_ESCAPE_REGEXP = /\\./
127
- DSTRING_ESCAPE_MAP = {
128
- '\\"' => '"', "\\\\" => "\\", '\n' => "\n",
129
- '\s' => "\s", '\r' => "\r", '\t' => "\t"
130
- }
131
-
132
- TAGS = {
133
- '{{' => :TOPEN, '{{!' => :TOPEN,
134
- '}}' => :TCLOSE
135
- }
136
-
137
- PREREGEXP = Set.new [
138
- :TOPEN, :NEWLINE, :SEMICOLON,
139
- :COLON, :COMMA, :PERIOD,
140
- :POPEN, :AOPEN, :HOPEN
141
- ]
142
-
143
- def initialize source
144
- @source = source
145
- @data = @source.unpack 'c*'
146
-
147
- %% write data;
148
- #%
149
- end
150
-
151
- def emit symbol, value
152
- @token_array << [symbol, value]
153
- end
154
-
155
- def current_value
156
- @data[@ts...@te].pack('c*').force_encoding('UTF-8')
157
- end
158
-
159
- def emit_operator
160
- value = current_value
161
- emit OPERATORS[value], value
162
- end
163
-
164
- def emit_numeric
165
- # last = @token_array[-1]
166
- # pre_last = @token_array[-2]
167
- # # This need to give unary minus with numeric higher precedence then unari minus with
168
- # last[0] = :NEGATIVE if last && last[0] == :MINUS &&
169
- # (!pre_last || pre_last[0].in?())
170
-
171
- value = current_value
172
- if value =~ /\./
173
- emit :FLOAT, Float(value)
174
- else
175
- emit :INTEGER, Integer(value)
176
- end
177
- end
178
-
179
- def emit_identifer
180
- value = current_value
181
- if args = CONSTANTS[value]
182
- emit *args
183
- else
184
- emit :IDENTIFER, value
185
- end
186
- end
187
-
188
- def emit_sstring
189
- emit :STRING, current_value[1..-2].gsub(SSTRING_ESCAPE_REGEXP) { |match|
190
- SSTRING_ESCAPE_MAP[match] }.force_encoding('UTF-8')
191
- end
192
-
193
- def emit_dstring
194
- emit :STRING, current_value[1..-2].gsub(DSTRING_ESCAPE_REGEXP) { |match|
195
- DSTRING_ESCAPE_MAP[match] || match[1] }
196
- end
197
-
198
- def regexp_ambiguity
199
- unless regexp_possible?
200
- emit_operator
201
- yield
202
- end
203
- end
204
-
205
- def regexp_possible?
206
- last = @token_array[-1]
207
- # Need more rules!
208
- !last || PREREGEXP.include?(last[0])
209
- end
210
-
211
- def emit_regexp
212
- value = current_value
213
- finish = value.rindex('/')
214
-
215
- options_string = value[finish+1..-1]
216
- options = 0
217
- options |= Regexp::EXTENDED if options_string.include?('x')
218
- options |= Regexp::IGNORECASE if options_string.include?('i')
219
- options |= Regexp::MULTILINE if options_string.include?('m')
220
-
221
- emit :REGEXP, Regexp.new(value[1..finish-1], options)
222
- end
223
-
224
- def emit_template
225
- # Hack this to glue templates going straight
226
- last = @token_array[-1]
227
- if last && last[0] == :TEMPLATE
228
- last[1] += current_value
229
- else
230
- emit :TEMPLATE, current_value
231
- end
232
- end
233
-
234
- def emit_tag_or_comment if_tag, if_comment
235
- value = current_value
236
- if value == '{{#'
237
- emit_comment
238
- if_comment.call
239
- else
240
- emit_tag
241
- if_tag.call
242
- end
243
- end
244
-
245
- def emit_tag
246
- value = current_value
247
- emit TAGS[value], value
248
- end
249
-
250
- def emit_comment
251
- last = @token_array[-1]
252
- if last && last[0] == :COMMENT
253
- last[1] += current_value
254
- else
255
- emit :COMMENT, current_value
256
- end
257
- end
258
-
259
- def current_position
260
- parsed = @data[0..@ts].pack('c*').force_encoding('UTF-8')
261
- line = parsed.count("\n") + 1
262
- column = parsed.size - 1 - (parsed.rindex("\n") || -1)
263
- [line, column]
264
- end
265
-
266
- def raise_unexpected_symbol
267
- raise Hotcell::Errors::UnexpectedSymbol.new *current_position
268
- end
269
-
270
- def raise_unterminated_string
271
- raise Hotcell::Errors::UnterminatedString.new *current_position
272
- end
273
-
274
- def raise_unterminated_regexp
275
- raise Hotcell::Errors::UnterminatedRegexp.new *current_position
276
- end
277
-
278
- def tokens
279
- @tokens ||= tokenize
280
- end
281
-
282
- def tokenize
283
- @token_array = []
284
-
285
- %% write init;
286
- #%
287
-
288
- eof = pe
289
- stack = []
290
-
291
- %% write exec;
292
- #%
293
-
294
- raise_unexpected_symbol unless @ts.nil?
295
-
296
- @token_array
297
- end
298
- end
299
- end