mirror of
https://github.com/boxgaming/qbjs.git
synced 2024-05-12 08:00:12 +00:00
added initial support for module Import/Export
This commit is contained in:
parent
afa7eae5bb
commit
223f923077
174
qb2js.js
174
qb2js.js
|
@ -20,26 +20,25 @@ async function _QBCompiler() {
|
|||
var globalVars = QB.initArray([{l:1,u:0}], {type:'',name:'',jsname:'',isConst:0,isArray:0,arraySize:0,typeId:0}); // VARIABLE
|
||||
var localVars = QB.initArray([{l:1,u:0}], {type:'',name:'',jsname:'',isConst:0,isArray:0,arraySize:0,typeId:0}); // VARIABLE
|
||||
var warnings = QB.initArray([{l:1,u:0}], {line:0,text:''}); // CODELINE
|
||||
var exportLines = QB.initArray([{l:1,u:0}], ''); // STRING
|
||||
var exportMethods = QB.initArray([{l:1,u:0}], {line:0,type:'',returnType:'',name:'',uname:'',argc:0,args:'',jsname:'',sync:0}); // METHOD
|
||||
var modLevel = 0; // INTEGER
|
||||
var currentMethod = ''; // STRING
|
||||
var currentModule = ''; // STRING
|
||||
var programMethods = 0; // INTEGER
|
||||
if (QB.func_Command() != "" ) {
|
||||
await sub_QBToJS( QB.func_Command(), FILE);
|
||||
await sub_QBToJS( QB.func_Command(), FILE, "");
|
||||
await sub_PrintJS();
|
||||
QB.halt(); return;
|
||||
}
|
||||
|
||||
async function sub_QBToJS(source/*STRING*/,sourceType/*INTEGER*/) {
|
||||
async function sub_QBToJS(source/*STRING*/,sourceType/*INTEGER*/,moduleName/*STRING*/) {
|
||||
if (QB.halted()) { return; }
|
||||
QB.resizeArray(lines, [{l:1,u:0}], {line:0,text:''}, false); // CODELINE
|
||||
QB.resizeArray(jsLines, [{l:1,u:0}], {line:0,text:''}, false); // CODELINE
|
||||
QB.resizeArray(methods, [{l:1,u:0}], {line:0,type:'',returnType:'',name:'',uname:'',argc:0,args:'',jsname:'',sync:0}, false); // METHOD
|
||||
QB.resizeArray(types, [{l:1,u:0}], {line:0,name:'',argc:0,args:''}, false); // QBTYPE
|
||||
QB.resizeArray(typeVars, [{l:1,u:0}], {type:'',name:'',jsname:'',isConst:0,isArray:0,arraySize:0,typeId:0}, false); // VARIABLE
|
||||
QB.resizeArray(globalVars, [{l:1,u:0}], {type:'',name:'',jsname:'',isConst:0,isArray:0,arraySize:0,typeId:0}, false); // VARIABLE
|
||||
QB.resizeArray(localVars, [{l:1,u:0}], {type:'',name:'',jsname:'',isConst:0,isArray:0,arraySize:0,typeId:0}, false); // VARIABLE
|
||||
QB.resizeArray(warnings, [{l:1,u:0}], {line:0,text:''}, false); // CODELINE
|
||||
currentMethod = "";
|
||||
programMethods = 0;
|
||||
currentModule = moduleName;
|
||||
await sub_ResetDataStructures();
|
||||
if ( moduleName == "" ) {
|
||||
QB.resizeArray(jsLines, [{l:1,u:0}], {line:0,text:''}, false); // CODELINE
|
||||
}
|
||||
if ( sourceType == FILE) {
|
||||
await sub_ReadLinesFromFile( source);
|
||||
} else {
|
||||
|
@ -57,13 +56,15 @@ if (QB.halted()) { return; }
|
|||
}
|
||||
if ( selfConvert) {
|
||||
await sub_AddJSLine( 0, "async function _QBCompiler() {");
|
||||
} else if ( moduleName != "" ) {
|
||||
await sub_AddJSLine( 0, "async function _" + moduleName +"() {");
|
||||
} else if ( sourceType == FILE) {
|
||||
await sub_AddJSLine( 0, "async function init() {");
|
||||
}
|
||||
if (! selfConvert) {
|
||||
if (! selfConvert && moduleName == "" ) {
|
||||
await sub_AddJSLine( 0, "QB.start();");
|
||||
}
|
||||
if (! selfConvert) {
|
||||
if (! selfConvert && moduleName == "" ) {
|
||||
var mtest = {line:0,type:'',returnType:'',name:'',uname:'',argc:0,args:'',jsname:'',sync:0}; // METHOD
|
||||
if ((await func_FindMethod( "GXOnGameEvent", mtest, "SUB")) ) {
|
||||
await sub_AddJSLine( 0, " await GX.registerGameEvents(sub_GXOnGameEvent);");
|
||||
|
@ -75,13 +76,13 @@ if (QB.halted()) { return; }
|
|||
}
|
||||
await sub_AddJSLine( 0, "");
|
||||
await sub_ConvertLines( 1, await func_MainEnd(), "");
|
||||
if (! selfConvert && ! isGX) {
|
||||
if (! selfConvert && ! isGX && moduleName == "" ) {
|
||||
await sub_AddJSLine( 0, "QB.end();");
|
||||
}
|
||||
await sub_ConvertMethods();
|
||||
if ( selfConvert) {
|
||||
await sub_AddJSLine( 0, "this.compile = async function(src) {");
|
||||
await sub_AddJSLine( 0, " await sub_QBToJS(src, TEXT);");
|
||||
await sub_AddJSLine( 0, " await sub_QBToJS(src, TEXT, '');");
|
||||
await sub_AddJSLine( 0, " var js = '';");
|
||||
await sub_AddJSLine( 0, " for (var i=1; i<= QB.func_UBound(jsLines); i++) {");
|
||||
await sub_AddJSLine( 0, " js += QB.arrayValue(jsLines, [i]).value.text + '\\n';");
|
||||
|
@ -100,10 +101,29 @@ if (QB.halted()) { return; }
|
|||
await sub_AddJSLine( 0, "};");
|
||||
await sub_AddJSLine( 0, "return this;");
|
||||
await sub_AddJSLine( 0, "}");
|
||||
} else if ( moduleName != "" ) {
|
||||
await sub_AddJSLine( 0, "return this;");
|
||||
await sub_AddJSLine( 0, "}");
|
||||
await sub_AddJSLine( 0, "const " + moduleName +" = await _" + moduleName +"();");
|
||||
} else if ( sourceType == FILE) {
|
||||
await sub_AddJSLine( 0, "};");
|
||||
}
|
||||
}
|
||||
async function sub_ResetDataStructures() {
|
||||
if (QB.halted()) { return; }
|
||||
QB.resizeArray(lines, [{l:1,u:0}], {line:0,text:''}, false); // CODELINE
|
||||
QB.resizeArray(methods, [{l:1,u:0}], {line:0,type:'',returnType:'',name:'',uname:'',argc:0,args:'',jsname:'',sync:0}, false); // METHOD
|
||||
QB.resizeArray(types, [{l:1,u:0}], {line:0,name:'',argc:0,args:''}, false); // QBTYPE
|
||||
QB.resizeArray(typeVars, [{l:1,u:0}], {type:'',name:'',jsname:'',isConst:0,isArray:0,arraySize:0,typeId:0}, false); // VARIABLE
|
||||
QB.resizeArray(globalVars, [{l:1,u:0}], {type:'',name:'',jsname:'',isConst:0,isArray:0,arraySize:0,typeId:0}, false); // VARIABLE
|
||||
QB.resizeArray(localVars, [{l:1,u:0}], {type:'',name:'',jsname:'',isConst:0,isArray:0,arraySize:0,typeId:0}, false); // VARIABLE
|
||||
QB.resizeArray(warnings, [{l:1,u:0}], {line:0,text:''}, false); // CODELINE
|
||||
if ( modLevel == 0) {
|
||||
QB.resizeArray(exportMethods, [{l:1,u:0}], {line:0,type:'',returnType:'',name:'',uname:'',argc:0,args:'',jsname:'',sync:0}, false); // METHOD
|
||||
}
|
||||
currentMethod = "";
|
||||
programMethods = 0;
|
||||
}
|
||||
async function sub_PrintJS() {
|
||||
if (QB.halted()) { return; }
|
||||
var i = 0; // INTEGER
|
||||
|
@ -262,7 +282,7 @@ if (QB.halted()) { return; }
|
|||
} else if ( first == "SYSTEM" ) {
|
||||
js = "QB.halt(); return;";
|
||||
} else if ( first == "$IF" ) {
|
||||
if ((QB.func_UBound( parts)) == 2) {
|
||||
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" ) {
|
||||
jsMode = True;
|
||||
js = "//-------- BEGIN JS native code block --------";
|
||||
|
@ -323,6 +343,54 @@ if (QB.halted()) { return; }
|
|||
qbtype.name = (QB.func_UCase( QB.arrayValue(parts, [ 2]).value));
|
||||
await sub_AddType( qbtype);
|
||||
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;
|
||||
}
|
||||
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 {
|
||||
}
|
||||
} else if ( first == "CALL" ) {
|
||||
var subline = ''; // STRING
|
||||
subline = (QB.func__Trim( (await func_Join( parts, 2, -1, " "))));
|
||||
|
@ -712,7 +780,9 @@ var ConvertInput = null;
|
|||
js = "var " + vname +" = new Array(" +(QB.func_Str( (QB.func_UBound( vars)))) +");" + GX.LF;
|
||||
js = js +(await func_CallMethod( m)) +"(" + vname +", " + preventNewline +", " + addQuestionPrompt +", " + prompt +");" + GX.LF;
|
||||
for ( i= 1; i <= (QB.func_UBound( vars)); i= i + 1) { if (QB.halted()) { return; }
|
||||
js = js +(await func_ConvertExpression( QB.arrayValue(vars, [ i]).value)) +" = " + vname +"[" +(QB.func_Str( i - 1)) +"];" + GX.LF;
|
||||
if (!(await func_StartsWith( (QB.func__Trim( QB.arrayValue(vars, [ i]).value)), "#")) ) {
|
||||
js = js +(await func_ConvertExpression( QB.arrayValue(vars, [ i]).value)) +" = " + vname +"[" +(QB.func_Str( i - 1)) +"];" + GX.LF;
|
||||
}
|
||||
}
|
||||
ConvertInput = js;
|
||||
return ConvertInput;
|
||||
|
@ -1181,6 +1251,23 @@ var FindMethod = null;
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (! found) {
|
||||
for ( i= 1; i <= (QB.func_UBound( exportMethods)); i= i + 1) { if (QB.halted()) { return; }
|
||||
if (QB.arrayValue(exportMethods, [ i]).value .uname == (QB.func__Trim( (QB.func_UCase( (await func_RemoveSuffix( mname)))))) && QB.arrayValue(exportMethods, [ i]).value .type == t) {
|
||||
found = True;
|
||||
m.line = QB.arrayValue(exportMethods, [ i]).value .line;
|
||||
m.type = QB.arrayValue(exportMethods, [ i]).value .type;
|
||||
m.returnType = QB.arrayValue(exportMethods, [ i]).value .returnType;
|
||||
m.name = QB.arrayValue(exportMethods, [ i]).value .name;
|
||||
m.jsname = QB.arrayValue(exportMethods, [ i]).value .jsname;
|
||||
m.uname = QB.arrayValue(exportMethods, [ i]).value .uname;
|
||||
m.argc = QB.arrayValue(exportMethods, [ i]).value .argc;
|
||||
m.args = QB.arrayValue(exportMethods, [ i]).value .args;
|
||||
m.sync = QB.arrayValue(exportMethods, [ i]).value .sync;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
FindMethod = found;
|
||||
return FindMethod;
|
||||
}
|
||||
|
@ -1238,6 +1325,10 @@ if (QB.halted()) { return; }
|
|||
await sub_AddJSLine( lastLine, "}");
|
||||
}
|
||||
}
|
||||
for ( i= 1; i <= (QB.func_UBound( exportLines)); i= i + 1) { if (QB.halted()) { return; }
|
||||
await sub_AddJSLine( i, QB.arrayValue(exportLines, [ i]).value);
|
||||
}
|
||||
QB.resizeArray(exportLines, [{l:1,u:0}], '', false); // STRING
|
||||
}
|
||||
async function sub_ReadLinesFromFile(filename/*STRING*/) {
|
||||
if (QB.halted()) { return; }
|
||||
|
@ -1247,7 +1338,6 @@ if (QB.halted()) { return; }
|
|||
while (!(( 1))) { if (QB.halted()) { return; }
|
||||
var ___v7055475 = new Array( 2);
|
||||
QB.sub_LineInput(___v7055475, false, false, undefined);
|
||||
// #1 = ___v7055475[ 0];
|
||||
fline = ___v7055475[ 1];
|
||||
|
||||
lineIndex = lineIndex + 1;
|
||||
|
@ -1256,7 +1346,6 @@ QB.sub_LineInput(___v7055475, false, false, undefined);
|
|||
var nextLine = ''; // STRING
|
||||
var ___v5334240 = new Array( 2);
|
||||
QB.sub_LineInput(___v5334240, false, false, undefined);
|
||||
// #1 = ___v5334240[ 0];
|
||||
nextLine = ___v5334240[ 1];
|
||||
|
||||
fline = (QB.func_Left( fline, (QB.func_Len( fline)) - 1)) + nextLine;
|
||||
|
@ -1278,6 +1367,24 @@ if (QB.halted()) { return; }
|
|||
if ((QB.func__Trim( fline)) != "" ) {
|
||||
var lineIndex = 0; // INTEGER
|
||||
lineIndex = i;
|
||||
if ((await func_StartsWith( (QB.func_UCase( fline)), "IMPORT")) ) {
|
||||
var parts = QB.initArray([{l:1,u:0}], ''); // STRING
|
||||
var pcount = 0; // INTEGER
|
||||
pcount = (await func_SLSplit( fline, parts, False));
|
||||
if ( pcount == 4) {
|
||||
var moduleName = ''; // STRING
|
||||
var sourceUrl = ''; // STRING
|
||||
var importRes = {ok:0,status:0,statusText:'',text:''}; // FETCHRESPONSE
|
||||
moduleName = QB.arrayValue(parts, [ 2]).value;
|
||||
sourceUrl = (QB.func_Mid( QB.arrayValue(parts, [ 4]).value, 2, (QB.func_Len( QB.arrayValue(parts, [ 4]).value)) - 2));
|
||||
await QB.sub_Fetch( sourceUrl, importRes);
|
||||
modLevel = modLevel + 1;
|
||||
await sub_QBToJS( importRes.text, TEXT, moduleName);
|
||||
await sub_ResetDataStructures();
|
||||
modLevel = modLevel - 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
while ((await func_EndsWith( fline, "_"))) { if (QB.halted()) { return; }
|
||||
i = i + 1;
|
||||
var nextLine = ''; // STRING
|
||||
|
@ -1684,6 +1791,13 @@ if (QB.halted()) { return; }
|
|||
}
|
||||
}
|
||||
}
|
||||
async function func_CopyMethod(fromMethod/*METHOD*/,toMethod/*METHOD*/) {
|
||||
if (QB.halted()) { return; }
|
||||
var CopyMethod = null;
|
||||
toMethod.type = fromMethod.type;
|
||||
toMethod.name = fromMethod.name;
|
||||
return CopyMethod;
|
||||
}
|
||||
async function sub_AddMethod(m/*METHOD*/,prefix/*STRING*/,sync/*INTEGER*/) {
|
||||
if (QB.halted()) { return; }
|
||||
var mcount = 0; // SINGLE
|
||||
|
@ -1697,6 +1811,22 @@ if (QB.halted()) { return; }
|
|||
m.sync = sync;
|
||||
QB.arrayValue(methods, [ mcount]).value = m;
|
||||
}
|
||||
async function sub_AddExportMethod(m/*METHOD*/,prefix/*STRING*/,sync/*INTEGER*/) {
|
||||
if (QB.halted()) { return; }
|
||||
var mcount = 0; // SINGLE
|
||||
mcount = (QB.func_UBound( exportMethods)) + 1;
|
||||
QB.resizeArray(exportMethods, [{l:1,u:mcount}], {line:0,type:'',returnType:'',name:'',uname:'',argc:0,args:'',jsname:'',sync:0}, true); // METHOD
|
||||
if ( m.type == "FUNCTION" ) {
|
||||
m.returnType = (await func_DataTypeFromName( m.name));
|
||||
}
|
||||
m.uname = (QB.func_UCase( (await func_RemoveSuffix( m.name))));
|
||||
m.jsname = (await func_MethodJS( m, prefix));
|
||||
m.uname = (QB.func_UCase( prefix)) + m.uname;
|
||||
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; }
|
||||
var mcount = 0; // SINGLE
|
||||
|
@ -2423,8 +2553,10 @@ if (QB.halted()) { return; }
|
|||
await sub_AddQBConst( "SESSION");
|
||||
await sub_AddSystemType( "FETCHRESPONSE", "ok:INTEGER,status:INTEGER,statusText:STRING,text:STRING");
|
||||
await sub_AddQBMethod( "FUNCTION", "Fetch", True);
|
||||
await sub_AddQBMethod( "SUB", "Fetch", True);
|
||||
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);
|
||||
|
@ -2444,7 +2576,7 @@ if (QB.halted()) { return; }
|
|||
await sub_AddQBMethod( "SUB", "StorageRemove", False);
|
||||
}
|
||||
this.compile = async function(src) {
|
||||
await sub_QBToJS(src, TEXT);
|
||||
await sub_QBToJS(src, TEXT, '');
|
||||
var js = '';
|
||||
for (var i=1; i<= QB.func_UBound(jsLines); i++) {
|
||||
js += QB.arrayValue(jsLines, [i]).value.text + '\n';
|
||||
|
|
178
tools/qb2js.bas
178
tools/qb2js.bas
|
@ -54,30 +54,28 @@ ReDim Shared As Variable typeVars(0)
|
|||
ReDim Shared As Variable globalVars(0)
|
||||
ReDim Shared As Variable localVars(0)
|
||||
ReDim Shared As CodeLine warnings(0)
|
||||
ReDim Shared As String exportLines(0)
|
||||
ReDim Shared As Method exportMethods(0)
|
||||
Dim Shared modLevel As Integer
|
||||
Dim Shared As String currentMethod
|
||||
Dim Shared As String currentModule
|
||||
Dim Shared As Integer programMethods
|
||||
|
||||
|
||||
' Only execute the conversion from the native version if we have been passed the
|
||||
' source file to convert on the command line
|
||||
If Command$ <> "" Then
|
||||
QBToJS Command$, FILE
|
||||
QBToJS Command$, FILE, ""
|
||||
PrintJS
|
||||
System
|
||||
End If
|
||||
|
||||
Sub QBToJS (source As String, sourceType As Integer)
|
||||
' Reset data structures
|
||||
ReDim As CodeLine lines(0)
|
||||
ReDim As CodeLine jsLines(0)
|
||||
ReDim As Method methods(0)
|
||||
ReDim As QBType types(0)
|
||||
ReDim As Variable typeVars(0)
|
||||
ReDim As Variable globalVars(0)
|
||||
ReDim As Variable localVars(0)
|
||||
ReDim As CodeLine warnings(0)
|
||||
currentMethod = ""
|
||||
programMethods = 0
|
||||
'$Include: 'qb2js.bi'
|
||||
|
||||
Sub QBToJS (source As String, sourceType As Integer, moduleName As String)
|
||||
currentModule = moduleName
|
||||
|
||||
ResetDataStructures
|
||||
If moduleName = "" Then ReDim As CodeLine jsLines(0)
|
||||
|
||||
If sourceType = FILE Then
|
||||
ReadLinesFromFile source
|
||||
|
@ -102,13 +100,16 @@ Sub QBToJS (source As String, sourceType As Integer)
|
|||
If selfConvert Then
|
||||
AddJSLine 0, "async function _QBCompiler() {"
|
||||
|
||||
ElseIf moduleName <> "" Then
|
||||
AddJSLine 0, "async function _" + moduleName + "() {"
|
||||
|
||||
ElseIf sourceType = FILE Then
|
||||
AddJSLine 0, "async function init() {"
|
||||
End If
|
||||
|
||||
If Not selfConvert Then AddJSLine 0, "QB.start();"
|
||||
If Not selfConvert And moduleName = "" Then AddJSLine 0, "QB.start();"
|
||||
|
||||
If Not selfConvert Then
|
||||
If Not selfConvert And moduleName = "" Then
|
||||
Dim mtest As Method
|
||||
If FindMethod("GXOnGameEvent", mtest, "SUB") Then
|
||||
AddJSLine 0, " await GX.registerGameEvents(sub_GXOnGameEvent);"
|
||||
|
@ -121,13 +122,14 @@ Sub QBToJS (source As String, sourceType As Integer)
|
|||
AddJSLine 0, ""
|
||||
|
||||
ConvertLines 1, MainEnd, ""
|
||||
If Not selfConvert And Not isGX Then AddJSLine 0, "QB.end();"
|
||||
If Not selfConvert And Not isGX And moduleName = "" Then AddJSLine 0, "QB.end();"
|
||||
'If Not selfConvert And moduleName = "" Then End
|
||||
ConvertMethods
|
||||
|
||||
|
||||
If selfConvert Then
|
||||
AddJSLine 0, "this.compile = async function(src) {"
|
||||
AddJSLine 0, " await sub_QBToJS(src, TEXT);"
|
||||
AddJSLine 0, " await sub_QBToJS(src, TEXT, '');"
|
||||
AddJSLine 0, " var js = '';"
|
||||
AddJSLine 0, " for (var i=1; i<= QB.func_UBound(jsLines); i++) {"
|
||||
AddJSLine 0, " js += QB.arrayValue(jsLines, [i]).value.text + '\n';"
|
||||
|
@ -146,11 +148,30 @@ Sub QBToJS (source As String, sourceType As Integer)
|
|||
AddJSLine 0, "};"
|
||||
AddJSLine 0, "return this;"
|
||||
AddJSLine 0, "}"
|
||||
|
||||
ElseIf moduleName <> "" Then
|
||||
AddJSLine 0, "return this;"
|
||||
AddJSLine 0, "}"
|
||||
AddJSLine 0, "const " + moduleName + " = await _" + moduleName + "();"
|
||||
|
||||
ElseIf sourceType = FILE Then
|
||||
AddJSLine 0, "};"
|
||||
End If
|
||||
End Sub
|
||||
|
||||
Sub ResetDataStructures
|
||||
ReDim As CodeLine lines(0)
|
||||
ReDim As Method methods(0)
|
||||
ReDim As QBType types(0)
|
||||
ReDim As Variable typeVars(0)
|
||||
ReDim As Variable globalVars(0)
|
||||
ReDim As Variable localVars(0)
|
||||
ReDim As CodeLine warnings(0)
|
||||
If modLevel = 0 Then ReDim As Method exportMethods(0)
|
||||
currentMethod = ""
|
||||
programMethods = 0
|
||||
End Sub
|
||||
|
||||
Sub PrintJS
|
||||
Dim i As Integer
|
||||
For i = 1 To UBound(jsLines)
|
||||
|
@ -211,6 +232,7 @@ Sub ConvertLines (firstLine As Integer, lastLine As Integer, functionName As Str
|
|||
End If
|
||||
Else
|
||||
If first = "CONST" Then
|
||||
' TODO: add support for comma-separated list of constants
|
||||
js = "const " + parts(2) + " = " + ConvertExpression(Join(parts(), 4, -1, " ")) + ";"
|
||||
AddConst parts(2)
|
||||
|
||||
|
@ -313,7 +335,7 @@ Sub ConvertLines (firstLine As Integer, lastLine As Integer, functionName As Str
|
|||
js = "QB.halt(); return;"
|
||||
|
||||
ElseIf first = "$IF" Then
|
||||
If UBound(parts) = 2 Then
|
||||
If UBound(parts) > 1 Then
|
||||
If UCase$(parts(2)) = "JS" Or UCase$(parts(2)) = "JAVASCRIPT" Then
|
||||
jsMode = True
|
||||
js = "//-------- BEGIN JS native code block --------"
|
||||
|
@ -383,6 +405,53 @@ Sub ConvertLines (firstLine As Integer, lastLine As Integer, functionName As Str
|
|||
AddType qbtype
|
||||
currType = UBound(types)
|
||||
|
||||
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)
|
||||
|
||||
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 + ";"
|
||||
_Continue
|
||||
Else
|
||||
' TODO: add syntax warning
|
||||
End If
|
||||
|
||||
ElseIf first = "CALL" Then
|
||||
Dim subline As String
|
||||
subline = _Trim$(Join(parts(), 2, -1, " "))
|
||||
|
@ -782,7 +851,9 @@ Function ConvertInput$ (m As Method, args As String)
|
|||
js = "var " + vname + " = new Array(" + Str$(UBound(vars)) + ");" + GX_LF
|
||||
js = js + CallMethod(m) + "(" + vname + ", " + preventNewline + ", " + addQuestionPrompt + ", " + prompt + ");" + GX_LF
|
||||
For i = 1 To UBound(vars)
|
||||
js = js + ConvertExpression(vars(i)) + " = " + vname + "[" + Str$(i - 1) + "];" + GX_LF
|
||||
If Not StartsWith(_Trim$(vars(i)), "#") Then ' special case to prevent file references from being output during self-compilation
|
||||
js = js + ConvertExpression(vars(i)) + " = " + vname + "[" + Str$(i - 1) + "];" + GX_LF
|
||||
End If
|
||||
Next i
|
||||
ConvertInput = js
|
||||
End Function
|
||||
|
@ -1250,6 +1321,24 @@ Function FindMethod (mname As String, m As Method, t As String)
|
|||
Exit For
|
||||
End If
|
||||
Next i
|
||||
If Not found Then
|
||||
For i = 1 To UBound(exportMethods)
|
||||
If exportMethods(i).uname = _Trim$(UCase$(RemoveSuffix(mname))) And exportMethods(i).type = t Then
|
||||
found = True
|
||||
m.line = exportMethods(i).line
|
||||
m.type = exportMethods(i).type
|
||||
m.returnType = exportMethods(i).returnType
|
||||
m.name = exportMethods(i).name
|
||||
m.jsname = exportMethods(i).jsname
|
||||
m.uname = exportMethods(i).uname
|
||||
m.argc = exportMethods(i).argc
|
||||
m.args = exportMethods(i).args
|
||||
m.sync = exportMethods(i).sync
|
||||
Exit For
|
||||
End If
|
||||
Next i
|
||||
|
||||
End If
|
||||
FindMethod = found
|
||||
End Function
|
||||
|
||||
|
@ -1316,6 +1405,12 @@ Sub ConvertMethods ()
|
|||
AddJSLine lastLine, "}"
|
||||
End If
|
||||
Next i
|
||||
|
||||
' Add the export lines
|
||||
For i = 1 To UBound(exportLines)
|
||||
AddJSLine i, exportLines(i)
|
||||
Next i
|
||||
ReDim exportLines(0) As String
|
||||
End Sub
|
||||
|
||||
|
||||
|
@ -1355,6 +1450,26 @@ Sub ReadLinesFromText (sourceText As String)
|
|||
Dim lineIndex As Integer
|
||||
lineIndex = i
|
||||
|
||||
If StartsWith(UCase$(fline), "IMPORT") Then
|
||||
ReDim parts(0) As String
|
||||
Dim pcount As Integer
|
||||
pcount = SLSplit(fline, parts(), False)
|
||||
If pcount = 4 Then
|
||||
Dim moduleName As String
|
||||
Dim sourceUrl As String
|
||||
Dim importRes As FetchResponse
|
||||
moduleName = parts(2)
|
||||
sourceUrl = Mid$(parts(4), 2, Len(parts(4)) - 2)
|
||||
Fetch sourceUrl, importRes
|
||||
modLevel = modLevel + 1
|
||||
QBToJS importRes.text, TEXT, moduleName
|
||||
ResetDataStructures
|
||||
modLevel = modLevel - 1
|
||||
|
||||
_Continue
|
||||
End If
|
||||
End If
|
||||
|
||||
While EndsWith(fline, "_")
|
||||
i = i + 1
|
||||
Dim nextLine As String
|
||||
|
@ -1820,6 +1935,10 @@ Sub PrintTypes
|
|||
Next i
|
||||
End Sub
|
||||
|
||||
Function CopyMethod (fromMethod As Method, toMethod As Method)
|
||||
toMethod.type = fromMethod.type
|
||||
toMethod.name = fromMethod.name
|
||||
End Function
|
||||
|
||||
Sub AddMethod (m As Method, prefix As String, sync As Integer)
|
||||
Dim mcount: mcount = UBound(methods) + 1
|
||||
|
@ -1833,6 +1952,22 @@ Sub AddMethod (m As Method, prefix As String, sync As Integer)
|
|||
methods(mcount) = m
|
||||
End Sub
|
||||
|
||||
Sub AddExportMethod (m As Method, prefix As String, sync As Integer)
|
||||
Dim mcount: mcount = UBound(exportMethods) + 1
|
||||
ReDim _Preserve As Method exportMethods(mcount)
|
||||
If m.type = "FUNCTION" Then
|
||||
m.returnType = DataTypeFromName(m.name)
|
||||
End If
|
||||
m.uname = UCase$(RemoveSuffix(m.name))
|
||||
m.jsname = MethodJS(m, prefix)
|
||||
m.uname = UCase$(prefix) + m.uname
|
||||
m.name = prefix + m.name
|
||||
m.sync = sync
|
||||
exportMethods(mcount) = m
|
||||
|
||||
AddJSLine 0, "////: " + m.name + " : " + m.uname + " : " + m.jsname
|
||||
End Sub
|
||||
|
||||
Sub AddGXMethod (mtype As String, mname As String, sync As Integer)
|
||||
Dim mcount: mcount = UBound(methods) + 1
|
||||
ReDim _Preserve As Method methods(mcount)
|
||||
|
@ -2565,9 +2700,12 @@ Sub InitQBMethods
|
|||
|
||||
AddSystemType "FETCHRESPONSE", "ok:INTEGER,status:INTEGER,statusText:STRING,text:STRING"
|
||||
AddQBMethod "FUNCTION", "Fetch", True
|
||||
AddQBMethod "SUB", "Fetch", True
|
||||
AddQBMethod "FUNCTION", "FromJSON", False
|
||||
AddQBMethod "FUNCTION", "ToJSON", False
|
||||
|
||||
AddQBMethod "SUB", "$TouchMouse", False
|
||||
|
||||
AddQBMethod "SUB", "Alert", False
|
||||
AddQBMethod "FUNCTION", "Confirm", False
|
||||
AddQBMethod "SUB", "DomAdd", False
|
||||
|
|
9
tools/qb2js.bi
Normal file
9
tools/qb2js.bi
Normal file
|
@ -0,0 +1,9 @@
|
|||
' Define web-only types and methods needed for compilation
|
||||
Type FetchResponse
|
||||
ok As Integer
|
||||
status As Integer
|
||||
statusText As String
|
||||
text As String
|
||||
End Type
|
||||
|
||||
Sub Fetch (url As String, response As FetchResponse): End Sub
|
Loading…
Reference in a new issue