Skip to content

Commit daaf93e

Browse files
committed
add bin, cast & unary nodes
1 parent 4585ca4 commit daaf93e

File tree

8 files changed

+236
-70
lines changed

8 files changed

+236
-70
lines changed

docs/AST.md

Lines changed: 77 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2,44 +2,6 @@
22

33
# AST
44

5-
The AST builder class
6-
7-
**Parameters**
8-
9-
- `withPositions`
10-
- `withSource`
11-
12-
**Properties**
13-
14-
- `withPositions` **[Boolean](#boolean)** Should locate any node (by default false)
15-
- `withSource` **[Boolean](#boolean)** Should extract the node original code (by default false)
16-
17-
## position
18-
19-
Create a position node from specified parser
20-
including it's lexer current state
21-
22-
**Parameters**
23-
24-
- `Parser`
25-
- `parser`
26-
27-
Returns **[Position](#position)**
28-
29-
## prepare
30-
31-
Prepares an AST node
32-
33-
**Parameters**
34-
35-
- `kind` **([String](#string) | null)** Defines the node type
36-
(if null, the kind must be passed at the function call)
37-
- `parser` **Parser** The parser instance (use for extracting locations)
38-
39-
Returns **[Function](#function)**
40-
41-
# AST
42-
435
## Class hierarchy
446

457
- [Location](#location)
@@ -61,6 +23,9 @@ Returns **[Function](#function)**
6123
- [Operation](#operation)
6224
- [Coalesce](#coalesce)
6325
- [Post](#post)
26+
- [Bin](#bin)
27+
- [Unary](#unary)
28+
- [Cast](#cast)
6429
- [Literal](#literal)
6530
- [Boolean](#boolean)
6631
- [String](#string)
@@ -138,6 +103,44 @@ Prepares an AST node
138103

139104
Returns **[Function](#function)**
140105

106+
# AST
107+
108+
The AST builder class
109+
110+
**Parameters**
111+
112+
- `withPositions`
113+
- `withSource`
114+
115+
**Properties**
116+
117+
- `withPositions` **[Boolean](#boolean)** Should locate any node (by default false)
118+
- `withSource` **[Boolean](#boolean)** Should extract the node original code (by default false)
119+
120+
## position
121+
122+
Create a position node from specified parser
123+
including it's lexer current state
124+
125+
**Parameters**
126+
127+
- `Parser`
128+
- `parser`
129+
130+
Returns **[Position](#position)**
131+
132+
## prepare
133+
134+
Prepares an AST node
135+
136+
**Parameters**
137+
138+
- `kind` **([String](#string) | null)** Defines the node type
139+
(if null, the kind must be passed at the function call)
140+
- `parser` **Parser** The parser instance (use for extracting locations)
141+
142+
Returns **[Function](#function)**
143+
141144
# Array
142145

143146
**Extends Expression**
@@ -161,6 +164,18 @@ Assigns a value to the specified target
161164
- `right` **[Expression](#expression)**
162165
- `operator` **[String](#string)**
163166

167+
# Bin
168+
169+
**Extends Operation**
170+
171+
Binary operations
172+
173+
**Properties**
174+
175+
- `type` **[String](#string)**
176+
- `left` **[Expression](#expression)**
177+
- `right` **[Expression](#expression)**
178+
164179
# Block
165180

166181
**Extends Statement**
@@ -204,6 +219,17 @@ A switch case statement
204219
- `test` **([Expression](#expression) | null)** if null, means that the default case
205220
- `body` **([Block](#block) | null)**
206221

222+
# Cast
223+
224+
**Extends Operation**
225+
226+
Binary operations
227+
228+
**Properties**
229+
230+
- `type` **[String](#string)**
231+
- `what` **[Expression](#expression)**
232+
207233
# Try
208234

209235
**Extends Statement**
@@ -446,6 +472,7 @@ Defines a classic function
446472
- `arguments` **[Array](#array)<[Parameter](#parameter)>**
447473
- `type` **[Identifier](#identifier)**
448474
- `byref` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
475+
- `nullable` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
449476
- `body` **([Block](#block) | null)**
450477

451478
# Goto
@@ -663,6 +690,7 @@ Defines a function parameter
663690
- `value` **([Node](#node) | null)**
664691
- `byref` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
665692
- `variadic` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
693+
- `nullable` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
666694

667695
# Position
668696

@@ -822,6 +850,17 @@ Defines a trait usage
822850
- `traits` **[Array](#array)<[Identifier](#identifier)>**
823851
- `adaptations` **([Array](#array)<[Node](#node)> | null)**
824852

853+
# Unary
854+
855+
**Extends Operation**
856+
857+
Unary operations
858+
859+
**Properties**
860+
861+
- `type` **[String](#string)**
862+
- `what` **[Expression](#expression)**
863+
825864
# Unset
826865

827866
**Extends Sys**

docs/parser.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,8 @@ reads a list of parameters
345345

346346
# read_function_argument_list
347347

348+
Reads a list of arguments
349+
348350
```ebnf
349351
function_argument_list ::= '(' (argument_list (',' argument_list)*)? ')'
350352
```

src/ast.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ var Position = require('./ast/position');
2929
* - [Operation](#operation)
3030
* - [Coalesce](#coalesce)
3131
* - [Post](#post)
32+
* - [Bin](#bin)
33+
* - [Unary](#unary)
34+
* - [Cast](#cast)
3235
* - [Literal](#literal)
3336
* - [Boolean](#boolean)
3437
* - [String](#string)
@@ -158,11 +161,13 @@ AST.prototype.prepare = function(kind, parser) {
158161
[
159162
require('./ast/array'),
160163
require('./ast/assign'),
164+
require('./ast/bin'),
161165
require('./ast/block'),
162166
require('./ast/boolean'),
163167
require('./ast/break'),
164168
require('./ast/call'),
165169
require('./ast/case'),
170+
require('./ast/cast'),
166171
require('./ast/catch'),
167172
require('./ast/class'),
168173
require('./ast/classconstant'),
@@ -210,6 +215,7 @@ AST.prototype.prepare = function(kind, parser) {
210215
require('./ast/traitprecedence'),
211216
require('./ast/traituse'),
212217
require('./ast/try'),
218+
require('./ast/unary'),
213219
require('./ast/unset'),
214220
require('./ast/usegroup'),
215221
require('./ast/useitem'),

src/ast/traitalias.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ var TraitAlias = Node.extends(function TraitAlias(trait, method, as, flags, loca
3030
this.visibility = IS_PUBLIC;
3131
} else if (flags[0] === 1) {
3232
this.visibility = IS_PROTECTED;
33-
} else if (flags[0] === 2) {
33+
} else {
3434
this.visibility = IS_PRIVATE;
3535
}
3636
} else {

src/parser/expr.js

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,28 @@
33
* @authors https://github.com/glayzzle/php-parser/graphs/contributors
44
* @url http://glayzzle.com
55
*/
6+
"use strict";
67

78
module.exports = {
89

910
read_expr: function() {
11+
var result = this.node();
1012
var expr = this.read_expr_item();
13+
// binary operations
14+
if (this.token === '|') return result('bin', '|', expr, this.next().read_expr());
15+
if (this.token === '&') return result('bin', '&', expr, this.next().read_expr());
16+
if (this.token === '^') return result('bin', '^', expr, this.next().read_expr());
17+
if (this.token === '.') return result('bin', '.', expr, this.next().read_expr());
18+
if (this.token === '+') return result('bin', '+', expr, this.next().read_expr());
19+
if (this.token === '-') return result('bin', '-', expr, this.next().read_expr());
20+
if (this.token === '*') return result('bin', '*', expr, this.next().read_expr());
21+
if (this.token === '/') return result('bin', '/', expr, this.next().read_expr());
22+
if (this.token === '%') return result('bin', '%', expr, this.next().read_expr());
23+
if (this.token === this.tok.T_POW) return result('bin', '**', expr, this.next().read_expr());
24+
if (this.token === this.tok.T_SL) return result('bin', '<<', expr, this.next().read_expr());
25+
if (this.token === this.tok.T_SR) return result('bin', '>>', expr, this.next().read_expr());
26+
// boolean operations
1127
switch(this.token) {
12-
// binary operations
13-
case '|': return this.node('bin')('|', expr, this.next().read_expr());
14-
case '&': return this.node('bin')('&', expr, this.next().read_expr());
15-
case '^': return ['bin', '^', expr, this.next().read_expr()];
16-
case '.': return ['bin', '.', expr, this.next().read_expr()];
17-
case '+': return ['bin', '+', expr, this.next().read_expr()];
18-
case '-': return ['bin', '-', expr, this.next().read_expr()];
19-
case '*': return ['bin', '*', expr, this.next().read_expr()];
20-
case '/': return ['bin', '/', expr, this.next().read_expr()];
21-
case '%': return ['bin', '%', expr, this.next().read_expr()];
22-
case this.tok.T_POW: return ['bin', '**', expr, this.next().read_expr()];
23-
case this.tok.T_SL: return ['bin', '<<', expr, this.next().read_expr()];
24-
case this.tok.T_SR: return ['bin', '>>', expr, this.next().read_expr()];
25-
26-
// boolean operations
2728
case this.tok.T_BOOLEAN_OR:
2829
case this.tok.T_LOGICAL_OR: return ['bool', '|', expr, this.next().read_expr()];
2930

@@ -94,7 +95,7 @@ module.exports = {
9495
case '+':
9596
case '!':
9697
case '~':
97-
return this.node('unary')(this.token, this.read_expr());
98+
return this.node('unary')(this.token, this.next().read_expr());
9899

99100
case '(':
100101
var expr = this.next().read_expr();
@@ -242,22 +243,22 @@ module.exports = {
242243
return result(expr);
243244

244245
case this.tok.T_INT_CAST:
245-
return ['cast', 'int', this.next().read_expr()];
246+
return this.node('cast')('int', this.next().read_expr());
246247

247248
case this.tok.T_DOUBLE_CAST:
248-
return ['cast', 'double', this.next().read_expr()];
249+
return this.node('cast')('double', this.next().read_expr());
249250

250251
case this.tok.T_STRING_CAST:
251-
return ['cast', 'string', this.next().read_expr()];
252+
return this.node('cast')('string', this.next().read_expr());
252253

253254
case this.tok.T_ARRAY_CAST:
254-
return ['cast', 'array', this.next().read_expr()];
255+
return this.node('cast')('array', this.next().read_expr());
255256

256257
case this.tok.T_OBJECT_CAST:
257-
return ['cast', 'object', this.next().read_expr()];
258+
return this.node('cast')('object', this.next().read_expr());
258259

259260
case this.tok.T_BOOL_CAST:
260-
return ['cast', 'boolean', this.next().read_expr()];
261+
return this.node('cast')('boolean', this.next().read_expr());
261262

262263
case this.tok.T_UNSET_CAST:
263264
return this.node('unset')(

test/astTests.js

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,7 @@ describe('Test AST structure', function() {
7070
ast.children[3].kind.should.be.exactly('unset');
7171
ast.children[4].kind.should.be.exactly('empty');
7272
});
73-
it('test list statements', function() {
74-
var ast = parser.parseEval([
75-
'list($a, $b) = [1, 2];'
76-
].join('\n'));
77-
// @todo
78-
});
73+
7974
it('should be variable', function() {
8075
// @todo
8176
});

test/classTests.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ describe('Test classes', function() {
1717
' use A, B {',
1818
' B::smallTalk insteadof A;',
1919
' A::bigTalk insteadof B, C;',
20+
' B::bigTalk as public talk;',
2021
' B::bigTalk as protected talk;',
22+
' B::bigTalk as private talk;',
2123
' }',
2224
' /**',
2325
' * Some informations',
@@ -79,7 +81,7 @@ describe('Test classes', function() {
7981
use.traits[0].name.should.be.exactly('A');
8082
use.traits[1].name.should.be.exactly('B');
8183
// test adaptations
82-
use.adaptations.length.should.be.exactly(3);
84+
use.adaptations.length.should.be.exactly(5);
8385
use.adaptations[0].kind.should.be.exactly('traitprecedence');
8486
use.adaptations[1].kind.should.be.exactly('traitprecedence');
8587
use.adaptations[2].kind.should.be.exactly('traitalias');
@@ -98,8 +100,10 @@ describe('Test classes', function() {
98100
// test adaptation contents
99101
use.adaptations[2].trait.name.should.be.exactly('B');
100102
use.adaptations[2].method.should.be.exactly('bigTalk');
101-
use.adaptations[2].visibility.should.be.exactly('protected');
102103
use.adaptations[2].as.should.be.exactly('talk');
104+
use.adaptations[2].visibility.should.be.exactly('public');
105+
use.adaptations[3].visibility.should.be.exactly('protected');
106+
use.adaptations[4].visibility.should.be.exactly('private');
103107

104108
});
105109

0 commit comments

Comments
 (0)