2929 * JavaScript based Music Blocks code.
3030 */
3131class ASTUtils {
32+ static _isValidIdentifier ( name ) {
33+ return typeof name === "string" && / ^ [ A - Z a - z _ $ ] [ 0 - 9 A - Z a - z _ $ ] * $ / . test ( name ) ;
34+ }
35+
36+ static _getMouseCallExpression ( methodName , args ) {
37+ return {
38+ type : "CallExpression" ,
39+ callee : {
40+ type : "MemberExpression" ,
41+ object : {
42+ type : "Identifier" ,
43+ name : "mouse"
44+ } ,
45+ computed : false ,
46+ property : {
47+ type : "Identifier" ,
48+ name : methodName
49+ }
50+ } ,
51+ arguments : args
52+ } ;
53+ }
54+
3255 /**
3356 * @static
3457 * Abstract Syntax Tree for the bare minimum program code
@@ -304,9 +327,34 @@ class ASTUtils {
304327 * @returns {Object } Abstract Syntax Tree of increment assignment statement
305328 */
306329 static _getIncrementStmntAST ( args , isIncrement ) {
307- const identifier = args [ 0 ] . split ( "_" ) [ 1 ] ;
330+ const identifier =
331+ typeof args [ 0 ] === "string" && args [ 0 ] . startsWith ( "box_" ) ? args [ 0 ] . slice ( 4 ) : args [ 0 ] ;
308332 const arg = ASTUtils . _getArgsAST ( [ args [ 1 ] ] ) [ 0 ] ;
309333
334+ if ( ! ASTUtils . _isValidIdentifier ( identifier ) ) {
335+ const deltaAst = isIncrement
336+ ? arg
337+ : {
338+ type : "UnaryExpression" ,
339+ operator : "-" ,
340+ argument : arg ,
341+ prefix : true
342+ } ;
343+ return {
344+ type : "ExpressionStatement" ,
345+ expression : {
346+ type : "AwaitExpression" ,
347+ argument : ASTUtils . _getMouseCallExpression ( "incrementBox" , [
348+ {
349+ type : "Literal" ,
350+ value : identifier
351+ } ,
352+ deltaAst
353+ ] )
354+ }
355+ } ;
356+ }
357+
310358 return {
311359 type : "ExpressionStatement" ,
312360 expression : {
@@ -353,6 +401,22 @@ class ASTUtils {
353401 {
354402 type : "Identifier" ,
355403 name : "mouse"
404+ } ,
405+ {
406+ type : "AssignmentPattern" ,
407+ left : {
408+ type : "Identifier" ,
409+ name : "actionArgs"
410+ } ,
411+ right : {
412+ type : "ArrayExpression" ,
413+ elements : [
414+ {
415+ type : "Literal" ,
416+ value : null
417+ }
418+ ]
419+ }
356420 }
357421 ] ,
358422 body : {
@@ -430,6 +494,18 @@ class ASTUtils {
430494 name : "mouse"
431495 }
432496 ] ;
497+ if ( args !== undefined && args !== null ) {
498+ AST [ "expression" ] [ "argument" ] [ "arguments" ] . push ( {
499+ type : "ArrayExpression" ,
500+ elements : [
501+ {
502+ type : "Literal" ,
503+ value : null
504+ } ,
505+ ...ASTUtils . _getArgsAST ( args )
506+ ]
507+ } ) ;
508+ }
433509 }
434510 if ( props . statement === false ) {
435511 AST = AST [ "expression" ] ;
@@ -448,6 +524,44 @@ class ASTUtils {
448524 * @returns {Object } - Abstract Syntax Tree of method call
449525 */
450526 static _getArgExpAST ( methodName , args ) {
527+ if ( methodName === "arg" ) {
528+ const indexAst = ASTUtils . _getArgsAST ( args ) [ 0 ] || {
529+ type : "Literal" ,
530+ value : 1
531+ } ;
532+ return {
533+ type : "MemberExpression" ,
534+ object : {
535+ type : "Identifier" ,
536+ name : "actionArgs"
537+ } ,
538+ property : indexAst ,
539+ computed : true
540+ } ;
541+ }
542+
543+ if ( methodName === "box" ) {
544+ const nameAst = ASTUtils . _getArgsAST ( args ) [ 0 ] ;
545+ if ( nameAst && nameAst . type === "Identifier" ) {
546+ return nameAst ;
547+ }
548+ if ( nameAst && nameAst . type === "Literal" && typeof nameAst . value === "string" ) {
549+ if ( ASTUtils . _isValidIdentifier ( nameAst . value ) ) {
550+ return {
551+ type : "Identifier" ,
552+ name : nameAst . value
553+ } ;
554+ }
555+ }
556+ if ( ! nameAst ) {
557+ return {
558+ type : "Identifier" ,
559+ name : "undefined"
560+ } ;
561+ }
562+ return ASTUtils . _getMouseCallExpression ( "getBox" , [ nameAst ] ) ;
563+ }
564+
451565 const mathOps = {
452566 plus : [ "binexp" , "+" ] ,
453567 minus : [ "binexp" , "-" ] ,
@@ -457,8 +571,8 @@ class ASTUtils {
457571 equal : [ "binexp" , "==" ] ,
458572 less : [ "binexp" , "<" ] ,
459573 greater : [ "binexp" , ">" ] ,
460- or : [ "binexp" , "|" ] ,
461- and : [ "binexp" , "&" ] ,
574+ or : [ "binexp" , "|| " ] ,
575+ and : [ "binexp" , "&& " ] ,
462576 xor : [ "binexp" , "^" ] ,
463577 not : [ "unexp" , "!" ] ,
464578 neg : [ "unexp" , "-" ] ,
@@ -470,7 +584,10 @@ class ASTUtils {
470584
471585 function getBinaryExpAST ( operator , operand1 , operand2 ) {
472586 return {
473- type : "BinaryExpression" ,
587+ type :
588+ operator === "&&" || operator === "||"
589+ ? "LogicalExpression"
590+ : "BinaryExpression" ,
474591 left : ASTUtils . _getArgsAST ( [ operand1 ] ) [ 0 ] ,
475592 right : ASTUtils . _getArgsAST ( [ operand2 ] ) [ 0 ] ,
476593 operator : `${ operator } `
@@ -538,17 +655,35 @@ class ASTUtils {
538655 ) ;
539656 }
540657 } else {
541- if ( typeof arg === "string" && arg . split ( "_" ) . length > 1 ) {
542- const [ type , argVal ] = arg . split ( "_" ) ;
658+ if ( typeof arg === "string" && arg . includes ( "_" ) ) {
659+ const sepIndex = arg . indexOf ( "_" ) ;
660+ const type = arg . slice ( 0 , sepIndex ) ;
661+ const argVal = arg . slice ( sepIndex + 1 ) ;
543662 if ( type === "bool" ) {
544663 ASTs . push ( {
545664 type : "Literal" ,
546665 value : argVal === "true"
547666 } ) ;
548667 } else if ( type === "box" ) {
668+ if ( ASTUtils . _isValidIdentifier ( argVal ) ) {
669+ ASTs . push ( {
670+ type : "Identifier" ,
671+ name : argVal
672+ } ) ;
673+ } else {
674+ ASTs . push (
675+ ASTUtils . _getMouseCallExpression ( "getBox" , [
676+ {
677+ type : "Literal" ,
678+ value : argVal
679+ }
680+ ] )
681+ ) ;
682+ }
683+ } else {
549684 ASTs . push ( {
550- type : "Identifier " ,
551- name : argVal
685+ type : "Literal " ,
686+ value : arg
552687 } ) ;
553688 }
554689 } else {
@@ -674,23 +809,13 @@ class ASTUtils {
674809 } else if ( flow [ 0 ] === "decrementOne" ) {
675810 ASTs . push ( ASTUtils . _getIncrementStmntAST ( [ flow [ 1 ] [ 0 ] , 1 ] , false ) ) ;
676811 } else if ( flow [ 0 ] === "storein" ) {
677- ASTs . push ( {
678- type : "VariableDeclaration" ,
679- kind : "var" ,
680- declarations : [
681- {
682- type : "VariableDeclarator" ,
683- id : {
684- type : "Identifier" ,
685- name : flow [ 1 ] [ 0 ]
686- } ,
687- init : ASTUtils . _getArgsAST ( [ flow [ 1 ] [ 1 ] ] ) [ 0 ]
688- }
689- ]
690- } ) ;
691- } else if ( flow [ 0 ] . split ( "_" ) . length > 1 ) {
692- const [ instruction , idName ] = flow [ 0 ] . split ( "_" ) ;
693- if ( instruction === "storein2" ) {
812+ const nameAst = ASTUtils . _getArgsAST ( [ flow [ 1 ] [ 0 ] ] ) [ 0 ] ;
813+ const valueAst = ASTUtils . _getArgsAST ( [ flow [ 1 ] [ 1 ] ] ) [ 0 ] ;
814+ if (
815+ nameAst &&
816+ nameAst . type === "Literal" &&
817+ ASTUtils . _isValidIdentifier ( nameAst . value )
818+ ) {
694819 ASTs . push ( {
695820 type : "VariableDeclaration" ,
696821 kind : "var" ,
@@ -699,14 +824,63 @@ class ASTUtils {
699824 type : "VariableDeclarator" ,
700825 id : {
701826 type : "Identifier" ,
702- name : idName
827+ name : nameAst . value
703828 } ,
704- init : ASTUtils . _getArgsAST ( flow [ 1 ] ) [ 0 ]
829+ init : valueAst
705830 }
706831 ]
707832 } ) ;
833+ } else {
834+ ASTs . push ( {
835+ type : "ExpressionStatement" ,
836+ expression : {
837+ type : "AwaitExpression" ,
838+ argument : ASTUtils . _getMouseCallExpression ( "setBox" , [
839+ nameAst ,
840+ valueAst
841+ ] )
842+ }
843+ } ) ;
844+ }
845+ } else if ( flow [ 0 ] . split ( "_" ) . length > 1 ) {
846+ const splitIndex = flow [ 0 ] . indexOf ( "_" ) ;
847+ const instruction = flow [ 0 ] . slice ( 0 , splitIndex ) ;
848+ const idName = flow [ 0 ] . slice ( splitIndex + 1 ) ;
849+ if ( instruction === "storein2" ) {
850+ if ( ASTUtils . _isValidIdentifier ( idName ) ) {
851+ ASTs . push ( {
852+ type : "VariableDeclaration" ,
853+ kind : "var" ,
854+ declarations : [
855+ {
856+ type : "VariableDeclarator" ,
857+ id : {
858+ type : "Identifier" ,
859+ name : idName
860+ } ,
861+ init : ASTUtils . _getArgsAST ( flow [ 1 ] ) [ 0 ]
862+ }
863+ ]
864+ } ) ;
865+ } else {
866+ ASTs . push ( {
867+ type : "ExpressionStatement" ,
868+ expression : {
869+ type : "AwaitExpression" ,
870+ argument : ASTUtils . _getMouseCallExpression ( "setBox" , [
871+ {
872+ type : "Literal" ,
873+ value : idName
874+ } ,
875+ ASTUtils . _getArgsAST ( flow [ 1 ] ) [ 0 ]
876+ ] )
877+ }
878+ } ) ;
879+ }
708880 } else if ( instruction === "nameddo" ) {
709881 ASTs . push ( ASTUtils . _getMethodCallAST ( idName , flow [ 1 ] , { action : true } ) ) ;
882+ } else if ( instruction === "nameddoArg" ) {
883+ ASTs . push ( ASTUtils . _getMethodCallAST ( idName , flow [ 1 ] , { action : true } ) ) ;
710884 }
711885 } else {
712886 if ( JSInterface . isSetter ( flow [ 0 ] ) ) {
0 commit comments