Skip to content

Commit

Permalink
Added support for qb2js to compile itself from its own source via nodejs
Browse files Browse the repository at this point in the history
  • Loading branch information
boxgaming committed Oct 11, 2024
1 parent d738122 commit 35ecfaf
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 14 deletions.
23 changes: 18 additions & 5 deletions qb2js.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ async function _QBCompiler() {
var programMethods = 0; /* INTEGER */
var staticVarLine = 0; /* INTEGER */
var condWords = QB.initArray([{l:0,u:4}], ''); /* STRING */
var forceSelfConvert = 0; /* INTEGER */
if (QB.func_Command() != "" ) {
await sub_QBToJS( QB.func_Command(), FILE, "");
await sub_PrintJS();
Expand Down Expand Up @@ -70,6 +71,9 @@ if (QB.halted()) { return; }; sourceType = Math.round(sourceType);
if ( sourceType == FILE) {
selfConvert = (await func_EndsWith( source, "qb2js.bas"));
}
if ( forceSelfConvert) {
selfConvert = True;
}
if ( selfConvert) {
await sub_AddJSLine( 0, "if (typeof QB == 'undefined' && module) { QB = require('./qb-console.js').QB(); }");
await sub_AddJSLine( 0, "async function _QBCompiler() {");
Expand Down Expand Up @@ -162,24 +166,30 @@ if (QB.halted()) { return; }; sourceType = Math.round(sourceType);
await sub_AddJSLine( 0, " line = QB.arrayValue(lines, [line]).value.line;");
await sub_AddJSLine( 0, " return line;");
await sub_AddJSLine( 0, "}");
await sub_AddJSLine( 0, "function setSelfConvert() { sub_SetSelfConvert(); }");
await sub_AddJSLine( 0, "");
await sub_AddJSLine( 0, "return {");
await sub_AddJSLine( 0, " compile: compile,");
await sub_AddJSLine( 0, " getWarnings: getWarnings,");
await sub_AddJSLine( 0, " getMethods: getMethods,");
await sub_AddJSLine( 0, " getExportMethods: getExportMethods,");
await sub_AddJSLine( 0, " getExportConsts: getExportConsts,");
await sub_AddJSLine( 0, " getSourceLine: getSourceLine");
await sub_AddJSLine( 0, " getSourceLine: getSourceLine,");
await sub_AddJSLine( 0, " setSelfConvert: setSelfConvert,");
await sub_AddJSLine( 0, "};");
await sub_AddJSLine( 0, "}");
await sub_AddJSLine( 0, "if (module) { module.exports.QBCompiler = _QBCompiler; }");
await sub_AddJSLine( 0, "if (typeof module != 'undefined') { module.exports.QBCompiler = _QBCompiler; }");
} else if ( moduleName != "" ) {
await sub_AddJSLine( 0, "}");
await sub_AddJSLine( 0, "const " + moduleName + " = await _" + moduleName + "();");
} else if ( sourceType == FILE) {
await sub_AddJSLine( 0, "};");
}
}
async function sub_SetSelfConvert() {
if (QB.halted()) { return; };
forceSelfConvert = True;
}
async function sub_InitTypes() {
if (QB.halted()) { return; };
var i = 0; /* INTEGER */ var j = 0; /* INTEGER */ var jsidx = 0; /* INTEGER */
Expand Down Expand Up @@ -2256,10 +2266,11 @@ if (QB.halted()) { return; };
continue;
}
}
var ___v4744592 = 0; ___l1556631: while ((await func_EndsWith( fline, "_"))) { if (QB.halted()) { return; }___v4744592++; if (___v4744592 % 100 == 0) { await QB.autoLimit(); }
fline = (await func_Replace( fline, await func_CR(), ""));
var ___v4744592 = 0; ___l1556631: while ((await func_EndsWith( fline, " _"))) { if (QB.halted()) { return; }___v4744592++; if (___v4744592 % 100 == 0) { await QB.autoLimit(); }
i = i + 1;
var nextLine = ''; /* STRING */
nextLine = QB.arrayValue(sourceLines, [ i]).value;
nextLine = (await func_Replace( QB.arrayValue(sourceLines, [ i]).value , await func_CR(), ""));
fline = (QB.func_Left( fline, (QB.func_Len( fline)) - 1)) + nextLine;
}
rawJS = (await func_ReadLine( i, fline, rawJS));
Expand Down Expand Up @@ -3873,14 +3884,16 @@ function getSourceLine(jsLine) {
line = QB.arrayValue(lines, [line]).value.line;
return line;
}
function setSelfConvert() { sub_SetSelfConvert(); }

return {
compile: compile,
getWarnings: getWarnings,
getMethods: getMethods,
getExportMethods: getExportMethods,
getExportConsts: getExportConsts,
getSourceLine: getSourceLine
getSourceLine: getSourceLine,
setSelfConvert: setSelfConvert,
};
}
if (typeof module != 'undefined') { module.exports.QBCompiler = _QBCompiler; }
13 changes: 11 additions & 2 deletions qbc.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,17 @@ async function compile(src) {
const qbc = await require("./qb2js.js").QBCompiler();
const fs = require("fs");

const data = fs.readFileSync(process.argv[2], "utf8");
var result = "async function __qbjs_run() {\n" + await qbc.compile(data) + "\n}";
const sourceFile = process.argv[2];
const data = fs.readFileSync(sourceFile, "utf8");

var result = "";
if (sourceFile.endsWith("qb2js.bas")) {
qbc.setSelfConvert();
result = await qbc.compile(data);
}
else {
result = "async function __qbjs_run() {\n" + await qbc.compile(data) + "\n}";
}
fs.writeFileSync(process.argv[3], result, "utf8");

var warnings = qbc.getWarnings();
Expand Down
22 changes: 15 additions & 7 deletions tools/qb2js.bas
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ Dim Shared As String currentModule
Dim Shared As Integer programMethods
Dim Shared As Integer staticVarLine
Dim Shared As String condWords(4)
Dim Shared As Integer forceSelfConvert

' Only execute the conversion from the native version if we have been passed the
' source file to convert on the command line
Expand Down Expand Up @@ -124,6 +125,7 @@ Sub QBToJS (source As String, sourceType As Integer, moduleName As String)
Dim selfConvert As Integer
Dim isGX As Integer: isGX = False
If sourceType = FILE Then selfConvert = EndsWith(source, "qb2js.bas")
If forceSelfConvert Then selfConvert = True

If selfConvert Then
AddJSLine 0, "if (typeof QB == 'undefined' && module) { QB = require('./qb-console.js').QB(); }"
Expand Down Expand Up @@ -226,14 +228,16 @@ Sub QBToJS (source As String, sourceType As Integer, moduleName As String)
AddJSLine 0, " line = QB.arrayValue(lines, [line]).value.line;"
AddJSLine 0, " return line;"
AddJSLine 0, "}"
AddJSLine 0, "function setSelfConvert() { sub_SetSelfConvert(); }"
AddJSLine 0, ""
AddJSLine 0, "return {"
AddJSLine 0, " compile: compile,"
AddJSLine 0, " getWarnings: getWarnings,"
AddJSLine 0, " getMethods: getMethods,"
AddJSLine 0, " getExportMethods: getExportMethods,"
AddJSLine 0, " getExportConsts: getExportConsts,"
AddJSLine 0, " getSourceLine: getSourceLine"
AddJSLine 0, " getSourceLine: getSourceLine,"
AddJSLine 0, " setSelfConvert: setSelfConvert,"
AddJSLine 0, "};"
AddJSLine 0, "}"
AddJSLine 0, "if (typeof module != 'undefined') { module.exports.QBCompiler = _QBCompiler; }"
Expand All @@ -251,6 +255,10 @@ Sub QBToJS (source As String, sourceType As Integer, moduleName As String)
End If
End Sub

Sub SetSelfConvert()
forceSelfConvert = True
End Sub

Sub InitTypes
Dim As Integer i, j, jsidx
Dim As String typestr
Expand Down Expand Up @@ -2386,7 +2394,7 @@ Sub ReadLinesFromText (sourceText As String)
fline = sourceLines(i)

If _Trim$(fline) <> "" Then ' remove all blank lines

Dim lineIndex As Integer
lineIndex = i

Expand All @@ -2410,11 +2418,13 @@ Sub ReadLinesFromText (sourceText As String)
End If
End If

While EndsWith(fline, "_")
fline = Replace(fline, CR, "")
While EndsWith(fline, " _")
i = i + 1
Dim nextLine As String
nextLine = sourceLines(i)
nextLine = Replace(sourceLines(i), CR, "")
fline = Left$(fline, Len(fline) - 1) + nextLine
'AddWarning i, "Found it: [" + fline + "]"
Wend

rawJS = ReadLine(i, fline, rawJS)
Expand Down Expand Up @@ -3495,9 +3505,7 @@ Function GXMethodJS$ (mname As String)
c = Mid$(mname, i, 1)
a = Asc(c)
' uppercase, lowercase, numbers, - and .
If (a >= 65 And a <= 90) Or (a >= 97 And a <= 122) Or _
(a >= 48 And a <= 57) Or _
a = 95 Or a = 46 Then
If (a >= 65 And a <= 90) Or (a >= 97 And a <= 122) Or (a >= 48 And a <= 57) Or a = 95 Or a = 46 Then
jsname = jsname + c
End If
Next i
Expand Down

0 comments on commit 35ecfaf

Please sign in to comment.