1
1
Fork 0
mirror of https://github.com/boxgaming/qbjs.git synced 2024-05-12 08:00:12 +00:00

File I/O Support - Part 2

This commit is contained in:
boxgaming 2022-10-27 09:04:15 -05:00
parent 6d8fa317df
commit 9058e9c536
17 changed files with 3529 additions and 187 deletions

View file

@ -58,8 +58,9 @@ CodeMirror.defineMode("qbjs", function(conf, parserConf) {
'str', 'swap', 'tan', 'time', 'timer', 'ubound', 'ucase',
'val', 'varptr', 'window',
'mkdir', 'chdir', 'rmdir', 'kill', 'name', 'files', 'open', 'close', 'lof', 'eof', 'put', 'get', 'freefile',
'seek', 'write',
// QBJS-specific
'export', 'from', 'import', '_label']
'export', 'from', 'import']
var builtinConsts = ['_off', '_smooth', '_stretch', '_squarepixels', 'append', 'binary', 'input', 'output', 'random',
'gx_true', 'gx_false', 'gxevent_init', 'gxevent_update', 'gxevent_drawbg', 'gxevent_drawmap', 'gxevent_drawscreen',

View file

@ -31,6 +31,9 @@ var GX = new function() {
var _touchPos = { x:0, y:0 };
var _bindTouchToMouse = true;
var _vfs = new VFS();
var _vfsCwd = null;
// javascript specific
var _onGameEvent = null;
var _pressedKeys = {};
@ -81,6 +84,8 @@ var GX = new function() {
_mousePos = { x:0, y:0 };
_mouseInputFlag = false;
_vfsCwd = _vfs.rootDirectory();
// javascript specific
_onGameEvent = null;
_pressedKeys = {};
@ -535,7 +540,17 @@ var GX = new function() {
callbackFn(img);
}
}
img.src = filename;
var file = _vfs.getNode(filename, _vfsCwd);
if (file && file.type == _vfs.FILE) {
//img.src = await _vfs.getDataURL(file);
_vfs.getDataURL(file).then((dataUrl) => {
img.src = dataUrl;
});
}
else {
img.src = filename;
}
_images.push(img);
return _images.length;
}
@ -2354,6 +2369,8 @@ var GX = new function() {
};
function _init() {
_vfsCwd = _vfs.rootDirectory();
// init
_fontCreateDefault(GX.FONT_DEFAULT);
_fontCreateDefault(GX.FONT_DEFAULT_BLACK);
@ -2376,6 +2393,13 @@ var GX = new function() {
this.ctx = function() { return _ctx; };
this.canvas = function() { return _canvas; };
this.vfs = function() { return _vfs; };
this.vfsCwd = function(cwd) {
if (cwd != undefined) {
_vfsCwd = cwd;
}
return _vfsCwd;
};
this.frame = _frame;
this.frameRate = _frameRate;

48
img/open-hover.svg Normal file
View file

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 32 32"
version="1.1"
id="svg956"
sodipodi:docname="open-hover.svg"
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview958"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="29.90625"
inkscape:cx="16.016719"
inkscape:cy="16.016719"
inkscape:window-width="1920"
inkscape:window-height="1137"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg956" />
<defs
id="defs947">
<style
id="style945">.cls-1{fill:#101820;}</style>
</defs>
<title
id="title949" />
<path
class="cls-1"
d="M 4,28 A 3,3 0 0 1 1,25 V 7 A 3,3 0 0 1 4,4 h 7 a 1,1 0 0 1 0.77,0.36 L 14.8,8 H 27 a 1,1 0 0 1 0,2 H 14.33 A 1,1 0 0 1 13.57,9.64 L 10.53,6 H 4 A 1,1 0 0 0 3,7 v 18 a 1,1 0 0 0 1,1 1,1 0 0 1 0,2 z"
id="path951"
style="fill:#ffffff;fill-opacity:1" />
<path
class="cls-1"
d="M 25.38,28 H 4 A 1,1 0 0 1 3,26.79 l 3,-14 A 1,1 0 0 1 7,12 h 23 a 1,1 0 0 1 1,1.21 L 28.32,25.63 A 3,3 0 0 1 25.38,28 Z M 5.24,26 h 20.14 a 1,1 0 0 0 1,-0.79 L 28.76,14 h -21 z"
id="path953"
style="fill:#ffffff;fill-opacity:1" />
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

48
img/open.svg Normal file
View file

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 32 32"
version="1.1"
id="svg956"
sodipodi:docname="open2.svg"
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview958"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="29.90625"
inkscape:cx="16.016719"
inkscape:cy="16.016719"
inkscape:window-width="1920"
inkscape:window-height="1137"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg956" />
<defs
id="defs947">
<style
id="style945">.cls-1{fill:#101820;}</style>
</defs>
<title
id="title949" />
<path
class="cls-1"
d="M 4,28 A 3,3 0 0 1 1,25 V 7 A 3,3 0 0 1 4,4 h 7 a 1,1 0 0 1 0.77,0.36 L 14.8,8 H 27 a 1,1 0 0 1 0,2 H 14.33 A 1,1 0 0 1 13.57,9.64 L 10.53,6 H 4 A 1,1 0 0 0 3,7 v 18 a 1,1 0 0 0 1,1 1,1 0 0 1 0,2 z"
id="path951"
style="fill:#cccccc;fill-opacity:1" />
<path
class="cls-1"
d="M 25.38,28 H 4 A 1,1 0 0 1 3,26.79 l 3,-14 A 1,1 0 0 1 7,12 h 23 a 1,1 0 0 1 1,1.21 L 28.32,25.63 A 3,3 0 0 1 25.38,28 Z M 5.24,26 h 20.14 a 1,1 0 0 0 1,-0.79 L 28.76,14 h -21 z"
id="path953"
style="fill:#cccccc;fill-opacity:1" />
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

41
img/run-hover.svg Normal file
View file

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
height="512"
viewBox="0 0 512 512"
width="512"
version="1.1"
id="svg6"
sodipodi:docname="run-hover.svg"
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs10" />
<sodipodi:namedview
id="namedview8"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="1.8691406"
inkscape:cx="256.2675"
inkscape:cy="256.2675"
inkscape:window-width="1920"
inkscape:window-height="1137"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg6" />
<title
id="title2" />
<path
d="M112,111V401c0,17.44,17,28.52,31,20.16l247.9-148.37c12.12-7.25,12.12-26.33,0-33.58L143,90.84C129,82.48,112,93.56,112,111Z"
style="fill:none;stroke:#ffffff;stroke-miterlimit:10;stroke-width:32px;stroke-opacity:1"
id="path4" />
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

41
img/run.svg Normal file
View file

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
height="512"
viewBox="0 0 512 512"
width="512"
version="1.1"
id="svg6"
sodipodi:docname="run.svg"
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs10" />
<sodipodi:namedview
id="namedview8"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="1.8691406"
inkscape:cx="256.2675"
inkscape:cy="256.2675"
inkscape:window-width="1920"
inkscape:window-height="1137"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg6" />
<title
id="title2" />
<path
d="M112,111V401c0,17.44,17,28.52,31,20.16l247.9-148.37c12.12-7.25,12.12-26.33,0-33.58L143,90.84C129,82.48,112,93.56,112,111Z"
style="fill:none;stroke:#cccccc;stroke-miterlimit:10;stroke-width:32px;stroke-opacity:1"
id="path4" />
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

1156
img/save-hover.svg Normal file

File diff suppressed because it is too large Load diff

After

Width:  |  Height:  |  Size: 63 KiB

1156
img/save.svg Normal file

File diff suppressed because it is too large Load diff

After

Width:  |  Height:  |  Size: 63 KiB

52
img/share-hover.svg Normal file
View file

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
height="512"
viewBox="0 0 512 512"
width="512"
version="1.1"
id="svg13977"
sodipodi:docname="share-hover.svg"
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs13981" />
<sodipodi:namedview
id="namedview13979"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="1.8691406"
inkscape:cx="256.2675"
inkscape:cy="256.2675"
inkscape:window-width="1920"
inkscape:window-height="1137"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg13977" />
<title
id="title13969" />
<path
d="M336,192h40a40,40,0,0,1,40,40V424a40,40,0,0,1-40,40H136a40,40,0,0,1-40-40V232a40,40,0,0,1,40-40h40"
style="fill:none;stroke:#ffffff;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px;stroke-opacity:1"
id="path13971" />
<polyline
points="336 128 256 48 176 128"
style="fill:none;stroke:#ffffff;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px;stroke-opacity:1"
id="polyline13973" />
<line
style="fill:none;stroke:#ffffff;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px;stroke-opacity:1"
x1="256"
x2="256"
y1="321"
y2="48"
id="line13975" />
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

52
img/share.svg Normal file
View file

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
height="512"
viewBox="0 0 512 512"
width="512"
version="1.1"
id="svg13977"
sodipodi:docname="share2.svg"
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs13981" />
<sodipodi:namedview
id="namedview13979"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="1.8691406"
inkscape:cx="256.2675"
inkscape:cy="256.2675"
inkscape:window-width="1920"
inkscape:window-height="1137"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg13977" />
<title
id="title13969" />
<path
d="M336,192h40a40,40,0,0,1,40,40V424a40,40,0,0,1-40,40H136a40,40,0,0,1-40-40V232a40,40,0,0,1,40-40h40"
style="fill:none;stroke:#cccccc;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px;stroke-opacity:1"
id="path13971" />
<polyline
points="336 128 256 48 176 128"
style="fill:none;stroke:#cccccc;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px;stroke-opacity:1"
id="polyline13973" />
<line
style="fill:none;stroke:#cccccc;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px;stroke-opacity:1"
x1="256"
x2="256"
y1="321"
y2="48"
id="line13975" />
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -23,11 +23,18 @@
</head>
<body>
<div id="code-container">
<div id="toolbar">
<a href="javascript:openProject()" class="toolbar-button" id="toolbar-button-open" title="Open"></a>
<a href="javascript:saveProject()" class="toolbar-button" id="toolbar-button-save" title="Save"></a>
<div class="spacer"></div>
<a href="javascript:runProgram()" class="toolbar-button" id="toolbar-button-run" title="Run"></a>
<a href="javascript:shareProgram()" class="toolbar-button" id="toolbar-button-share" title="Share / Export"></a>
</div>
<div id="code"></div>
<a id="edit-button" href="javascript:slideRight()" display="none">Edit</a>
<a id="run-button" href="javascript:runProgram()">Run</a>
<a id="stop-button" href="javascript:stopProgram()">Stop</a>
<a id="share-button" href="javascript:shareProgram()">Share</a>
<a id="edit-button" href="javascript:slideRight()" display="none">Edit</a>
<a id="run-button" href="javascript:runProgram()">Run</a>
<a id="stop-button" href="javascript:stopProgram()">Stop</a>
<a id="share-button" href="javascript:shareProgram()">Share</a>
</div>
<div id="slider">
<div id="slider-left" class="slider-button" onclick="slideLeft()">&lt;</div>
@ -60,6 +67,10 @@
</div>
<div id="gx-footer"></div>
<form style="display:none">
<input id="file-input" type="file" accept=".bas, .zip">
</form>
<dialog id="share-dialog">
<div style="margin-bottom:5px">Copy the link below to share your code:</div>
<div><textarea id="share-code" rows="15" cols="80" readonly></textarea></div>
@ -74,9 +85,21 @@
<a href="javascript:closeDialog()" style="display:block; float:right; margin-top: 7px">Close</a>
<a href="javascript:testShare()" style="display: block; float:right; margin-top: 7px; margin-right: 10px">Test</a>
</dialog>
<dialog id="prog-sel-dialog">
<div>
No main.bas file found.<br/>
Select main program source file:
</div>
<select id="prog-sel-sources" size="10" style="display:block; width:100%; margin-top:10px"></select>
<div style="text-align:center; margin-top:10px">
<a href="javascript:onSelMainProg()">Ok</a>
<a href="javascript:closeProgSelDlg()">Cancel</a>
</div>
</dialog>
</body>
<script language="javascript" src="gx/gx.js"></script>
<script language="javascript" src="vfs.js"></script>
<script language="javascript" src="gx/gx.js"></script>
<script language="javascript" src="qb.js"></script>
<script language="javascript" src="qb2js.js"></script>
<script language="javascript" src="qbjs-ide.js"></script>

308
qb.js
View file

@ -46,8 +46,6 @@ var QB = new function() {
var _strokeLineThickness = 2;
var _windowAspect = [];
var _windowDef = [];
var _vfs = new VFS();
var _vfsCwd = null;
var _fileHandles = null;
var _typeMap = {};
@ -136,7 +134,7 @@ var QB = new function() {
_rndSeed = 327680;
_runningFlag = true;
_sourceImage = 0;
_vfsCwd = _vfs.rootDirectory();
GX.vfsCwd(GX.vfs().rootDirectory());
_fileHandles = {};
_initColorTable();
GX._enableTouchMouse(true);
@ -244,7 +242,7 @@ var QB = new function() {
};
this.func__CWD = function() {
return _vfs.fullPath(_vfsCwd);
return GX.vfs().fullPath(GX.vfsCwd());
};
this.func__D2R = function(x) {
@ -268,8 +266,9 @@ var QB = new function() {
};
this.func__DirExists = function(path) {
var dir = _vfs.getNode(path, _vfsCwd);
if (dir && dir.type == _vfs.DIRECTORY) {
var vfs = GX.vfs();
var dir = vfs.getNode(path, GX.vfsCwd());
if (dir && dir.type == vfs.DIRECTORY) {
return -1;
}
return 0;
@ -284,8 +283,9 @@ var QB = new function() {
};
this.func__FileExists = function(path) {
var file = _vfs.getNode(path, _vfsCwd);
if (file && file.type == _vfs.FILE) {
var vfs = GX.vfs();
var file = vfs.getNode(path, GX.vfsCwd());
if (file && file.type == vfs.FILE) {
return -1;
}
return 0;
@ -403,19 +403,25 @@ var QB = new function() {
};
this.func__LoadImage = async function(url) {
var vfs = GX.vfs();
var vfsCwd = GX.vfsCwd();
var img = null;
var img = new Image();
img.src = url;
while (!img.complete) {
await GX.sleep(10);
}
if (!img.width) {
// attempt to read the image from the virtual file system
var node = _vfs.getNode(url, _vfsCwd);
// attempt to read the image from the virtual file system
var file = vfs.getNode(url, vfsCwd);
if (file && file.type == vfs.FILE) {
img = new Image();
img.src = await _vfs.getDataURL(node);
img.src = await vfs.getDataURL(file);
while (!img.complete) {
await GX.sleep(10);
}
}
else {
// otherwise, read it from the url location
var img = new Image();
img.src = url;
while (!img.complete) {
await GX.sleep(10);
}
@ -464,7 +470,33 @@ var QB = new function() {
};
this.func__OS = function() {
return "[QBJS][64BIT]";
var browser = "";
if ((navigator.userAgent.indexOf("Opera") || navigator.userAgent.indexOf('OPR')) != -1 ) {
browser = "Opera";
}
else if (navigator.userAgent.indexOf("Edg") != -1 ) {
browser = "Edge";
}
else if (navigator.userAgent.indexOf("Chrome") != -1 ) {
browser = "Chrome";
}
else if (navigator.userAgent.indexOf("Safari") != -1) {
browser = "Safari";
}
else if(navigator.userAgent.indexOf("Firefox") != -1 ) {
browser = "Firefox";
}
else if((navigator.userAgent.indexOf("MSIE") != -1 ) || (!!document.documentMode == true )) //IF IE > 10
{
browser = "IE";
}
else
{
browser = "Unknown";
}
return "[WEB][" + browser.toUpperCase() + "]";
};
this.sub__PaletteColor = function(x, y) {
@ -743,7 +775,7 @@ var QB = new function() {
};
this.func__StartDir = function() {
return _vfs.fullPath(_vfs.rootDirectory());
return GX.vfs().fullPath(GX.vfs().rootDirectory());
}
this.func__Strcmp = function(x, y) {
@ -819,10 +851,10 @@ var QB = new function() {
};
this.sub_ChDir = function(path) {
var node = _vfs.getNode(path, _vfsCwd);
var node = GX.vfs().getNode(path, GX.vfsCwd());
//alert("CHDIR: " + path + " node: " + node);
if (node) {
_vfsCwd = node;
GX.vfsCwd(node);
}
else {
// TODO: error handling
@ -1287,19 +1319,6 @@ var QB = new function() {
return _fileHandles[fh].file.data.byteLength;
};
this.sub_LineInputFromFile = async function(fh, returnValues) {
if (!_fileHandles[fh]) {
throw new Error("Invalid file handle");
}
if (_fileHandles[fh].mode == QB.RANDOM) {
throw new Error("Bad file mode");
}
fh = _fileHandles[fh];
var text = _vfs.readLine(fh.file, fh.offset);
fh.offset += text.length + 1;
returnValues[0] = text;
};
this.sub_Input = async function(values, preventNewline, addQuestionPrompt, prompt) {
_lastKey = null;
@ -1358,6 +1377,30 @@ var QB = new function() {
_images[_activeImage].dirty = true;
}
this.sub_InputFromFile = async function(fh, returnValues) {
if (!_fileHandles[fh]) {
throw new Error("Invalid file handle");
}
if (_fileHandles[fh].mode != QB.INPUT) {
throw new Error("Bad file mode");
}
fh = _fileHandles[fh];
var text = GX.vfs().readLine(fh.file, fh.offset);
fh.offset += text.length + 1;
var values = text.match(/(".*?"|[^",\s]+)(?=\s*,|\s*$)/g);
for (var i=0; i < returnValues.length; i++) {
if (i < values.length) {
var v = values[i];
// remove surrounding double quotes from string values
if (v.startsWith('"') && v.endsWith('"')) {
v = v.substring(1, v.length-1);
}
returnValues[i] = v;
}
}
};
this.func_InKey = function() {
if (_inkeyBuffer.length < 1) {
return "";
@ -1480,16 +1523,18 @@ var QB = new function() {
};
this.sub_Files = function(path) {
var vfs = GX.vfs();
var vfsCwd = GX.vfsCwd();
var childNodes = null;
if (path == undefined) {
childNodes = _vfs.getChildren(_vfsCwd);
childNodes = vfs.getChildren(vfsCwd);
}
else {
var parent = _vfs.getNode(path, _vfsCwd);
childNodes = _vfs.getChildren(parent);
var parent = vfs.getNode(path, vfsCwd);
childNodes = vfs.getChildren(parent);
}
for (var i=0; i < childNodes.length; i++) {
this.sub_Print(childNodes[i].name + ((childNodes[i].type == _vfs.DIRECTORY) ? " <DIR>" : ""));
this.sub_Print(childNodes[i].name + ((childNodes[i].type == vfs.DIRECTORY) ? " <DIR>" : ""));
}
};
@ -1499,12 +1544,13 @@ var QB = new function() {
_images[_activeImage].dirty = true;
if (color == undefined) {
if (style == "BF") {
color = _fgColor;
/*if (style == "BF") {
color = _bgColor;
}
else {
color = _fgColor;
}
}*/
}
else {
color = _color(color);
@ -1638,6 +1684,20 @@ var QB = new function() {
await QB.sub_Input(values, preventNewline, addQuestionPrompt, prompt);
}
this.sub_LineInputFromFile = async function(fh, returnValues) {
if (!_fileHandles[fh]) {
throw new Error("Invalid file handle");
}
if (_fileHandles[fh].mode == QB.RANDOM) {
throw new Error("Bad file mode");
}
fh = _fileHandles[fh];
var text = GX.vfs().readLine(fh.file, fh.offset);
fh.offset += text.length + 1;
returnValues[0] = text;
};
this.sub_Locate = function(row, col) {
// TODO: implement cursor positioning/display
if (row && row > 0 && row <= _textRows()) {
@ -1653,7 +1713,7 @@ var QB = new function() {
};
this.sub_Kill = function(path) {
_vfs.removeFile(path, _vfsCwd);
GX.vfs().removeFile(path, GX.vfsCwd());
};
this.func_Mid = function(value, n, len) {
@ -1666,11 +1726,13 @@ var QB = new function() {
};
this.sub_MkDir = function(path) {
var parent = _vfs.getParentPath(path);
var filename = _vfs.getFileName(path);
var parentNode = _vfs.getNode(parent, _vfsCwd);
if (!parentNode) { parentNode = _vfsCwd; }
_vfs.createDirectory(filename, parentNode);
var vfs = GX.vfs();
var vfsCwd = GX.vfsCwd();
var parent = vfs.getParentPath(path);
var filename = vfs.getFileName(path);
var parentNode = vfs.getNode(parent, vfsCwd);
if (!parentNode) { parentNode = vfsCwd; }
vfs.createDirectory(filename, parentNode);
}
this.func_Mki = function(num) {
@ -1690,8 +1752,10 @@ var QB = new function() {
};
this.sub_Name = function(oldName, newName) {
var node = _vfs.getNode(oldName, _vfsCwd);
_vfs.renameNode(node, newName);
var vfs = GX.vfs();
var vfsCwd = GX.vfsCwd();
var node = vfs.getNode(oldName, vfsCwd);
vfs.renameNode(node, newName);
};
this.func_Oct = function(n) {
@ -1699,24 +1763,26 @@ var QB = new function() {
};
this.sub_Open = function(path, mode, handle) {
if (mode == QB.OUTPUT || mode == QB.APPEND || mode == QB.BINARY) {
var parent = _vfs.getParentPath(path);
var filename = _vfs.getFileName(path);
var parentNode = _vfs.getNode(parent, _vfsCwd);
if (!parentNode) { parentNode = _vfsCwd; }
var vfs = GX.vfs();
var vfsCwd = GX.vfsCwd();
if (mode == QB.OUTPUT || mode == QB.APPEND || mode == QB.BINARY) {
var parent = vfs.getParentPath(path);
var filename = vfs.getFileName(path);
var parentNode = vfs.getNode(parent, vfsCwd);
if (!parentNode) { parentNode = vfsCwd; }
var file = null;
if (mode == QB.APPEND || mode == QB.BINARY) {
file = _vfs.getNode(path, _vfsCwd);
file = vfs.getNode(path, vfsCwd);
// TODO: make sure this is not a directory
}
if (!file) {
file = _vfs.createFile(filename, parentNode);
file = vfs.createFile(filename, parentNode);
}
_fileHandles[handle] = { file: file, mode: mode, offset: 0 };
}
else if (mode == QB.INPUT) {
var file = _vfs.getNode(path, _vfsCwd);
if (!file || file.type != _vfs.FILE) {
var file = vfs.getNode(path, vfsCwd);
if (!file || file.type != vfs.FILE) {
throw new Error("File not found");
}
_fileHandles[handle] = { file: file, mode: mode, offset: 0 };
@ -1881,7 +1947,7 @@ var QB = new function() {
_strokeDrawColor = _color(color);
};
this.vfs = function() { return _vfs; }
this.vfs = function() { return GX.vfs(); }
this.sub_PrintToFile = function(fh, args) {
if (!_fileHandles[fh]) {
@ -1912,18 +1978,18 @@ var QB = new function() {
var chars = 14 - locX % 13;
var padStr = "";
padStr = padStr.padStart(chars, " ");
_vfs.writeText(file, padStr);
GX.vfs().writeText(file, padStr);
locX += chars;
}
else {
//alert(args[ai]);
locX = args[ai].length;
_vfs.writeText(file, args[ai]);
GX.vfs().writeText(file, args[ai]);
}
}
if (!preventNewline) {
_vfs.writeText(file, "\r\n");
GX.vfs().writeText(file, "\r\n");
}
};
@ -2112,44 +2178,45 @@ var QB = new function() {
};
function _readDataElement(fh, position, type) {
var vfs = GX.vfs();
var data = null;
if (type == "SINGLE") {
data = _vfs.readData(fh.file, position, 4);
data = vfs.readData(fh.file, position, 4);
fh.offset = position + data.byteLength;
return (new DataView(data)).getFloat32(0, true);
}
else if (type == "DOUBLE") {
data = _vfs.readData(fh.file, position, 8);
data = vfs.readData(fh.file, position, 8);
fh.offset = position + data.byteLength;
return (new DataView(data)).getFloat64(0, true);
}
else if (type == "_BYTE") {
data = _vfs.readData(fh.file, position, 1);
data = vfs.readData(fh.file, position, 1);
fh.offset = position + data.byteLength;
return (new DataView(data)).getInt8(0, true);
}
else if (type == "_UNSIGNED _BYTE") {
data = _vfs.readData(fh.file, position, 1);
data = vfs.readData(fh.file, position, 1);
fh.offset = position + data.byteLength;
return (new DataView(data)).getUint8(0, true);
}
else if (type == "INTEGER") {
data = _vfs.readData(fh.file, position, 2);
data = vfs.readData(fh.file, position, 2);
fh.offset = position + data.byteLength;
return (new DataView(data)).getInt16(0, true);
}
else if (type == "_UNSIGNED INTEGER") {
data = _vfs.readData(fh.file, position, 2);
data = vfs.readData(fh.file, position, 2);
fh.offset = position + data.byteLength;
return (new DataView(data)).getUint16(0, true);
}
else if (type == "LONG") {
data = _vfs.readData(fh.file, position, 4);
data = vfs.readData(fh.file, position, 4);
fh.offset = position + data.byteLength;
return (new DataView(data)).getInt32(0, true);
}
else if (type == "_UNSIGNED LONG") {
data = _vfs.readData(fh.file, position, 4);
data = vfs.readData(fh.file, position, 4);
fh.offset = position + data.byteLength;
return (new DataView(data)).getUint32(0, true);
}
@ -2252,7 +2319,7 @@ var QB = new function() {
else if (type == "_UNSIGNED INTEGER") { data = new Uint16Array([value]).buffer; }
else if (type == "LONG") { data = new Int32Array([value]).buffer; }
else if (type == "_UNSIGNED LONG") { data = new Uint32Array([value]).buffer; }
else if (type == "STRING") { data = _vfs.textToData(value); }
else if (type == "STRING") { data = vfs.textToData(value); }
else if (type == "_BIT" || type == "_UNSIGNED _BIT") {
// mimicking QB64 error message here
throw new Error("Variable/element cannot be BIT aligned on current line");
@ -2278,7 +2345,7 @@ var QB = new function() {
}
if (!customType) {
_vfs.writeData(fh.file, data, position);
vfs.writeData(fh.file, data, position);
fh.offset = position + data.byteLength;
}
};
@ -2332,7 +2399,7 @@ var QB = new function() {
};
this.sub_RmDir = function(path) {
_vfs.removeDirectory(path, _vfsCwd);
vfs.removeDirectory(path, vfsCwd);
};
this.func_Rnd = function(n) {
@ -2365,7 +2432,6 @@ var QB = new function() {
}
else if (mode == 1) {
GX.sceneCreate(320, 200);
_fgColor = _rgb(168, 168, 168);
}
else if (mode == 2 || mode == 7 || mode == 13) {
GX.sceneCreate(320, 200);
@ -2401,7 +2467,12 @@ var QB = new function() {
// initialize the graphics
_screenMode = mode;
_fgColor = _color(7);
if (mode < 2) {
_fgColor = _color(7);
}
else {
_fgColor = _color(15);
}
_bgColor = _color(0);
_locX = 0;
_locY = 0;
@ -2427,6 +2498,22 @@ var QB = new function() {
*/
};
this.func_Seek = function(fh) {
if (!_fileHandles[fh]) {
throw new Error("Invalid file handle");
}
return _fileHandles[fh].offset + 1;
};
this.sub_Seek = function(fh, pos) {
if (!_fileHandles[fh]) {
throw new Error("Invalid file handle");
}
_fileHandles[fh].offset = pos - 1;
};
this.func_Sgn = function(value) {
if (value > 0) { return 1; }
else if (value < 0) { return -1; }
@ -2578,22 +2665,77 @@ var QB = new function() {
}
}
this.sub_Write = function(args) {
QB.sub_Print([_getWriteString(args)]);
}
this.sub_WriteToFile = function(fh, args) {
if (!_fileHandles[fh]) {
throw new Error("Invalid file handle");
}
if (_fileHandles[fh].mode != QB.OUTPUT && _fileHandles[fh].mode != QB.APPEND) {
throw new Error("Bad file mode");
}
fh = _fileHandles[fh];
var vfs = GX.vfs();
vfs.writeText(fh.file, _getWriteString(args) + "\r\n");
}
function _getWriteString(args) {
if (!args || !args.length) { return ""; }
var output = "";
for (var i=0; i < args.length; i++) {
if (i > 0) {
output += ","
}
if (args[i].type == "STRING" && !args[i].value.startsWith('"')) {
output += "\"" + args[i].value + "\"";
}
else {
output += args[i].value;
}
}
return output;
}
// QBJS-only methods
// ---------------------------------------------------------------------------------
this.sub_IncludeJS = async function(url) {
var vfs = GX.vfs();
var vfsCwd = GX.vfsCwd();
var script = document.createElement("script")
document.body.appendChild(script);
script.id = url;
script.src = url;
var file = vfs.getNode(url, vfsCwd);
if (file && file.type == vfs.FILE) {
script.innerHTML = vfs.readText(file);
}
else {
script.src = url;
}
};
this.sub_Fetch = async function(url, fetchRes) {
var response = await fetch(url);
var responseText = await(response.text());
fetchRes.ok = response.ok;
fetchRes.status = response.status;
fetchRes.statusText = response.statusText;
fetchRes.text = responseText;
var vfs = GX.vfs();
var vfsCwd = GX.vfsCwd();
var file = vfs.getNode(url, vfsCwd);
if (file && file.type == vfs.FILE) {
fetchRes.ok = true;
fetchRes.status = 200;
fetchRes.statusText = "";
fetchRes.text = vfs.readText(file);
}
else {
var response = await fetch(url);
var responseText = await(response.text());
fetchRes.ok = response.ok;
fetchRes.status = response.status;
fetchRes.statusText = response.statusText;
fetchRes.text = responseText;
}
};
this.func_Fetch = async function(url) {

278
qb2js.js
View file

@ -630,14 +630,19 @@ var ConvertSub = null;
} else if ( m.name == "Close" ) {
js = (await func_CallMethod( m)) + "(" + (await func_Replace( args, "#" , "")) + ");";
} else if ( m.name == "Input" ) {
if ((await func_StartsWith( (QB.func__Trim( QB.arrayValue(parts, [ 1]).value)) , "#")) ) {
if ((await func_StartsWith( (QB.func__Trim( args)) , "#")) ) {
m.jsname = "QB.sub_InputFromFile";
js = (await func_ConvertFileInput( m, args, lineNumber));
} else {
m.jsname = "QB.sub_Input";
js = (await func_ConvertInput( m, args, lineNumber));
}
} else if ( m.name == "Line Input" ) {
if ((await func_StartsWith( (QB.func__Trim( args)) , "#")) ) {
m.jsname = "QB.sub_LineInputFromFile";
js = (await func_ConvertFileLineInput( m, args, lineNumber));
m.name = "Line";
m.jsname = "QB.sub_Line";
} else {
js = (await func_ConvertInput( m, args, lineNumber));
m.name = "Line";
@ -660,6 +665,8 @@ var ConvertSub = null;
js = (await func_ConvertSwap( m, args, lineNumber));
} else if ( m.name == "Window" ) {
js = (await func_CallMethod( m)) + "(" + (await func_ConvertWindow( args, lineNumber)) + ");";
} else if ( m.name == "Write" ) {
js = (await func_ConvertWrite( m, args, lineNumber));
} else if ( m.name == "_PrintString" ) {
js = (await func_CallMethod( m)) + "(" + (await func_ConvertPrintString( args, lineNumber)) + ");";
} else if ( m.name == "_PutImage" ) {
@ -778,13 +785,13 @@ var ConvertLine = null;
if ( argc >= 1) {
coord = (await func_ConvertCoordParam( QB.arrayValue(parts, [ 1]).value , True, lineNumber));
}
if ( argc >= 2) {
if ( argc >= 2 && (QB.func__Trim( QB.arrayValue(parts, [ 2]).value)) != "" ) {
lcolor = (await func_ConvertExpression( QB.arrayValue(parts, [ 2]).value , lineNumber));
}
if ( argc >= 3) {
if ( argc >= 3 && (QB.func__Trim( QB.arrayValue(parts, [ 3]).value)) != "" ) {
mode = "'" + (QB.func_UCase( (QB.func__Trim( QB.arrayValue(parts, [ 3]).value)))) + "'";
}
if ( argc >= 4) {
if ( argc >= 4 && (QB.func__Trim( QB.arrayValue(parts, [ 4]).value)) != "" ) {
style = (await func_ConvertExpression( QB.arrayValue(parts, [ 4]).value , lineNumber));
}
ConvertLine = coord + ", " + lcolor + ", " + mode + ", " + style;
@ -1072,6 +1079,53 @@ var ConvertPrint = null;
ConvertPrint = js + "]);";
return ConvertPrint;
}
async function func_ConvertWrite(m/*METHOD*/,args/*STRING*/,lineNumber/*INTEGER*/) {
if (QB.halted()) { return; }
var ConvertWrite = null;
var fh = ''; /* STRING */
var pcount = 0; /* INTEGER */
var startIdx = 0; /* INTEGER */
var parts = QB.initArray([{l:0,u:0}], ''); /* STRING */
pcount = (await func_ListSplit( args, parts));
startIdx = 1;
m.jsname = "QB.sub_Write";
if ( pcount > 0) {
if ((await func_StartsWith( (QB.func__Trim( QB.arrayValue(parts, [ 1]).value)) , "#")) ) {
fh = (await func_Replace( (QB.func__Trim( QB.arrayValue(parts, [ 1]).value)) , "#" , ""));
m.jsname = "QB.sub_WriteToFile";
startIdx = 2;
}
}
var js = ''; /* STRING */
js = (await func_CallMethod( m)) + "(";
if ( fh != "" ) {
js = js + fh + ", ";
}
js = js + "[";
var i = 0; /* INTEGER */
var ___v8714458 = 0; for ( i= startIdx; i <= pcount; i= i + 1) { if (QB.halted()) { return; } ___v8714458++; if (___v8714458 % 100 == 0) { await QB.autoLimit(); }
if ( i > startIdx) {
js = js + ",";
}
var t = ''; /* STRING */
t = "UNKNOWN";
var v = {type:'',name:'',jsname:'',isConst:0,isArray:0,arraySize:0,typeId:0}; /* VARIABLE */
var isVar = 0; /* INTEGER */
isVar = (await func_FindVariable( QB.arrayValue(parts, [ i]).value , v, False));
if ( isVar) {
t = v.type;
} else if ((await func_StartsWith( QB.arrayValue(parts, [ i]).value , (QB.func_Chr( 34)))) ) {
t = "STRING";
}
if ( isVar) {
js = js + "{ type:'" + t + "', value:" + (QB.func__Trim( (await func_ConvertExpression( QB.arrayValue(parts, [ i]).value , lineNumber)))) + "}";
} else {
js = js + "{ type:'" + t + "', value:'" + (await func_Replace( (QB.func__Trim( (await func_ConvertExpression( QB.arrayValue(parts, [ i]).value , lineNumber)))) , "'" , "\\'")) + "'}";
}
}
ConvertWrite = js + "]);";
return ConvertWrite;
}
async function func_ConvertPrintString(args/*STRING*/,lineNumber/*INTEGER*/) {
if (QB.halted()) { return; }
var ConvertPrintString = null;
@ -1137,7 +1191,7 @@ var ConvertInput = null;
var p = ''; /* STRING */
pcount = (await func_PrintSplit( args, parts));
var i = 0; /* INTEGER */
var ___v8714458 = 0; for ( i= 1; i <= pcount; i= i + 1) { if (QB.halted()) { return; } ___v8714458++; if (___v8714458 % 100 == 0) { await QB.autoLimit(); }
var ___v562369 = 0; for ( i= 1; i <= pcount; i= i + 1) { if (QB.halted()) { return; } ___v562369++; if (___v562369 % 100 == 0) { await QB.autoLimit(); }
p = (QB.func__Trim( QB.arrayValue(parts, [ i]).value));
if ( p == ";" ) {
if ( i == 1) {
@ -1156,14 +1210,106 @@ var ConvertInput = null;
vname = await func_GenJSVar();
js = "var " + vname + " = new Array(" + (QB.func_Str( (QB.func_UBound( vars)))) + "); ";
js = js + (await func_CallMethod( m)) + "(" + vname + ", " + preventNewline + ", " + addQuestionPrompt + ", " + prompt + "); ";
var ___v562369 = 0; for ( i= 1; i <= (QB.func_UBound( vars)); i= i + 1) { if (QB.halted()) { return; } ___v562369++; if (___v562369 % 100 == 0) { await QB.autoLimit(); }
if (!(await func_StartsWith( (QB.func__Trim( QB.arrayValue(vars, [ i]).value)) , "#")) ) {
var ___v9495566 = 0; for ( i= 1; i <= (QB.func_UBound( vars)); i= i + 1) { if (QB.halted()) { return; } ___v9495566++; if (___v9495566 % 100 == 0) { await QB.autoLimit(); }
var vartype = ''; /* STRING */
vartype = (await func_GetVarType( QB.arrayValue(vars, [ i]).value));
if ( vartype == "_BIT" || vartype == "_BYTE" || vartype == "INTEGER" || vartype == "LONG" || vartype == "_INTEGER64" || vartype == "_OFFSET" || vartype == "_UNSIGNED _BIT" || vartype == "_UNSIGNED _BYTE" || vartype == "_UNSIGNED INTEGER" || vartype == "_UNSIGNED LONG" || vartype == "_UNSIGNED _INTEGER64" || vartype == "_UNSIGNED _OFFSET" ) {
js = js + (await func_ConvertExpression( QB.arrayValue(vars, [ i]).value , lineNumber)) + " = parseInt(" + vname + "[" + (QB.func_Str( i - 1)) + "]); ";
} else if ( vartype == "SINGLE" || vartype == "DOUBLE" || vartype == "_FLOAT" ) {
js = js + (await func_ConvertExpression( QB.arrayValue(vars, [ i]).value , lineNumber)) + " = parseFloat(" + vname + "[" + (QB.func_Str( i - 1)) + "]); ";
} else {
js = js + (await func_ConvertExpression( QB.arrayValue(vars, [ i]).value , lineNumber)) + " = " + vname + "[" + (QB.func_Str( i - 1)) + "]; ";
}
}
ConvertInput = js;
return ConvertInput;
}
async function func_ConvertFileInput(m/*METHOD*/,args/*STRING*/,lineNumber/*INTEGER*/) {
if (QB.halted()) { return; }
var ConvertFileInput = null;
var js = ''; /* STRING */
var fh = ''; /* STRING */
var vname = ''; /* STRING */
var retvar = ''; /* STRING */
var pcount = 0; /* INTEGER */
var parts = QB.initArray([{l:0,u:0}], ''); /* STRING */
pcount = (await func_ListSplit( args, parts));
if ( pcount < 2) {
await sub_AddWarning( lineNumber, "Syntax error");
ConvertFileInput = "";
return ConvertFileInput;
}
fh = (await func_Replace( (QB.func__Trim( QB.arrayValue(parts, [ 1]).value)) , "#" , ""));
retvar = (QB.func__Trim( QB.arrayValue(parts, [ 2]).value));
vname = await func_GenJSVar();
js = "var " + vname + " = new Array(" + (QB.func_Str( (QB.func_UBound( parts)) - 1)) + "); ";
js = js + (await func_CallMethod( m)) + "(" + fh + ", " + vname + "); ";
var i = 0; /* INTEGER */
var ___v3640187 = 0; for ( i= 2; i <= (QB.func_UBound( parts)); i= i + 1) { if (QB.halted()) { return; } ___v3640187++; if (___v3640187 % 100 == 0) { await QB.autoLimit(); }
var vartype = ''; /* STRING */
vartype = (await func_GetVarType( QB.arrayValue(parts, [ i]).value));
if ( vartype == "_BIT" || vartype == "_BYTE" || vartype == "INTEGER" || vartype == "LONG" || vartype == "_INTEGER64" || vartype == "_OFFSET" || vartype == "_UNSIGNED _BIT" || vartype == "_UNSIGNED _BYTE" || vartype == "_UNSIGNED INTEGER" || vartype == "_UNSIGNED LONG" || vartype == "_UNSIGNED _INTEGER64" || vartype == "_UNSIGNED _OFFSET" ) {
js = js + (await func_ConvertExpression( QB.arrayValue(parts, [ i]).value , lineNumber)) + " = parseInt(" + vname + "[" + (QB.func_Str( i - 2)) + "]); ";
} else if ( vartype == "SINGLE" || vartype == "DOUBLE" || vartype == "_FLOAT" ) {
js = js + (await func_ConvertExpression( QB.arrayValue(parts, [ i]).value , lineNumber)) + " = parseFloat(" + vname + "[" + (QB.func_Str( i - 2)) + "]); ";
} else {
js = js + (await func_ConvertExpression( QB.arrayValue(parts, [ i]).value , lineNumber)) + " = " + vname + "[" + (QB.func_Str( i - 2)) + "]; ";
}
}
ConvertFileInput = js;
return ConvertFileInput;
}
async function func_GetVarType(vname/*STRING*/) {
if (QB.halted()) { return; }
var GetVarType = null;
var vartype = ''; /* STRING */
vartype = "UNKNOWN";
var parts = QB.initArray([{l:0,u:0}], ''); /* STRING */
var pcount = 0; /* INTEGER */
var found = 0; /* INTEGER */
var v = {type:'',name:'',jsname:'',isConst:0,isArray:0,arraySize:0,typeId:0}; /* VARIABLE */
var pidx = 0; /* INTEGER */
pcount = (await func_Split( vname, "." , parts));
if ( pcount == 1) {
pidx = (QB.func_InStr( vname, "("));
if ( pidx) {
vname = (QB.func_Left( vname, pidx - 1));
}
found = (await func_FindVariable( vname, v, False));
if (! found) {
found = (await func_FindVariable( vname, v, True));
}
if ( found) {
vartype = v.type;
}
} else {
vname = QB.arrayValue(parts, [ 1]).value;
pidx = (QB.func_InStr( vname, "("));
if ( pidx) {
vname = (QB.func_Left( vname, pidx - 1));
}
found = (await func_FindVariable( vname, v, False));
if (! found) {
found = (await func_FindVariable( vname, v, True));
}
if ( found) {
var typeId = 0; /* INTEGER */
typeId = (await func_FindTypeId( v.type));
var i = 0; /* INTEGER */
var j = 0; /* INTEGER */
var ___v5248684 = 0; for ( i= 2; i <= pcount; i= i + 1) { if (QB.halted()) { return; } ___v5248684++; if (___v5248684 % 100 == 0) { await QB.autoLimit(); }
var ___v7671116 = 0; for ( j= 1; j <= (QB.func_UBound( typeVars)); j= j + 1) { if (QB.halted()) { return; } ___v7671116++; if (___v7671116 % 100 == 0) { await QB.autoLimit(); }
if (QB.arrayValue(typeVars, [ j]).value .typeId == typeId && QB.arrayValue(typeVars, [ j]).value .name == QB.arrayValue(parts, [ i]).value ) {
vartype = QB.arrayValue(typeVars, [ j]).value .type;
typeId = (await func_FindTypeId( vartype));
}
}
}
}
}
GetVarType = vartype;
return GetVarType;
}
async function func_ConvertSwap(m/*METHOD*/,args/*STRING*/,lineNumber/*INTEGER*/) {
if (QB.halted()) { return; }
var ConvertSwap = null;
@ -1199,7 +1345,7 @@ var FindParamChar = null;
var quote = 0; /* INTEGER */
var paren = 0; /* INTEGER */
var i = 0; /* INTEGER */
var ___v9495566 = 0; for ( i= 1; i <= (QB.func_Len( s)); i= i + 1) { if (QB.halted()) { return; } ___v9495566++; if (___v9495566 % 100 == 0) { await QB.autoLimit(); }
var ___v535045 = 0; for ( i= 1; i <= (QB.func_Len( s)); i= i + 1) { if (QB.halted()) { return; } ___v535045++; if (___v535045 % 100 == 0) { await QB.autoLimit(); }
c = (QB.func_Mid( s, i, 1));
if ( c == (QB.func_Chr( 34)) ) {
quote = ! quote;
@ -1240,7 +1386,7 @@ var DeclareVar = null;
var preserve = ''; /* STRING */
preserve = "false";
var i = 0; /* INTEGER */
var ___v3640187 = 0; for ( i= 1; i <= (QB.func_UBound( parts)); i= i + 1) { if (QB.halted()) { return; } ___v3640187++; if (___v3640187 % 100 == 0) { await QB.autoLimit(); }
var ___v5924582 = 0; for ( i= 1; i <= (QB.func_UBound( parts)); i= i + 1) { if (QB.halted()) { return; } ___v5924582++; if (___v5924582 % 100 == 0) { await QB.autoLimit(); }
if ((QB.func_UCase( QB.arrayValue(parts, [ i]).value)) == "AS" ) {
asIdx = i;
}
@ -1261,7 +1407,7 @@ var DeclareVar = null;
}
bvar.typeId = (await func_FindTypeId( bvar.type));
vnamecount = (await func_ListSplit( (await func_Join( parts , nextIdx, - 1, " ")) , varnames));
var ___v5248684 = 0; for ( i= 1; i <= vnamecount; i= i + 1) { if (QB.halted()) { return; } ___v5248684++; if (___v5248684 % 100 == 0) { await QB.autoLimit(); }
var ___v4687001 = 0; for ( i= 1; i <= vnamecount; i= i + 1) { if (QB.halted()) { return; } ___v4687001++; if (___v4687001 % 100 == 0) { await QB.autoLimit(); }
vname = (QB.func__Trim( QB.arrayValue(varnames, [ i]).value));
pstart = (QB.func_InStr( vname, "("));
if ( pstart > 0) {
@ -1296,7 +1442,7 @@ var DeclareVar = null;
var vpartcount = 0; /* INTEGER */
var vparts = QB.initArray([{l:0,u:0}], ''); /* STRING */
nextIdx = 0;
var ___v7671116 = 0; for ( i= 1; i <= (QB.func_UBound( parts)); i= i + 1) { if (QB.halted()) { return; } ___v7671116++; if (___v7671116 % 100 == 0) { await QB.autoLimit(); }
var ___v2981654 = 0; for ( i= 1; i <= (QB.func_UBound( parts)); i= i + 1) { if (QB.halted()) { return; } ___v2981654++; if (___v2981654 % 100 == 0) { await QB.autoLimit(); }
var p = ''; /* STRING */
p = (QB.func_UCase( QB.arrayValue(parts, [ i]).value));
if ( p == "DIM" || p == "REDIM" || p == "SHARED" || p == "_PRESERVE" ) {
@ -1304,17 +1450,17 @@ var DeclareVar = null;
}
}
vnamecount = (await func_ListSplit( (await func_Join( parts , nextIdx, - 1, " ")) , varnames));
var ___v535045 = 0; for ( i= 1; i <= vnamecount; i= i + 1) { if (QB.halted()) { return; } ___v535045++; if (___v535045 % 100 == 0) { await QB.autoLimit(); }
var ___v6226967 = 0; for ( i= 1; i <= vnamecount; i= i + 1) { if (QB.halted()) { return; } ___v6226967++; if (___v6226967 % 100 == 0) { await QB.autoLimit(); }
vpartcount = (await func_SLSplit2( QB.arrayValue(varnames, [ i]).value , vparts));
bvar.name = (await func_RemoveSuffix( QB.arrayValue(vparts, [ 1]).value));
if ( vpartcount == 1) {
bvar.type = (await func_DataTypeFromName( bvar.name));
bvar.type = (await func_DataTypeFromName( QB.arrayValue(vparts, [ 1]).value));
} else if ( vpartcount == 3) {
bvar.type = (QB.func_UCase( QB.arrayValue(vparts, [ 3]).value));
} else if ( vpartcount == 4) {
bvar.type = (QB.func_UCase( (await func_Join( vparts , 3, - 1, " "))));
} else {
}
bvar.name = (await func_RemoveSuffix( QB.arrayValue(vparts, [ 1]).value));
bvar.typeId = (await func_FindTypeId( bvar.type));
pstart = (QB.func_InStr( bvar.name, "("));
if ( pstart > 0) {
@ -1357,7 +1503,7 @@ var FormatArraySize = null;
var pcount = 0; /* INTEGER */
pcount = (await func_ListSplit( sizeString, parts));
var i = 0; /* INTEGER */
var ___v5924582 = 0; for ( i= 1; i <= pcount; i= i + 1) { if (QB.halted()) { return; } ___v5924582++; if (___v5924582 % 100 == 0) { await QB.autoLimit(); }
var ___v6478212 = 0; for ( i= 1; i <= pcount; i= i + 1) { if (QB.halted()) { return; } ___v6478212++; if (___v6478212 % 100 == 0) { await QB.autoLimit(); }
var subparts = QB.initArray([{l:0,u:0}], ''); /* STRING */
var scount = 0; /* INTEGER */
scount = (await func_SLSplit2( QB.arrayValue(parts, [ i]).value , subparts));
@ -1388,7 +1534,7 @@ var InitTypeValue = null;
var typeId = 0; /* INTEGER */
typeId = (await func_FindTypeId( vtype));
var i = 0; /* INTEGER */
var ___v4687001 = 0; for ( i= 1; i <= (QB.func_UBound( typeVars)); i= i + 1) { if (QB.halted()) { return; } ___v4687001++; if (___v4687001 % 100 == 0) { await QB.autoLimit(); }
var ___v2637929 = 0; for ( i= 1; i <= (QB.func_UBound( typeVars)); i= i + 1) { if (QB.halted()) { return; } ___v2637929++; if (___v2637929 % 100 == 0) { await QB.autoLimit(); }
if ( typeId == QB.arrayValue(typeVars, [ i]).value .typeId) {
value = value + QB.arrayValue(typeVars, [ i]).value .name + ":" + (await func_InitTypeValue( QB.arrayValue(typeVars, [ i]).value .type)) + ",";
}
@ -1404,7 +1550,7 @@ var FindTypeId = null;
var id = 0; /* INTEGER */
id = - 1;
var i = 0; /* INTEGER */
var ___v2981654 = 0; for ( i= 1; i <= (QB.func_UBound( types)); i= i + 1) { if (QB.halted()) { return; } ___v2981654++; if (___v2981654 % 100 == 0) { await QB.autoLimit(); }
var ___v2793420 = 0; for ( i= 1; i <= (QB.func_UBound( types)); i= i + 1) { if (QB.halted()) { return; } ___v2793420++; if (___v2793420 % 100 == 0) { await QB.autoLimit(); }
if (QB.arrayValue(types, [ i]).value .name == typeName) {
id = i;
break;
@ -1426,7 +1572,7 @@ var ConvertExpression = null;
var stringLiteral = 0; /* INTEGER */
var i = 0; /* INTEGER */
i = 1;
var ___v6226967 = 0; while ( i <= (QB.func_Len( ex))) { if (QB.halted()) { return; }___v6226967++; if (___v6226967 % 100 == 0) { await QB.autoLimit(); }
var ___v8298016 = 0; while ( i <= (QB.func_Len( ex))) { if (QB.halted()) { return; }___v8298016++; if (___v8298016 % 100 == 0) { await QB.autoLimit(); }
c = (QB.func_Mid( ex, i, 1));
if ( c == (QB.func_Chr( 34)) ) {
js = js + c;
@ -1448,6 +1594,8 @@ var ConvertExpression = null;
js = js + " || ";
} else if ( uword == "MOD" ) {
js = js + " % ";
} else if ( uword == "XOR" ) {
js = js + " ^ ";
} else if ( uword == "=" ) {
js = js + " == ";
} else if ( uword == "<>" ) {
@ -1488,7 +1636,7 @@ var ConvertExpression = null;
var stringLiteral2 = 0; /* INTEGER */
stringLiteral2 = False;
i = i + 1;
var ___v6478212 = 0; while (! done && i <= (QB.func_Len( ex))) { if (QB.halted()) { return; }___v6478212++; if (___v6478212 % 100 == 0) { await QB.autoLimit(); }
var ___v8246022 = 0; while (! done && i <= (QB.func_Len( ex))) { if (QB.halted()) { return; }___v8246022++; if (___v8246022 % 100 == 0) { await QB.autoLimit(); }
c2 = (QB.func_Mid( ex, i, 1));
if ( c2 == (QB.func_Chr( 34)) ) {
stringLiteral2 = ! stringLiteral2;
@ -1546,7 +1694,7 @@ var ConvertMethodParams = null;
var argc = 0; /* INTEGER */
argc = (await func_ListSplit( args, params));
var i = 0; /* INTEGER */
var ___v2637929 = 0; for ( i= 1; i <= argc; i= i + 1) { if (QB.halted()) { return; } ___v2637929++; if (___v2637929 % 100 == 0) { await QB.autoLimit(); }
var ___v5891630 = 0; for ( i= 1; i <= argc; i= i + 1) { if (QB.halted()) { return; } ___v5891630++; if (___v5891630 % 100 == 0) { await QB.autoLimit(); }
if ( i > 1) {
js = js + ",";
}
@ -1578,7 +1726,7 @@ var FindVariable = null;
var i = 0; /* INTEGER */
var fvarname = ''; /* STRING */
fvarname = (QB.func__Trim( (QB.func_UCase( (await func_RemoveSuffix( varname))))));
var ___v2793420 = 0; for ( i= 1; i <= (QB.func_UBound( localVars)); i= i + 1) { if (QB.halted()) { return; } ___v2793420++; if (___v2793420 % 100 == 0) { await QB.autoLimit(); }
var ___v9860932 = 0; for ( i= 1; i <= (QB.func_UBound( localVars)); i= i + 1) { if (QB.halted()) { return; } ___v9860932++; if (___v9860932 % 100 == 0) { await QB.autoLimit(); }
if (QB.arrayValue(localVars, [ i]).value .isArray == isArray && (QB.func_UCase( QB.arrayValue(localVars, [ i]).value .name)) == fvarname) {
found = True;
bvar.type = QB.arrayValue(localVars, [ i]).value .type;
@ -1592,7 +1740,7 @@ var FindVariable = null;
}
}
if (! found) {
var ___v8298016 = 0; for ( i= 1; i <= (QB.func_UBound( globalVars)); i= i + 1) { if (QB.halted()) { return; } ___v8298016++; if (___v8298016 % 100 == 0) { await QB.autoLimit(); }
var ___v9109643 = 0; for ( i= 1; i <= (QB.func_UBound( globalVars)); i= i + 1) { if (QB.halted()) { return; } ___v9109643++; if (___v9109643 % 100 == 0) { await QB.autoLimit(); }
if (QB.arrayValue(globalVars, [ i]).value .isArray == isArray && (QB.func_UCase( QB.arrayValue(globalVars, [ i]).value .name)) == fvarname) {
found = True;
bvar.type = QB.arrayValue(globalVars, [ i]).value .type;
@ -1615,7 +1763,7 @@ var FindMethod = null;
var found = 0; /* INTEGER */
found = False;
var i = 0; /* INTEGER */
var ___v8246022 = 0; for ( i= 1; i <= (QB.func_UBound( methods)); i= i + 1) { if (QB.halted()) { return; } ___v8246022++; if (___v8246022 % 100 == 0) { await QB.autoLimit(); }
var ___v2268660 = 0; for ( i= 1; i <= (QB.func_UBound( methods)); i= i + 1) { if (QB.halted()) { return; } ___v2268660++; if (___v2268660 % 100 == 0) { await QB.autoLimit(); }
if (QB.arrayValue(methods, [ i]).value .uname == (QB.func__Trim( (QB.func_UCase( (await func_RemoveSuffix( mname)))))) && QB.arrayValue(methods, [ i]).value .type == t) {
found = True;
m.line = QB.arrayValue(methods, [ i]).value .line;
@ -1631,7 +1779,7 @@ var FindMethod = null;
}
}
if (! found) {
var ___v5891630 = 0; for ( i= 1; i <= (QB.func_UBound( exportMethods)); i= i + 1) { if (QB.halted()) { return; } ___v5891630++; if (___v5891630 % 100 == 0) { await QB.autoLimit(); }
var ___v6951155 = 0; for ( i= 1; i <= (QB.func_UBound( exportMethods)); i= i + 1) { if (QB.halted()) { return; } ___v6951155++; if (___v6951155 % 100 == 0) { await QB.autoLimit(); }
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;
@ -1654,7 +1802,7 @@ async function sub_ConvertMethods() {
if (QB.halted()) { return; }
await sub_AddJSLine( 0, "");
var i = 0; /* INTEGER */
var ___v9860932 = 0; for ( i= 1; i <= (QB.func_UBound( methods)); i= i + 1) { if (QB.halted()) { return; } ___v9860932++; if (___v9860932 % 100 == 0) { await QB.autoLimit(); }
var ___v9800032 = 0; for ( i= 1; i <= (QB.func_UBound( methods)); i= i + 1) { if (QB.halted()) { return; } ___v9800032++; if (___v9800032 % 100 == 0) { await QB.autoLimit(); }
if ((QB.arrayValue(methods, [ i]).value .line != 0) ) {
var lastLine = 0; /* INTEGER */
lastLine = QB.arrayValue(methods, [ i + 1]).value .line - 1;
@ -1669,16 +1817,16 @@ if (QB.halted()) { return; }
var c = 0; /* INTEGER */
c = (await func_Split( QB.arrayValue(methods, [ i]).value .args, "," , args));
var a = 0; /* INTEGER */
var ___v9109643 = 0; for ( a= 1; a <= c; a= a + 1) { if (QB.halted()) { return; } ___v9109643++; if (___v9109643 % 100 == 0) { await QB.autoLimit(); }
var ___v2439314 = 0; for ( a= 1; a <= c; a= a + 1) { if (QB.halted()) { return; } ___v2439314++; if (___v2439314 % 100 == 0) { await QB.autoLimit(); }
var v = 0; /* INTEGER */
var parts = QB.initArray([{l:0,u:0}], ''); /* STRING */
v = (await func_Split( QB.arrayValue(args, [ a]).value , ":" , parts));
methodDec = methodDec + QB.arrayValue(parts, [ 1]).value + "/*" + QB.arrayValue(parts, [ 2]).value + "*/";
methodDec = methodDec + (await func_RemoveSuffix( QB.arrayValue(parts, [ 1]).value)) + "/*" + QB.arrayValue(parts, [ 2]).value + "*/";
if ( a < c) {
methodDec = methodDec + ",";
}
var bvar = {type:'',name:'',jsname:'',isConst:0,isArray:0,arraySize:0,typeId:0}; /* VARIABLE */
bvar.name = QB.arrayValue(parts, [ 1]).value;
bvar.name = (await func_RemoveSuffix( QB.arrayValue(parts, [ 1]).value));
bvar.type = QB.arrayValue(parts, [ 2]).value;
bvar.typeId = (await func_FindTypeId( bvar.type));
if (QB.arrayValue(parts, [ 3]).value == "true" ) {
@ -1702,7 +1850,7 @@ if (QB.halted()) { return; }
await sub_AddJSLine( lastLine, "}");
}
}
var ___v2268660 = 0; for ( i= 1; i <= (QB.func_UBound( exportLines)); i= i + 1) { if (QB.halted()) { return; } ___v2268660++; if (___v2268660 % 100 == 0) { await QB.autoLimit(); }
var ___v5338731 = 0; for ( i= 1; i <= (QB.func_UBound( exportLines)); i= i + 1) { if (QB.halted()) { return; } ___v5338731++; if (___v5338731 % 100 == 0) { await QB.autoLimit(); }
await sub_AddJSLine( i, QB.arrayValue(exportLines, [ i]).value);
}
QB.resizeArray(exportLines, [{l:0,u:0}], '', false); /* STRING */
@ -1713,13 +1861,13 @@ if (QB.halted()) { return; }
var lineIndex = 0; /* INTEGER */
var rawJS = 0; /* SINGLE */
QB.sub_Open(filename, QB.INPUT, 1);
var ___v6951155 = 0; while (!((QB.func_EOF( 1)))) { if (QB.halted()) { return; }___v6951155++; if (___v6951155 % 100 == 0) { await QB.autoLimit(); }
var ___v9800032 = new Array(1); await QB.sub_LineInputFromFile(1, ___v9800032); fline = ___v9800032[0];
var ___v1063697 = 0; while (!((QB.func_EOF( 1)))) { if (QB.halted()) { return; }___v1063697++; if (___v1063697 % 100 == 0) { await QB.autoLimit(); }
var ___v9994146 = new Array(1); await QB.sub_LineInputFromFile(1, ___v9994146); fline = ___v9994146[0];
lineIndex = lineIndex + 1;
if ((QB.func__Trim( fline)) != "" ) {
var ___v2439314 = 0; while ((await func_EndsWith( fline, " _"))) { if (QB.halted()) { return; }___v2439314++; if (___v2439314 % 100 == 0) { await QB.autoLimit(); }
var ___v6761759 = 0; while ((await func_EndsWith( fline, " _"))) { if (QB.halted()) { return; }___v6761759++; if (___v6761759 % 100 == 0) { await QB.autoLimit(); }
var nextLine = ''; /* STRING */
var ___v5338731 = new Array(1); await QB.sub_LineInputFromFile(1, ___v5338731); nextLine = ___v5338731[0];
var ___v157039 = new Array(1); await QB.sub_LineInputFromFile(1, ___v157039); nextLine = ___v157039[0];
fline = (QB.func_Left( fline, (QB.func_Len( fline)) - 1)) + nextLine;
}
rawJS = (await func_ReadLine( lineIndex, fline, rawJS));
@ -1734,7 +1882,7 @@ if (QB.halted()) { return; }
var lcount = 0; /* INTEGER */
var i = 0; /* INTEGER */
lcount = (await func_Split( sourceText, await func_LF(), sourceLines));
var ___v1063697 = 0; for ( i= 1; i <= lcount; i= i + 1) { if (QB.halted()) { return; } ___v1063697++; if (___v1063697 % 100 == 0) { await QB.autoLimit(); }
var ___v5751838 = 0; for ( i= 1; i <= lcount; i= i + 1) { if (QB.halted()) { return; } ___v5751838++; if (___v5751838 % 100 == 0) { await QB.autoLimit(); }
var fline = ''; /* STRING */
fline = QB.arrayValue(sourceLines, [ i]).value;
if ((QB.func__Trim( fline)) != "" ) {
@ -1758,7 +1906,7 @@ if (QB.halted()) { return; }
continue;
}
}
var ___v9994146 = 0; while ((await func_EndsWith( fline, "_"))) { if (QB.halted()) { return; }___v9994146++; if (___v9994146 % 100 == 0) { await QB.autoLimit(); }
var ___v1000522 = 0; while ((await func_EndsWith( fline, "_"))) { if (QB.halted()) { return; }___v1000522++; if (___v1000522 % 100 == 0) { await QB.autoLimit(); }
i = i + 1;
var nextLine = ''; /* STRING */
nextLine = QB.arrayValue(sourceLines, [ i]).value;
@ -1774,7 +1922,7 @@ var ReadLine = null;
var quoteDepth = 0; /* INTEGER */
quoteDepth = 0;
var i = 0; /* INTEGER */
var ___v6761759 = 0; for ( i= 1; i <= (QB.func_Len( fline)); i= i + 1) { if (QB.halted()) { return; } ___v6761759++; if (___v6761759 % 100 == 0) { await QB.autoLimit(); }
var ___v1030226 = 0; for ( i= 1; i <= (QB.func_Len( fline)); i= i + 1) { if (QB.halted()) { return; } ___v1030226++; if (___v1030226 % 100 == 0) { await QB.autoLimit(); }
var c = ''; /* STRING */ var c4 = ''; /* STRING */
c = (QB.func_Mid( fline, i, 1));
c4 = (QB.func_UCase( (QB.func_Mid( fline, i, 4))));
@ -1834,7 +1982,7 @@ var ReadLine = null;
var dcount = 0; /* INTEGER */
var de = QB.initArray([{l:0,u:0}], ''); /* STRING */
dcount = (await func_ListSplit( dstr, de));
var ___v157039 = 0; for ( i= 1; i <= dcount; i= i + 1) { if (QB.halted()) { return; } ___v157039++; if (___v157039 % 100 == 0) { await QB.autoLimit(); }
var ___v7988844 = 0; for ( i= 1; i <= dcount; i= i + 1) { if (QB.halted()) { return; } ___v7988844++; if (___v7988844 % 100 == 0) { await QB.autoLimit(); }
index = (QB.func_UBound( dataArray)) + 1;
QB.resizeArray(dataArray, [{l:0,u:index}], '', true); /* STRING */
QB.arrayValue(dataArray, [ index]).value = QB.arrayValue(de, [ i]).value;
@ -1842,7 +1990,7 @@ var ReadLine = null;
return ReadLine;
}
var ifIdx = 0; /* INTEGER */ var thenIdx = 0; /* INTEGER */ var elseIdx = 0; /* INTEGER */
var ___v5751838 = 0; for ( i= 1; i <= wcount; i= i + 1) { if (QB.halted()) { return; } ___v5751838++; if (___v5751838 % 100 == 0) { await QB.autoLimit(); }
var ___v2844803 = 0; for ( i= 1; i <= wcount; i= i + 1) { if (QB.halted()) { return; } ___v2844803++; if (___v2844803 % 100 == 0) { await QB.autoLimit(); }
word = (QB.func_UCase( QB.arrayValue(words, [ i]).value));
if ( word == "IF" ) {
ifIdx = i;
@ -1872,7 +2020,7 @@ if (QB.halted()) { return; }
var quoteDepth = 0; /* INTEGER */
quoteDepth = 0;
var i = 0; /* INTEGER */
var ___v1000522 = 0; for ( i= 1; i <= (QB.func_Len( fline)); i= i + 1) { if (QB.halted()) { return; } ___v1000522++; if (___v1000522 % 100 == 0) { await QB.autoLimit(); }
var ___v456492 = 0; for ( i= 1; i <= (QB.func_Len( fline)); i= i + 1) { if (QB.halted()) { return; } ___v456492++; if (___v456492 % 100 == 0) { await QB.autoLimit(); }
var c = ''; /* STRING */
c = (QB.func_Mid( fline, i, 1));
if ( c == (QB.func_Chr( 34)) ) {
@ -1896,7 +2044,7 @@ if (QB.halted()) { return; }
var pcount = 0; /* INTEGER */
var rawJS = 0; /* INTEGER */
var parts = QB.initArray([{l:0,u:0}], ''); /* STRING */
var ___v1030226 = 0; for ( i= 1; i <= (QB.func_UBound( lines)); i= i + 1) { if (QB.halted()) { return; } ___v1030226++; if (___v1030226 % 100 == 0) { await QB.autoLimit(); }
var ___v2957728 = 0; for ( i= 1; i <= (QB.func_UBound( lines)); i= i + 1) { if (QB.halted()) { return; } ___v2957728++; if (___v2957728 % 100 == 0) { await QB.autoLimit(); }
pcount = (await func_Split( QB.arrayValue(lines, [ i]).value .text, " " , parts));
var word = ''; /* STRING */
word = (QB.func_UCase( QB.arrayValue(parts, [ 1]).value));
@ -1940,7 +2088,7 @@ if (QB.halted()) { return; }
var a = 0; /* INTEGER */
var args = ''; /* STRING */
args = "";
var ___v7988844 = 0; for ( a= 1; a <= m.argc; a= a + 1) { if (QB.halted()) { return; } ___v7988844++; if (___v7988844 % 100 == 0) { await QB.autoLimit(); }
var ___v3820107 = 0; for ( a= 1; a <= m.argc; a= a + 1) { if (QB.halted()) { return; } ___v3820107++; if (___v3820107 % 100 == 0) { await QB.autoLimit(); }
var aparts = QB.initArray([{l:0,u:0}], ''); /* STRING */
var apcount = 0; /* INTEGER */
var argname = ''; /* STRING */
@ -1976,7 +2124,7 @@ var Split = null;
if ( delimiter == " " ) {
cstr = (QB.func_RTrim( (QB.func_LTrim( cstr))));
p = (QB.func_InStr( cstr, " "));
var ___v2844803 = 0; while ( p > 0) { if (QB.halted()) { return; }___v2844803++; if (___v2844803 % 100 == 0) { await QB.autoLimit(); }
var ___v3009705 = 0; while ( p > 0) { if (QB.halted()) { return; }___v3009705++; if (___v3009705 % 100 == 0) { await QB.autoLimit(); }
cstr = (QB.func_Mid( cstr, 1, p - 1)) + (QB.func_Mid( cstr, p + 1));
p = (QB.func_InStr( cstr, " "));
}
@ -1984,7 +2132,7 @@ var Split = null;
curpos = 1;
arrpos = 0;
dpos = (QB.func_InStr( curpos, cstr, delimiter));
var ___v456492 = 0; while (!( dpos == 0)) { if (QB.halted()) { return; }___v456492++; if (___v456492 % 100 == 0) { await QB.autoLimit(); }
var ___v9485711 = 0; while (!( dpos == 0)) { if (QB.halted()) { return; }___v9485711++; if (___v9485711 % 100 == 0) { await QB.autoLimit(); }
arrpos = arrpos + 1;
QB.resizeArray(results, [{l:0,u:arrpos}], '', true); /* STRING */
QB.arrayValue(results, [ arrpos]).value = (QB.func_Mid( cstr, curpos, dpos - curpos));
@ -2009,7 +2157,7 @@ var SLSplit = null;
var result = ''; /* STRING */
var count = 0; /* INTEGER */
var i = 0; /* INTEGER */
var ___v2957728 = 0; for ( i= 1; i <= (QB.func_Len( cstr)); i= i + 1) { if (QB.halted()) { return; } ___v2957728++; if (___v2957728 % 100 == 0) { await QB.autoLimit(); }
var ___v9798294 = 0; for ( i= 1; i <= (QB.func_Len( cstr)); i= i + 1) { if (QB.halted()) { return; } ___v9798294++; if (___v9798294 % 100 == 0) { await QB.autoLimit(); }
var c = ''; /* STRING */ var c2 = ''; /* STRING */
c = (QB.func_Mid( cstr, i, 1));
c2 = (QB.func_Mid( cstr, i, 2));
@ -2111,7 +2259,7 @@ var SLSplit2 = null;
var paren = 0; /* INTEGER */
var count = 0; /* INTEGER */
var i = 0; /* INTEGER */
var ___v3820107 = 0; for ( i= 1; i <= (QB.func_Len( cstr)); i= i + 1) { if (QB.halted()) { return; } ___v3820107++; if (___v3820107 % 100 == 0) { await QB.autoLimit(); }
var ___v4013744 = 0; for ( i= 1; i <= (QB.func_Len( cstr)); i= i + 1) { if (QB.halted()) { return; } ___v4013744++; if (___v4013744 % 100 == 0) { await QB.autoLimit(); }
var c = ''; /* STRING */
c = (QB.func_Mid( cstr, i, 1));
if ( c == (QB.func_Chr( 34)) ) {
@ -2160,7 +2308,7 @@ var ListSplit = null;
var count = 0; /* INTEGER */
var paren = 0; /* INTEGER */
var i = 0; /* INTEGER */
var ___v3009705 = 0; for ( i= 1; i <= (QB.func_Len( cstr)); i= i + 1) { if (QB.halted()) { return; } ___v3009705++; if (___v3009705 % 100 == 0) { await QB.autoLimit(); }
var ___v2782800 = 0; for ( i= 1; i <= (QB.func_Len( cstr)); i= i + 1) { if (QB.halted()) { return; } ___v2782800++; if (___v2782800 % 100 == 0) { await QB.autoLimit(); }
var c = ''; /* STRING */
c = (QB.func_Mid( cstr, i, 1));
if ( c == (QB.func_Chr( 34)) ) {
@ -2205,7 +2353,7 @@ var PrintSplit = null;
var count = 0; /* INTEGER */
var paren = 0; /* INTEGER */
var i = 0; /* INTEGER */
var ___v9485711 = 0; for ( i= 1; i <= (QB.func_Len( cstr)); i= i + 1) { if (QB.halted()) { return; } ___v9485711++; if (___v9485711 % 100 == 0) { await QB.autoLimit(); }
var ___v1604415 = 0; for ( i= 1; i <= (QB.func_Len( cstr)); i= i + 1) { if (QB.halted()) { return; } ___v1604415++; if (___v1604415 % 100 == 0) { await QB.autoLimit(); }
var c = ''; /* STRING */
c = (QB.func_Mid( cstr, i, 1));
if ( c == (QB.func_Chr( 34)) ) {
@ -2249,7 +2397,7 @@ if (QB.halted()) { return; }
await QB.sub_Print(["Methods"]);
await QB.sub_Print(["------------------------------------------------------------"]);
var i = 0; /* INTEGER */
var ___v9798294 = 0; for ( i= 1; i <= (QB.func_UBound( methods)); i= i + 1) { if (QB.halted()) { return; } ___v9798294++; if (___v9798294 % 100 == 0) { await QB.autoLimit(); }
var ___v1628216 = 0; for ( i= 1; i <= (QB.func_UBound( methods)); i= i + 1) { if (QB.halted()) { return; } ___v1628216++; if (___v1628216 % 100 == 0) { await QB.autoLimit(); }
var m = {line:0,type:'',returnType:'',name:'',uname:'',argc:0,args:'',jsname:'',sync:0}; /* METHOD */
m = QB.arrayValue(methods, [ i]).value;
await QB.sub_Print([(QB.func_Str( m.line)) + ": " + m.type + " - " + m.name + " [" + m.jsname + "] - " + m.returnType + " - " + m.args]);
@ -2261,12 +2409,12 @@ if (QB.halted()) { return; }
await QB.sub_Print(["Types"]);
await QB.sub_Print(["------------------------------------------------------------"]);
var i = 0; /* INTEGER */
var ___v4013744 = 0; for ( i= 1; i <= (QB.func_UBound( types)); i= i + 1) { if (QB.halted()) { return; } ___v4013744++; if (___v4013744 % 100 == 0) { await QB.autoLimit(); }
var ___v6465872 = 0; for ( i= 1; i <= (QB.func_UBound( types)); i= i + 1) { if (QB.halted()) { return; } ___v6465872++; if (___v6465872 % 100 == 0) { await QB.autoLimit(); }
var t = {line:0,name:'',argc:0,args:''}; /* QBTYPE */
t = QB.arrayValue(types, [ i]).value;
await QB.sub_Print([(QB.func_Str( t.line)) + ": " + t.name]);
var v = 0; /* INTEGER */
var ___v2782800 = 0; for ( v= 1; v <= (QB.func_UBound( typeVars)); v= v + 1) { if (QB.halted()) { return; } ___v2782800++; if (___v2782800 % 100 == 0) { await QB.autoLimit(); }
var ___v4100732 = 0; for ( v= 1; v <= (QB.func_UBound( typeVars)); v= v + 1) { if (QB.halted()) { return; } ___v4100732++; if (___v4100732 % 100 == 0) { await QB.autoLimit(); }
if (QB.arrayValue(typeVars, [ i]).value .typeId == i) {
await QB.sub_Print([" -> " + QB.arrayValue(typeVars, [ v]).value .name + ": " + QB.arrayValue(typeVars, [ v]).value .type]);
}
@ -2339,6 +2487,19 @@ if (QB.halted()) { return; }
m.name = mname;
await sub_AddMethod( m, "QB." , sync);
}
async function sub_AddNativeMethod(mtype/*STRING*/,mname/*STRING*/,jsname/*STRING*/,sync/*INTEGER*/) {
if (QB.halted()) { return; }
var m = {line:0,type:'',returnType:'',name:'',uname:'',argc:0,args:'',jsname:'',sync:0}; /* METHOD */
m.type = mtype;
m.name = mname;
m.uname = (QB.func_UCase( m.name));
m.jsname = jsname;
m.sync = sync;
var mcount = 0; /* SINGLE */
mcount = (QB.func_UBound( methods)) + 1;
QB.resizeArray(methods, [{l:0,u:mcount}], {line:0,type:'',returnType:'',name:'',uname:'',argc:0,args:'',jsname:'',sync:0}, true); /* METHOD */
QB.arrayValue(methods, [ mcount]).value = m;
}
async function sub_AddLine(lineIndex/*INTEGER*/,fline/*STRING*/) {
if (QB.halted()) { return; }
await sub___AddLine( lineIndex, fline);
@ -2462,7 +2623,7 @@ if (QB.halted()) { return; }
var pairs = QB.initArray([{l:0,u:0}], ''); /* STRING */
count = (await func_Split( args, "," , pairs));
var i = 0; /* INTEGER */
var ___v1604415 = 0; for ( i= 1; i <= (QB.func_UBound( pairs)); i= i + 1) { if (QB.halted()) { return; } ___v1604415++; if (___v1604415 % 100 == 0) { await QB.autoLimit(); }
var ___v4127668 = 0; for ( i= 1; i <= (QB.func_UBound( pairs)); i= i + 1) { if (QB.halted()) { return; } ___v4127668++; if (___v4127668 % 100 == 0) { await QB.autoLimit(); }
var nv = QB.initArray([{l:0,u:0}], ''); /* STRING */
count = (await func_Split( QB.arrayValue(pairs, [ i]).value , ":" , nv));
var tvar = {type:'',name:'',jsname:'',isConst:0,isArray:0,arraySize:0,typeId:0}; /* VARIABLE */
@ -2490,7 +2651,7 @@ var RemoveSuffix = null;
var c = ''; /* STRING */
vname = (QB.func__Trim( vname));
i = (QB.func_Len( vname));
var ___v1628216 = 0; while (! done) { if (QB.halted()) { return; }___v1628216++; if (___v1628216 % 100 == 0) { await QB.autoLimit(); }
var ___v7127304 = 0; while (! done) { if (QB.halted()) { return; }___v7127304++; if (___v7127304 % 100 == 0) { await QB.autoLimit(); }
c = (QB.func_Mid( vname, i, 1));
if ( c == "`" || c == "%" || c == "&" || c == "$" || c == "~" || c == "!" || c == "#" ) {
i = i - 1;
@ -2575,7 +2736,7 @@ var Join = null;
}
var s = ''; /* STRING */
var i = 0; /* INTEGER */
var ___v6465872 = 0; for ( i= startIndex; i <= endIndex; i= i + 1) { if (QB.halted()) { return; } ___v6465872++; if (___v6465872 % 100 == 0) { await QB.autoLimit(); }
var ___v3262062 = 0; for ( i= startIndex; i <= endIndex; i= i + 1) { if (QB.halted()) { return; } ___v3262062++; if (___v3262062 % 100 == 0) { await QB.autoLimit(); }
s = s + QB.arrayValue(parts, [ i]).value;
if ( i != (QB.func_UBound( parts)) ) {
s = s + delimiter;
@ -2599,7 +2760,7 @@ var Replace = null;
var i = 0; /* INTEGER */
var slen = 0; /* INTEGER */
slen = (QB.func_Len( searchString));
var ___v4100732 = 0; for ( i= 1; i <= (QB.func_Len( s)); i= i + 1) { if (QB.halted()) { return; } ___v4100732++; if (___v4100732 % 100 == 0) { await QB.autoLimit(); }
var ___v6331789 = 0; for ( i= 1; i <= (QB.func_Len( s)); i= i + 1) { if (QB.halted()) { return; } ___v6331789++; if (___v6331789 % 100 == 0) { await QB.autoLimit(); }
if ((QB.func_Mid( s, i, slen)) == searchString) {
ns = ns + newString;
i = i + slen - 1;
@ -2641,7 +2802,7 @@ var MethodJS = null;
var i = 0; /* INTEGER */
var c = ''; /* STRING */
var a = 0; /* INTEGER */
var ___v4127668 = 0; for ( i= 1; i <= (QB.func_Len( m.name)); i= i + 1) { if (QB.halted()) { return; } ___v4127668++; if (___v4127668 % 100 == 0) { await QB.autoLimit(); }
var ___v2075611 = 0; for ( i= 1; i <= (QB.func_Len( m.name)); i= i + 1) { if (QB.halted()) { return; } ___v2075611++; if (___v2075611 % 100 == 0) { await QB.autoLimit(); }
c = (QB.func_Mid( m.name, i, 1));
a = (QB.func_Asc( c));
if (( a >= 65 && a <= 90) || ( a >= 97 && a <= 122) || ( a >= 48 && a <= 57) || a == 95 || a == 46) {
@ -2667,7 +2828,7 @@ var GXMethodJS = null;
var i = 0; /* INTEGER */
var c = ''; /* STRING */
var a = 0; /* INTEGER */
var ___v7127304 = 0; for ( i= startIdx + 1; i <= (QB.func_Len( mname)); i= i + 1) { if (QB.halted()) { return; } ___v7127304++; if (___v7127304 % 100 == 0) { await QB.autoLimit(); }
var ___v1860135 = 0; for ( i= startIdx + 1; i <= (QB.func_Len( mname)); i= i + 1) { if (QB.halted()) { return; } ___v1860135++; if (___v1860135 % 100 == 0) { await QB.autoLimit(); }
c = (QB.func_Mid( mname, i, 1));
a = (QB.func_Asc( c));
if (( a >= 65 && a <= 90) || ( a >= 97 && a <= 122) || ( a >= 48 && a <= 57) || a == 95 || a == 46) {
@ -3134,6 +3295,8 @@ if (QB.halted()) { return; }
await sub_AddQBMethod( "SUB" , "RmDir" , False);
await sub_AddQBMethod( "FUNCTION" , "Rnd" , False);
await sub_AddQBMethod( "SUB" , "Screen" , False);
await sub_AddQBMethod( "FUNCTION" , "Seek" , False);
await sub_AddQBMethod( "SUB" , "Seek" , False);
await sub_AddQBMethod( "FUNCTION" , "Sgn" , False);
await sub_AddQBMethod( "FUNCTION" , "Sin" , False);
await sub_AddQBMethod( "SUB" , "Sleep" , True);
@ -3150,7 +3313,10 @@ if (QB.halted()) { return; }
await sub_AddQBMethod( "FUNCTION" , "Val" , False);
await sub_AddQBMethod( "FUNCTION" , "Varptr" , False);
await sub_AddQBMethod( "SUB" , "Window" , False);
await sub_AddQBMethod( "SUB" , "Write" , True);
await sub_AddQBMethod( "SUB" , "IncludeJS" , True);
await sub_AddNativeMethod( "FUNCTION" , "JSON.Parse" , "JSON.parse" , False);
await sub_AddNativeMethod( "FUNCTION" , "JSON.Stringify" , "JSON.stringify" , False);
await sub_AddSystemType( "FETCHRESPONSE" , "ok:INTEGER,status:INTEGER,statusText:STRING,text:STRING");
await sub_AddQBMethod( "FUNCTION" , "Fetch" , True);
await sub_AddQBMethod( "SUB" , "Fetch" , True);

View file

@ -51,7 +51,7 @@ a:after { content: " >"; }
}
#output-content {
border: 1px solid #666;
overflow: scroll;
overflow: auto;
height: 250px;
}
#js-code {
@ -159,17 +159,20 @@ a:after { content: " >"; }
font-size: 14px;
}
#share-dialog {
#share-dialog,
#prog-sel-dialog {
background-color:#ddd;
}
#share-dialog textarea {
#share-dialog textarea,
#prog-sel-dialog select {
font-family: dosvga;
font-size: 1em;
letter-spacing: -1px;
background-color: #efefef;
padding: 5px;
}
#share-dialog a { color: #333; }
#share-dialog a:hover { color: #000; }
#share-dialog a, #prog-sel-dialog a { color: #333; }
#share-dialog a:hover, #prog-sel-dialog a:hover { color: #000; }
#logo {
position: absolute;
@ -219,4 +222,38 @@ a:after { content: " >"; }
#fs-refresh {
float: right;
}
#toolbar {
border: 1px solid #666;
border-bottom: 0;
padding: 3px 5px 0px;
/*background-color: rgb(0, 49, 78);*/
}
.toolbar-button {
display: inline-block;
background-size: 1.25em 1.25em;
width: 1.25em;
height: 1.25em;
background-repeat: no-repeat;
margin: 0 !important;
}
.toolbar-button:before { content: ""; }
.toolbar-button:after { content: ""; }
#toolbar-button-open { background-image: url('img/open.svg'); }
#toolbar-button-save { background-image: url('img/save.svg'); background-size: 1.08em, 1.08em; background-position: .05em .05em; }
#toolbar-button-run { background-image: url('img/run.svg'); }
#toolbar-button-share { background-image: url('img/share.svg'); float: right; }
#toolbar-button-open:hover { background-image: url('img/open-hover.svg'); }
#toolbar-button-save:hover { background-image: url('img/save-hover.svg'); }
#toolbar-button-run:hover { background-image: url('img/run-hover.svg'); }
#toolbar-button-share:hover { background-image: url('img/share-hover.svg'); }
#toolbar .spacer {
display: inline-block;
height: 1.25em;
border-left: 1px solid rgba(102,102,102,.6);
margin: 0 2px;
}

View file

@ -9,12 +9,14 @@ var currTab = "js";
var editor;
var selectedError = null;
var currPath = "/";
var mainProg = null;
async function init() {
if (window.innerWidth < 1200) {
sizeMode = "max";
}
var srcUrl = null;
if (url && url.indexOf("?")) {
var queryString = url.substring(url.indexOf("?")+1);
var nvpairs = queryString.split("&");
@ -32,9 +34,10 @@ async function init() {
appMode = nv[1];
}
else if (nv[0] == "src") {
var res = await fetch(nv[1]);
var decoder = new TextDecoder("iso-8859-1");
qbcode = decoder.decode(await res.arrayBuffer());
srcUrl = nv[1];
}
else if (nv[0] == "main") {
mainProg = nv[1];
}
}
}
@ -69,6 +72,24 @@ async function init() {
document.getElementsByClassName("CodeMirror-cursor")[0].innerHTML = " ";
if (srcUrl) {
var res = await fetch(nv[1]);
var contentType = res.headers.get("Content-Type");
if (contentType == "application/zip") {
// load a project
await loadProject(await res.arrayBuffer(), mainProg);
// TODO: shouldn't have to do this
//qbcode = editor.getValue();
}
else {
// otherwise, assume a single source file
var decoder = new TextDecoder("iso-8859-1");
qbcode = decoder.decode(await res.arrayBuffer());
editor.setValue(qbcode);
}
}
var warnCount = 0;
changeTab("console");
window.onresize();
@ -222,23 +243,167 @@ async function exportProgram() {
link.click();
link.remove();
});
}
function addVFSFiles(vfs, zip, parent) {
alert("addVFSFiles: " + parent);
var files = vfs.getChildren(parent, vfs.FILE);
for (var i=0; i < files.length; i++) {
var f = files[i];
var path = vfs.fullPath(f).substring(1);
zip.file(path, f.data);
}
function addVFSFiles(vfs, zip, parent) {
//alert("addVFSFiles: " + parent);
var files = vfs.getChildren(parent, vfs.FILE);
for (var i=0; i < files.length; i++) {
var f = files[i];
var path = vfs.fullPath(f).substring(1);
zip.file(path, f.data);
}
var dirs = vfs.getChildren(parent, vfs.DIRECTORY);
for (var i=0; i < dirs.length; i++) {
addVFSFiles(vfs, zip, dirs[i]);
}
var dirs = vfs.getChildren(parent, vfs.DIRECTORY);
for (var i=0; i < dirs.length; i++) {
addVFSFiles(vfs, zip, dirs[i]);
}
}
async function saveProject() {
var vfs = QB.vfs();
var node = vfs.getNode("/");
var count = vfs.getChildren(node, vfs.FILE).length;
// save a single .bas file
if (count == 0) {
var progFile = new Blob([ editor.getValue() ]);
const link = document.createElement("a");
link.href = URL.createObjectURL(progFile);
link.download = "program.bas";
link.click();
link.remove();
}
// save a project .zip file
else {
var zip = new JSZip();
zip.file("main.bas", editor.getValue());
var vfs = QB.vfs();
var node = vfs.getNode("/");
addVFSFiles(vfs, zip, node);
zip.generateAsync({type:"blob"}).then(function(content) {
const link = document.createElement("a");
link.href = URL.createObjectURL(content);
link.download = "project.zip";
link.click();
link.remove();
});
}
}
async function openProject() {
var f = document.getElementById("file-input");
f.click();
}
async function onOpenProject(event) {
var f = event.target.files[0];
// load a single BASIC source file
if (f.name.toLowerCase().endsWith(".bas") || f.type.startsWith("text/")) {
var fr = new FileReader();
fr.onload = function() {
editor.setValue(fr.result);
}
fr.readAsText(f);
}
// load a project from a zip file
else if (f.name.endsWith(".zip") || f.type == "application/x-zip-compressed") {
await loadProject(f);
}
}
document.getElementById("file-input").onchange = onOpenProject;
async function loadProject(zipData, mainFilename) {
if (!mainFilename) {
mainFilename = "main.bas";
}
else {
mainFilename = mainFilename.toLowerCase();
}
var vfs = GX.vfs();
vfs.reset();
JSZip.loadAsync(zipData).then(async function(zip) {
var basFiles = [];
var fnames = "";
var mainFound = false;
for (let [filename, file] of Object.entries(zip.files)) {
fnames += filename + " - " + zip.files[filename].name + "\n";
var parentDir = dirFromPath(vfs.getParentPath(filename));
if (filename.toLowerCase() == mainFilename) {
var text = await zip.file(filename).async("text");
editor.setValue(text);
mainFound = true;
}
else {
var fdata = await zip.file(filename).async("arraybuffer");
var f = vfs.createFile(vfs.getFileName(filename), parentDir);
vfs.writeData(f, fdata);
if (filename.toLowerCase().endsWith(".bas")) {
basFiles.push(filename);
}
}
}
if (!mainFound) {
var fileList = document.getElementById("prog-sel-sources");
fileList.innerHTML = "";
for (var i=0; i < basFiles.length; i++) {
var opt = new Option(basFiles[i], basFiles[i]);
fileList.append(opt);
}
var progSelDlg = document.getElementById("prog-sel-dialog");
progSelDlg.showModal();
}
refreshFS();
});
function dirFromPath(path) {
var vfs = GX.vfs();
if (path == "") { return vfs.rootDirectory(); }
var dirnames = path.split("/");
var dirpath = ""
var parent = vfs.rootDirectory();
for (var i=0; i < dirnames.length; i++) {
dirpath += "/" + dirnames[i];
var dir = vfs.getNode(dirpath);
if (!dir) {
dir = vfs.createDirectory(dirnames[i], parent);
}
parent = dir;
}
return parent;
}
}
function onSelMainProg() {
var fileList = document.getElementById("prog-sel-sources");
if (fileList.value == "") {
alert("No file selected.");
}
else {
var vfs = GX.vfs();
var file = vfs.getNode("/" + fileList.value);
editor.setValue(vfs.readText(file));
vfs.removeFile(file);
closeProgSelDlg();
}
}
function closeProgSelDlg() {
var progSelDlg = document.getElementById("prog-sel-dialog");
progSelDlg.close();
}
async function getFile(path, type) {
var file = await fetch(path);
if (type == "text") {
@ -458,8 +623,9 @@ window.onresize = function() {
document.getElementById("show-js-container").style.top = (window.innerHeight - 45) + "px";
document.getElementById("show-js-container").style.right = "5px";
editor.setSize(cmwidth, window.innerHeight - 50);
document.getElementById("code").style.height = (window.innerHeight - 50) + "px";
editor.setSize(cmwidth, window.innerHeight - 79);
//document.getElementById("code").style.height = (window.innerHeight - 50) + "px";
document.getElementById("code").style.height = (window.innerHeight - 79) + "px";
document.getElementById("slider").style.height = (window.innerHeight - 50) + "px";
}
//QB.resize(f.style.width.replace("px", ""), f.style.height.replace("px", ""));

View file

@ -738,10 +738,11 @@ Function ConvertSub$ (m As Method, args As String, lineNumber As Integer)
' js = ConvertGet(m, args, lineNumber)
ElseIf m.name = "Input" Then
If StartsWith(_Trim$(parts(1)), "#") Then
' TODO
'js = ConvertFileInput(m, args, lineNumber)
If StartsWith(_Trim$(args), "#") Then
m.jsname = "QB.sub_InputFromFile"
js = ConvertFileInput(m, args, lineNumber)
Else
m.jsname = "QB.sub_Input"
js = ConvertInput(m, args, lineNumber)
End If
@ -749,6 +750,8 @@ Function ConvertSub$ (m As Method, args As String, lineNumber As Integer)
If StartsWith(_Trim$(args), "#") Then
m.jsname = "QB.sub_LineInputFromFile"
js = ConvertFileLineInput(m, args, lineNumber)
m.name = "Line"
m.jsname = "QB.sub_Line"
Else
js = ConvertInput(m, args, lineNumber)
m.name = "Line"
@ -781,6 +784,9 @@ Function ConvertSub$ (m As Method, args As String, lineNumber As Integer)
ElseIf m.name = "Window" Then
js = CallMethod(m) + "(" + ConvertWindow(args, lineNumber) + ");"
ElseIf m.name = "Write" Then
js = ConvertWrite(m, args, lineNumber)
ElseIf m.name = "_PrintString" Then
js = CallMethod(m) + "(" + ConvertPrintString(args, lineNumber) + ");"
@ -914,9 +920,9 @@ Function ConvertLine$ (args As String, lineNumber As Integer)
argc = ListSplit(args, parts())
If argc >= 1 Then coord = ConvertCoordParam(parts(1), True, lineNumber)
If argc >= 2 Then lcolor = ConvertExpression(parts(2), lineNumber)
If argc >= 3 Then mode = "'" + UCase$(_Trim$(parts(3))) + "'"
If argc >= 4 Then style = ConvertExpression(parts(4), lineNumber)
If argc >= 2 And _Trim$(parts(2)) <> "" Then lcolor = ConvertExpression(parts(2), lineNumber)
If argc >= 3 And _Trim$(parts(3)) <> "" Then mode = "'" + UCase$(_Trim$(parts(3))) + "'"
If argc >= 4 And _Trim$(parts(4)) <> "" Then style = ConvertExpression(parts(4), lineNumber)
ConvertLine = coord + ", " + lcolor + ", " + mode + ", " + style
End Function
@ -1195,6 +1201,56 @@ Function ConvertPrint$ (m As Method, args As String, lineNumber As Integer)
ConvertPrint = js + "]);"
End Function
Function ConvertWrite$ (m As Method, args As String, lineNumber As Integer)
Dim fh As String
Dim pcount As Integer
Dim startIdx As Integer
Dim parts(0) As String
pcount = ListSplit(args, parts())
startIdx = 1
m.jsname = "QB.sub_Write"
If pcount > 0 Then
If StartsWith(_Trim$(parts(1)), "#") Then
fh = Replace(_Trim$(parts(1)), "#", "")
m.jsname = "QB.sub_WriteToFile"
startIdx = 2
End If
End If
Dim js As String
js = CallMethod(m) + "("
If fh <> "" Then
js = js + fh + ", "
End If
js = js + "["
Dim i As Integer
For i = startIdx To pcount
If i > startIdx Then js = js + ","
Dim t As String
t = "UNKNOWN"
Dim v As Variable
Dim isVar As Integer
isVar = FindVariable(parts(i), v, False)
If isVar Then
t = v.type
ElseIf StartsWith(parts(i), Chr$(34)) Then
t = "STRING"
End If
If isVar Then
js = js + "{ type:'" + t + "', value:" + _Trim$(ConvertExpression(parts(i), lineNumber)) + "}"
Else
js = js + "{ type:'" + t + "', value:'" + Replace(_Trim$(ConvertExpression(parts(i), lineNumber)), "'", "\'") + "'}"
End If
Next i
ConvertWrite = js + "]);"
End Function
Function ConvertPrintString$ (args As String, lineNumber As Integer)
Dim firstParam As String
Dim theRest As String
@ -1279,13 +1335,112 @@ Function ConvertInput$ (m As Method, args As String, lineNumber As Integer)
js = "var " + vname + " = new Array(" + Str$(UBound(vars)) + "); "
js = js + CallMethod(m) + "(" + vname + ", " + preventNewline + ", " + addQuestionPrompt + ", " + prompt + "); "
For i = 1 To UBound(vars)
If Not StartsWith(_Trim$(vars(i)), "#") Then ' special case to prevent file references from being output during self-compilation
'If Not StartsWith(_Trim$(vars(i)), "#") Then ' special case to prevent file references from being output during self-compilation
' Convert to appropriate variable type on assignment
Dim vartype As String
vartype = GetVarType(vars(i))
If vartype = "_BIT" Or vartype = "_BYTE" Or vartype = "INTEGER" Or vartype = "LONG" Or vartype = "_INTEGER64" Or vartype = "_OFFSET" Or _
vartype = "_UNSIGNED _BIT" Or vartype = "_UNSIGNED _BYTE" Or vartype = "_UNSIGNED INTEGER" Or vartype = "_UNSIGNED LONG" Or vartype = "_UNSIGNED _INTEGER64" Or vartype = "_UNSIGNED _OFFSET" Then
js = js + ConvertExpression(vars(i), lineNumber) + " = parseInt(" + vname + "[" + Str$(i - 1) + "]); "
ElseIf vartype = "SINGLE" Or vartype = "DOUBLE" Or vartype = "_FLOAT" Then
js = js + ConvertExpression(vars(i), lineNumber) + " = parseFloat(" + vname + "[" + Str$(i - 1) + "]); "
Else
js = js + ConvertExpression(vars(i), lineNumber) + " = " + vname + "[" + Str$(i - 1) + "]; "
End If
'End If
Next i
ConvertInput = js
End Function
Function ConvertFileInput$ (m As Method, args As String, lineNumber As Integer)
Dim js As String
Dim fh As String
Dim vname As String
Dim retvar As String
Dim pcount As Integer
ReDim parts(0) As String
pcount = ListSplit(args, parts())
If pcount < 2 Then
AddWarning lineNumber, "Syntax error"
ConvertFileInput = ""
Exit Function
End If
fh = Replace(_Trim$(parts(1)), "#", "")
retvar = _Trim$(parts(2))
vname = GenJSVar
js = "var " + vname + " = new Array(" + Str$(UBound(parts) - 1) + "); "
js = js + CallMethod(m) + "(" + fh + ", " + vname + "); "
Dim i As Integer
For i = 2 To UBound(parts)
' Convert to appropriate variable type on assignment
Dim vartype As String
vartype = GetVarType(parts(i))
If vartype = "_BIT" Or vartype = "_BYTE" Or vartype = "INTEGER" Or vartype = "LONG" Or vartype = "_INTEGER64" Or vartype = "_OFFSET" Or _
vartype = "_UNSIGNED _BIT" Or vartype = "_UNSIGNED _BYTE" Or vartype = "_UNSIGNED INTEGER" Or vartype = "_UNSIGNED LONG" Or vartype = "_UNSIGNED _INTEGER64" Or vartype = "_UNSIGNED _OFFSET" Then
js = js + ConvertExpression(parts(i), lineNumber) + " = parseInt(" + vname + "[" + Str$(i - 2) + "]); "
ElseIf vartype = "SINGLE" Or vartype = "DOUBLE" Or vartype = "_FLOAT" Then
js = js + ConvertExpression(parts(i), lineNumber) + " = parseFloat(" + vname + "[" + Str$(i - 2) + "]); "
Else
js = js + ConvertExpression(parts(i), lineNumber) + " = " + vname + "[" + Str$(i - 2) + "]; "
End If
Next i
ConvertFileInput = js
End Function
Function GetVarType$ (vname As String)
Dim vartype As String
vartype = "UNKNOWN"
ReDim parts(0) As String
Dim pcount As Integer
Dim found As Integer
Dim v As Variable
Dim pidx As Integer
pcount = Split(vname, ".", parts())
If pcount = 1 Then
pidx = InStr(vname, "(")
If pidx Then vname = Left$(vname, pidx - 1)
found = FindVariable(vname, v, False)
If Not found Then found = FindVariable(vname, v, True)
If found Then
vartype = v.type
End If
Else
vname = parts(1)
pidx = InStr(vname, "(")
If pidx Then vname = Left$(vname, pidx - 1)
found = FindVariable(vname, v, False)
If Not found Then found = FindVariable(vname, v, True)
If found Then
Dim typeId As Integer
typeId = FindTypeId(v.type)
Dim i As Integer
Dim j As Integer
For i = 2 To pcount
For j = 1 To UBound(typeVars)
If typeVars(j).typeId = typeId And typeVars(j).name = parts(i) Then
vartype = typeVars(j).type
typeId = FindTypeId(vartype)
End If
Next j
Next i
End If
End If
GetVarType = vartype
End Function
Function ConvertSwap$ (m As Method, args As String, lineNumber As Integer)
Dim js As String
Dim swapArray As String: swapArray = GenJSVar
@ -1426,9 +1581,8 @@ Function DeclareVar$ (parts() As String, lineNumber As Integer)
For i = 1 To vnamecount
vpartcount = SLSplit2(varnames(i), vparts())
bvar.name = RemoveSuffix(vparts(1))
If vpartcount = 1 Then
bvar.type = DataTypeFromName(bvar.name)
bvar.type = DataTypeFromName(vparts(1))
ElseIf vpartcount = 3 Then
bvar.type = UCase$(vparts(3))
ElseIf vpartcount = 4 Then
@ -1436,6 +1590,7 @@ Function DeclareVar$ (parts() As String, lineNumber As Integer)
Else
' Log error?
End If
bvar.name = RemoveSuffix(vparts(1))
bvar.typeId = FindTypeId(bvar.type)
@ -1570,6 +1725,8 @@ Function ConvertExpression$ (ex As String, lineNumber As Integer)
js = js + " || "
ElseIf uword = "MOD" Then
js = js + " % "
ElseIf uword = "XOR" Then
js = js + " ^ "
ElseIf uword = "=" Then
js = js + " == "
ElseIf uword = "<>" Then
@ -1797,12 +1954,12 @@ Sub ConvertMethods ()
Dim v As Integer
ReDim As String parts(0)
v = Split(args(a), ":", parts())
methodDec = methodDec + parts(1) + "/*" + parts(2) + "*/"
methodDec = methodDec + RemoveSuffix(parts(1)) + "/*" + parts(2) + "*/"
If a < c Then methodDec = methodDec + ","
' add the parameter to the local variables
Dim bvar As Variable
bvar.name = parts(1)
bvar.name = RemoveSuffix(parts(1))
bvar.type = parts(2)
bvar.typeId = FindTypeId(bvar.type)
If parts(3) = "true" Then
@ -2554,6 +2711,19 @@ Sub AddQBMethod (mtype As String, mname As String, sync As Integer)
AddMethod m, "QB.", sync
End Sub
Sub AddNativeMethod (mtype As String, mname As String, jsname As String, sync As Integer)
Dim m As Method
m.type = mtype
m.name = mname
m.uname = UCase$(m.name)
m.jsname = jsname
m.sync = sync
Dim mcount: mcount = UBound(methods) + 1
ReDim _Preserve As Method methods(mcount)
methods(mcount) = m
End Sub
Sub AddLine (lineIndex As Integer, fline As String)
__AddLine lineIndex, fline
End Sub
@ -3335,6 +3505,8 @@ Sub InitQBMethods
AddQBMethod "SUB", "RmDir", False
AddQBMethod "FUNCTION", "Rnd", False
AddQBMethod "SUB", "Screen", False
AddQBMethod "FUNCTION", "Seek", False
AddQBMethod "SUB", "Seek", False
AddQBMethod "FUNCTION", "Sgn", False
AddQBMethod "FUNCTION", "Sin", False
AddQBMethod "SUB", "Sleep", True
@ -3351,11 +3523,15 @@ Sub InitQBMethods
AddQBMethod "FUNCTION", "Val", False
AddQBMethod "FUNCTION", "Varptr", False
AddQBMethod "SUB", "Window", False
AddQBMethod "SUB", "Write", True
' QBJS-only language features
' --------------------------------------------------------------------------------
AddQBMethod "SUB", "IncludeJS", True
AddNativeMethod "FUNCTION", "JSON.Parse", "JSON.parse", False
AddNativeMethod "FUNCTION", "JSON.Stringify", "JSON.stringify", False
' Undocumented at present
AddSystemType "FETCHRESPONSE", "ok:INTEGER,status:INTEGER,statusText:STRING,text:STRING"
AddQBMethod "FUNCTION", "Fetch", True

29
vfs.js
View file

@ -8,6 +8,10 @@ let VFS = function() {
return _root;
};
this.reset = function() {
_root = { toString: function() { return "/"; }};
}
this.fullPath = function(node) {
if (node == _root) { return "/" };
@ -98,20 +102,27 @@ let VFS = function() {
return str;
};
this.readText = function(file) {
let offset = 0;
let view = new Uint8Array(file.data);
let c = null;
let str = "";
while (offset < file.data.byteLength) {
c = String.fromCharCode(view[offset]);
str += c
offset++;
}
return str;
};
this.writeData = function(file, data, offset) {
if (offset == undefined) { offset = 0; }
//else { offset--; }
/*if (file.data.byteLength == 0) {
file.data = data;
return;
}*/
let start = file.data.slice(0, offset);
let end = file.data.slice(offset + data.byteLength, file.data.byteLength);
file.data = start;
//alert("sb: " + start.byteLength + " o: " + offset);
if (start.byteLength < offset) {
//alert(offset - start.byteLength);
file.data = appendBuffer(file.data, new ArrayBuffer(offset - start.byteLength));
}
file.data = appendBuffer(file.data, data);
@ -147,13 +158,15 @@ let VFS = function() {
else {
node = parent[parts[i]];
parent = node;
if (node == undefined) {
return null;
}
}
}
return node;
};
this.getDataURL = async function(file) {
//return "data:image/jpeg," + base64ArrayBuffer(file.data);
let blob = new Blob([file.data]);
let dataUrl = await new Promise(r => {let a=new FileReader(); a.onload=r; a.readAsDataURL(blob)}).then(e => e.target.result);
return dataUrl;