@@ -225,43 +225,42 @@ protected function parseBracketsArray()
225225 throw new Exception ('Missing } to match ' . $ exceptionInfos , 7 );
226226 }
227227
228- protected function parseVariable ( $ name )
228+ protected function getVariableChildFromToken ( $ token )
229229 {
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 ();
241233
242- $ this ->unexpected ($ next );
234+ if ($ token ->is ('variable ' )) {
235+ return new Constant ('string ' , var_export ($ token ->value , true ));
243236 }
244237
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+ }
251240
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 ());
255245
256- if (!$ next ->is ('] ' )) {
257- $ this ->unexpected ($ next );
258- }
246+ $ token = $ this ->next ();
259247
260- $ children [] = $ value ;
248+ if (!$ token ) {
249+ throw new Exception ('Missing ] to match ' . $ exceptionInfos , 13 );
250+ }
261251
262- continue ;
252+ if ($ token ->is ('] ' )) {
253+ return $ value ;
263254 }
264255
256+ $ this ->unexpected ($ token );
257+ }
258+ }
259+
260+ protected function parseVariable ($ name )
261+ {
262+ $ children = array ();
263+ while ($ next = $ this ->get (0 )) {
265264 if ($ next ->is ('lambda ' )) {
266265 $ this ->skip ();
267266 $ parenthesis = new Parenthesis ();
@@ -270,6 +269,12 @@ protected function parseVariable($name)
270269 return $ this ->parseLambda ($ parenthesis );
271270 }
272271
272+ if ($ value = $ this ->getVariableChildFromToken ($ next )) {
273+ $ children [] = $ value ;
274+
275+ continue ;
276+ }
277+
273278 break ;
274279 }
275280
@@ -330,29 +335,34 @@ protected function parseValue($token)
330335 : new Constant ($ token ->type , $ token ->value );
331336 }
332337
333- protected function getInitialValue ($ token )
338+ protected function parseFunction ($ token )
334339 {
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 ' )) {
345343 $ this ->skip ();
346- $ function ->setValue ($ this ->parseParentheses ());
347344 $ 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+ }
354361
355- return $ function ;
362+ protected function getInitialValue ($ token )
363+ {
364+ if ($ token ->is ('function ' )) {
365+ return $ this ->parseFunction ($ token );
356366 }
357367 if ($ token ->is ('( ' )) {
358368 return $ this ->parseParentheses ();
@@ -430,19 +440,62 @@ protected function getValueFromToken($token)
430440 return $ value ;
431441 }
432442
433- public function parseBlock ( $ block )
443+ protected function parseKeyword ( $ token )
434444 {
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+ }
440479 }
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 );
445482 }
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+ {
446499 while ($ token = $ this ->next ()) {
447500 if ($ token ->is ('} ' ) && $ waitForClosure ) {
448501 break ;
@@ -451,53 +504,11 @@ public function parseBlock($block)
451504 continue ;
452505 }
453506 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 ));
459508 continue ;
460509 }
461510 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 ));
501512 continue ;
502513 }
503514 if ($ value = $ this ->getValueFromToken ($ token )) {
@@ -513,6 +524,22 @@ public function parseBlock($block)
513524 }
514525 $ this ->unexpected ($ token );
515526 }
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 );
516543 array_pop ($ this ->stack );
517544 }
518545
0 commit comments