diff --git a/lib/scripting/estree.ts b/lib/scripting/estree.ts index 78435d6b..e31ad7e4 100644 --- a/lib/scripting/estree.ts +++ b/lib/scripting/estree.ts @@ -40,6 +40,8 @@ import { Identifier, IfStatement, Literal, + LogicalExpression, + LogicalOperator, MemberExpression, NewExpression, Pattern, @@ -179,6 +181,15 @@ export function functionExpression(body: BlockStatement, params: Pattern[]): Fun }; } +export function logicalExpression(operator: LogicalOperator, left: Expression, right: Expression): LogicalExpression { + return { + type: 'LogicalExpression', + operator, + left, + right, + }; +} + export function memberExpression(object: Expression | Super, property: Expression): MemberExpression { return { type: 'MemberExpression', diff --git a/lib/scripting/post-process/expr.spec.ts b/lib/scripting/post-process/expr.spec.ts index 7bb1f0e3..f9700e02 100644 --- a/lib/scripting/post-process/expr.spec.ts +++ b/lib/scripting/post-process/expr.spec.ts @@ -34,15 +34,15 @@ describe('The VBScript transpiler - Expressions', () => { }); it('should transpile a "Or" expression', () => { - const vbs = `EnableBallControl = 10 Or 8\n`; + const vbs = `If test = 5 Or Err Then test = 6\n`; const js = vbsToJs(vbs); - expect(js).to.equal('EnableBallControl = 10 | 8;'); + expect(js).to.equal('if (test == 5 || Err)\n test = 6;'); }); it('should transpile a "And" expression', () => { - const vbs = `EnableBallControl = 10 And 8\n`; + const vbs = `If test = 5 And Err Then test = 6`; const js = vbsToJs(vbs); - expect(js).to.equal('EnableBallControl = 10 & 8;'); + expect(js).to.equal('if (test == 5 && Err)\n test = 6;'); }); it('should transpile a "Not" expression', () => { diff --git a/lib/scripting/post-process/expr.ts b/lib/scripting/post-process/expr.ts index 947341d0..7a8d29d2 100644 --- a/lib/scripting/post-process/expr.ts +++ b/lib/scripting/post-process/expr.ts @@ -58,13 +58,13 @@ export function xor(result: [Expression, null, Token, null, Expression]): Expres export function or(result: [Expression, null, Token, null, Expression]): Expression { const leftExpr = result[0]; const rightExpr = result[4]; - return estree.binaryExpression('|', leftExpr, rightExpr); + return estree.logicalExpression('||', leftExpr, rightExpr); } export function and(result: [Expression, null, Token, null, Expression]): Expression { const leftExpr = result[0]; const rightExpr = result[4]; - return estree.binaryExpression('&', leftExpr, rightExpr); + return estree.logicalExpression('&&', leftExpr, rightExpr); } export function not(result: [Token, null, Expression]): Expression { diff --git a/lib/scripting/post-process/if.spec.ts b/lib/scripting/post-process/if.spec.ts index d04822b2..0e62dd77 100644 --- a/lib/scripting/post-process/if.spec.ts +++ b/lib/scripting/post-process/if.spec.ts @@ -84,4 +84,12 @@ describe('The VBScript transpiler - If', () => { const js = vbsToJs(vbs); expect(js).to.equal('if (x == 1) {\n x = 2;\n} else if (x == 3)\n x = 4;\nelse\n x = 5;'); }); + + it('should transpile multiple inline "If/Then" statement', () => { + const vbs = `If VPMver > "" Then If Controller.Version < VPMver Or Err Then MsgBox "VPinMAME ver " & VPMver & " required."\n`; + const js = vbsToJs(vbs); + expect(js).to.equal( + "if (VPMver > '')\n if (Controller.Version < VPMver || Err)\n MsgBox('VPinMAME ver ' + VPMver + ' required.');", + ); + }); }); diff --git a/lib/scripting/post-process/if.ts b/lib/scripting/post-process/if.ts index 9fbec97e..81356bb4 100644 --- a/lib/scripting/post-process/if.ts +++ b/lib/scripting/post-process/if.ts @@ -21,7 +21,7 @@ import { BlockStatement, Comment, Expression, IfStatement, Statement } from 'est import { Token } from 'moo'; import * as estree from '../estree'; -export function stmt1( +export function stmt( result: [Token, null, Expression, null, Token, Comment[], BlockStatement, Statement, Token, null, Token, Comment[]], ): IfStatement { const test = result[2]; @@ -32,14 +32,13 @@ export function stmt1( return estree.ifStatement(test, consequent, alternate, leadingComments, trailingComments); } -export function stmt2( - result: [Token, null, Expression, null, Token, null, Statement, null, Statement, null, Token, Comment[]], +export function stmtInline( + result: [Token, null, Expression, null, Token, null, Statement, null, Statement, null, Token], ): IfStatement { const test = result[2]; const consequent = result[6]; const alternate = result[8]; - const comments = result[11] || []; - return estree.ifStatement(test, consequent, alternate, [], comments); + return estree.ifStatement(test, consequent, alternate, [], []); } export function elseStmt1( diff --git a/lib/scripting/vbscript.ne b/lib/scripting/vbscript.ne index 6afa3ecb..796da4d2 100644 --- a/lib/scripting/vbscript.ne +++ b/lib/scripting/vbscript.ne @@ -230,6 +230,7 @@ InlineStmt -> AssignStmt | SubCallStmt {% id %} | ErrorStmt {% id %} | ExitStmt {% id %} + | IfStmtInline {% id %} GlobalStmtList -> GlobalStmt GlobalStmtList {% ppHelpers.globalStmtList %} | null @@ -322,8 +323,9 @@ RedimDecl -> ExtendedID _ %paren_left _ ExprList _ %paren_right #========= If Statement -IfStmt -> %kw_if _ Expr _ %kw_then NL BlockStmtList ElseStmtList %kw_end __ %kw_if NL {% ppIf.stmt1 %} - | %kw_if _ Expr _ %kw_then __ InlineStmt _ ElseOpt _ EndIfOpt NL {% ppIf.stmt2 %} +IfStmt -> %kw_if _ Expr _ %kw_then NL BlockStmtList ElseStmtList %kw_end __ %kw_if NL {% ppIf.stmt %} + +IfStmtInline -> %kw_if _ Expr _ %kw_then __ InlineStmt _ ElseOpt _ EndIfOpt {% ppIf.stmtInline %} ElseStmtList -> %kw_elseif _ Expr _ %kw_then NL BlockStmtList ElseStmtList {% ppIf.elseStmt1 %} | %kw_elseif _ Expr _ %kw_then __ InlineStmt NL ElseStmtList {% ppIf.elseStmt2 %}