Skip to content

Commit 152764a

Browse files
authored
Merge pull request #61 from motiz88/master
Improvements on AST nodes
2 parents 49a7081 + b84b990 commit 152764a

File tree

11 files changed

+363
-412
lines changed

11 files changed

+363
-412
lines changed

dist/php-parser.js

Lines changed: 173 additions & 201 deletions
Large diffs are not rendered by default.

dist/php-parser.min.js

Lines changed: 72 additions & 72 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/php-parser.min.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/AST.md

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,10 @@
2828
- [StaticLookup](#staticlookup)
2929
- [OffsetLookup](#offsetlookup)
3030
- [Operation](#operation)
31-
- [Coalesce](#coalesce)
3231
- [Pre](#pre)
3332
- [Post](#post)
3433
- [Bin](#bin)
3534
- [Parenthesis](#parenthesis)
36-
- [Bool](#Bool)
3735
- [Unary](#unary)
3836
- [Cast](#cast)
3937
- [Literal](#literal)
@@ -207,18 +205,6 @@ A block statement, i.e., a sequence of statements surrounded by braces.
207205

208206
- `children` **[Array](#array)<[Node](#node)>**
209207

210-
# Bool
211-
212-
**Extends Operation**
213-
214-
Boolean operations
215-
216-
**Properties**
217-
218-
- `type` **[String](#string)**
219-
- `left` **[Expression](#expression)**
220-
- `right` **[Expression](#expression)**
221-
222208
# Boolean
223209

224210
**Extends Literal**
@@ -341,18 +327,6 @@ Defines a closure
341327
- `nullable` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
342328
- `body` **([Block](#block) | null)**
343329

344-
# Coalesce
345-
346-
**Extends Operation**
347-
348-
Verify is the test property is defined and is not null, and returns
349-
is, otherwise returns the ifnull expression.
350-
351-
**Properties**
352-
353-
- `test` **[Expression](#expression)** The expression to be testes
354-
- `ifnull` **[Expression](#expression)** The returned expression if test is null
355-
356330
# Constant
357331

358332
**Extends Declaration**

src/ast.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,10 @@ var Position = require('./ast/position');
3434
* - [StaticLookup](#staticlookup)
3535
* - [OffsetLookup](#offsetlookup)
3636
* - [Operation](#operation)
37-
* - [Coalesce](#coalesce)
3837
* - [Pre](#pre)
3938
* - [Post](#post)
4039
* - [Bin](#bin)
4140
* - [Parenthesis](#parenthesis)
42-
* - [Bool](#Bool)
4341
* - [Unary](#unary)
4442
* - [Cast](#cast)
4543
* - [Literal](#literal)
@@ -184,7 +182,6 @@ AST.prototype.prepare = function(kind, parser) {
184182
require('./ast/assign'),
185183
require('./ast/bin'),
186184
require('./ast/block'),
187-
require('./ast/bool'),
188185
require('./ast/boolean'),
189186
require('./ast/break'),
190187
require('./ast/call'),
@@ -195,7 +192,6 @@ AST.prototype.prepare = function(kind, parser) {
195192
require('./ast/classconstant'),
196193
require('./ast/clone'),
197194
require('./ast/closure'),
198-
require('./ast/coalesce'),
199195
require('./ast/constant'),
200196
require('./ast/constref'),
201197
require('./ast/continue'),

src/ast/bin.js

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,44 @@
88
var Operation = require('./operation');
99
var KIND = 'bin';
1010

11+
// operators in ascending order of precedence
12+
var binOperatorsPrecedence = [
13+
['or'],
14+
['xor'],
15+
['and'],
16+
// TODO: assignment
17+
// TODO: ternary ? :
18+
['??'],
19+
['||'],
20+
['&&'],
21+
['|'],
22+
['^'],
23+
['&'],
24+
['==', '!=', '===', '!==', /* '<>', */ '<=>'],
25+
['<', '<=', '>', '>='],
26+
['<<', '>>'],
27+
['+', '-', '.'],
28+
['*', '/', '%'],
29+
// TODO: unary !
30+
['instanceof'],
31+
// TODO: unary ++, --, ~, @, typecasts
32+
// TODO: [ (array)
33+
// TODO: clone, new
34+
];
35+
1136
// define nodes shifting
12-
var precedence = {
13-
'+': 1,
14-
'-': 1,
15-
'.': 1,
16-
'*': 2,
17-
'/': 2,
18-
'%': 2
19-
};
37+
var precedence = {};
38+
binOperatorsPrecedence.forEach(function (list, index) {
39+
list.forEach(function (operator) {
40+
precedence[operator] = index + 1;
41+
});
42+
});
2043

44+
/*
45+
x OP1 (y OP2 z)
46+
z OP1 (x OP2 y)
47+
z OP2 (x OP1 y)
48+
*/
2149
/**
2250
* Binary operations
2351
* @constructor Bin
@@ -40,6 +68,9 @@ var Bin = Operation.extends(function Bin(type, left, right, location) {
4068
buffer = right.type;
4169
right.type = type;
4270
type = buffer;
71+
buffer = left;
72+
left = right;
73+
right = buffer;
4374
}
4475
}
4576
this.type = type;

src/ast/bool.js

Lines changed: 0 additions & 26 deletions
This file was deleted.

src/ast/coalesce.js

Lines changed: 0 additions & 25 deletions
This file was deleted.

src/parser/expr.js

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -35,42 +35,42 @@ module.exports = {
3535
return result('bin', '<<', expr, this.next().read_expr());
3636
if (this.token === this.tok.T_SR)
3737
return result('bin', '>>', expr, this.next().read_expr());
38-
// boolean operations
38+
// more binary operations (formerly bool)
3939
if (this.token === this.tok.T_BOOLEAN_OR)
40-
return result('bool', '|', expr, this.next().read_expr());
40+
return result('bin', '||', expr, this.next().read_expr());
4141
if (this.token === this.tok.T_LOGICAL_OR)
42-
return result('bool', '|', expr, this.next().read_expr());
42+
return result('bin', 'or', expr, this.next().read_expr());
4343
if (this.token === this.tok.T_BOOLEAN_AND)
44-
return result('bool', '&', expr, this.next().read_expr());
44+
return result('bin', '&&', expr, this.next().read_expr());
4545
if (this.token === this.tok.T_LOGICAL_AND)
46-
return result('bool', '&', expr, this.next().read_expr());
46+
return result('bin', 'and', expr, this.next().read_expr());
4747
if (this.token === this.tok.T_LOGICAL_XOR)
48-
return result('bool', '^', expr, this.next().read_expr());
48+
return result('bin', 'xor', expr, this.next().read_expr());
4949
if (this.token === this.tok.T_IS_IDENTICAL)
50-
return result('bool', '=', expr, this.next().read_expr());
50+
return result('bin', '===', expr, this.next().read_expr());
5151
if (this.token === this.tok.T_IS_NOT_IDENTICAL)
52-
return result('bool', '!=', expr, this.next().read_expr());
52+
return result('bin', '!==', expr, this.next().read_expr());
5353
if (this.token === this.tok.T_IS_EQUAL)
54-
return result('bool', '~', expr, this.next().read_expr());
54+
return result('bin', '==', expr, this.next().read_expr());
5555
if (this.token === this.tok.T_IS_NOT_EQUAL)
56-
return result('bool', '!~', expr, this.next().read_expr());
56+
return result('bin', '!=', expr, this.next().read_expr());
5757
if (this.token === '<')
58-
return result('bool', '<', expr, this.next().read_expr());
58+
return result('bin', '<', expr, this.next().read_expr());
5959
if (this.token === '>')
60-
return result('bool', '!~', expr, this.next().read_expr());
60+
return result('bin', '>', expr, this.next().read_expr());
6161
if (this.token === this.tok.T_IS_SMALLER_OR_EQUAL)
62-
return result('bool', '<=', expr, this.next().read_expr());
62+
return result('bin', '<=', expr, this.next().read_expr());
6363
if (this.token === this.tok.T_IS_GREATER_OR_EQUAL)
64-
return result('bool', '=>', expr, this.next().read_expr());
64+
return result('bin', '>=', expr, this.next().read_expr());
6565
if (this.token === this.tok.T_SPACESHIP)
66-
return result('bool', '<=>', expr, this.next().read_expr());
66+
return result('bin', '<=>', expr, this.next().read_expr());
6767
if (this.token === this.tok.T_INSTANCEOF)
68-
return result('bool', '?', expr, this.next().read_expr());
68+
return result('bin', 'instanceof', expr, this.next().read_expr());
6969

7070
// extra operations :
7171
// $username = $_GET['user'] ?? 'nobody';
7272
if (this.token === this.tok.T_COALESCE)
73-
return result('coalesce', expr, this.next().read_expr());
73+
return result('bin', '??', expr, this.next().read_expr());
7474

7575
// extra operations :
7676
// $username = $_GET['user'] ? true : false;

test/astTests.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,12 @@ describe('Test AST structure', function() {
100100
ast.children[0].status.value.should.be.exactly('-1');
101101
});
102102

103-
it('test coalesce', function() {
103+
it('test coalesce operator', function() {
104104
var ast = parser.parseEval('$var = $a ?? true;');
105-
ast.children[0].right.kind.should.be.exactly('coalesce');
106-
ast.children[0].right.test.kind.should.be.exactly('variable');
107-
ast.children[0].right.ifnull.kind.should.be.exactly('boolean');
105+
ast.children[0].right.kind.should.be.exactly('bin');
106+
ast.children[0].right.type.should.be.exactly('??');
107+
ast.children[0].right.left.kind.should.be.exactly('variable');
108+
ast.children[0].right.right.kind.should.be.exactly('boolean');
108109
});
109110

110111
it('test include / require', function() {

0 commit comments

Comments
 (0)