@@ -225,43 +225,42 @@ protected function parseBracketsArray()
225
225
throw new Exception ('Missing } to match ' . $ exceptionInfos , 7 );
226
226
}
227
227
228
- protected function parseVariable ( $ name )
228
+ protected function getVariableChildFromToken ( $ token )
229
229
{
230
- $ children = array ();
231
- while ($ next = $ this ->get (0 )) {
232
- if ($ next ->is ('. ' )) {
233
- $ this ->skip ();
234
- $ next = $ this ->next ();
235
-
236
- if ($ next ->is ('variable ' )) {
237
- $ children [] = new Constant ('string ' , var_export ($ next ->value , true ));
238
-
239
- continue ;
240
- }
230
+ if ($ token ->is ('. ' )) {
231
+ $ this ->skip ();
232
+ $ token = $ this ->next ();
241
233
242
- $ this ->unexpected ($ next );
234
+ if ($ token ->is ('variable ' )) {
235
+ return new Constant ('string ' , var_export ($ token ->value , true ));
243
236
}
244
237
245
- if ($ next ->is ('[ ' )) {
246
- $ exceptionInfos = $ this ->exceptionInfos ();
247
- $ this ->skip ();
248
- $ value = $ this ->expectValue ($ this ->next ());
249
-
250
- $ next = $ this ->next ();
238
+ $ this ->unexpected ($ token );
239
+ }
251
240
252
- if (!$ next ) {
253
- throw new Exception ('Missing ] to match ' . $ exceptionInfos , 13 );
254
- }
241
+ if ($ token ->is ('[ ' )) {
242
+ $ exceptionInfos = $ this ->exceptionInfos ();
243
+ $ this ->skip ();
244
+ $ value = $ this ->expectValue ($ this ->next ());
255
245
256
- if (!$ next ->is ('] ' )) {
257
- $ this ->unexpected ($ next );
258
- }
246
+ $ token = $ this ->next ();
259
247
260
- $ children [] = $ value ;
248
+ if (!$ token ) {
249
+ throw new Exception ('Missing ] to match ' . $ exceptionInfos , 13 );
250
+ }
261
251
262
- continue ;
252
+ if ($ token ->is ('] ' )) {
253
+ return $ value ;
263
254
}
264
255
256
+ $ this ->unexpected ($ token );
257
+ }
258
+ }
259
+
260
+ protected function parseVariable ($ name )
261
+ {
262
+ $ children = array ();
263
+ while ($ next = $ this ->get (0 )) {
265
264
if ($ next ->is ('lambda ' )) {
266
265
$ this ->skip ();
267
266
$ parenthesis = new Parenthesis ();
@@ -270,6 +269,12 @@ protected function parseVariable($name)
270
269
return $ this ->parseLambda ($ parenthesis );
271
270
}
272
271
272
+ if ($ value = $ this ->getVariableChildFromToken ($ next )) {
273
+ $ children [] = $ value ;
274
+
275
+ continue ;
276
+ }
277
+
273
278
break ;
274
279
}
275
280
@@ -330,29 +335,34 @@ protected function parseValue($token)
330
335
: new Constant ($ token ->type , $ token ->value );
331
336
}
332
337
333
- protected function getInitialValue ($ token )
338
+ protected function parseFunction ($ token )
334
339
{
335
- if ($ token ->is ('function ' )) {
336
- $ function = new Block ('function ' );
337
- $ token = $ this ->get (0 );
338
- if ($ token ->is ('variable ' )) {
339
- $ this ->skip ();
340
- $ token = $ this ->get (0 );
341
- }
342
- if (!$ token ->is ('( ' )) {
343
- $ this ->unexpected ($ token );
344
- }
340
+ $ function = new Block ('function ' );
341
+ $ token = $ this ->get (0 );
342
+ if ($ token ->is ('variable ' )) {
345
343
$ this ->skip ();
346
- $ function ->setValue ($ this ->parseParentheses ());
347
344
$ token = $ this ->get (0 );
348
- if (!$ token ->is ('{ ' )) {
349
- $ this ->unexpected ($ token );
350
- }
351
- $ this ->skip ();
352
- $ this ->parseBlock ($ function );
353
- $ this ->skip ();
345
+ }
346
+ if (!$ token ->is ('( ' )) {
347
+ $ this ->unexpected ($ token );
348
+ }
349
+ $ this ->skip ();
350
+ $ function ->setValue ($ this ->parseParentheses ());
351
+ $ token = $ this ->get (0 );
352
+ if (!$ token ->is ('{ ' )) {
353
+ $ this ->unexpected ($ token );
354
+ }
355
+ $ this ->skip ();
356
+ $ this ->parseBlock ($ function );
357
+ $ this ->skip ();
358
+
359
+ return $ function ;
360
+ }
354
361
355
- return $ function ;
362
+ protected function getInitialValue ($ token )
363
+ {
364
+ if ($ token ->is ('function ' )) {
365
+ return $ this ->parseFunction ($ token );
356
366
}
357
367
if ($ token ->is ('( ' )) {
358
368
return $ this ->parseParentheses ();
@@ -430,19 +440,62 @@ protected function getValueFromToken($token)
430
440
return $ value ;
431
441
}
432
442
433
- public function parseBlock ( $ block )
443
+ protected function parseKeyword ( $ token )
434
444
{
435
- $ this ->stack [] = $ block ;
436
- $ next = $ this ->get (0 );
437
- if ($ next ->is ('( ' )) {
438
- $ this ->skip ();
439
- $ block ->setValue ($ this ->parseParentheses ());
445
+ $ name = $ token ->value ;
446
+ $ keyword = new Block ($ name );
447
+ switch ($ name ) {
448
+ case 'return ' :
449
+ case 'continue ' :
450
+ case 'break ' :
451
+ $ afterKeyword = $ this ->get (0 );
452
+ if (!$ afterKeyword ->is ('; ' )) {
453
+ $ value = $ this ->expectValue ($ this ->next ());
454
+ $ keyword ->setValue ($ value );
455
+ }
456
+ break ;
457
+ case 'case ' :
458
+ $ value = $ this ->expectValue ($ this ->next ());
459
+ $ keyword ->setValue ($ value );
460
+ $ colon = $ this ->next ();
461
+ if (!$ colon || !$ colon ->is (': ' )) {
462
+ throw new Exception ("'case' must be followed by a value and a colon. " , 21 );
463
+ }
464
+ break ;
465
+ case 'default ' :
466
+ $ colon = $ this ->next ();
467
+ if (!$ colon || !$ colon ->is (': ' )) {
468
+ throw new Exception ("'default' must be followed by a colon. " , 22 );
469
+ }
470
+ break ;
471
+ default :
472
+ $ next = $ this ->get (0 );
473
+ if ($ next ->is ('( ' )) {
474
+ $ this ->skip ();
475
+ $ keyword ->setValue ($ this ->parseParentheses ());
476
+ } elseif ($ keyword ->needParenthesis ()) {
477
+ throw new Exception ("' " . $ keyword ->type . "' block need parentheses. " , 17 );
478
+ }
440
479
}
441
- $ next = $ this ->get (0 );
442
- $ waitForClosure = $ next ->is ('{ ' );
443
- if ($ waitForClosure && $ block ->type !== 'main ' ) {
444
- $ this ->skip ();
480
+ if ($ keyword ->handleInstructions ()) {
481
+ $ this ->parseBlock ($ keyword );
445
482
}
483
+
484
+ return $ keyword ;
485
+ }
486
+
487
+ protected function parseLet ($ token )
488
+ {
489
+ $ letVariable = $ this ->get (0 );
490
+ if (!$ letVariable ->is ('variable ' )) {
491
+ $ this ->unexpected ($ letVariable , $ token );
492
+ }
493
+
494
+ return $ letVariable ->value ;
495
+ }
496
+
497
+ protected function parseInstructions ($ block , $ waitForClosure )
498
+ {
446
499
while ($ token = $ this ->next ()) {
447
500
if ($ token ->is ('} ' ) && $ waitForClosure ) {
448
501
break ;
@@ -451,53 +504,11 @@ public function parseBlock($block)
451
504
continue ;
452
505
}
453
506
if ($ token ->is ('let ' )) {
454
- $ letVariable = $ this ->get (0 );
455
- if (!$ letVariable ->is ('variable ' )) {
456
- $ this ->unexpected ($ letVariable , $ token );
457
- }
458
- $ block ->let ($ letVariable ->value );
507
+ $ block ->let ($ this ->parseLet ($ token ));
459
508
continue ;
460
509
}
461
510
if ($ token ->is ('keyword ' )) {
462
- $ name = $ token ->value ;
463
- $ keyword = new Block ($ name );
464
- switch ($ name ) {
465
- case 'return ' :
466
- case 'continue ' :
467
- case 'break ' :
468
- $ afterKeyword = $ this ->get (0 );
469
- if (!$ afterKeyword ->is ('; ' )) {
470
- $ value = $ this ->expectValue ($ this ->next ());
471
- $ keyword ->setValue ($ value );
472
- }
473
- break ;
474
- case 'case ' :
475
- $ value = $ this ->expectValue ($ this ->next ());
476
- $ keyword ->setValue ($ value );
477
- $ colon = $ this ->next ();
478
- if (!$ colon || !$ colon ->is (': ' )) {
479
- throw new Exception ("'case' must be followed by a value and a colon. " , 21 );
480
- }
481
- break ;
482
- case 'default ' :
483
- $ colon = $ this ->next ();
484
- if (!$ colon || !$ colon ->is (': ' )) {
485
- throw new Exception ("'default' must be followed by a colon. " , 22 );
486
- }
487
- break ;
488
- default :
489
- $ next = $ this ->get (0 );
490
- if ($ next ->is ('( ' )) {
491
- $ this ->skip ();
492
- $ keyword ->setValue ($ this ->parseParentheses ());
493
- } elseif ($ keyword ->needParenthesis ()) {
494
- throw new Exception ("' " . $ keyword ->type . "' block need parentheses. " , 17 );
495
- }
496
- }
497
- if ($ keyword ->handleInstructions ()) {
498
- $ this ->parseBlock ($ keyword );
499
- }
500
- $ block ->addInstruction ($ keyword );
511
+ $ block ->addInstruction ($ this ->parseKeyword ($ token ));
501
512
continue ;
502
513
}
503
514
if ($ value = $ this ->getValueFromToken ($ token )) {
@@ -513,6 +524,22 @@ public function parseBlock($block)
513
524
}
514
525
$ this ->unexpected ($ token );
515
526
}
527
+ }
528
+
529
+ public function parseBlock ($ block )
530
+ {
531
+ $ this ->stack [] = $ block ;
532
+ $ next = $ this ->get (0 );
533
+ if ($ next ->is ('( ' )) {
534
+ $ this ->skip ();
535
+ $ block ->setValue ($ this ->parseParentheses ());
536
+ }
537
+ $ next = $ this ->get (0 );
538
+ $ waitForClosure = $ next ->is ('{ ' );
539
+ if ($ waitForClosure && $ block ->type !== 'main ' ) {
540
+ $ this ->skip ();
541
+ }
542
+ $ this ->parseInstructions ($ block , $ waitForClosure );
516
543
array_pop ($ this ->stack );
517
544
}
518
545
0 commit comments