8bitworkshop/gen/basic-O4Z2JMQ2.js

38 lines
27 KiB
JavaScript

import{b as v}from"./chunk-3XE5YOCV.js";import{a as d,t as S}from"./chunk-JNII2TLU.js";import"./chunk-UC2UKQOH.js";import"./chunk-B2GOFULO.js";import"./chunk-IJD2K6VH.js";import"./chunk-ULPRULB6.js";import{B as c,J as b,T as g,U as f,a as p}from"./chunk-RXF2JDJ3.js";import"./chunk-WAARL7ET.js";function O(o){return o.value!=null}function E(o){return o.name!=null}function N(o){return o.op!=null&&o.left!=null&&o.right!=null}function I(o){return o.op!=null&&o.expr!=null}var y=class{randomize(){this.seed(Math.random()*2147483647,Math.random()*2147483647,Math.random()*2147483647,Math.random()*2147483647)}constructor(){(()=>{var r,e,i,n;this.seed=function(s,a,u,h){r=s,e=a,i=u,n=h},this.seedfloat=function(s){this.seed(s,s*4294,s*429496,s*4294967296),this.next(),this.next(),this.next()},this.next=function(){r>>>=0,e>>>=0,i>>>=0,n>>>=0;var s=r+e|0;return r=e^e>>>9,e=i+(i<<3)|0,i=i<<21|i>>>11,n=n+1|0,s=s+n|0,i=i+s|0,(s>>>0)/4294967296}})(),this.seedfloat(-1)}},L=1024*1024,l=class{constructor(){this.margin=80;this.running=!1;this.exited=!0;this.trace=!1}load(t){let r=null,e=0;if(this.pc2label!=null){let s=this.curpc;for(;s>0&&(r=this.pc2label.get(s))==null;)s--;e=this.curpc-s,console.log("oldpc=",this.curpc,"restart @ label",r,"+",e)}this.program=t,this.opts=t.opts,this.opts.maxArrayElements||(this.opts.maxArrayElements=L),this.allstmts=t.stmts,this.label2pc=t.labels,this.label2dataptr={},this.pc2label=new Map,this.datums=[],this.subroutines={},this.builtins=this.getBuiltinFunctions();for(var i in t.labels){var n=t.labels[i];this.pc2label.set(n,i)}return this.allstmts.forEach((s,a)=>{this.curpc=a+1,this.compileStatement(s),s.command=="DATA"&&(this.label2dataptr[s.$loc.label]=this.datums.length,s.datums.forEach(u=>{this.curpc=s.$loc.offset,this.datums.push(u)}))}),this.label2pc[r]!=null?(this.curpc=this.label2pc[r]+e,!0):(this.curpc=0,!1)}reset(){this.curpc=0,this.dataptr=0,this.clearVars(),this.returnStack=[],this.column=0,this.running=!0,this.exited=!1}clearVars(){this.globals=this.vars={},this.arrays={},this.defs={},this.forLoops={},this.forLoopStack=[],this.whileLoops=[],this.rng=new y,this.opts&&this.opts.staticArrays&&this.allstmts.filter(t=>t.command=="DIM").forEach(t=>{t.args.forEach(r=>this.compileJS(this._DIM(r))())})}saveState(){return $.extend(!0,{},this)}loadState(t){$.extend(!0,this,t)}getBuiltinFunctions(){var t=this.program&&this.opts.validFunctions;t||(t=Object.getOwnPropertyNames(l.prototype).filter(i=>/^[A-Z]{3,}[$]?$/.test(i)));var r={};for(var e of t)this.supportsFunction(e)&&(r[e]=this[e].bind(this));return r}supportsFunction(t){return typeof this[t]=="function"}runtimeError(t){throw this.curpc--,new g(t,this.getCurrentSourceLocation())}dialectError(t){this.runtimeError(`I can't ${t} in this dialect of BASIC.`)}getLineForPC(t){var r=this.allstmts[t];return r&&r.$loc&&r.$loc.line}getLabelForPC(t){var r=this.allstmts[t];return r&&r.$loc&&r.$loc.label}getCurrentSourceLocation(){var t=this.getStatement();return t&&t.$loc}getCurrentLabel(){var t=this.getCurrentSourceLocation();return t&&t.label}getStatement(){return this.allstmts[this.curpc]}step(){if(!this.running)return!1;var t=this.getStatement();return t?(this.trace&&console.log(this.curpc,t,this.vars,Object.keys(this.arrays)),this.curpc++,this.executeStatement(t),this.running):(this.running=!1,this.exited=!0,!1)}compileStatement(t){if(t.$run==null)try{var r=this["do__"+t.command];r==null&&this.runtimeError(`I don't know how to "${t.command}".`);var e=r.bind(this)(t);this.trace&&console.log(e),t.$run=this.compileJS(e)}catch(i){throw e&&console.log(e),i}}compileJS(t){return new Function(t).bind(this)}executeStatement(t){this.compileStatement(t),t.$run()}skipToEOL(){do this.curpc++;while(this.curpc<this.allstmts.length&&!this.pc2label.get(this.curpc))}skipToElse(){for(;this.curpc<this.allstmts.length;){var t=this.allstmts[this.curpc].command;if(t=="ELSE"){this.curpc++;break}else if(t=="IF")return this.skipToEOL();if(this.curpc++,this.pc2label.get(this.curpc))break}}skipToEOF(){this.curpc=this.allstmts.length}skipToAfterNext(t){for(var r=this.curpc;r<this.allstmts.length;){var e=this.allstmts[r];if(e.command=="NEXT"){var i=e.lexpr;if(i&&i.name==t){this.curpc=r+1;return}}r++}this.runtimeError(`I couldn't find a matching NEXT ${t} to skip this for loop.`)}skipToAfterWend(){for(var t=this.curpc-1,r=0;t<this.allstmts.length;){var e=this.allstmts[t];if(e.command=="WHILE")r++;else if(e.command=="WEND"&&(r--,r==0)){this.curpc=t+1;return}t++}this.runtimeError("I couldn't find a matching WEND for this WHILE.")}gotoLabel(t){var r=this.label2pc[t];r>=0?this.curpc=r:this.runtimeError(`I tried to go to the label "${t}" but couldn't find it.`)}newLocalScope(){this.vars=Object.create(this.vars)}popLocalScope(){this.vars!==this.globals&&(this.vars=Object.getPrototypeOf(this.vars))}gosubLabel(t){this.returnStack.length>32767&&this.runtimeError("I did too many GOSUBs without a RETURN."),this.returnStack.push(this.curpc),this.gotoLabel(t)}returnFromGosub(){this.returnStack.length==0&&this.runtimeError("I tried to RETURN, but there wasn't a corresponding GOSUB.");var t=this.returnStack.pop();this.curpc=t,this.popLocalScope()}popReturnStack(){this.returnStack.length==0&&this.runtimeError("I tried to POP, but there wasn't a corresponding GOSUB."),this.returnStack.pop()}valueToString(t,r){var e;if(typeof t=="number"){var i=this.float2str(t,this.opts.printZoneLength-4);return r?i.startsWith("-")?`${i} `:` ${i} `:i}else if(t==`
`)this.column=0,e=t;else if(t==" "){var n=this.opts.printZoneLength,s=Math.floor(this.column/n),a=(s+1)*this.opts.printZoneLength;a+n>this.margin?(this.column=0,e=`
`):e=this.TAB(a)}else e=`${t}`;return e}float2str(t,r){var e=t.toString().toUpperCase();if(r>0){for(var i=r;e.length>r;)e=t.toPrecision(i--);e.startsWith("0.")?e=e.substr(1):e.startsWith("-0.")&&(e="-"+e.substr(2))}return e}printExpr(t){var r=this.valueToString(t,this.opts.numericPadding);this.column+=r.length,this.print(r)}print(t){console.log(t)}async input(t,r){return{line:"",vals:[]}}resume(){}expr2js(t,r){if(r||(r={}),O(t))return JSON.stringify(t.value);if(E(t)){if(!t.args&&r.locals&&r.locals.indexOf(t.name)>=0)return t.name;{r.isconst&&this.runtimeError("I expected a constant value here.");var e="",i=JSON.stringify(t.name);let u=t.args?t.args.map(h=>this.expr2js(h,r)).join(", "):[];return t.name.startsWith("FN")?e+=`this.getDef(${i})(${u})`:this.builtins[t.name]?(this.checkFuncArgs(t,this.builtins[t.name]),e+=`this.builtins.${t.name}(${u})`):t.args?this.opts.arraysContainChars&&t.name.endsWith("$")?e+=`this.getStringSlice(this.vars.${t.name}, ${u})`:e+=`this.arrayGet(${i}, ${u})`:e+=`this.vars.${t.name}`,r.novalid?e:`this.checkValue(${e}, ${i})`}}else if(N(t)){var n=this.expr2js(t.left,r),s=this.expr2js(t.right,r);return`this.${t.op}(${n}, ${s})`}else if(I(t)){var a=this.expr2js(t.expr,r);return`this.${t.op}(${a})`}}assign2js(t,r){r||(r={});var e="";return(t.name.startsWith("FN")||this.builtins[t.name])&&this.runtimeError("I can't call a function here."),t.args?this.opts.arraysContainChars&&t.name.endsWith("$")?this.runtimeError("I can't set array slices via this command yet."):e+=this.array2js(t,r):e=`this.globals.${t.name}`,e}array2js(t,r){var e=JSON.stringify(t.name),i=t.args||[];return this.expr2js(t,{novalid:!0})+`;this.getArray(${e}, ${i.length})`+i.map(n=>"[this.ROUND("+this.expr2js(n,r)+")]").join("")}checkFuncArgs(t,r){var e=t.args?t.args.length:0;t.name=="RND"&&e==0||t.name=="MID$"&&e==2||t.name=="INSTR"&&e==2||r.length!=e&&this.runtimeError(`I expected ${r.length} arguments for the ${t.name} function, but I got ${e}.`)}startForLoop(t,r,e,i,n){var s=this.curpc-1,a=this.pc2label.get(s);i||(i=1),this.vars[t]=r,this.trace&&console.log(`FOR ${t} = ${r} TO ${e} STEP ${i}`);var u=()=>i>=0?this.vars[t]>e:this.vars[t]<e;this.opts.testInitialFor&&u()&&(n!=null?this.curpc=n+1:this.skipToAfterNext(t)),this.forLoopStack[t]!=null&&(this.forLoopStack=this.forLoopStack.filter(h=>h==t)),this.forLoopStack.push(t),this.forLoops[t]={$next:h=>{h&&t!=h&&this.runtimeError(`I executed NEXT "${h}", but the last FOR was for "${t}".`),this.vars[t]+=i;var m=u();m?(this.forLoopStack.pop(),delete this.forLoops[t]):this.curpc=(a!=null&&this.label2pc[a]||s)+1,this.trace&&console.log(`NEXT ${t}: ${this.vars[t]} TO ${e} STEP ${i} DONE=${m}`)}}}nextForLoop(t){var r=this.forLoops[t||this.opts.optionalNextVar&&this.forLoopStack[this.forLoopStack.length-1]];r||this.runtimeError("I couldn't find a matching FOR for this NEXT."),r.$next(t)}whileLoop(t){t?this.whileLoops.push(this.curpc-1):this.skipToAfterWend()}nextWhileLoop(){var t=this.whileLoops.pop();t==null?this.runtimeError("I couldn't find a matching WHILE for this WEND."):this.curpc=t}assign(t,r,e){return e&&t.endsWith("$")?this.checkValue(this.convert(t,r),t):t.endsWith("$")?this.convertToString(r,t):this.convertToNumber(r,t)}convert(t,r){return t.endsWith("$")?r==null?"":r.toString():typeof r=="number"?r:parseFloat(r+"")}convertToString(t,r){if(typeof t!="string")this.runtimeError(`I can't convert ${t} to a string.`);else return t}convertToNumber(t,r){if(typeof t!="number")this.runtimeError(`I can't convert ${t} to a number.`);else return this.checkNum(t)}dimArray(t,...r){if(r=r.map(Math.round),this.arrays[t]!=null){if(this.opts.staticArrays)return;this.runtimeError(`I already dimensioned this array (${t}) earlier.`)}var e=this.getTotalArrayLength(r);e>this.opts.maxArrayElements&&this.runtimeError("I can't create an array with this many elements.");var i=t.endsWith("$"),n=i?Array:Float64Array;if(r.length==1)this.arrays[t]=new n(r[0]+1);else if(r.length==2){this.arrays[t]=new Array(r[0]+1);for(var s=0;s<r[0]+1;s++)this.arrays[t][s]=new n(r[1]+1)}else this.runtimeError("I only support arrays of one or two dimensions.")}getTotalArrayLength(t){for(var r=1,e=0;e<t.length;e++)t[e]<this.opts.defaultArrayBase&&this.runtimeError(`I can't create an array with a dimension less than ${this.opts.defaultArrayBase}.`),r*=t[e];return r}getArray(t,r){return this.arrays[t]||(this.opts.defaultArraySize==0&&this.dialectError("automatically declare arrays without a DIM statement (or did you mean to call a function?)"),r==1?this.dimArray(t,this.opts.defaultArraySize-1):r==2?this.dimArray(t,this.opts.defaultArraySize-1,this.opts.defaultArraySize-1):this.runtimeError("I only support arrays of one or two dimensions.")),this.arrays[t]}arrayGet(t,...r){var e=this.getArray(t,r.length);r=r.map(this.ROUND.bind(this));for(var i=e,n=0;n<r.length;n++){var s=r[n];c(i)||this.runtimeError(`I tried to lookup ${t}(${r}) but used too many dimensions.`),s<this.opts.defaultArrayBase&&this.runtimeError(`I tried to lookup ${t}(${r}) but an index was less than ${this.opts.defaultArrayBase}.`),s>=i.length&&this.runtimeError(`I tried to lookup ${t}(${r}) but it exceeded the dimensions of the array.`),i=i[r[n]]}return c(i)&&this.runtimeError(`I tried to lookup ${t}(${r}) but used too few dimensions.`),i}modifyStringSlice(t,r,e,i){return t=t||"",this.checkString(t),this.checkString(r),i||(i=e),e=this.ROUND(e),i=this.ROUND(i),e<1&&this.dialectError("accept a string slice index less than 1"),i<e&&this.dialectError("accept a string slice index less than the starting index"),(t+" ".repeat(e)).substr(0,e-1)+r.substr(0,i+1-e)+t.substr(i)}getStringSlice(t,r,e){return t=this.checkString(t),r=this.ROUND(r),r<1&&this.dialectError("accept a string slice index less than 1"),e!=null?(e=this.ROUND(e),e<r&&this.dialectError("accept a string slice index less than the starting index"),t.substr(r-1,e+1-r)):t.substr(r-1)}checkOnGoto(t,r){return t=this.ROUND(t),t<0&&this.runtimeError(`I needed a number between 1 and ${r.length}, but I got ${t}.`),this.opts.checkOnGotoIndex&&(t<1||t>r.length)&&this.runtimeError(`I needed a number between 1 and ${r.length}, but I got ${t}.`),t<1||t>r.length?0:t}onGotoLabel(t,...r){t=this.checkOnGoto(t,r),t&&this.gotoLabel(r[t-1])}onGosubLabel(t,...r){t=this.checkOnGoto(t,r),t&&this.gosubLabel(r[t-1])}nextDatum(){return this.dataptr>=this.datums.length&&this.runtimeError("I tried to READ, but ran out of data."),this.datums[this.dataptr++].value}do__PRINT(t){var r="";for(var e of t.args){var i=this.expr2js(e),n=i.name;r+=`this.printExpr(this.checkValue(${i}, ${JSON.stringify(n)}));`}return r}preInput(){this.running=!1,this.curpc--}postInput(t){t&&this.curpc++,this.running=!0,this.resume()}do__INPUT(t){var r=t.prompt!=null?this.expr2js(t.prompt):'""',e=t.elapsed!=null?this.assign2js(t.elapsed):"let ___",i="";return t.args.forEach((n,s)=>{var a=this.assign2js(n);i+=`
var value = this.convert(${JSON.stringify(n.name)}, response.vals[${s}]);
valid &= this.isValid(value);
${a} = value;
`}),`this.preInput();
this.input(${r}, ${t.args.length}).then((response) => {
let valid = 1;
${i}
this.postInput(valid);
this.column = 0; // assume linefeed
${e} = response.elapsed;
})`}do__LET(t){var r=this.expr2js(t.right),e=`let _right = ${r};`;for(var i of t.lexprs)if(this.opts.arraysContainChars&&i.args&&i.name.endsWith("$"))e+=`this.globals.${i.name} = this.modifyStringSlice(this.vars.${i.name}, _right, `,e+=i.args.map(s=>this.expr2js(s)).join(", "),e+=");";else{var n=this.assign2js(i);e+=`${n} = this.assign(${JSON.stringify(i.name)}, _right);`}return e}do__FOR(t){var r=JSON.stringify(t.lexpr.name),e=this.expr2js(t.initial),i=this.expr2js(t.target),n=t.step?this.expr2js(t.step):"null";return`this.startForLoop(${r}, ${e}, ${i}, ${n}, ${t.endpc})`}do__NEXT(t){var r=t.lexpr&&JSON.stringify(t.lexpr.name);return`this.nextForLoop(${r})`}do__IF(t){var r=this.expr2js(t.cond);return t.endpc!=null?`if (!(${r})) { this.curpc = ${t.endpc}; }`:`if (!(${r})) { this.skipToElse(); }`}do__ELSE(t){return t.endpc!=null?`this.curpc = ${t.endpc}`:"this.skipToEOL()"}do__WHILE(t){var r=this.expr2js(t.cond);return t.endpc!=null?`if (!(${r})) { this.curpc = ${t.endpc+1}; }`:`this.whileLoop(${r})`}do__WEND(t){return t.startpc!=null?`this.curpc = ${t.startpc}`:"this.nextWhileLoop()"}do__DEF(t){var r=[];for(var e of t.lexpr.args||[])E(e)?r.push(e.name):this.runtimeError("I found a DEF statement with arguments other than variable names.");var i=this.expr2js(t.def,{locals:r});return`this.defs.${t.lexpr.name} = function(${r.join(",")}) { return ${i}; }.bind(this)`}_DIM(t){if(this.opts.arraysContainChars&&t.name.endsWith("$"))return"";var r="";for(var e of t.args)r+=", "+this.expr2js(e,{isconst:this.opts.staticArrays});return`this.dimArray(${JSON.stringify(t.name)}${r});`}do__DIM(t){if(!this.opts.staticArrays){var r="";return t.args.forEach(e=>r+=this._DIM(e)),r}}do__GOTO(t){var r=this.expr2js(t.label);return`this.gotoLabel(${r})`}do__GOSUB(t){var r=this.expr2js(t.label);return`this.gosubLabel(${r})`}do__RETURN(t){return"this.returnFromGosub()"}do__ONGOTO(t){var r=this.expr2js(t.expr),e=t.labels.map(i=>this.expr2js(i,{isconst:!0})).join(", ");return t.command=="ONGOTO"?`this.onGotoLabel(${r}, ${e})`:`this.onGosubLabel(${r}, ${e})`}do__ONGOSUB(t){return this.do__ONGOTO(t)}do__DATA(){}do__READ(t){var r="";return t.args.forEach(e=>{r+=`${this.assign2js(e)} = this.assign(${JSON.stringify(e.name)}, this.nextDatum(), true);`}),r}do__RESTORE(t){return t.label!=null?`this.dataptr = this.label2dataptr[${this.expr2js(t.label,{isconst:!0})}] || 0`:"this.dataptr = 0"}do__END(){return"this.skipToEOF()"}do__STOP(){return"this.skipToEOF()"}do__OPTION(t){}do__POP(){return"this.popReturnStack()"}do__GET(t){var r=this.assign2js(t.lexpr);return`this.preInput();
this.input().then((vals) => {
${r} = this.convert(${JSON.stringify(t.lexpr.name)}, vals[0]);
this.postInput(true);
})`}do__CLEAR(){return"this.clearVars()"}do__RANDOMIZE(){return"this.rng.randomize()"}do__CHANGE(t){var r=t.dest.name.endsWith("$");if(r){let e=t.src.name||this.runtimeError("I can only change to a string from an array."),i=this.assign2js(t.dest);return`
let arrname = ${JSON.stringify(e)};
let len = this.arrayGet(arrname, 0);
let s = '';
for (let i=0; i<len; i++) {
s += String.fromCharCode(this.arrayGet(arrname, i+1));
}
${i} = s;
`}else{let e=this.expr2js(t.src),i=this.array2js(t.dest);return`
let src = ${e}+"";
${i}[0] = src.length;
for (let i=0; i<src.length; i++) {
${i}[i+1] = src.charCodeAt(i);
}
`}}do__CONVERT(t){var r=t.dest.name.endsWith("$");let e=this.expr2js(t.src),i=this.assign2js(t.dest);return r?`${i} = this.valueToString(${e}, false)`:`${i} = this.VAL(${e})`}do__SUB(t){return this.subroutines[t.lexpr.name]=t,`this.curpc = ${t.endpc}`}do__CALL(t){var r=this.subroutines[t.call.name];r==null&&this.runtimeError(`I can't find a subroutine named "${t.call.name}".`);var e=r.lexpr.args||[],i=t.call.args||[];e.length!=i.length&&this.runtimeError(`I tried to call ${t.call.name} with the wrong number of parameters.`);var n="";n+=`this.gosubLabel(${JSON.stringify(t.call.name)});`,n+="this.newLocalScope();";for(var s=0;s<e.length;s++){var a=e[s];n+=`this.vars.${a.name} = ${this.expr2js(i[s])};`}return n}isValid(t){return typeof t=="number"&&!isNaN(t)&&(!this.opts.checkOverflow||isFinite(t))?!0:typeof t=="string"}checkValue(t,r){if(typeof t!="number"&&typeof t!="string"){if(t==null&&this.opts.defaultValues)return r.endsWith("$")?"":0;r!=null&&t==null?this.runtimeError(`I haven't assigned a value to ${r}.`):r!=null?this.runtimeError(`I got an invalid value for ${r}: ${t}`):this.runtimeError(`I got an invalid value: ${t}`)}return t}getDef(t){var r=this.defs[t];return r||this.runtimeError(`I haven't run a DEF statement for ${t}.`),r}checkNum(t){return this.checkValue(t,"this"),t===1/0&&this.runtimeError("I computed a number too big to store."),isNaN(t)&&this.runtimeError("I computed an invalid number."),t}checkString(t){return this.checkValue(t,"this"),typeof t!="string"?this.runtimeError("I expected a string here."):t.length>this.opts.maxStringLength&&this.dialectError(`create strings longer than ${this.opts.maxStringLength} characters`),t}add(t,r){if(typeof t=="number"&&typeof r=="number")return this.checkNum(t+r);if(this.opts.stringConcat)return this.checkString(t+r);this.dialectError('use the "+" operator to concatenate strings')}sub(t,r){return this.checkNum(t-r)}mul(t,r){return this.checkNum(t*r)}div(t,r){return r==0&&this.runtimeError("I can't divide by zero."),this.checkNum(t/r)}idiv(t,r){return this.FIX(this.INT(t)/this.INT(r))}mod(t,r){return this.checkNum(t%r)}pow(t,r){return t==0&&r<0&&this.runtimeError("I can't raise zero to a negative power."),this.checkNum(Math.pow(t,r))}band(t,r){return t&r}bor(t,r){return t|r}bnot(t){return~t}bxor(t,r){return t^r}bimp(t,r){return this.bor(this.bnot(t),r)}beqv(t,r){return this.bnot(this.bxor(t,r))}land(t,r){return t&&r?this.opts.bitwiseLogic?-1:1:0}lor(t,r){return t||r?this.opts.bitwiseLogic?-1:1:0}lnot(t){return t?0:this.opts.bitwiseLogic?-1:1}neg(t){return-t}eq(t,r){return t==r?this.opts.bitwiseLogic?-1:1:0}ne(t,r){return t!=r?this.opts.bitwiseLogic?-1:1:0}lt(t,r){return t<r?this.opts.bitwiseLogic?-1:1:0}gt(t,r){return t>r?this.opts.bitwiseLogic?-1:1:0}le(t,r){return t<=r?this.opts.bitwiseLogic?-1:1:0}ge(t,r){return t>=r?this.opts.bitwiseLogic?-1:1:0}min(t,r){return t<r?t:r}max(t,r){return t>r?t:r}ABS(t){return this.checkNum(Math.abs(t))}ASC(t){return t=this.checkString(t),t==""&&this.runtimeError("I tried to call ASC() on an empty string."),t.charCodeAt(0)}ATN(t){return this.checkNum(Math.atan(t))}CHR$(t){return String.fromCharCode(this.checkNum(t))}CINT(t){return this.ROUND(t)}COS(t){return this.checkNum(Math.cos(t))}COT(t){return this.checkNum(1/Math.tan(t))}CTL(t){return this.CHR$(t)}EXP(t){return this.checkNum(Math.exp(t))}FIX(t){return this.checkNum(t<0?Math.ceil(t):Math.floor(t))}HEX$(t){return this.ROUND(t).toString(16)}INSTR(t,r,e){return e!=null?this.checkString(r).indexOf(this.checkString(e),this.checkNum(t)-1)+1:this.checkString(t).indexOf(this.checkString(r))+1}INT(t){return this.checkNum(Math.floor(t))}LEFT$(t,r){return t=this.checkString(t),r=this.ROUND(r),t.substr(0,r)}LEN(t){return this.checkString(t).length}LIN(t){return this.STRING$(t,`
`)}LOG(t){return t==0&&this.runtimeError(`I can't take the logarithm of zero (${t}).`),t<0&&this.runtimeError(`I can't take the logarithm of a negative number (${t}).`),this.checkNum(Math.log(t))}LOG10(t){return t==0&&this.runtimeError(`I can't take the logarithm of zero (${t}).`),t<0&&this.runtimeError(`I can't take the logarithm of a negative number (${t}).`),this.checkNum(Math.log10(t))}MID$(t,r,e){return t=this.checkString(t),e||(e=t.length),r=this.ROUND(r),e=this.ROUND(e),r<1&&this.runtimeError("I can't compute MID$ if the starting index is less than 1."),t.substr(r-1,e)}OCT$(t){return this.ROUND(t).toString(8)}PI(){return Math.PI}POS(t,r){return typeof t=="string"&&typeof r=="string"?t.indexOf(r)>=0+1:this.column+1}RIGHT$(t,r){return t=this.checkString(t),r=this.ROUND(r),t.substr(t.length-r,r)}RND(t){return t<0&&this.rng.seedfloat(t),this.rng.next()}ROUND(t){return this.checkNum(Math.round(t))}SGN(t){return this.checkNum(t),t<0?-1:t>0?1:0}SIN(t){return this.checkNum(Math.sin(t))}SPACE$(t){return this.STRING$(t," ")}SPC(t){return this.SPACE$(t)}SQR(t){return t<0&&this.runtimeError(`I can't take the square root of a negative number (${t}).`),this.checkNum(Math.sqrt(t))}STR$(t){return this.valueToString(this.checkNum(t),!1)}STRING$(t,r){return t=this.ROUND(t),t<=0?"":(t>this.opts.maxStringLength&&this.dialectError(`create a string longer than ${this.opts.maxStringLength} characters`),typeof r=="string"?r.substr(0,1).repeat(t):String.fromCharCode(r).repeat(t))}TAB(t){t<1&&(t=1);var r=this.ROUND(t)-1-this.column;return this.SPACE$(r)}TAN(t){return this.checkNum(Math.tan(t))}TIM(t){var r=new Date;switch(this.ROUND(t)){case 0:return r.getMinutes();case 1:return r.getHours();case 2:var e=[0,31,59,90,120,151,181,212,243,273,304,334],i=r.getMonth(),n=r.getDate(),s=e[i]+n,a=(r.getFullYear()&3)==0;return i>1&&a&&s++,s;case 3:return r.getFullYear()%100;case 4:return r.getSeconds();default:return 0}}TIMER(){return Date.now()/1e3}UPS$(t){return this.checkString(t).toUpperCase()}VAL(t){var r=parseFloat(this.checkString(t));return isNaN(r)?0:r}LPAD$(t,r){for(t=this.checkString(t);t.length<r;)t=" "+t;return t}RPAD$(t,r){for(t=this.checkString(t);t.length<r;)t=t+" ";return t}NFORMAT$(t,r){var e=this.float2str(t,r);return r>0?this.LPAD$(e,r):this.RPAD$(e,-r)}};var T=[{id:"hello.bas",name:"Hello"},{id:"tutorial.bas",name:"Tutorial"},{id:"sieve.bas",name:"Sieve Benchmark"},{id:"mortgage.bas",name:"Interest Calculator"},{id:"23match.bas",name:"23 Matches"},{id:"craps.bas",name:"Craps"},{id:"lander.bas",name:"Lander"},{id:"hamurabi.bas",name:"Hammurabi"},{id:"wumpus.bas",name:"Hunt The Wumpus"},{id:"startrader.bas",name:"Star Trader"},{id:"haunted.bas",name:"Haunted House"}],k=class{constructor(t){this.clock=0;this.hotReload=!0;this.animcount=0;this.internalFiles={};this.mainElement=t,t.style.overflowY="auto"}async start(){this.runtime=new l,this.runtime.reset();var t=this.mainElement,r=$('<div id="gameport" style="margin-top:calc(100vh - 8em)"/>').appendTo(t),e=$('<div id="windowport" class="transcript transcript-style-2"/>').appendTo(r),i=$('<div id="inputport" class="transcript-bottom"/>').appendTo(r),n=$('<input class="transcript-input transcript-style-2" type="text" style="max-width:95%"/>').appendTo(i);this.tty=new v(e[0],!0,n[0]),this.tty.keepinput=!0,this.tty.splitInput=!0,this.tty.keephandler=!1,this.tty.hideinput(),this.tty.scrolldiv=t,this.tty.bell=new Audio("res/ttybell.mp3"),this.runtime.input=async(s,a)=>new Promise((u,h)=>{s!=null?(this.tty.addtext(s,0),this.tty.addtext("? ",0),this.tty.waitingfor="line"):this.tty.waitingfor="char",this.tty.focusinput(),this.tty.resolveInput=u}),this.timer=new f(60,this.animate.bind(this)),this.resize=()=>{this.tty.resize(80)},this.resize(),this.runtime.print=s=>{this.animcount=0,this.tty.print(s),this.transcript.push(s)},this.runtime.resume=this.resume.bind(this)}animate(){if(!this.tty.isBusy()){var t=this.program.opts.commandsPerSec||1e3;for(this.animcount+=t/60;this.runtime.running&&this.animcount-- >0&&this.advance(););}}advance(t){if(this.runtime.running){if(this.checkDebugTrap())return 0;var r=this.runtime.step();return r||(this.pause(),this.runtime.exited&&(this.exitmsg(),this.didExit())),this.clock++,1}else return 0}exitmsg(){this.tty.print(`
`),this.tty.addtext("*** END OF PROGRAM ***",1),this.tty.showPrintHead(!1)}loadROM(t,r){var e=this.runtime.exited;this.program=r;var i=this.runtime.load(r);this.tty.uppercaseOnly=!0,d.input=this.program.opts.uppercaseOnly?n=>n.toUpperCase():null,(!this.hotReload||e||!i)&&this.reset()}getROMExtension(){return".json"}reset(){this.tty.clear(),this.runtime.reset(),this.clock=0,this.transcript=[]}pause(){this.timer.stop()}resume(){this.isBlocked()||(this.animcount=0,this.timer.start())}isBlocked(){return this.tty.waitingfor!=null||this.runtime.exited}isRunning(){return this.timer.isRunning()}getDefaultExtension(){return".bas"}getToolForFilename(){return"basic"}getPresets(){return T}getPC(){return this.runtime.curpc}getSP(){return 4096-this.runtime.returnStack.length}isStable(){return!0}getCPUState(){return{PC:this.getPC(),SP:this.getSP()}}saveState(){return{c:this.getCPUState(),rt:this.runtime.saveState()}}loadState(t){this.runtime.loadState(t)}getDebugTree(){return{CurrentLine:this.runtime.getCurrentLabel(),Variables:this.runtime.vars,Arrays:this.runtime.arrays,Functions:this.runtime.defs,ForLoops:this.runtime.forLoops,WhileLoops:this.runtime.whileLoops,ReturnStack:this.runtime.returnStack,NextDatum:this.runtime.datums[this.runtime.dataptr],Clock:this.clock,Options:this.runtime.opts,Internals:this.runtime}}inspect(t){let r=this.runtime.vars[t];if(r!=null)return`${t} = ${r}`}showHelp(){return"https://8bitworkshop.com/docs/platforms/basic/"}getDebugCategories(){return["Variables"]}getDebugInfo(t,r){switch(t){case"Variables":return this.varsToLongString()}}varsToLongString(){var t="",r=Object.keys(this.runtime.vars);r.sort();for(var e of r){var i=this.runtime.vars[e],n=JSON.stringify(i);n.length>24&&(n=`${n.substr(0,24)}...(${n.length})`),t+=p(e,3)+" = "+n+`
`}return t}setupDebug(t){this.onBreakpointHit=t}clearDebug(){this.onBreakpointHit=null,this.debugTrap=null}checkDebugTrap(){return this.debugTrap&&this.debugTrap()?(this.pause(),this.break(),!0):!1}break(){this.onBreakpointHit&&this.onBreakpointHit(this.saveState())}step(){var t=this.clock;this.debugTrap=()=>this.clock>t,this.resume()}stepOver(){var t=this.runtime.getStatement();if(t&&(t.command=="GOSUB"||t.command=="ONGOSUB")){var r=this.getPC()+1;this.runEval(()=>this.getPC()==r)}else this.step()}runUntilReturn(){var t=this.getSP();this.runEval(()=>this.getSP()>t)}runEval(t){this.debugTrap=()=>t(this.getCPUState()),this.resume()}restartAtPC(t){return t=Math.round(t),t>=0&&t<this.runtime.allstmts.length?(this.runtime.curpc=t,this.tty.cancelinput(),this.clock=0,!0):!1}readFile(t){return this.internalFiles[t]}writeFile(t,r){return this.internalFiles[t]=r,!0}didExit(){this.internalFiles["stdout.txt"]=this.transcript.join(""),S()}};b.basic=k;
//# sourceMappingURL=basic-O4Z2JMQ2.js.map