Skip to content

Commit 6c1d412

Browse files
authored
Merge pull request #961 from glayzzle/support-php81-explicit-octals
Implement parsing of PHP 8.1's explicit octals
2 parents 6881ec8 + dce61de commit 6c1d412

File tree

4 files changed

+88
-1
lines changed

4 files changed

+88
-1
lines changed

src/lexer/numbers.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,13 @@ module.exports = {
3535
} else {
3636
this.unput(ch ? 2 : 1);
3737
}
38-
// @fixme check octal notation ? not usefull
38+
} else if (ch === "o" || ch === "O") {
39+
ch = this.input();
40+
if (ch !== "_" && this.is_OCTAL()) {
41+
return this.consume_ONUM();
42+
} else {
43+
this.unput(ch ? 2 : 1);
44+
}
3945
} else if (!this.is_NUM()) {
4046
if (ch) this.unput(1);
4147
}
@@ -151,4 +157,15 @@ module.exports = {
151157
}
152158
return this.tok.T_LNUMBER;
153159
},
160+
// read an octal number
161+
consume_ONUM: function () {
162+
while (this.offset < this.size) {
163+
const ch = this.input();
164+
if (!this.is_OCTAL()) {
165+
if (ch) this.unput(1);
166+
break;
167+
}
168+
}
169+
return this.tok.T_LNUMBER;
170+
},
154171
};

src/lexer/utils.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,4 +99,14 @@ module.exports = {
9999
// else
100100
return false;
101101
},
102+
// check if current char can be an octal number
103+
is_OCTAL: function () {
104+
const ch = this._input.charCodeAt(this.offset - 1);
105+
// 0 - 7
106+
if (ch > 47 && ch < 56) return true;
107+
// _ (code 95)
108+
if (ch === 95) return true;
109+
// else
110+
return false;
111+
},
102112
};

test/snapshot/__snapshots__/scalar.test.js.snap

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,63 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3+
exports[`Test scalar statements implicit octal 1`] = `
4+
Program {
5+
"children": Array [
6+
ExpressionStatement {
7+
"expression": Assign {
8+
"kind": "assign",
9+
"left": Variable {
10+
"curly": false,
11+
"kind": "variable",
12+
"name": "var",
13+
},
14+
"operator": "=",
15+
"right": Number {
16+
"kind": "number",
17+
"value": "0123",
18+
},
19+
},
20+
"kind": "expressionstatement",
21+
},
22+
],
23+
"errors": Array [],
24+
"kind": "program",
25+
}
26+
`;
27+
28+
exports[`Test scalar statements php 8.1 explicit octal 1`] = `
29+
Program {
30+
"children": Array [
31+
ExpressionStatement {
32+
"expression": Assign {
33+
"kind": "assign",
34+
"left": Variable {
35+
"curly": false,
36+
"kind": "variable",
37+
"name": "var",
38+
},
39+
"operator": "=",
40+
"right": Bin {
41+
"kind": "bin",
42+
"left": Number {
43+
"kind": "number",
44+
"value": "0o123",
45+
},
46+
"right": Number {
47+
"kind": "number",
48+
"value": "0o001_234",
49+
},
50+
"type": "+",
51+
},
52+
},
53+
"kind": "expressionstatement",
54+
},
55+
],
56+
"errors": Array [],
57+
"kind": "program",
58+
}
59+
`;
60+
361
exports[`Test scalar statements test constants #2 1`] = `
462
Program {
563
"children": Array [

test/snapshot/scalar.test.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ describe("Test scalar statements", function () {
1717
["test dereferencable_scalar", "$var = array(1);"],
1818
["test dereferencable_scalar #2", "$var = [1];"],
1919
["test dereferencable_scalar #3", '$var = "test";'],
20+
["php 8.1 explicit octal", "$var = 0o123 + 0o001_234;"],
21+
["implicit octal", "$var = 0123;"],
2022
])("%s", function (_, code) {
2123
expect(parser.parseEval(code)).toMatchSnapshot();
2224
});

0 commit comments

Comments
 (0)