diff --git a/addons/web/static/lib/py.js/lib/py.js b/addons/web/static/lib/py.js/lib/py.js index 7ba8107937d..680051bb285 100644 --- a/addons/web/static/lib/py.js/lib/py.js +++ b/addons/web/static/lib/py.js/lib/py.js @@ -263,8 +263,12 @@ var py = {}; var DecNumber = '\\d+(L|l)?'; var IntNumber = DecNumber; - var PointFloat = group('\\d+\\.\\d*', '\\.\\d+'); - var FloatNumber = PointFloat; + + var Exponent = '[eE][+-]?\\d+'; + var PointFloat = group(`\\d+\\.\\d*(${Exponent})?`, `\\.\\d+(${Exponent})?`); + // Exponent not optional when no decimal point + var FloatNumber = group(PointFloat, `\\d+${Exponent}`); + var Number = group(FloatNumber, IntNumber); var Operator = group("\\*\\*=?", ">>=?", "<<=?", "<>", "!=", diff --git a/addons/web/static/src/core/py_js/py_tokenizer.js b/addons/web/static/src/core/py_js/py_tokenizer.js index e472ba2a32a..08e61c2ea8a 100644 --- a/addons/web/static/src/core/py_js/py_tokenizer.js +++ b/addons/web/static/src/core/py_js/py_tokenizer.js @@ -210,8 +210,12 @@ const Name = "[a-zA-Z_]\\w*"; const Whitespace = "[ \\f\\t]*"; const DecNumber = "\\d+(L|l)?"; const IntNumber = DecNumber; -const PointFloat = group("\\d+\\.\\d*", "\\.\\d+"); -const FloatNumber = PointFloat; + +const Exponent = "[eE][+-]?\\d+"; +const PointFloat = group(`\\d+\\.\\d*(${Exponent})?`, `\\.\\d+(${Exponent})?`); +// Exponent not optional when no decimal point +const FloatNumber = group(PointFloat, `\\d+${Exponent}`); + const Number = group(FloatNumber, IntNumber); const Operator = group("\\*\\*=?", ">>=?", "<<=?", "<>", "!=", "//=?", "[+\\-*/%&|^=<>]=?", "~"); const Bracket = "[\\[\\]\\(\\)\\{\\}]"; diff --git a/addons/web/static/tests/core/py_js/py_tokenizer_tests.js b/addons/web/static/tests/core/py_js/py_tokenizer_tests.js index 2a4a221eb8d..cdd053ba3f4 100644 --- a/addons/web/static/tests/core/py_js/py_tokenizer_tests.js +++ b/addons/web/static/tests/core/py_js/py_tokenizer_tests.js @@ -12,16 +12,51 @@ QUnit.module("py", {}, () => { }); QUnit.test("can tokenize numbers", (assert) => { + /* Without exponent */ assert.deepEqual(tokenize("1"), [{ type: 0 /* Number */, value: 1 }]); assert.deepEqual(tokenize("13"), [{ type: 0 /* Number */, value: 13 }]); - assert.deepEqual(tokenize("12.0"), [{ type: 0 /* Number */, value: 12 }]); - assert.deepEqual(tokenize("1.2"), [{ type: 0 /* Number */, value: 1.2 }]); - assert.deepEqual(tokenize("1.2"), [{ type: 0 /* Number */, value: 1.2 }]); - assert.deepEqual(tokenize(".42"), [{ type: 0 /* Number */, value: 0.42 }]); assert.deepEqual(tokenize("-1"), [ { type: 2 /* Symbol */, value: "-" }, { type: 0 /* Number */, value: 1 }, ]); + + /* With exponent */ + assert.deepEqual(tokenize("1e2"), [{ type: 0 /* Number */, value: 100 }]); + assert.deepEqual(tokenize("13E+02"), [{ type: 0 /* Number */, value: 1300 }]); + assert.deepEqual(tokenize("15E-2"), [{ type: 0 /* Number */, value: 0.15 }]); + assert.deepEqual(tokenize("-30e+002"), [ + { type: 2 /* Symbol */, value: "-" }, + { type: 0 /* Number */, value: 3000 }, + ]); + }); + + QUnit.test("can tokenize floats", (assert) => { + /* Without exponent */ + assert.deepEqual(tokenize("12.0"), [{ type: 0 /* Number */, value: 12 }]); + assert.deepEqual(tokenize("1.2"), [{ type: 0 /* Number */, value: 1.2 }]); + assert.deepEqual(tokenize(".42"), [{ type: 0 /* Number */, value: 0.42 }]); + assert.deepEqual(tokenize("12."), [{type: 0 /* Number */, value: 12}]); + assert.deepEqual(tokenize("-1.23"), [ + { type: 2 /* Symbol */, value: "-" }, + { type: 0 /* Number */, value: 1.23 }, + ]); + + /* With exponent */ + assert.deepEqual(tokenize("1234e-3"), [{type: 0 /* Number */, value: 1.234}]); + assert.deepEqual(tokenize("1.23E-03"), [{type: 0 /* Number */, value: 0.00123}]); + assert.deepEqual(tokenize('.23e-3'), [{type: 0 /* Number */, value: 0.00023}]); + assert.deepEqual(tokenize('23.e-03'), [{type: 0 /* Number */, value: 0.023}]); + + assert.deepEqual(tokenize("12.1E2"), [{type: 0 /* Number */, value: 1210}]); + assert.deepEqual(tokenize("1.23e+03"), [{type: 0 /* Number */, value: 1230}]); + assert.deepEqual(tokenize('.23e2'), [{type: 0 /* Number */, value: 23}]); + assert.deepEqual(tokenize('15.E+02'), [{type: 0 /* Number */, value: 1500}]); + + assert.deepEqual(tokenize("-23E02"), [ + {type: 2 /* Symbol */, value: "-"}, + {type: 0 /* Number */, value: 2300} + ]); + }); QUnit.test("can tokenize strings", (assert) => {