From 8ad8687c268c7ae0eb495da35b70b732b7de007a Mon Sep 17 00:00:00 2001 From: boxgaming <75969133+boxgaming@users.noreply.github.com> Date: Mon, 25 Apr 2022 22:56:54 -0500 Subject: [PATCH] Import/Export fixes --- qb2js.js | 155 +++++++++++++++++++++++++------------------ tools/qb2js.bas | 170 ++++++++++++++++++++++++++++++------------------ 2 files changed, 196 insertions(+), 129 deletions(-) diff --git a/qb2js.js b/qb2js.js index 9780fd2..20f1272 100644 --- a/qb2js.js +++ b/qb2js.js @@ -283,7 +283,7 @@ if (QB.halted()) { return; } js = "QB.halt(); return;"; } else if ( first == "$IF" ) { if ((QB.func_UBound( parts)) > 1) { - if ((QB.func_UCase( QB.arrayValue(parts, [ 2]).value)) == "JS" || (QB.func_UCase( QB.arrayValue(parts, [ 2]).value)) == "JAVASCRIPT" ) { + if ((QB.func_UCase( QB.arrayValue(parts, [ 2]).value)) == "JAVASCRIPT" ) { jsMode = True; js = "//-------- BEGIN JS native code block --------"; } @@ -345,49 +345,13 @@ if (QB.halted()) { return; } currType = (QB.func_UBound( types)); } else if ( first == "EXPORT" ) { if ( c > 1) { - var exportedItem = ''; // STRING - var em = {line:0,type:'',returnType:'',name:'',uname:'',argc:0,args:'',jsname:'',sync:0}; // METHOD - var ev = {type:'',name:'',jsname:'',isConst:0,isArray:0,arraySize:0,typeId:0}; // VARIABLE - var exportName = ''; // STRING - exportName = ""; - if ( c > 3) { - exportName = QB.arrayValue(parts, [ 4]).value; + var exparts = QB.initArray([{l:1,u:0}], ''); // STRING + var excount = 0; // INTEGER + excount = (await func_ListSplit( (await func_Join( parts, 2, -1, " ")), exparts)); + var exi = 0; // INTEGER + for ( exi= 1; exi <= excount; exi= exi + 1) { if (QB.halted()) { return; } + await sub_ParseExport( QB.arrayValue(exparts, [ exi]).value); } - if ((await func_FindMethod( QB.arrayValue(parts, [ 2]).value, em, "SUB")) ) { - exportedItem = em.jsname; - if ( exportName == "" ) { - exportName = QB.arrayValue(parts, [ 2]).value; - } - em.name = exportName; - await sub_AddExportMethod( em, currentModule +".", True); - exportName = "sub_" + exportName; - } else if ((await func_FindMethod( QB.arrayValue(parts, [ 2]).value, em, "FUNCTION")) ) { - exportedItem = em.jsname; - if ( exportName == "" ) { - exportName = QB.arrayValue(parts, [ 2]).value; - } - em.name = exportName; - await sub_AddExportMethod( em, currentModule +".", True); - exportName = "func_" + exportName; - } else if ((await func_FindVariable( QB.arrayValue(parts, [ 2]).value, ev, False)) ) { - exportedItem = ev.jsname; - if ( exportName == "" ) { - exportName = QB.arrayValue(parts, [ 2]).value; - } - ev.name = exportName; - } else if ((await func_FindVariable( QB.arrayValue(parts, [ 2]).value, ev, True)) ) { - exportedItem = ev.jsname; - if ( exportName == "" ) { - exportName = QB.arrayValue(parts, [ 2]).value; - } - ev.name = exportName; - } else { - continue; - } - var esize = 0; // SINGLE - esize = (QB.func_UBound( exportLines)) + 1; - QB.resizeArray(exportLines, [{l:1,u:esize}], '', true); // STRING - QB.arrayValue(exportLines, [ esize]).value = "this." + exportName +" = " + exportedItem +";"; continue; } else { } @@ -451,6 +415,48 @@ if (QB.halted()) { return; } } } } +async function sub_ParseExport(s/*STRING*/) { +if (QB.halted()) { return; } + var exportedItem = ''; // STRING + var ef = {line:0,type:'',returnType:'',name:'',uname:'',argc:0,args:'',jsname:'',sync:0}; // METHOD + var es = {line:0,type:'',returnType:'',name:'',uname:'',argc:0,args:'',jsname:'',sync:0}; // METHOD + var ev = {type:'',name:'',jsname:'',isConst:0,isArray:0,arraySize:0,typeId:0}; // VARIABLE + var exportName = ''; // STRING + var c = 0; // INTEGER + var parts = QB.initArray([{l:1,u:0}], ''); // STRING + c = (await func_SLSplit( s, parts, False)); + if ((await func_FindMethod( QB.arrayValue(parts, [ 1]).value, es, "SUB")) ) { + if ( c > 2) { + exportName = QB.arrayValue(parts, [ 3]).value; + } else { + exportName = QB.arrayValue(parts, [ 1]).value; + } + exportedItem = es.jsname; + es.name = exportName; + await sub_AddExportMethod( es, currentModule +".", True); + exportName = "sub_" + exportName; + await sub_RegisterExport( exportName, exportedItem); + } + if ((await func_FindMethod( QB.arrayValue(parts, [ 1]).value, ef, "FUNCTION")) ) { + if ( c > 2) { + exportName = QB.arrayValue(parts, [ 3]).value; + } else { + exportName = QB.arrayValue(parts, [ 1]).value; + } + exportedItem = ef.jsname; + ef.name = exportName; + await sub_AddExportMethod( ef, currentModule +".", True); + exportName = "func_" + exportName; + await sub_RegisterExport( exportName, exportedItem); + } +} +async function sub_RegisterExport(exportName/*STRING*/,exportedItem/*STRING*/) { +if (QB.halted()) { return; } + var esize = 0; // SINGLE + esize = (QB.func_UBound( exportLines)) + 1; + QB.resizeArray(exportLines, [{l:1,u:esize}], '', true); // STRING + QB.arrayValue(exportLines, [ esize]).value = "this." + exportName +" = " + exportedItem +";"; +} async function func_ConvertSub(m/*METHOD*/,args/*STRING*/) { if (QB.halted()) { return; } var ConvertSub = null; @@ -1334,6 +1340,7 @@ async function sub_ReadLinesFromFile(filename/*STRING*/) { if (QB.halted()) { return; } var fline = ''; // STRING var lineIndex = 0; // INTEGER + var rawJS = 0; // SINGLE // Open filename For Input As #1 while (!(( 1))) { if (QB.halted()) { return; } var ___v7055475 = new Array( 2); @@ -1350,7 +1357,7 @@ QB.sub_LineInput(___v5334240, false, false, undefined); fline = (QB.func_Left( fline, (QB.func_Len( fline)) - 1)) + nextLine; } - await sub_ReadLine( lineIndex, fline); + rawJS = (await func_ReadLine( lineIndex, fline, rawJS)); } } // Close #1 @@ -1358,6 +1365,7 @@ QB.sub_LineInput(___v5334240, false, false, undefined); async function sub_ReadLinesFromText(sourceText/*STRING*/) { if (QB.halted()) { return; } var sourceLines = QB.initArray([{l:1,u:0}], ''); // STRING + var rawJS = 0; // SINGLE var lcount = 0; // INTEGER var i = 0; // INTEGER lcount = (await func_Split( sourceText, GX.LF, sourceLines)); @@ -1391,12 +1399,13 @@ if (QB.halted()) { return; } nextLine = QB.arrayValue(sourceLines, [ i]).value; fline = (QB.func_Left( fline, (QB.func_Len( fline)) - 1)) + nextLine; } - await sub_ReadLine( i, fline); + rawJS = (await func_ReadLine( i, fline, rawJS)); } } } -async function sub_ReadLine(lineIndex/*INTEGER*/,fline/*STRING*/) { +async function func_ReadLine(lineIndex/*INTEGER*/,fline/*STRING*/,rawJS/*INTEGER*/) { if (QB.halted()) { return; } +var ReadLine = null; var quoteDepth = 0; // INTEGER quoteDepth = 0; var i = 0; // INTEGER @@ -1415,13 +1424,34 @@ if (QB.halted()) { return; } break; } } + ReadLine = rawJS; if ((QB.func__Trim( fline)) == "" ) { - return; + return ReadLine; } var word = ''; // STRING var words = QB.initArray([{l:1,u:0}], ''); // STRING var wcount = 0; // INTEGER wcount = (await func_SLSplit( fline, words, False)); + if ( rawJS) { + await sub_AddLine( lineIndex, fline); + return ReadLine; + } + if ((QB.func_UCase( QB.arrayValue(words, [ 1]).value)) == "$IF" && wcount > 1) { + if ((QB.func_UCase( QB.arrayValue(words, [ 2]).value)) == "JAVASCRIPT" ) { + rawJS = True; + await sub_AddLine( lineIndex, fline); + ReadLine = rawJS; + return ReadLine; + } + } + if ((QB.func_UCase( QB.arrayValue(words, [ 1]).value)) == "$END" ) { + if ( rawJS) { + rawJS = ! rawJS; + } + await sub_AddLine( lineIndex, fline); + ReadLine = rawJS; + return ReadLine; + } var ifIdx = 0; // INTEGER var thenIdx = 0; // INTEGER var elseIdx = 0; // INTEGER @@ -1448,6 +1478,7 @@ var elseIdx = 0; // INTEGER } else { await sub_AddSubLines( lineIndex, fline); } +return ReadLine; } async function sub_AddSubLines(lineIndex/*INTEGER*/,fline/*STRING*/) { if (QB.halted()) { return; } @@ -1476,11 +1507,23 @@ async function sub_FindMethods() { if (QB.halted()) { return; } var i = 0; // INTEGER var pcount = 0; // INTEGER + var rawJS = 0; // INTEGER var parts = QB.initArray([{l:1,u:0}], ''); // STRING for ( i= 1; i <= (QB.func_UBound( lines)); i= i + 1) { if (QB.halted()) { return; } pcount = (await func_Split( QB.arrayValue(lines, [ i]).value .text, " ", parts)); var word = ''; // STRING word = (QB.func_UCase( QB.arrayValue(parts, [ 1]).value)); + if ( word == "$IF" && pcount > 1) { + if ((QB.func_UCase( QB.arrayValue(parts, [ 2]).value)) == "JAVASCRIPT" ) { + rawJS = True; + } + } + if ( word == "$END" && rawJS) { + rawJS = False; + } + if ( rawJS) { + continue; + } if ( word == "FUNCTION" || word == "SUB" ) { var m = {line:0,type:'',returnType:'',name:'',uname:'',argc:0,args:'',jsname:'',sync:0}; // METHOD m.line = i; @@ -1825,7 +1868,6 @@ if (QB.halted()) { return; } m.name = prefix + m.name; m.sync = sync; QB.arrayValue(exportMethods, [ mcount]).value = m; - await sub_AddJSLine( 0, "////: " + m.name +" : " + m.uname +" : " + m.jsname); } async function sub_AddGXMethod(mtype/*STRING*/,mname/*STRING*/,sync/*INTEGER*/) { if (QB.halted()) { return; } @@ -2560,23 +2602,6 @@ if (QB.halted()) { return; } await sub_AddQBMethod( "FUNCTION", "FromJSON", False); await sub_AddQBMethod( "FUNCTION", "ToJSON", False); await sub_AddQBMethod( "SUB", "$TouchMouse", False); - await sub_AddQBMethod( "SUB", "Alert", False); - await sub_AddQBMethod( "FUNCTION", "Confirm", False); - await sub_AddQBMethod( "SUB", "DomAdd", False); - await sub_AddQBMethod( "SUB", "DomCreate", False); - await sub_AddQBMethod( "FUNCTION", "DomContainer", False); - await sub_AddQBMethod( "FUNCTION", "DomCreate", False); - await sub_AddQBMethod( "SUB", "DomEvent", False); - await sub_AddQBMethod( "FUNCTION", "DomGet", False); - await sub_AddQBMethod( "FUNCTION", "DomGetImage", False); - await sub_AddQBMethod( "SUB", "DomRemove", False); - await sub_AddQBMethod( "FUNCTION", "Prompt", False); - await sub_AddQBMethod( "SUB", "StorageClear", False); - await sub_AddQBMethod( "FUNCTION", "StorageGet", False); - await sub_AddQBMethod( "FUNCTION", "StorageKey", False); - await sub_AddQBMethod( "FUNCTION", "StorageLength", False); - await sub_AddQBMethod( "SUB", "StorageSet", False); - await sub_AddQBMethod( "SUB", "StorageRemove", False); } this.compile = async function(src) { await sub_QBToJS(src, TEXT, ''); diff --git a/tools/qb2js.bas b/tools/qb2js.bas index c79945a..d0b8b00 100644 --- a/tools/qb2js.bas +++ b/tools/qb2js.bas @@ -336,7 +336,7 @@ Sub ConvertLines (firstLine As Integer, lastLine As Integer, functionName As Str ElseIf first = "$IF" Then If UBound(parts) > 1 Then - If UCase$(parts(2)) = "JS" Or UCase$(parts(2)) = "JAVASCRIPT" Then + If UCase$(parts(2)) = "JAVASCRIPT" Then jsMode = True js = "//-------- BEGIN JS native code block --------" End If @@ -407,46 +407,14 @@ Sub ConvertLines (firstLine As Integer, lastLine As Integer, functionName As Str ElseIf first = "EXPORT" Then If c > 1 Then - Dim exportedItem As String - Dim em As Method - Dim ev As Variable - 'Dim etype As String - Dim exportName As String - exportName = "" - If c > 3 Then exportName = parts(4) + Dim exparts(0) As String + Dim excount As Integer + excount = ListSplit(Join(parts(), 2, -1, " "), exparts()) - If FindMethod(parts(2), em, "SUB") Then - exportedItem = em.jsname - If exportName = "" Then exportName = parts(2) - em.name = exportName - AddExportMethod em, currentModule + ".", True - exportName = "sub_" + exportName - - ElseIf FindMethod(parts(2), em, "FUNCTION") Then - exportedItem = em.jsname - If exportName = "" Then exportName = parts(2) - em.name = exportName - AddExportMethod em, currentModule + ".", True - exportName = "func_" + exportName - - ElseIf FindVariable(parts(2), ev, False) Then - exportedItem = ev.jsname - If exportName = "" Then exportName = parts(2) - ev.name = exportName - - ElseIf FindVariable(parts(2), ev, True) Then - exportedItem = ev.jsname - If exportName = "" Then exportName = parts(2) - ev.name = exportName - Else - ' TODO: add warning - _Continue - End If - - Dim esize - esize = UBound(exportLines) + 1 - ReDim _Preserve exportLines(esize) As String - exportLines(esize) = "this." + exportName + " = " + exportedItem + ";" + Dim exi As Integer + For exi = 1 To excount + ParseExport exparts(exi) + Next exi _Continue Else ' TODO: add syntax warning @@ -522,6 +490,62 @@ Sub ConvertLines (firstLine As Integer, lastLine As Integer, functionName As Str End Sub +Sub ParseExport (s As String) + Dim exportedItem As String + Dim ef As Method + Dim es As Method + Dim ev As Variable + Dim exportName As String + Dim c As Integer + Dim parts(0) As String + c = SLSplit(s, parts(), False) + + If FindMethod(parts(1), es, "SUB") Then + If c > 2 Then + exportName = parts(3) + Else + exportName = parts(1) + End If + exportedItem = es.jsname + es.name = exportName + AddExportMethod es, currentModule + ".", True + exportName = "sub_" + exportName + RegisterExport exportName, exportedItem + End If + + If FindMethod(parts(1), ef, "FUNCTION") Then + If c > 2 Then + exportName = parts(3) + Else + exportName = parts(1) + End If + exportedItem = ef.jsname + ef.name = exportName + AddExportMethod ef, currentModule + ".", True + exportName = "func_" + exportName + RegisterExport exportName, exportedItem + End If + + 'If FindVariable(parts(1), ev, False) Then + ' exportedItem = ev.jsname + ' If exportName = "" Then exportName = parts(1) + ' ev.name = exportName + + 'ElseIf FindVariable(parts(1), ev, True) Then + ' exportedItem = ev.jsname + ' If exportName = "" Then exportName = parts(1) + ' ev.name = exportName + 'End If + +End Sub + +Sub RegisterExport (exportName As String, exportedItem As String) + Dim esize + esize = UBound(exportLines) + 1 + ReDim _Preserve exportLines(esize) As String + exportLines(esize) = "this." + exportName + " = " + exportedItem + ";" +End Sub + Function ConvertSub$ (m As Method, args As String) ' This actually converts the parameters passed to the sub Dim js As String @@ -1417,6 +1441,7 @@ End Sub Sub ReadLinesFromFile (filename As String) Dim fline As String Dim lineIndex As Integer + Dim rawJS Open filename For Input As #1 Do Until EOF(1) Line Input #1, fline @@ -1430,7 +1455,7 @@ Sub ReadLinesFromFile (filename As String) fline = Left$(fline, Len(fline) - 1) + nextLine Wend - ReadLine lineIndex, fline + rawJS = ReadLine(lineIndex, fline, rawJS) End If Loop Close #1 @@ -1438,6 +1463,7 @@ End Sub Sub ReadLinesFromText (sourceText As String) ReDim As String sourceLines(0) + Dim rawJS Dim lcount As Integer Dim i As Integer lcount = Split(sourceText, GX_LF, sourceLines()) @@ -1477,12 +1503,12 @@ Sub ReadLinesFromText (sourceText As String) fline = Left$(fline, Len(fline) - 1) + nextLine Wend - ReadLine i, fline + rawJS = ReadLine(i, fline, rawJS) End If Next i End Sub -Sub ReadLine (lineIndex As Integer, fline As String) +Function ReadLine (lineIndex As Integer, fline As String, rawJS As Integer) ' Step 1: Remove any comments from the line Dim quoteDepth As Integer quoteDepth = 0 @@ -1503,13 +1529,37 @@ Sub ReadLine (lineIndex As Integer, fline As String) End If Next i - If _Trim$(fline) = "" Then Exit Sub + ReadLine = rawJS + + If _Trim$(fline) = "" Then Exit Function + - ' Step 2: Determine whether this line contains a single line if/then or if/then/else statement Dim word As String Dim words(0) As String Dim wcount As Integer wcount = SLSplit(fline, words(), False) + + ' Step 2: Determine whether native js is being included + If rawJS Then + AddLine lineIndex, fline + Exit Function + End If + If UCase$(words(1)) = "$IF" And wcount > 1 Then + If UCase$(words(2)) = "JAVASCRIPT" Then + rawJS = True + AddLine lineIndex, fline + ReadLine = rawJS + Exit Function + End If + End If + If UCase$(words(1)) = "$END" Then + If rawJS Then rawJS = Not rawJS + AddLine lineIndex, fline + ReadLine = rawJS + Exit Function + End If + + ' Step 3: Determine whether this line contains a single line if/then or if/then/else statement Dim As Integer ifIdx, thenIdx, elseIdx For i = 1 To wcount word = UCase$(words(i)) @@ -1532,10 +1582,11 @@ Sub ReadLine (lineIndex As Integer, fline As String) AddSubLines lineIndex, Join(words(), thenIdx + 1, -1, " ") End If AddLine lineIndex, "End If" + Else AddSubLines lineIndex, fline End If -End Sub +End Function Sub AddSubLines (lineIndex As Integer, fline As String) Dim quoteDepth As Integer @@ -1565,11 +1616,19 @@ End Sub Sub FindMethods Dim i As Integer Dim pcount As Integer + Dim rawJS As Integer ReDim As String parts(0) For i = 1 To UBound(lines) pcount = Split(lines(i).text, " ", parts()) Dim word As String: word = UCase$(parts(1)) + + If word = "$IF" And pcount > 1 Then + If UCase$(parts(2)) = "JAVASCRIPT" Then rawJS = True + End If + If word = "$END" And rawJS Then rawJS = False + If rawJS Then _Continue + If word = "FUNCTION" Or word = "SUB" Then Dim m As Method @@ -1965,7 +2024,7 @@ Sub AddExportMethod (m As Method, prefix As String, sync As Integer) m.sync = sync exportMethods(mcount) = m - AddJSLine 0, "////: " + m.name + " : " + m.uname + " : " + m.jsname + 'AddJSLine 0, "////: " + m.name + " : " + m.uname + " : " + m.jsname End Sub Sub AddGXMethod (mtype As String, mname As String, sync As Integer) @@ -2709,23 +2768,6 @@ Sub InitQBMethods AddQBMethod "SUB", "$TouchMouse", False - AddQBMethod "SUB", "Alert", False - AddQBMethod "FUNCTION", "Confirm", False - AddQBMethod "SUB", "DomAdd", False - AddQBMethod "SUB", "DomCreate", False - AddQBMethod "FUNCTION", "DomContainer", False - AddQBMethod "FUNCTION", "DomCreate", False - AddQBMethod "SUB", "DomEvent", False - AddQBMethod "FUNCTION", "DomGet", False - AddQBMethod "FUNCTION", "DomGetImage", False - AddQBMethod "SUB", "DomRemove", False - AddQBMethod "FUNCTION", "Prompt", False - AddQBMethod "SUB", "StorageClear", False - AddQBMethod "FUNCTION", "StorageGet", False - AddQBMethod "FUNCTION", "StorageKey", False - AddQBMethod "FUNCTION", "StorageLength", False - AddQBMethod "SUB", "StorageSet", False - AddQBMethod "SUB", "StorageRemove", False End Sub '$include: '../../gx/gx/gx_str.bm'