From 75a4f0d9317709e00f5c84b6b9d8cc4241f26d84 Mon Sep 17 00:00:00 2001 From: kpdecker Date: Fri, 15 Feb 2013 20:22:11 -0600 Subject: [PATCH] Negative number literal support Fixes #422 --- dist/handlebars.js | 2 +- spec/qunit_spec.js | 10 ++++++++++ spec/tokenizer_spec.rb | 4 ++++ src/handlebars.l | 2 +- 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/dist/handlebars.js b/dist/handlebars.js index 26d920778..8f3433af7 100644 --- a/dist/handlebars.js +++ b/dist/handlebars.js @@ -635,7 +635,7 @@ case 32: return 5; break; } }; -lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|$)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\{\{>)/,/^(?:\{\{#)/,/^(?:\{\{\/)/,/^(?:\{\{\^)/,/^(?:\{\{\s*else\b)/,/^(?:\{\{\{)/,/^(?:\{\{&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{)/,/^(?:=)/,/^(?:\.(?=[} ]))/,/^(?:\.\.)/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}\}\})/,/^(?:\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@[a-zA-Z]+)/,/^(?:true(?=[}\s]))/,/^(?:false(?=[}\s]))/,/^(?:[0-9]+(?=[}\s]))/,/^(?:[a-zA-Z0-9_$-]+(?=[=}\s\/.]))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:\s+)/,/^(?:[a-zA-Z0-9_$-/]+)/,/^(?:$)/]; +lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|$)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\{\{>)/,/^(?:\{\{#)/,/^(?:\{\{\/)/,/^(?:\{\{\^)/,/^(?:\{\{\s*else\b)/,/^(?:\{\{\{)/,/^(?:\{\{&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{)/,/^(?:=)/,/^(?:\.(?=[} ]))/,/^(?:\.\.)/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}\}\})/,/^(?:\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@[a-zA-Z]+)/,/^(?:true(?=[}\s]))/,/^(?:false(?=[}\s]))/,/^(?:-?[0-9]+(?=[}\s]))/,/^(?:[a-zA-Z0-9_$-]+(?=[=}\s\/.]))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:\s+)/,/^(?:[a-zA-Z0-9_$-/]+)/,/^(?:$)/]; lexer.conditions = {"mu":{"rules":[4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,32],"inclusive":false},"emu":{"rules":[2],"inclusive":false},"com":{"rules":[3],"inclusive":false},"par":{"rules":[30,31],"inclusive":false},"INITIAL":{"rules":[0,1,32],"inclusive":true}}; return lexer;})() parser.lexer = lexer; diff --git a/spec/qunit_spec.js b/spec/qunit_spec.js index fa15c3c05..5953bcacf 100644 --- a/spec/qunit_spec.js +++ b/spec/qunit_spec.js @@ -571,6 +571,16 @@ test("simple literals work", function() { }}; shouldCompileTo(string, [hash, helpers], "Message: Hello world 12 times: true false", "template with a simple String literal"); }); +test("negative number literals work", function() { + var string = 'Message: {{hello -12}}'; + var hash = {}; + var helpers = {hello: function(times) { + if(typeof times !== 'number') { times = "NaN"; } + return "Hello " + times + " times"; + }}; + shouldCompileTo(string, [hash, helpers], "Message: Hello -12 times", "template with a negative integer literal"); +}); + test("using a quote in the middle of a parameter raises an error", function() { shouldThrow(function() { diff --git a/spec/tokenizer_spec.rb b/spec/tokenizer_spec.rb index cb7f6eb09..9e189280a 100644 --- a/spec/tokenizer_spec.rb +++ b/spec/tokenizer_spec.rb @@ -235,6 +235,10 @@ def tokenize(string) result = tokenize(%|{{ foo 1 }}|) result.should match_tokens(%w(OPEN ID INTEGER CLOSE)) result[2].should be_token("INTEGER", "1") + + result = tokenize(%|{{ foo -1 }}|) + result.should match_tokens(%w(OPEN ID INTEGER CLOSE)) + result[2].should be_token("INTEGER", "-1") end it "tokenizes booleans" do diff --git a/src/handlebars.l b/src/handlebars.l index 04c7c4c2b..b32e39c64 100644 --- a/src/handlebars.l +++ b/src/handlebars.l @@ -42,7 +42,7 @@ "@"[a-zA-Z]+ { yytext = yytext.substr(1); return 'DATA'; } "true"/[}\s] { return 'BOOLEAN'; } "false"/[}\s] { return 'BOOLEAN'; } -[0-9]+/[}\s] { return 'INTEGER'; } +\-?[0-9]+/[}\s] { return 'INTEGER'; } [a-zA-Z0-9_$-]+/[=}\s\/.] { return 'ID'; } '['[^\]]*']' { yytext = yytext.substr(1, yyleng-2); return 'ID'; } . { return 'INVALID'; }