summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkpdecker <kpdecker@gmail.com>2014-01-17 20:42:02 -0600
committerkpdecker <kpdecker@gmail.com>2014-01-17 20:42:02 -0600
commitd4cfe90959c5a585e5d87e31038eb2f0432f87a5 (patch)
tree6a7699604f3165f7e089c899ca6b34d1f3a7def2
parent051618c024333404746795304f5858f3ef56a215 (diff)
downloadhandlebars.js-d4cfe90959c5a585e5d87e31038eb2f0432f87a5.zip
handlebars.js-d4cfe90959c5a585e5d87e31038eb2f0432f87a5.tar.gz
handlebars.js-d4cfe90959c5a585e5d87e31038eb2f0432f87a5.tar.bz2
Allow decimal number values
Fixes #472
-rw-r--r--lib/handlebars/compiler/ast.js8
-rw-r--r--lib/handlebars/compiler/compiler.js4
-rw-r--r--lib/handlebars/compiler/printer.js4
-rw-r--r--spec/ast.js4
-rw-r--r--spec/helpers.js11
-rw-r--r--spec/parser.js8
-rw-r--r--spec/tokenizer.js20
-rw-r--r--src/handlebars.l2
-rw-r--r--src/handlebars.yy4
9 files changed, 42 insertions, 23 deletions
diff --git a/lib/handlebars/compiler/ast.js b/lib/handlebars/compiler/ast.js
index 5538f40..8fa6495 100644
--- a/lib/handlebars/compiler/ast.js
+++ b/lib/handlebars/compiler/ast.js
@@ -201,12 +201,12 @@ var AST = {
this.stringModeValue = string;
},
- IntegerNode: function(integer, locInfo) {
+ NumberNode: function(number, locInfo) {
LocationInfo.call(this, locInfo);
- this.type = "INTEGER";
+ this.type = "NUMBER";
this.original =
- this.integer = integer;
- this.stringModeValue = Number(integer);
+ this.number = number;
+ this.stringModeValue = Number(number);
},
BooleanNode: function(bool, locInfo) {
diff --git a/lib/handlebars/compiler/compiler.js b/lib/handlebars/compiler/compiler.js
index b92289a..83eca24 100644
--- a/lib/handlebars/compiler/compiler.js
+++ b/lib/handlebars/compiler/compiler.js
@@ -321,8 +321,8 @@ Compiler.prototype = {
this.opcode('pushString', string.string);
},
- INTEGER: function(integer) {
- this.opcode('pushLiteral', integer.integer);
+ NUMBER: function(number) {
+ this.opcode('pushLiteral', number.number);
},
BOOLEAN: function(bool) {
diff --git a/lib/handlebars/compiler/printer.js b/lib/handlebars/compiler/printer.js
index b7b760f..be66d73 100644
--- a/lib/handlebars/compiler/printer.js
+++ b/lib/handlebars/compiler/printer.js
@@ -108,8 +108,8 @@ PrintVisitor.prototype.STRING = function(string) {
return '"' + string.string + '"';
};
-PrintVisitor.prototype.INTEGER = function(integer) {
- return "INTEGER{" + integer.integer + "}";
+PrintVisitor.prototype.NUMBER = function(number) {
+ return "NUMBER{" + number.number + "}";
};
PrintVisitor.prototype.BOOLEAN = function(bool) {
diff --git a/spec/ast.js b/spec/ast.js
index 430574e..17a982c 100644
--- a/spec/ast.js
+++ b/spec/ast.js
@@ -150,10 +150,10 @@ describe('ast', function() {
});
});
- describe("IntegerNode", function(){
+ describe("NumberNode", function(){
it('stores location info', function(){
- var integer = new handlebarsEnv.AST.IntegerNode("6", LOCATION_INFO);
+ var integer = new handlebarsEnv.AST.NumberNode("6", LOCATION_INFO);
testLocationInfoStorage(integer);
});
});
diff --git a/spec/helpers.js b/spec/helpers.js
index 180fc98..904f56a 100644
--- a/spec/helpers.js
+++ b/spec/helpers.js
@@ -188,6 +188,17 @@ describe('helpers', function() {
"found it! Goodbye cruel world!!");
});
+ it("decimal number literals work", function() {
+ var string = 'Message: {{hello -1.2 1.2}}';
+ var hash = {};
+ var helpers = {hello: function(times, times2) {
+ if(typeof times !== 'number') { times = "NaN"; }
+ if(typeof times2 !== 'number') { times2 = "NaN"; }
+ return "Hello " + times + " " + times2 + " times";
+ }};
+ shouldCompileTo(string, [hash, helpers], "Message: Hello -1.2 1.2 times", "template with a negative integer literal");
+ });
+
it("negative number literals work", function() {
var string = 'Message: {{hello -12}}';
var hash = {};
diff --git a/spec/parser.js b/spec/parser.js
index 0f6ed31..5b6dc8a 100644
--- a/spec/parser.js
+++ b/spec/parser.js
@@ -41,8 +41,8 @@ describe('parser', function() {
equals(ast_for("{{foo bar \"baz\" }}"), '{{ ID:foo [ID:bar, "baz"] }}\n');
});
- it('parses mustaches with INTEGER parameters', function() {
- equals(ast_for("{{foo 1}}"), "{{ ID:foo [INTEGER{1}] }}\n");
+ it('parses mustaches with NUMBER parameters', function() {
+ equals(ast_for("{{foo 1}}"), "{{ ID:foo [NUMBER{1}] }}\n");
});
it('parses mustaches with BOOLEAN parameters', function() {
@@ -56,7 +56,7 @@ describe('parser', function() {
it('parses mustaches with hash arguments', function() {
equals(ast_for("{{foo bar=baz}}"), "{{ ID:foo [] HASH{bar=ID:baz} }}\n");
- equals(ast_for("{{foo bar=1}}"), "{{ ID:foo [] HASH{bar=INTEGER{1}} }}\n");
+ equals(ast_for("{{foo bar=1}}"), "{{ ID:foo [] HASH{bar=NUMBER{1}} }}\n");
equals(ast_for("{{foo bar=true}}"), "{{ ID:foo [] HASH{bar=BOOLEAN{true}} }}\n");
equals(ast_for("{{foo bar=false}}"), "{{ ID:foo [] HASH{bar=BOOLEAN{false}} }}\n");
equals(ast_for("{{foo bar=@baz}}"), "{{ ID:foo [] HASH{bar=@ID:baz} }}\n");
@@ -67,7 +67,7 @@ describe('parser', function() {
equals(ast_for("{{foo bat='bam'}}"), '{{ ID:foo [] HASH{bat="bam"} }}\n');
equals(ast_for("{{foo omg bar=baz bat=\"bam\"}}"), '{{ ID:foo [ID:omg] HASH{bar=ID:baz, bat="bam"} }}\n');
- equals(ast_for("{{foo omg bar=baz bat=\"bam\" baz=1}}"), '{{ ID:foo [ID:omg] HASH{bar=ID:baz, bat="bam", baz=INTEGER{1}} }}\n');
+ equals(ast_for("{{foo omg bar=baz bat=\"bam\" baz=1}}"), '{{ ID:foo [ID:omg] HASH{bar=ID:baz, bat="bam", baz=NUMBER{1}} }}\n');
equals(ast_for("{{foo omg bar=baz bat=\"bam\" baz=true}}"), '{{ ID:foo [ID:omg] HASH{bar=ID:baz, bat="bam", baz=BOOLEAN{true}} }}\n');
equals(ast_for("{{foo omg bar=baz bat=\"bam\" baz=false}}"), '{{ ID:foo [ID:omg] HASH{bar=ID:baz, bat="bam", baz=BOOLEAN{false}} }}\n');
});
diff --git a/spec/tokenizer.js b/spec/tokenizer.js
index 841a5ab..36a632b 100644
--- a/spec/tokenizer.js
+++ b/spec/tokenizer.js
@@ -295,12 +295,20 @@ describe('Tokenizer', function() {
it('tokenizes numbers', function() {
var result = tokenize('{{ foo 1 }}');
- shouldMatchTokens(result, ['OPEN', 'ID', 'INTEGER', 'CLOSE']);
- shouldBeToken(result[2], "INTEGER", "1");
+ shouldMatchTokens(result, ['OPEN', 'ID', 'NUMBER', 'CLOSE']);
+ shouldBeToken(result[2], "NUMBER", "1");
+
+ result = tokenize('{{ foo 1.1 }}');
+ shouldMatchTokens(result, ['OPEN', 'ID', 'NUMBER', 'CLOSE']);
+ shouldBeToken(result[2], "NUMBER", "1.1");
result = tokenize('{{ foo -1 }}');
- shouldMatchTokens(result, ['OPEN', 'ID', 'INTEGER', 'CLOSE']);
- shouldBeToken(result[2], "INTEGER", "-1");
+ shouldMatchTokens(result, ['OPEN', 'ID', 'NUMBER', 'CLOSE']);
+ shouldBeToken(result[2], "NUMBER", "-1");
+
+ result = tokenize('{{ foo -1.1 }}');
+ shouldMatchTokens(result, ['OPEN', 'ID', 'NUMBER', 'CLOSE']);
+ shouldBeToken(result[2], "NUMBER", "-1.1");
});
it('tokenizes booleans', function() {
@@ -321,7 +329,7 @@ describe('Tokenizer', function() {
shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'ID', 'EQUALS', 'ID', 'CLOSE']);
result = tokenize("{{ foo bar baz=1 }}");
- shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'ID', 'EQUALS', 'INTEGER', 'CLOSE']);
+ shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'ID', 'EQUALS', 'NUMBER', 'CLOSE']);
result = tokenize("{{ foo bar baz=true }}");
shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'ID', 'EQUALS', 'BOOLEAN', 'CLOSE']);
@@ -389,6 +397,6 @@ describe('Tokenizer', function() {
it('tokenizes nested subexpressions: literals', function() {
var result = tokenize("{{foo (bar (lol true) false) (baz 1) (blah 'b') (blorg \"c\")}}");
- shouldMatchTokens(result, ['OPEN', 'ID', 'OPEN_SEXPR', 'ID', 'OPEN_SEXPR', 'ID', 'BOOLEAN', 'CLOSE_SEXPR', 'BOOLEAN', 'CLOSE_SEXPR', 'OPEN_SEXPR', 'ID', 'INTEGER', 'CLOSE_SEXPR', 'OPEN_SEXPR', 'ID', 'STRING', 'CLOSE_SEXPR', 'OPEN_SEXPR', 'ID', 'STRING', 'CLOSE_SEXPR', 'CLOSE']);
+ shouldMatchTokens(result, ['OPEN', 'ID', 'OPEN_SEXPR', 'ID', 'OPEN_SEXPR', 'ID', 'BOOLEAN', 'CLOSE_SEXPR', 'BOOLEAN', 'CLOSE_SEXPR', 'OPEN_SEXPR', 'ID', 'NUMBER', 'CLOSE_SEXPR', 'OPEN_SEXPR', 'ID', 'STRING', 'CLOSE_SEXPR', 'OPEN_SEXPR', 'ID', 'STRING', 'CLOSE_SEXPR', 'CLOSE']);
});
});
diff --git a/src/handlebars.l b/src/handlebars.l
index 996badb..630840e 100644
--- a/src/handlebars.l
+++ b/src/handlebars.l
@@ -77,7 +77,7 @@ ID [^\s!"#%-,\.\/;->@\[-\^`\{-~]+/{LOOKAHEAD}
<mu>"@" return 'DATA';
<mu>"true"/{LITERAL_LOOKAHEAD} return 'BOOLEAN';
<mu>"false"/{LITERAL_LOOKAHEAD} return 'BOOLEAN';
-<mu>\-?[0-9]+/{LITERAL_LOOKAHEAD} return 'INTEGER';
+<mu>\-?[0-9]+(?:\.[0-9]+)?/{LITERAL_LOOKAHEAD} return 'NUMBER';
<mu>{ID} return 'ID';
diff --git a/src/handlebars.yy b/src/handlebars.yy
index bac1cc9..40f68ce 100644
--- a/src/handlebars.yy
+++ b/src/handlebars.yy
@@ -79,7 +79,7 @@ sexpr
param
: path -> $1
| STRING -> new yy.StringNode($1, @$)
- | INTEGER -> new yy.IntegerNode($1, @$)
+ | NUMBER -> new yy.NumberNode($1, @$)
| BOOLEAN -> new yy.BooleanNode($1, @$)
| dataName -> $1
| OPEN_SEXPR sexpr CLOSE_SEXPR {$2.isHelper = true; $$ = $2;}
@@ -96,7 +96,7 @@ hashSegment
partialName
: path -> new yy.PartialNameNode($1, @$)
| STRING -> new yy.PartialNameNode(new yy.StringNode($1, @$), @$)
- | INTEGER -> new yy.PartialNameNode(new yy.IntegerNode($1, @$))
+ | NUMBER -> new yy.PartialNameNode(new yy.NumberNode($1, @$))
;
dataName