Changeset 2102119
- Timestamp:
- 06/07/2019 09:27:33 AM (7 years ago)
- Location:
- easycoder/trunk
- Files:
-
- 1 added
- 1 deleted
- 11 edited
-
easycoder-min.js (modified) (1 diff)
-
easycoder.js (modified) (39 diffs)
-
easycoder.php (modified) (2 diffs)
-
plugins-sample.js (modified) (1 diff)
-
plugins/aws.js (added)
-
plugins/browser.js (modified) (30 diffs)
-
plugins/codemirror.js (modified) (3 diffs)
-
plugins/json-rest.js (deleted)
-
plugins/json.js (modified) (5 diffs)
-
plugins/rest.js (modified) (2 diffs)
-
plugins/svg.js (modified) (1 diff)
-
readme.txt (modified) (1 diff)
-
rest.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
easycoder/trunk/easycoder-min.js
r2089142 r2102119 8 8 $jscomp.polyfill("String.prototype.endsWith",function(d){return d?d:function(d,g){var e=$jscomp.checkStringArgs(this,d,"endsWith");d+="";void 0===g&&(g=e.length);g=Math.max(0,Math.min(g|0,e.length));for(var b=d.length;0<b&&0<g;)if(e[--g]!=d[--b])return!1;return 0>=b}},"es6","es3");$jscomp.polyfill("Object.is",function(d){return d?d:function(d,g){return d===g?0!==d||1/d===1/g:d!==d&&g!==g}},"es6","es3"); 9 9 $jscomp.polyfill("Array.prototype.includes",function(d){return d?d:function(d,g){var e=this;e instanceof String&&(e=String(e));var b=e.length;g=g||0;for(0>g&&(g=Math.max(g+b,0));g<b;g++){var a=e[g];if(a===d||Object.is(a,d))return!0}return!1}},"es7","es3");$jscomp.polyfill("String.prototype.includes",function(d){return d?d:function(d,g){return-1!==$jscomp.checkStringArgs(this,d,"includes").indexOf(d,g||0)}},"es6","es3"); 10 $jscomp.polyfill("Math.trunc",function(d){return d?d:function(d){d=Number(d);if(isNaN(d)||Infinity===d||-Infinity===d||0===d)return d;var h=Math.floor(Math.abs(d));return 0>d?-h:h}},"es6","es3");$jscomp.polyfill(" Number.isFinite",function(d){return d?d:function(d){return"number"!==typeof d?!1:!isNaN(d)&&Infinity!==d&&-Infinity!==d}},"es6","es3");$jscomp.polyfill("Number.isInteger",function(d){return d?d:function(d){return Number.isFinite(d)?d===Math.floor(d):!1}},"es6","es3");11 $jscomp. polyfill("String.prototype.repeat",function(d){return d?d:function(d){var g=$jscomp.checkStringArgs(this,null,"repeat");if(0>d||1342177279<d)throw new RangeError("Invalid count value");d|=0;for(var e="";d;)if(d&1&&(e+=g),d>>>=1)g+=g;return e}},"es6","es3");$jscomp.stringPadding=function(d,h){d=void 0!==d?String(d):" ";return 0<h&&d?d.repeat(Math.ceil(h/d.length)).substring(0,h):""};12 $jscomp.polyfill(" String.prototype.padStart",function(d){return d?d:function(d,g){var e=$jscomp.checkStringArgs(this,null,"padStart");return $jscomp.stringPadding(g,d-e.length)+e}},"es8","es3");13 (function(){function d(h,g,e){function b(c,m){if(!g[c]){if(!h[c]){var f="function"==typeof require&&require;if(!m&&f)return f(c,!0);if(a)return a(c,!0);m=Error("Cannot find module '"+c+"'");throw m.code="MODULE_NOT_FOUND",m;}m=g[c]={exports:{}};h[c][0].call(m.exports,function(a){return b(h[c][1][a]||a)},m,m.exports,d,h,g,e)}return g[c].exports}for(var a="function"==typeof require&&require,c=0;c<e.length;c++)b(e[c]);return b}return d})()({1:[function(d,h,g){var e=d("./easycoder/Main");e.version="2.3. 0";10 $jscomp.polyfill("Math.trunc",function(d){return d?d:function(d){d=Number(d);if(isNaN(d)||Infinity===d||-Infinity===d||0===d)return d;var h=Math.floor(Math.abs(d));return 0>d?-h:h}},"es6","es3");$jscomp.polyfill("String.prototype.repeat",function(d){return d?d:function(d){var h=$jscomp.checkStringArgs(this,null,"repeat");if(0>d||1342177279<d)throw new RangeError("Invalid count value");d|=0;for(var e="";d;)if(d&1&&(e+=h),d>>>=1)h+=h;return e}},"es6","es3"); 11 $jscomp.stringPadding=function(d,h){d=void 0!==d?String(d):" ";return 0<h&&d?d.repeat(Math.ceil(h/d.length)).substring(0,h):""};$jscomp.polyfill("String.prototype.padStart",function(d){return d?d:function(d,g){var e=$jscomp.checkStringArgs(this,null,"padStart");return $jscomp.stringPadding(g,d-e.length)+e}},"es8","es3");$jscomp.polyfill("Number.isFinite",function(d){return d?d:function(d){return"number"!==typeof d?!1:!isNaN(d)&&Infinity!==d&&-Infinity!==d}},"es6","es3"); 12 $jscomp.polyfill("Number.isInteger",function(d){return d?d:function(d){return Number.isFinite(d)?d===Math.floor(d):!1}},"es6","es3"); 13 (function(){function d(h,g,e){function b(c,m){if(!g[c]){if(!h[c]){var f="function"==typeof require&&require;if(!m&&f)return f(c,!0);if(a)return a(c,!0);m=Error("Cannot find module '"+c+"'");throw m.code="MODULE_NOT_FOUND",m;}m=g[c]={exports:{}};h[c][0].call(m.exports,function(a){return b(h[c][1][a]||a)},m,m.exports,d,h,g,e)}return g[c].exports}for(var a="function"==typeof require&&require,c=0;c<e.length;c++)b(e[c]);return b}return d})()({1:[function(d,h,g){var e=d("./easycoder/Main");e.version="2.3.1"; 14 14 e.timestamp=Date.now();console.log("EasyCoder loaded; waiting for page");window.onload=function(){console.log(Date.now()-e.timestamp+" ms: Page loaded; reset timer & start EasyCoder");e.timestamp=Date.now();e.scripts={};window.EasyCoder=e;var b=document.getElementById("easycoder-script");if(b){b.style.display="none";try{e.start(b.innerText)}catch(a){e.reportError(a)}}}},{"./easycoder/Main":6}],2:[function(d,h,g){h.exports=function(d,b,a){b=d.value.evaluate(d,b);d=d.value.evaluate(d,a);a=b.content; 15 15 var c=d.content;b.numeric&&!d.numeric&&(a=a.toString());!b.numeric&&d.numeric&&(c=c.toString());b.numeric||"undefined"!==typeof a||(a="");d.numeric||"undefined"!==typeof c||(c="");return a>c?1:a<c?-1:0}},{}],3:[function(d,h,g){var e=Object.assign||function(a){for(var c=1;c<arguments.length;c++){var b=arguments[c],d;for(d in b)Object.prototype.hasOwnProperty.call(b,d)&&(a[d]=b[d])}return a},b=this,a={getTokens:function(){return b.tokens},addWarning:function(a){b.warnings.push(a)},warning:function(c){a.addWarning(c)}, 16 unrecognisedSymbol:function(c){a.addWarning("Unrecognised symbol '"+c+"'")},getWarnings:function(){return b.warnings},getIndex:function(){return b.index},next:function(a){b.index+=void 0===a?1:a},peek:function(){return b.tokens[b.index+1].token}, getToken:function(){return b.index>=b.tokens.length?null:b.tokens[b.index]?b.tokens[b.index].token:null},nextToken:function(){a.next();return a.getToken()},tokenIs:function(a){return b.index>=b.tokens.length?!1:a===b.tokens[b.index].token},nextTokenIs:function(c){a.next();17 return a.tokenIs(c)},skip:function(c){if(b.index>=b.tokens.length)return null;a.next();a.tokenIs(c)&&a.next()},prev:function(){b.index--},getLino:function(){return b.index>=b.tokens.length?0:b.tokens[b.index].lino},getTarget:function(a){a=void 0===a?b.index:a;return b.tokens[a].token},getTargetPc:function(c){c=void 0===c?b.index:c;return b.symbols[a.getTarget(c)].pc},getCommandAt:function(a){return b.program[a]},isSymbol:function(c){c=void 0===c?!1:c;if(a.getTarget()in b.symbols)return!0;if(c)throw Error("Unknown symbol: '"+ 18 a.getTarget()+"'");return!1},nextIsSymbol:function(c){c=void 0===c?!1:c;a.next();return a.isSymbol(c)},getSymbol:function(){return b.symbols[a.getToken()]},getSymbolPc:function(){return a.getSymbol().pc},getSymbolRecord:function(){var c=b.program[a.getSymbolPc()];c.used=!0;return c},getSymbols:function(){return b.symbols},getProgram:function(){return b.program},getPc:function(){return b.program.length},getValue:function(){return a.value.compile(a)},getNextValue:function(){a.next();return a.getValue()},19 get Condition:function(){return a.condition.compile(a)},constant:function(c,f){return a.value.constant(c,void 0===f?!1:f)},addCommand:function(a){b.program.push(e({pc:b.program.length},a))},addSymbol:function(a,f){b.symbols[a]={pc:f}},mark:function(){b.savedMark=b.index},rewind:function(){b.index=b.savedMark},rewindTo:function(a){b.index=a},completeHandler:function(){var c=a.getLino(),f=a.getPc();a.addCommand({domain:"core",keyword:"goto",lino:c,goto:0});a.compileOne();a.addCommand({domain:"core",20 keyword:"stop",lino:c,next:0});a.getCommandAt(f).goto=a.getPc();return!0},compileVariable:function(c,f,m,d){m=void 0===m?!1:m;d=void 0===d?null:d;a.next();var p=a.getLino(),l=a.getTokens()[a.getIndex()];if(b.symbols[l.token])throw Error("Duplicate variable name '"+l.token+"'");var n=a.getPc();a.next();a.addSymbol(l.token,n);c={domain:c,keyword:f,lino:p,isSymbol:!0,used:!1,isValueHolder:m,name:l.token,elements:1,index:0,value:[{}],element:[],extra:d};"dom"===d&&(c.element=[]);a.addCommand(c);return c}, 21 compileToken:function(){var c=a.getToken();if(c){a.mark();for(var f=$jscomp.makeIterator(Object.keys(a.domain)),b=f.next();!b.done;b=f.next()){if((b=a.domain[b.value])&&(b=b.getHandler(c))&&b.compile(a))return;a.rewind()}console.log("No handler found");throw Error("I don't understand '"+c+"...'");}},compileOne:function(){var c=a.getToken();if(c){b.warnings=[];var f=b.program.length;if(c.endsWith(":")){c=c.substring(0,c.length-1);if(b.symbols[c])throw Error("Duplicate symbol: '"+c+"'");b.symbols[c]= 22 {pc:f};b.index++}else a.compileToken()}},compileFromHere:function(c){for(;b.index<b.tokens.length;){var f=b.tokens[b.index].token;if("else"===f)return b.program;a.compileOne();if(-1<c.indexOf(f))break}},compile:function(c){b.tokens=c;b.index=0;b.program=[];b.symbols={};b.warnings=[];a.compileFromHere([]);a.addCommand({domain:"core",keyword:"stop",lino:a.getLino(),next:0});for(var f in b.symbols)c=b.program[b.symbols[f].pc],c.isSymbol&&!c.used&&console.log("Symbol '"+c.name+"' has not been used.");16 unrecognisedSymbol:function(c){a.addWarning("Unrecognised symbol '"+c+"'")},getWarnings:function(){return b.warnings},getIndex:function(){return b.index},next:function(a){b.index+=void 0===a?1:a},peek:function(){return b.tokens[b.index+1].token},more:function(){return b.index<b.tokens.length},getToken:function(){return b.index>=b.tokens.length?null:b.tokens[b.index]?b.tokens[b.index].token:null},nextToken:function(){a.next();return a.getToken()},tokenIs:function(a){return b.index>=b.tokens.length? 17 !1:a===b.tokens[b.index].token},nextTokenIs:function(c){a.next();return a.tokenIs(c)},skip:function(c){if(b.index>=b.tokens.length)return null;a.next();a.tokenIs(c)&&a.next()},prev:function(){b.index--},getLino:function(){return b.index>=b.tokens.length?0:b.tokens[b.index].lino},getTarget:function(a){a=void 0===a?b.index:a;return b.tokens[a].token},getTargetPc:function(c){c=void 0===c?b.index:c;return b.symbols[a.getTarget(c)].pc},getCommandAt:function(a){return b.program[a]},isSymbol:function(c){c= 18 void 0===c?!1:c;if(a.getTarget()in b.symbols)return!0;if(c)throw Error("Unknown symbol: '"+a.getTarget()+"'");return!1},nextIsSymbol:function(c){c=void 0===c?!1:c;a.next();return a.isSymbol(c)},getSymbol:function(){return b.symbols[a.getToken()]},getSymbolPc:function(){return a.getSymbol().pc},getSymbolRecord:function(){var c=b.program[a.getSymbolPc()];c.used=!0;return c},getSymbols:function(){return b.symbols},getProgram:function(){return b.program},getPc:function(){return b.program.length},getValue:function(){return a.value.compile(a)}, 19 getNextValue:function(){a.next();return a.getValue()},getCondition:function(){return a.condition.compile(a)},constant:function(c,f){return a.value.constant(c,void 0===f?!1:f)},addCommand:function(a){b.program.push(e({pc:b.program.length},a))},addSymbol:function(a,f){b.symbols[a]={pc:f}},mark:function(){b.savedMark=b.index},rewind:function(){b.index=b.savedMark},rewindTo:function(a){b.index=a},completeHandler:function(){var c=a.getLino(),f=a.getPc();a.addCommand({domain:"core",keyword:"goto",lino:c, 20 goto:0});a.compileOne();a.addCommand({domain:"core",keyword:"stop",lino:c,next:0});a.getCommandAt(f).goto=a.getPc();return!0},compileVariable:function(c,f,m,d){m=void 0===m?!1:m;d=void 0===d?null:d;a.next();var p=a.getLino(),l=a.getTokens()[a.getIndex()];if(b.symbols[l.token])throw Error("Duplicate variable name '"+l.token+"'");var n=a.getPc();a.next();a.addSymbol(l.token,n);c={domain:c,keyword:f,lino:p,isSymbol:!0,used:!1,isValueHolder:m,name:l.token,elements:1,index:0,value:[{}],element:[],extra:d}; 21 "dom"===d&&(c.element=[]);a.addCommand(c);return c},compileToken:function(){var c=a.getToken();if(c){a.mark();for(var f=$jscomp.makeIterator(Object.keys(a.domain)),b=f.next();!b.done;b=f.next()){if((b=a.domain[b.value])&&(b=b.getHandler(c))&&b.compile(a))return;a.rewind()}console.log("No handler found");throw Error("I don't understand '"+c+"...'");}},compileOne:function(){var c=a.getToken();if(c){b.warnings=[];var f=b.program.length;if(c.endsWith(":")){c=c.substring(0,c.length-1);if(b.symbols[c])throw Error("Duplicate symbol: '"+ 22 c+"'");b.symbols[c]={pc:f};b.index++}else a.compileToken()}},compileFromHere:function(c){for(;b.index<b.tokens.length;){var f=b.tokens[b.index].token;if("else"===f)return b.program;a.compileOne();if(-1<c.indexOf(f))break}},compile:function(c){b.tokens=c;b.index=0;b.program=[];b.symbols={};b.warnings=[];a.compileFromHere([]);a.addCommand({domain:"core",keyword:"exit",lino:a.getLino(),next:0});for(var f in b.symbols)c=b.program[b.symbols[f].pc],c.isSymbol&&!c.used&&console.log("Symbol '"+c.name+"' has not been used."); 23 23 return b.program}};h.exports=a},{}],4:[function(d,h,g){var e=Object.assign||function(b){for(var a=1;a<arguments.length;a++){var c=arguments[a],f;for(f in c)Object.prototype.hasOwnProperty.call(c,f)&&(b[f]=c[f])}return b};h.exports={compile:function(b){b.mark();for(var a=$jscomp.makeIterator(Object.keys(b.domain)),c=a.next();!c.done;c=a.next()){if(c=b.domain[c.value].condition.compile(b))return e({domain:name},c);b.rewind()}},test:function(b,a){return b.domain[a.domain].condition.test(b,a)}}},{}], 24 24 5:[function(d,h,g){var e=this,b={Add:{compile:function(a){var c=a.getLino();a.next();var f=a.getValue();if(a.tokenIs("to"))if(a.next(),a.isSymbol()){var b=a.getSymbol();if(a.getCommandAt(b.pc).isValueHolder){if("giving"===a.peek()){b=a.getValue();a.next();var d=a.getToken();a.next();a.addCommand({domain:"core",keyword:"add",lino:c,value1:f,value2:b,target:d})}else b=a.getToken(),a.next(),a.addCommand({domain:"core",keyword:"add",lino:c,value1:f,target:b});return!0}a.warning("core "+e.name+": Expected value holder")}else{b= 25 a.getValue();if(a.tokenIs("giving"))return a.next(),d=a.getToken(),a.next(),a.addCommand({domain:"core",keyword:"add",lino:c,value1:f,value2:b,target:d}),!0;a.warning("core "+e.name+': Expected "giving"')}return!1},run:function(a){var c=a[a.pc],f=c.value1,b=c.value2,d=a.getSymbolRecord(c.target);if(d.isValueHolder){var e=d.value[d.index];b?(a=a.getValue(b)+a.getValue(f),d.value[d.index]={type:"constant",numeric:!0,content:a}):(e.numeric||a.nonNumericValueError(c.lino),a=e.content+a.getValue(f),d.value[d.index]= 26 {type:"constant",numeric:!0,content:a})}else a.variableDoesNotHoldAValueError(c.lino,d.name);return c.pc+1}},Alias:{compile:function(a){var c=a.getLino();a.next();if(a.isSymbol()){var f=a.getToken();a.next();if(a.tokenIs("to")&&(a.next(),a.isSymbol())){var b=a.getSymbolRecord();b.used=!0;a.next();a.addCommand({domain:"core",keyword:"alias",lino:c,alias:f,symbol:b.name});return!0}}return!1},run:function(a){var c=a[a.pc],f=a.symbols[c.alias].pc,b=a[f],d=a.getSymbolRecord(c.symbol);a[f]={pc:b.pc,domain:d.domain, 27 keyword:d.keyword,lino:b.lino,name:b.name,alias:c.symbol};return c.pc+1}},Begin:{compile:function(a){a.next();a.compileFromHere(["end"]);return!0},run:function(a){return a[a.pc].pc+1}},Callback:{compile:function(a){a.compileVariable("core","callback");return!0},run:function(a){return a[a.pc].pc+1}},Clear:{compile:function(a){var c=a.getLino();a.next();if(a.isSymbol()){var f=a.getSymbolRecord();if(f.isValueHolder)return f=a.getToken(),a.next(),a.addCommand({domain:"core",keyword:"clear",lino:c,symbol:f}), 28 !0;a.warning("'Variable '"+f.name+"' does not hold a value")}return!1},run:function(a){var c=a[a.pc],f=a.getSymbolRecord(c.symbol);f.isValueHolder?(a.domain[f.domain].value.put(f,{type:"boolean",content:!1}),c.numeric=!1):a.variableDoesNotHoldAValueError(c.lino,f.name);return c.pc+1}},Close:{compile:function(a){var c=a.getLino();if(a.nextIsSymbol()){var f=a.getSymbolRecord();if("module"===f.keyword)return a.next(),a.addCommand({domain:"core",keyword:"close",lino:c,module:f.name}),!0}return!1},run:function(a){var c= 29 a[a.pc];a=a.getSymbolRecord(c.module).program;a.run(a.onClose);return c.pc+1}},Debug:{compile:function(a){var c=a.getLino();if(a.nextTokenIs("program")){a.next();if(["item","pc"].includes(a.getToken())){var f=a.getNextValue();a.addCommand({domain:"core",keyword:"debug",lino:c,item:f});return!0}a.addCommand({domain:"core",keyword:"debug",lino:c,item:-1});return!0}return a.tokenIs("symbols")?(a.next(),a.addCommand({domain:"core",keyword:"debug",lino:c,item:"symbols"}),!0):a.tokenIs("symbol")?(f=a.nextToken(), 30 a.next(),a.addCommand({domain:"core",keyword:"debug",lino:c,item:"symbol",name:f}),!0):a.tokenIs("step")?(a.next(),a.addCommand({domain:"core",keyword:"debug",lino:c,item:"step"}),!0):!1},run:function(a){var c=a[a.pc],f=c.item;switch(f){case "symbols":console.log("Symbols: "+JSON.stringify(a.symbols,null,2));break;case "symbol":a=a.getSymbolRecord(c.name);f=a.exporter;delete a.exporter;console.log("Symbol: "+JSON.stringify(a,null,2));a.exporter=f;break;case "step":a.debugStep=!0;break;default:0<= 31 f.content?console.log("Debug item "+f.content+": "+JSON.stringify(a[f.content],null,2)):console.log("Debug program: "+JSON.stringify(a,null,2))}return c.pc+1}},Decode:{compile:function(a){var c=a.getLino();if(a.nextIsSymbol()){var f=a.getToken();a.next();a.addCommand({domain:"core",keyword:"decode",lino:c,symbol:f});return!0}return!1},run:function(a){var c=a[a.pc],f=a.getSymbolRecord(c.symbol);if(f.isValueHolder){var b=a.getValue(f.value[f.index]);f.value[f.index]={type:"constant",numeric:!1,content:a.decode(b)}; 32 c.numeric=!1}else a.variableDoesNotHoldAValueError(c.lino,f.name);return c.pc+1}},Divide:{compile:function(a){var c=a.getLino();if(a.nextIsSymbol()){var f=a.getSymbol();var b=a.getCommandAt(f.pc).name}f=a.getValue();a.tokenIs("by")&&a.next();var d=a.getValue();if(a.tokenIs("giving")){a.next();if(a.isSymbol())return b=a.getSymbol(),b=a.getCommandAt(b.pc).name,a.next(),a.addCommand({domain:"core",keyword:"divide",lino:c,value1:f,value2:d,target:b}),!0;a.warning("core "+e.name+": Expected value holder")}else return"undefined"=== 33 typeof b&&a.warning("core "+e.name+": No target variable given"),a.addCommand({domain:"core",keyword:"divide",lino:c,value2:d,target:b}),!0;return!1},run:function(a){var c=a[a.pc],f=c.value1,b=c.value2,d=a.getSymbolRecord(c.target);if(d.isValueHolder){var e=d.value[d.index];f?(a=a.getValue(f)/a.getValue(b),d.value[d.index]={type:"constant",numeric:!0,content:Math.trunc(a)}):(e.numeric||a.nonNumericValueError(c,lino),a=e.content/a.getValue(b),d.value[d.index]={type:"constant",numeric:!0,content:Math.trunc(a)})}else a.variableDoesNotHoldAValueError(c.lino, 34 d.name);return c.pc+1}},Encode:{compile:function(a){var c=a.getLino();a.next();if(a.isSymbol()){var f=a.getToken();a.next();a.addCommand({domain:"core",keyword:"encode",lino:c,symbol:f});return!0}return!1},run:function(a){var c=a[a.pc],f=a.getSymbolRecord(c.symbol);if(f.isValueHolder){var b=a.getValue(f.value[f.index]);f.value[f.index]={type:"constant",numeric:!1,content:a.encode(b)};c.numeric=!1}else a.variableDoesNotHoldAValueError(c.lino,f.name);return c.pc+1}},End:{compile:function(a){a.next(); 35 return!0},run:function(){return 0}},Fork:{compile:function(a){var c=a.getLino();a.next();a.nextTokenIs("to")&&a.next();var f=a.getToken();a.next();a.addCommand({domain:"core",keyword:"fork",lino:c,label:f});return!0},run:function(a){var c=a[a.pc];try{a.run(a.symbols[c.label].pc)}catch(f){console.log(f.message),alert(f.message)}return c.pc+1}},Go:{compile:function(a){var c=a.getLino();a.nextTokenIs("to")&&a.next();var f=a.getToken();a.next();a.addCommand({domain:"core",keyword:"go",lino:c,label:f}); 36 return!0},run:function(a){var c=a[a.pc];if(c.label){if(a.verifySymbol(c.label)){var f=a.symbols[c.label];if(f)return f.pc}a.runtimeError(c.lino,"Unknown symbol '"+c.label+"'");return 0}return c.goto}},Gosub:{compile:function(a){var c=a.getLino();a.nextTokenIs("to")&&a.next();var f=a.getToken();a.next();a.addCommand({domain:"core",keyword:"gosub",lino:c,label:f});return!0},run:function(a){var c=a[a.pc];if(a.verifySymbol(c.label))return a.stack.push(a.pc+1),a.symbols[c.label].pc;a.runtimeError(c.lino, 37 "Unknown symbol '"+c.label+"'");return 0}},If:{compile:function(a){var c=a.getLino();a.next();var f=a.condition.compile(a),b=a.getPc();a.addCommand({domain:"core",keyword:"if",lino:c,condition:f});a.compileOne();if(!a.getToken())return a.getCommandAt(b).else=a.getPc(),!0;a.tokenIs("else")?(c=a.getPc(),a.addCommand({domain:"core",keyword:"goto",goto:0}),a.getCommandAt(b).else=a.getPc(),a.next(),a.compileOne(!0),a.getCommandAt(c).goto=a.getPc()):a.getCommandAt(b).else=a.getPc();return!0},run:function(a){var c= 38 a[a.pc];return a.condition.test(a,c.condition)?c.pc+1:c.else}},Import:{compile:function(a){var c=a.imports,b=a.getProgram();c=$jscomp.makeIterator(c);for(var d=c.next();!d.done;d=c.next()){d=d.value;var e=a.nextToken(),g=d.keyword;if(e===g){if(e=a.compileVariable(d.domain,g,!0),e=b[a.getSymbols()[e.name].pc],e.element=d.element,e.exporter=d.exporter,e.exportedName=d.name,e.extra=d.extra,e.isValueHolder=d.isValueHolder,e.imported=!0,!a.tokenIs("and"))break}else throw Error("Mismatched import variable type for '"+ 39 d.name+"'");}if(a.tokenIs("and"))throw Error("Imports do not match exports");return!0},run:function(a){return a[a.pc].pc+1}},Index:{compile:function(a){var c=a.getLino();if(a.nextIsSymbol(!0)){var b=a.getToken();if(a.nextTokenIs("to")){var d=a.getNextValue();a.addCommand({domain:"core",keyword:"index",lino:c,symbol:b,value:d});return!0}}return!1},run:function(a){var c=a[a.pc],b=a.getSymbolRecord(c.symbol),d=a.getValue(c.value);d>=b.elements&&a.runtimeError(c.lino,"Array index "+d+" is out of range for '"+ 40 b.name+"'");b.index=d;b.imported&&(b.exporter.getSymbolRecord(b.exportedName).index=d);return c.pc+1}},Load:{compile:function(a){var c=a.getLino();switch(a.nextToken()){case "plugin":var b=a.getNextValue();a.addCommand({domain:"core",keyword:"load",lino:c,name:b});return!0}return!1},run:function(a){var c=a[a.pc],b=a.getValue(c.name);switch(c.keyword){case "load":if(a.checkPlugin(b))return c.pc+1;EasyCoder_Plugins.getLocalPlugin(a.getPluginsPath,b,a.getPlugin,a.addLocalPlugin,function(){a.run(c.pc+ 41 1)});return 0}}},Module:{compile:function(a){a.compileVariable("core","module");return!0},run:function(a){a=a[a.pc];a.program=null;return a.pc+1}},Multiply:{compile:function(a){var c=a.getLino();a.next();if(a.isSymbol()){var b=a.getSymbol();var d=a.getCommandAt(b.pc).name}b=a.getValue();a.tokenIs("by")&&a.next();var e=a.getValue();if(a.tokenIs("giving")){a.next();if(a.isSymbol())return d=a.getSymbol(),d=a.getCommandAt(d.pc).name,a.next(),a.addCommand({domain:"core",keyword:"multiply",lino:c,value1:b, 42 value2:e,target:d}),!0;a.warning("core multiply: Expected value holder")}else return"undefined"===typeof d&&a.warning("core multiply: No target variable given"),a.addCommand({domain:"core",keyword:"multiply",lino:c,value2:e,target:d}),!0;return!1},run:function(a){var c=a[a.pc],b=c.value1,d=c.value2,e=a.getSymbolRecord(c.target);if(e.isValueHolder){var g=e.value[e.index];b?(a=a.getValue(b)*a.getValue(d),e.value[e.index]={type:"constant",numeric:!0,content:a}):(g.numeric||a.nonNumericValueError(c,lino), 43 a=g.content*a.getValue(d),e.value[e.index]={type:"constant",numeric:!0,content:a})}else a.variableDoesNotHoldAValueError(c.lino,e.name);return c.pc+1}},Negate:{compile:function(a){var c=a.getLino();a.next();if(a.isSymbol()){var b=a.getToken();a.next();a.addCommand({domain:"core",keyword:"negate",lino:c,symbol:b});return!0}return!1},run:function(a){var c=a[a.pc],b=a.getSymbolRecord(c.symbol);b.isValueHolder?b.value[b.index]={type:"constant",numeric:!0,content:-b.value[b.index].content}:a.variableDoesNotHoldAValueError(c.lino, 44 b.name);return c.pc+1}},On:{compile:function(a){var c=a.getLino(),b=a.nextToken();switch(b){case "trigger":case "close":case "restore":case "message":return a.next(),a.addCommand({domain:"core",keyword:"on",lino:c,action:b}),a.completeHandler()}return a.isSymbol()&&(b=a.getSymbolRecord(),"callback"===b.keyword)?(a.next(),a.addCommand({domain:"core",keyword:"on",lino:c,action:b.name}),a.completeHandler()):!1},run:function(a){var c=a[a.pc],b=c.pc+2;switch(c.action){case "trigger":a.onTrigger=b;break; 45 case "close":a.onClose=b;break;case "restore":a.onRestore=b;break;case "message":a.onMessage=b;break;default:var d=a.getSymbolRecord(c.action);if(d)d.cb=b;else return a.runtimeError(c.lino,"Unknown action '"+c.action+"'"),0}return c.pc+1}},Print:{compile:function(a){var c=a.getLino();a.next();var b=a.getValue();a.addCommand({domain:"core",keyword:"print",lino:c,value:b});return!0},run:function(a){var c=a[a.pc];a=a.getFormattedValue(c.value);console.log("-> "+a);return c.pc+1}},Put:{compile:function(a){var c= 46 a.getLino();a.next();var b=a.getValue();if(a.tokenIs("into")){a.next();if(a.isSymbol()){var d=a.getToken();a.next();a.addCommand({domain:"core",keyword:"put",lino:c,value:b,target:d});return!0}a.warning("core:put: No such variable: '"+a.getToken()+"'")}return!1},run:function(a){var c=a[a.pc],b=a.getSymbolRecord(c.target);b.isValueHolder||a.variableDoesNotHoldAValueError(c.lino,b.name);a=a.evaluate(c.value);b.value[b.index]=a;b.imported&&(b=b.exporter.getSymbolRecord(b.exportedName),b.value[b.index]= 47 a);return c.pc+1}},Replace:{compile:function(a){var c=a.getLino(),b=a.getNextValue();if(a.tokenIs("with")){var d=a.getNextValue();if(a.tokenIs("in")&&a.nextIsSymbol()){var e=a.getSymbolRecord();a.next();if(e.isValueHolder)return a.addCommand({domain:"core",keyword:"replace",lino:c,original:b,replacement:d,target:e.name}),!0}}return!1},run:function(a){var c=a[a.pc],b=a.getValue(c.original),d=a.getValue(c.replacement),e=a.getSymbolRecord(c.target);a=a.getValue(e.value[e.index]).split(b).join(d);e.value[e.index]= 48 {type:"constant",numeric:!1,content:a};return c.pc+1}},Require:{compile:function(a){var c=a.getLino(),b=a.nextToken();if(["css","js"].includes(b)){var d=a.getNextValue();a.addCommand({domain:"core",keyword:"require",lino:c,type:b,url:d});return!0}throw Error("File type must be 'css' or 'js'");},run:function(a){var c=a[a.pc];a.require(c.type,a.getValue(c.url),function(){a.run(c.pc+1)});return 0}},Return:{compile:function(a){var c=a.getLino();a.next();a.addCommand({domain:"core",keyword:"return",lino:c}); 49 return!0},run:function(a){return a.stack.pop()}},Run:{compile:function(a){var c=a.getLino(),b=a.getNextValue(),d=[];if(a.tokenIs("with"))for(;;)if(a.nextIsSymbol(!0)){var e=a.getSymbolRecord();e.exporter=a.getProgram();d.push(e);a.next();if(!a.tokenIs("and"))break}if(a.tokenIs("as")&&a.nextIsSymbol(!0)){e=a.getSymbolRecord();a.next();if("module"!==e.keyword)throw Error("'"+e.name+"' is not a module");var g=e.name}a.addCommand({domain:"core",keyword:"run",lino:c,script:b,imports:d,module:g});return!0}, 50 run:function(a){a.nextPc=a.pc+1;a.runScript(a);return 0}},Sanitize:{compile:function(a){var c=a.getLino();if(a.nextIsSymbol()){var b=a.getToken();a.next();a.addCommand({domain:"core",keyword:"sanitize",lino:c,name:b});return!0}return!1},run:function(a){var c=a[a.pc];a=a.getSymbolRecord(c.name);a=a.value[a.index];a.content=JSON.stringify(JSON.parse(a.content));return c.pc+1}},Script:{compile:function(a){var c=a.getLino(),b=a.nextToken();a.next();a.addCommand({domain:"core",keyword:"script",lino:c, 51 name:b});return!0},run:function(a){var c=a[a.pc];a.script=c.name;EasyCoder.scripts[c.name]=a;console.log(Date.now()-EasyCoder.timestamp+" ms: Script: "+c.name);return c.pc+1}},Send:{compile:function(a){var c=a.getLino(),b="";a.nextTokenIs("to")||(b=a.getValue());if(a.tokenIs("to")){if(a.nextTokenIs("parent"))var d="parent";else if(a.isSymbol){d=a.getSymbolRecord();if("module"!==d.keyword)throw Error("'"+d.name+"' is not a module");d=d.name}a.next();a.addCommand({domain:"core",keyword:"send",lino:c, 52 message:b,recipient:d})}return!0},run:function(a){var c=a[a.pc],b=a.getValue(c.message);if("parent"===c.recipient){var d=a.parent;d&&a.parent.onMessage&&(d.message=b,d.run(d.onMessage))}else a=a.getSymbolRecord(c.recipient),a.program&&(a.program.message=b,a.program.run(a.program.onMessage));return c.pc+1}},Set:{compile:function(a){var c=a.getLino();if(a.nextIsSymbol()){var b=a.getSymbolRecord();if(!b.isValueHolder)return!1;if(a.nextTokenIs("to")){a.next();for(var d=[];;){a.mark();try{d.push(a.getValue())}catch(k){a.rewind(); 53 break}}a.addCommand({domain:"core",keyword:"set",lino:c,request:"setArray",target:b.name,value:d});return!0}a.addCommand({domain:"core",keyword:"set",lino:c,request:"setBoolean",target:b.name});return!0}if(a.tokenIs("ready"))return a.next(),a.addCommand({domain:"core",keyword:"set",lino:c,request:"setReady"}),!0;if(a.tokenIs("property")&&(b=a.getNextValue(),a.tokenIs("of")&&a.nextIsSymbol()&&(d=a.getSymbolRecord(),"variable"===d.keyword&&a.nextTokenIs("to")))){var e=a.getNextValue();a.addCommand({domain:"core", 54 keyword:"set",lino:c,request:"setProperty",target:d.name,name:b,value:e});return!0}a.tokenIs("the")&&a.next();if(a.tokenIs("elements")&&(a.next(),a.tokenIs("of"))){a.next();if(!a.isSymbol())throw Error("Unknown variable '"+a.getToken()+"'");b=a.getToken();a.next();if(a.tokenIs("to"))return a.next(),d=a.getValue(),a.addCommand({domain:"core",keyword:"set",lino:c,request:"setElements",symbol:b,value:d}),!0}if(a.tokenIs("encoding")){if(a.nextTokenIs("to"))return b=a.getNextValue(),a.addCommand({domain:"core", 55 keyword:"set",request:"encoding",lino:c,encoding:b}),!0;a.addWarning("Unknown encoding option");return!1}return a.tokenIs("payload")&&a.nextTokenIs("of")&&a.nextIsSymbol()&&(b=a.getSymbolRecord(),"callback"===b.keyword&&a.nextTokenIs("to"))?(d=a.getNextValue(),a.addCommand({domain:"core",keyword:"set",request:"setPayload",lino:c,callback:b.name,payload:d}),!0):!1},run:function(a){var c=a[a.pc];switch(c.request){case "setBoolean":var b=a.getSymbolRecord(c.target);b.isValueHolder?(b.value[b.index]= 56 {type:"boolean",content:!0},c.numeric=!1):a.variableDoesNotHoldAValueError(c.lino,b.name);break;case "setReady":a.parent.run(a.parent.nextPc);break;case "setElements":b=a.getSymbolRecord(c.symbol);b.elements=a.getValue(c.value);b.index=0;b.value=[];b.element=[];for(a=0;a<b.elements;a++)b.value.push({}),b.element.push({});break;case "setArray":b=a.getSymbolRecord(c.target);b.elements=c.value.length;b.value=c.value;break;case "encoding":a.encoding=a.getValue(c.encoding);break;case "setProperty":b=a.getSymbolRecord(c.target); 57 var d=a.getValue(b.value[b.index]);d||(d="{}");var e="";try{e=JSON.parse(d)}catch(k){return a.runtimeError(c.lino,"Can't parse "+b.name),0}d=a.getValue(c.name);if(a=a.evaluate(c.value))e[d]="boolean"===a.type?a.content:a.numeric?a.content:'{"'===a.content.substr(0,2)?JSON.parse(a.content):a.content.split('"').join('\\"'),b.value[b.index]={type:"constant",numeric:!1,content:JSON.stringify(e)};break;case "setPayload":a.getSymbolRecord(c.callback).payload=a.getValue(c.payload)}return c.pc+1}},Stop:{compile:function(a){var c= 58 a.getLino();a.next();a.addCommand({domain:"core",keyword:"stop",lino:c,next:0});return!0},run:function(){return 0}},Take:{compile:function(a){var c=a.getLino();a.next();var b=a.getValue();if(a.tokenIs("from"))if(a.next(),a.isSymbol()){var d=a.getSymbol();if(a.getCommandAt(d.pc).isValueHolder){if("giving"===a.peek()){d=a.getValue();a.next();var g=a.getToken();a.next();a.addCommand({domain:"core",keyword:"take",lino:c,value1:b,value2:d,target:g})}else d=a.getToken(),a.next(),a.addCommand({domain:"core", 59 keyword:"take",lino:c,value1:b,target:d});return!0}a.warning("core "+e.name+": Expected value holder")}else{d=a.getValue();if(a.tokenIs("giving"))return a.next(),g=a.getToken(),a.next(),a.addCommand({domain:"core",keyword:"take",lino:c,value1:b,value2:d,target:g}),!0;a.warning("core "+e.name+': Expected "giving"')}return!1},run:function(a){var c=a[a.pc],b=c.value1,d=c.value2,e=a.getSymbolRecord(c.target);if(e.isValueHolder){var g=e.value[e.index];d?(a=a.getValue(d)-a.getValue(b),e.value[e.index]= 60 {type:"constant",numeric:!0,content:a}):(g.numeric||a.nonNumericValueError(c,lino),a=a.getValue(g)-a.getValue(b),e.value[e.index]={type:"constant",numeric:!0,content:a})}else a.variableDoesNotHoldAValueError(c.lino,e.name);return c.pc+1}},Toggle:{compile:function(a){var c=a.getLino();a.next();if(a.isSymbol()){var b=a.getSymbolPc();a.next();a.addCommand({domain:"core",keyword:"toggle",lino:c,symbol:b});return!0}return!1},run:function(a){var c=a[a.pc],b=a[c.symbol];if(b.isValueHolder){var d=a.domain[b.domain]; 61 a=d.value.get(a,b.value[b.index]).content;d.value.put(b,{type:"boolean",content:!a})}else a.variableDoesNotHoldAValueError(c.lino,b.name);return c.pc+1}},Variable:{compile:function(a){a.compileVariable("core","variable",!0);return!0},run:function(a){return a[a.pc].pc+1}},Wait:{compile:function(a){var c=a.getLino();a.next();var b=a.getValue(a),d=1E3;switch(a.getToken()){case "milli":case "millis":a.next();d=1;break;case "tick":case "ticks":a.next();d=10;break;case "second":case "seconds":a.next(); 62 d=1E3;break;case "minute":case "minutes":a.next(),d=6E4}a.addCommand({domain:"core",keyword:"wait",lino:c,value:b,multiplier:d});return!0},run:function(a){var c=a[a.pc],b=a.getValue(c.value);setTimeout(function(){a.run(c.pc+1)},b*c.multiplier);return 0}},While:{compile:function(a){var c=a.getLino();a.next();var b=a.getCondition(),d=a.getPc();a.addCommand({domain:"core",keyword:"while",lino:c,condition:b});c=a.getPc();a.addCommand({domain:"core",keyword:"goto",goto:0});a.compileOne();a.addCommand({domain:"core", 63 keyword:"goto",goto:d});a.getCommandAt(c).goto=a.getPc();return!0},run:function(a){return a.condition.test(a,a[a.pc].condition)?a.pc+2:a.pc+1}},getHandler:function(a){switch(a){case "add":return b.Add;case "alias":return b.Alias;case "begin":return b.Begin;case "callback":return b.Callback;case "clear":return b.Clear;case "close":return b.Close;case "debug":return b.Debug;case "decode":return b.Decode;case "divide":return b.Divide;case "encode":return b.Encode;case "end":return b.End;case "fork":return b.Fork; 64 case "go":case "goto":return b.Go;case "gosub":return b.Gosub;case "if":return b.If;case "import":return b.Import;case "index":return b.Index;case "load":return b.Load;case "module":return b.Module;case "multiply":return b.Multiply;case "negate":return b.Negate;case "on":return b.On;case "print":return b.Print;case "put":return b.Put;case "replace":return b.Replace;case "require":return b.Require;case "return":return b.Return;case "run":return b.Run;case "sanitize":return b.Sanitize;case "script":return b.Script; 65 case "send":return b.Send;case "set":return b.Set;case "stop":return b.Stop;case "take":return b.Take;case "toggle":return b.Toggle;case "variable":return b.Variable;case "wait":return b.Wait;case "while":return b.While;default:return!1}},run:function(a){var c=a[a.pc],d=b.getHandler(c.keyword);d||a.runtimeError(c.lino,"Unknown keyword '"+c.keyword+"' in 'core' package");return d.run(a)},isNegate:function(a){return"not"===a.getToken()?(a.next(),!0):!1},value:{compile:function(a){if(a.isSymbol()){var c= 66 a.getToken();switch(a.getSymbolRecord().keyword){case "module":return a.next(),{domain:"core",type:"module",name:c};case "variable":var b=a.nextToken();return["format","modulo"].includes(b)?(a=a.getNextValue(),{domain:"core",type:b,name:c,value:a}):{domain:"core",type:"symbol",name:c}}return null}c=a.getToken();if("true"===c)return a.next(),{domain:"core",type:"boolean",content:!0};if("false"===c)return a.next(),{domain:"core",type:"boolean",content:!1};if("random"===c)return a.next(),{domain:"core", 67 type:"random",range:a.getValue()};if("cos"===c)return a.next(),c=a.getValue(),a.skip("radius"),a=a.getValue(),{domain:"core",type:"cos",angle_c:c,radius_c:a};if("sin"===c)return a.next(),c=a.getValue(),a.skip("radius"),a=a.getValue(),{domain:"core",type:"sin",angle_s:c,radius_s:a};if("tan"===c)return a.next(),c=a.getValue(),a.skip("radius"),a=a.getValue(),{domain:"core",type:"tan",angle_t:c,radius_t:a};if("empty"===c)return a.next(),{domain:"core",type:"empty"};if(["now","today"].includes(c))return a.next(), 68 {domain:"core",type:c};if("newline"===c)return a.next(),{domain:"core",type:"newline"};if("break"===c)return a.next(),{domain:"core",type:"break"};if("encode"===c)return a.next(),{domain:"core",type:"encode",value:a.getValue()};if("decode"===c)return a.next(),{domain:"core",type:"decode",value:a.getValue()};if("lowercase"===c)return a.next(),{domain:"core",type:"lowercase",value:a.getValue()};if("element"===c)return c=a.getNextValue(),a.tokenIs("of")&&a.nextIsSymbol()&&(b=a.getSymbolRecord(),a.next(), 69 "variable"===b.keyword)?{domain:"core",type:"element",element:c,symbol:b.name}:null;if("property"===c)return c=a.getNextValue(),a.tokenIs("of")&&a.nextIsSymbol()&&(b=a.getSymbolRecord(),a.next(),"variable"===b.keyword)?{domain:"core",type:"property",property:c,symbol:b.name}:null;a.tokenIs("the")&&a.next();c=a.getToken();switch(c){case "elements":case "index":if(a.nextTokenIs("of")&&a.nextIsSymbol())return b=a.getToken(),a.next(),{domain:"core",type:c,name:b};break;case "value":if(a.nextTokenIs("of"))return a.next(), 70 {domain:"core",type:"valueOf",value:a.getValue()};break;case "length":if(a.nextTokenIs("of"))return a.next(),{domain:"core",type:"lengthOf",value:a.getValue()};break;case "left":case "right":b=a.getNextValue();if(a.tokenIs("of"))return a=a.getNextValue(),{domain:"core",type:c,count:b,value:a};break;case "from":b=a.getNextValue();var d=a.tokenIs("to")?a.getNextValue():null;if(a.tokenIs("of"))return a=a.getNextValue(),{domain:"core",type:c,from:b,to:d,value:a};break;case "position":if(a.nextTokenIs("of")&& 71 (c=!1,a.nextTokenIs("the")&&a.nextTokenIs("last")&&(a.next(),c=!0),b=a.getValue(),a.tokenIs("in")))return a=a.getNextValue(),{domain:"core",type:"position",needle:b,haystack:a,last:c};break;case "payload":if(a.nextTokenIs("of")&&a.nextIsSymbol()&&(c=a.getSymbolRecord(),"callback"===c.keyword))return a.next(),{domain:"core",type:"payload",callback:c.name};break;case "message":case "error":return a.next(),{domain:"core",type:c}}return null},get:function(a,c){switch(c.type){case "boolean":return{type:"boolean", 72 numeric:!1,content:c.content};case "elements":return{type:"constant",numeric:!0,content:a.getSymbolRecord(c.name).elements};case "index":return{type:"constant",numeric:!0,content:a.getSymbolRecord(c.name).index};case "random":return a=a.evaluate(c.range),{type:"constant",numeric:!0,content:Math.floor(Math.random()*a.content)};case "cos":var b=a.getValue(c.angle_c);a=a.getValue(c.radius_c);return{type:"constant",numeric:!0,content:parseInt(Math.cos(.01745329*parseFloat(b))*a,10)};case "sin":return b= 73 a.getValue(c.angle_s),a=a.getValue(c.radius_s),{type:"constant",numeric:!0,content:parseInt(Math.sin(.01745329*parseFloat(b))*a,10)};case "tan":return b=a.getValue(c.angle_t),a=a.getValue(c.radius_t),{type:"constant",numeric:!0,content:parseInt(Math.tan(.01745329*parseFloat(b))*a,10)};case "valueOf":return a=parseInt(a.getValue(c.value)),{type:"constant",numeric:!0,content:a?a:0};case "lengthOf":return{type:"constant",numeric:!0,content:a.getValue(c.value).length};case "left":return{type:"constant", 74 numeric:!1,content:a.getValue(c.value).substr(0,a.getValue(c.count))};case "right":return b=a.getValue(c.value),{type:"constant",numeric:!1,content:b.substr(b.length-a.getValue(c.count))};case "from":b=a.getValue(c.from);var d=c.to?a.getValue(c.to):null;a=a.getValue(c.value);return{type:"constant",numeric:!1,content:d?a.substr(b,d):a.substr(b)};case "position":return b=a.getValue(c.needle),a=a.getValue(c.haystack),{type:"constant",numeric:!0,content:c.last?a.lastIndexOf(b):a.indexOf(b)};case "payload":return{type:"constant", 75 numeric:!1,content:a.getSymbolRecord(c.callback).payload};case "modulo":return b=a.getSymbolRecord(c.name),a=a.evaluate(c.value),{type:"constant",numeric:!0,content:b.value[b.index].content%a.content};case "format":d=a.getSymbolRecord(c.name);d=1E3*a.getValue(d.value[d.index]);try{switch(b=JSON.parse(a.getValue(c.value)),b.mode){case "time":return{type:"constant",numeric:!0,content:(new Date(d)).toLocaleTimeString(b.locale,b.options)};default:return{type:"constant",numeric:!0,content:(new Date(d)).toLocaleDateString(b.locale, 76 b.options)}}}catch(p){a.runtimeError(a[a.pc].lino,"Can't parse "+c.value);break}case "empty":return{type:"constant",numeric:!1,content:""};case "now":return{type:"constant",numeric:!0,content:Math.floor(Date.now()/1E3)};case "today":return a=new Date,a.setHours(0,0,0,0),{type:"constant",numeric:!0,content:Math.floor(a.getTime()/1E3)};case "newline":return{type:"constant",numeric:!1,content:"\n"};case "break":return{type:"constant",numeric:!1,content:"<br />"};case "encode":return{type:"constant", 77 numeric:!1,content:a.encode(a.getValue(c.value))};case "decode":return{type:"constant",numeric:!1,content:a.decode(a.getValue(c.value))};case "lowercase":return{type:"constant",numeric:!1,content:a.getValue(c.value).toLowerCase()};case "element":b=a.getValue(c.element);c=a.getSymbolRecord(c.symbol);d="";try{d=JSON.parse(a.getValue(c.value[c.index]))[b]}catch(p){a.runtimeError(command.lino,"Can't parse JSON");break}return{type:"constant",numeric:!1,content:"object"===typeof d?JSON.stringify(d):d}; 78 case "property":b=a.getValue(c.property);c=a.getSymbolRecord(c.symbol);a=a.getValue(c.value[c.index]);c="";if(b&&a)if("object"===typeof a)c=a[b];else if("{"===a.charAt(0))try{c=JSON.parse(a)[b]}catch(p){console.log("Can't parse '"+a+"': "+p.message)}return{type:"constant",numeric:Number.isInteger(c),content:"object"===typeof c?JSON.stringify(c):c};case "module":return{type:"boolean",numeric:!1,content:a.getSymbolRecord(c.name).program};case "message":return c=a.message,{type:"constant",numeric:!1, 79 content:c};case "error":return c=a.errorMessage,{type:"constant",numeric:!1,content:c}}return null},put:function(a,c){a.value[a.index]=c}},condition:{compile:function(a){if(a.tokenIs("not"))return a.next(),{domain:"core",type:"not",value:a.getValue()};try{var c=a.getValue();if("is"===a.getToken()){a.next();var d=b.isNegate(a);switch(a.getToken()){case "numeric":return a.next(),{domain:"core",type:"numeric",value1:c};case "even":return a.next(),{domain:"core",type:"even",value1:c};case "odd":return a.next(), 80 {domain:"core",type:"odd",value1:c};case "greater":a.next();if(a.tokenIs("than")){a.next();var e=a.getValue();return{domain:"core",type:"greater",value1:c,value2:e,negate:d}}break;case "less":a.next();if(a.tokenIs("than")){a.next();var g=a.getValue();return{domain:"core",type:"less",value1:c,value2:g,negate:d}}break;default:var h=a.getValue();return{domain:"core",type:"is",value1:c,value2:h,negate:d}}}else if(c)return{domain:"core",type:"boolean",value:c}}catch(l){return a.warning("Can't get a value"), 81 0}return null},test:function(a,c){switch(c.type){case "boolean":return a.getValue(c.value);case "numeric":return Number.isInteger(a.getValue(c.value1));case "even":return 0===a.getValue(c.value1)%2;case "odd":return 1===a.getValue(c.value1)%2;case "is":return a=a.compare(a,c.value1,c.value2),c.negate?0!==a:0===a;case "greater":return a=a.compare(a,c.value1,c.value2),c.negate?0>=a:0<a;case "less":return a=a.compare(a,c.value1,c.value2),c.negate?0<=a:0>a;case "not":return!a.getValue(c.value)}return!1}}}; 82 h.exports=b},{}],6:[function(d,h,g){var e=this,b=d("./Tokenise"),a=d("./Compile"),c=d("./Run"),f=d("./Value"),m=d("./Condition"),p=d("./Compare"),k={domain:{core:d("./Core")},setupTracer:function(){var a=document.getElementById("easycoder-tracer");a&&(a.innerHTML='<div><input id="easycoder-run-button" type="button" value="Run" /><input id="easycoder-step-button" type="button" value="Step" /><div id="easycoder-tracer-content" style="border:1px solid black;padding:4px";width:100%></div>',a.style.display= 83 "none")},runtimeError:function(a,c){this.lino=a;this.reportError({message:"Line "+(0<=a?a:"")+": "+c},k.program)},nonNumericValueError:function(a){this.runtimeError(a,"Non-numeric value")},variableDoesNotHoldAValueError:function(a,c){this.runtimeError(a,"Variable '"+c+"' does not hold a value")},reportError:function(c,b,d){if(c.message)if(this.compiling||b){d=d?d:b.source;var e=d.tokens;d=d.scriptLines;e=this.compiling?e[a.getIndex()].lino:b[b.pc].lino;b=this.compiling?"Compile error":"Runtime error in '"+ 84 b.script+"'";b+=":\n";var f=e-5;for(f=0>f?0:f;f<e;f++){var l=(""+(f+1)).padStart(4," ");b+=l+" "+d[f].line.split("\\s").join(" ")+"\n"}b+=c.message+"\n";c=a.getWarnings();if(c.length)for(b+="Warnings:\n",c=$jscomp.makeIterator(c),d=c.next();!d.done;d=c.next())b+=d.value+"\n";console.log(b);alert(b);k.aborted=!0}else c="Error: "+c.message,alert(c),console.log(c);else console.log("An error occurred - origin was "+c.path[0])},getSymbolRecord:function(a){a=this[this.symbols[a].pc];return a.alias?this.getSymbolRecord(a.alias): 85 a.exporter&&a.exporter!=this?a.exporter.getSymbolRecord(a.exportedName):a},verifySymbol:function(a){return this.symbols.hasOwnProperty(a)},encode:function(a){return f.encode(a,this.encoding)},decode:function(a){return f.decode(a,this.encoding)},evaluate:function(a){return f.evaluate(this,a)},getValue:function(a){return f.getValue(this,a)},getFormattedValue:function(a){a=f.evaluate(this,a);return a.numeric?a.content:'{"'===a.content.substr(0,2)||"["===a.content.charAt(0)?JSON.stringify(JSON.parse(a.content), 86 null,2):a.content},getSimpleValue:function(a){return!0===a||!1===a?{type:"boolean",content:a}:{type:"constant",numeric:Number.isInteger(a),content:a}},run:function(a){a&&(k.program=this,c(this,a))},trigger:function(){this.onTrigger&&c(this,this.onTrigger)},register:function(a){k.program=a},require:function(a,c,b){var d=document.createElement("css"===a?"link":"script");switch(a){case "css":d.type="text/css";d.href=c;d.rel="stylesheet";break;case "js":d.type="text/javascript";d.src=c;break;default:return}d.onload= 87 function(){console.log(Date.now()-k.timestamp+" ms: Library "+c+" loaded");b()};document.head.appendChild(d)},isUndefined:function(a){return"undefined"===typeof a},runScript:function(a){var c=a[a.pc],b=a.getValue(c.script),d=c.imports;a=c.module?a.getSymbolRecord(c.module):null;k.tokeniseScript(b.split("\n"),d,a,this)},close:function(){},compileScript:function(c,b,d,e){var g=c.tokens;this.compiling=!0;var h=Date.now();a.value=f;a.condition=m;a.domain=k.domain;a.imports=b;b=a.compile(g);var l=Date.now(); 88 console.log(l-k.timestamp+" ms: Compiled "+g.length+" tokens in "+(l-h+" ms"));this.compiling=!1;b.EasyCoder=k;b.value=f;b.condition=m;b.compare=p;b.source=c;b.run=this.run;b.runScript=this.runScript;b.evaluate=this.evaluate;b.getValue=this.getValue;b.getFormattedValue=this.getFormattedValue;b.getSimpleValue=this.getSimpleValue;b.encode=this.encode;b.decode=this.decode;b.domain=this.domain;b.trigger=this.trigger;b.require=this.require;b.isUndefined=this.isUndefined;b.checkPlugin=this.checkPlugin; 89 b.getPlugin=this.getPlugin;b.addLocalPlugin=this.addLocalPlugin;b.getPluginsPath=this.getPluginsPath;b.getSymbolRecord=this.getSymbolRecord;b.verifySymbol=this.verifySymbol;b.runtimeError=this.runtimeError;b.nonNumericValueError=this.nonNumericValueError;b.variableDoesNotHoldAValueError=this.variableDoesNotHoldAValueError;b.reportError=this.reportError;b.register=this.register;b.symbols=a.getSymbols();b.encoding="ec";b.popups=[];b.stack=[];b.queue=[0];b.module=d;b.parent=e;d&&(d.program=b);return b}, 90 tokeniseScript:function(a,d,e,f){var g=null,h=Date.now();a=b.tokenise(a);var l=Date.now();console.log(l-k.timestamp+" ms: Tokenised "+a.scriptLines.length+" lines in "+(l-h+" ms"));try{g=k.compileScript(a,d,e,f)}catch(u){"stop"!==u.message&&this.reportError(u,k.program,a)}this.setupTracer();g&&c(g,0)},tokenize:function(a){var b=a.split("\n");if(!e.tokenising){try{k.tokeniseScript(b)}catch(q){k.reportError(q,null,a)}e.tokenising=!0}},setPluginCount:function(a){e.plugins=[];e.pluginCount=a},checkPlugin:function(a){return k.domain[a]}, 91 getPlugin:function(a,b,c){k.domain[a]?c():(a=document.createElement("script"),a.type="text/javascript",a.src=b+"?ver="+k.version,a.onload=function(){console.log(Date.now()-k.timestamp+" ms: Plugin "+b+" loaded");c()},document.head.appendChild(a))},addGlobalPlugin:function(a,b){e.plugins.push({name:a,handler:b});e.plugins.length===e.pluginCount&&(e.plugins.forEach(function(a){k.domain[a.name]=a.handler}),k.tokenize(e.source))},addLocalPlugin:function(a,b,c){k.domain[a]=b;c()},getPluginsPath:function(){return k.pluginsPath}, 92 loadPluginJs:function(a){console.log(Date.now()-k.timestamp+" ms: Load "+a+"/easycoder/plugins.js");var b=document.createElement("script");b.src=""+window.location.origin+a+"/easycoder/plugins.js?ver="+k.version;b.type="text/javascript";b.onload=function(){EasyCoder_Plugins.getGlobalPlugins(k.timestamp,a,k.setPluginCount,k.getPlugin,k.addGlobalPlugin)};b.onerror=function(){a?k.loadPluginJs(a.slice(0,a.lastIndexOf("/"))):k.reportError({message:"Can't load plugins.js"},k.program,e.source)};document.head.appendChild(b); 93 k.pluginsPath=a},start:function(a){e.source=a;a=window.location.pathname;a.endsWith("/")&&(a=a.slice(0,-1));k.loadPluginJs(a)}};h.exports=k},{"./Compare":2,"./Compile":3,"./Condition":4,"./Core":5,"./Run":7,"./Tokenise":8,"./Value":9}],7:[function(d,h,g){var e=function(b,a){var c=[],d=function(a){var b=9999;a.forEach(function(a){a=a.line;for(var c=0;c<a.length&&" "===a[c];)c++;0<c&&c<b&&(b=c)});return 0};if(c.length)c.push(a);else for(b.register(b),c.push(a);0<c.length&&!EasyCoder.aborted;)for(b.pc= 94 c.shift(),b.watchdog=0,a={};;){if(1E6<b.watchdog){b.lino=b[b.pc].lino;b.reportError(Error("Program runaway intercepted.\nHave you forgotten to increment a loop counter?",b),b);break}b.watchdog++;var g=b[b.pc].domain;b.debugStep&&console.log(b.script+" "+b.pc+" "+g+":"+b[b.pc].keyword);var h=b.domain[g];if(!h){b.runtimeError(b[b.pc].lino,"Unknown domain '"+g+"'");break}b.pc=h.run(b);if(!b.pc)break;if(b.stop){b.tracing=!1;return}if(b.tracing){g=b[b.pc];h=b.source.scriptLines;var k=d(h),l=document.getElementById("easycoder-tracer"); 95 if(!l){b.runtimeError(g.lino,"Element 'easycoder-tracer' was not found");return}l.style.display="block";l.style.visibility="visible";var n="";if(b.tracer){if(l=document.getElementById("easycoder-tracer-content")){b.tracer.variables.forEach(function(a,c,d){var e=b.getSymbolRecord(a);if(1<e.elements)for(n+=a+": "+e.index+"/"+e.elements+": ",a=0;a<e.elements;a++){var f=e.value[a];n=f?n+(f.content+" "):n+"undefined "}else n=(e=e.value[e.index])?n+(a+": "+e.content):n+(a+": undefined");switch(b.tracer.alignment){case "horizontal":c< 96 d.length-1&&(n+=", ");break;case "vertical":n+="<br>"}});n+="<hr>";for(var q="",r=5;0<r;r--)g.lino&&(q+='<input type="text" name="'+r+'"'+('value="'+h[g.lino-r].line.substr(k)+'"')+'style="width:100%;border:none;enabled:false">'),q+="<br>";l.innerHTML=n+" "+q;l.style.display="block";a.run=document.getElementById("easycoder-run-button");a.step=document.getElementById("easycoder-step-button");a.run.onclick=function(a){return function(){a.run.blur();b.tracing=!1;document.getElementById("easycoder-tracer-content").style.display= 97 "none";try{e(b,b.resume)}catch(t){var c="Error in run handler: "+t.message;console.log(c);alert(c)}}}(a);a.step.onclick=function(a){return function(){console.log("step");a.step.blur();b.tracing=!0;document.getElementById("easycoder-tracer-content").style.display="block";try{e(b,b.resume)}catch(t){var c="Error in step handler: "+t.message;console.log(c);alert(c)}}}(a)}b.resume=b.pc;b.pc=0}break}a={run:a.run,step:a.step}}};h.exports=e},{}],8:[function(d,h,g){var e={markComments:function(b){var a=b.list, 98 c=void 0===b.index?0:b.index,d=void 0===b.inComment?!1:b.inComment,g=void 0===b.newList?[]:b.newList;if(c>=a.length)return g;var h=a[c];b=h.lino;h=h.token;var k={list:a,index:c+1,inComment:!1,newList:g.concat({lino:b,index:c,token:h})};g={list:a,index:c+1,inComment:!0,newList:g.concat({lino:b,index:c,comment:!0,token:h})};return d&&0<c&&b===a[c-1].lino?e.markComments(g):"!"===h.charAt(0)?e.markComments(g):e.markComments(k)},findStrings:function(b){var a=b.original,c=b.line,d=void 0===b.inComment? 99 !1:b.inComment;b=void 0===b.inQuote?!1:b.inQuote;var g=c.charAt(0),h=b&&[" ","\\t"].includes(g)?"\\s":g;if(1===c.length)return h;c=c.substring(1);if("!"===g&&!b)return g+e.findStrings({original:a,line:c,inComment:!0,inQuote:!1});if("`"===g&&!d&&!b)return g+e.findStrings({original:a,line:c,inComment:d,inQuote:!0});if("`"===g&&b)return g+e.findStrings({original:a,line:c,inComment:d,inQuote:!1});if(!d&&!b&&!g.match(/[A-z0-9_\-+*/\- \t]/)){if(["'",'"'].includes(g))throw Error('Bad syntax in "'+a+'":\nStrings in EasyCoder must be enclosed in backticks.'); 100 throw Error('Unrecognised character "'+g+'" in\n"'+a+'".');}return h+e.findStrings({original:a,line:c,inComment:d,inQuote:b})},tokenise:function(b){b=b.map(function(a){var b=a.trim();return b.length?e.findStrings({original:a,line:b}):""}).map(function(a,b){return{lino:b+1,line:a}});var a=b.map(function(a){return a.line.trim().split(/\s+/).map(function(b,c){return{lino:a.lino,index:c,token:b}})});a=[].concat.apply([],a).filter(function(a){return a.token}).map(function(a){return{lino:a.lino,index:a.index, 101 token:a.token.split("\\s").join(" ")}});a=e.markComments({list:a}).filter(function(a){return!a.comment});return{scriptLines:b,tokens:a}}};h.exports=e},{}],9:[function(d,h,g){var e={getItem:function(b){var a=b.getToken();if(!a)return null;if("true"===a)return b.next(),{type:"boolean",content:!0};if("false"===a)return b.next(),{type:"boolean",content:!1};if("`"===a.charAt(0))return b.next(),{type:"constant",numeric:!1,content:a.substring(1,a.length-1)};if(a.charAt(0).match(/[0-9-]/)){var c=eval(a); 102 if(Number.isInteger(c))return b.next(),{type:"constant",numeric:!0,content:c};throw Error("'"+a+"' is not an integer");}a=b.getIndex();c=$jscomp.makeIterator(Object.keys(b.domain));for(var d=c.next();!d.done;d=c.next())if(d=d.value,b.rewindTo(a),d=b.domain[d].value.compile(b))return d;return null},compile:function(b){var a=b.getToken(),c=e.getItem(b);if(!c)throw Error("Undefined value: '"+a+"'");if("cat"===b.getToken()){for(a={type:"cat",numeric:!1,parts:[c]};b.tokenIs("cat");)b.next(),a.parts.push(b.value.getItem(b)); 103 return a}return c},doValue:function(b,a){if("undefined"===typeof a.type)return b.runtimeError(b[b.pc].lino,"Undefined value (variable not initialized?)"),null;switch(a.type){case "cat":return{type:"constant",numeric:!1,content:a.parts.reduce(function(a,c){return a+e.doValue(b,c).content},"")};case "boolean":case "constant":return a;case "symbol":var c=b.getSymbolRecord(a.name);if(c.isValueHolder){if(a=c.value[c.index]){c=a.content;if(null===c||"undefined"===typeof c)a.content=a.numeric?0:"";return a}return null}return b.domain[c.domain].value.get(b, 104 a)}return b.domain[a.domain].value.get(b,a)},constant:function(b,a){return{type:"constant",numeric:a,content:b}},evaluate:function(b,a){if(!a)return{type:"constant",numeric:!1,content:""};var c=e.doValue(b,a);if(c)return c;b.runtimeError(b[b.pc].lino,"Can't decode value: "+a)},getValue:function(b,a){return e.evaluate(b,a).content},encode:function(b,a){if(b)switch(a){case "ec":return b.replace(/'/g,"~sq~").replace(/"/g,"~dq~").replace(/\n/g,"%0a").replace(/\r/g,"%0d");case "url":return encodeURIComponent(b.replace(/\s/g, 105 "+"));case "sanitize":return b.normalize("NFD").replace(/[\u0300-\u036f]/g,"")}return b},decode:function(b,a){if(b)switch(a){case "ec":return b.replace(/~dq~/g,'"').replace(/~sq~/g,"'").replace(/%0a/g,"\n").replace(/%0d/g,"\r");case "url":return decodeURIComponent(b).replace(/\+/g," ")}return b}};h.exports=e},{}]},{},[1]); 25 a.getValue();if(a.tokenIs("giving"))return a.next(),d=a.getToken(),a.next(),a.addCommand({domain:"core",keyword:"add",lino:c,value1:f,value2:b,target:d}),!0;a.warning("core "+e.name+': Expected "giving"')}return!1},run:function(a){var c=a[a.pc],f=c.value1,b=c.value2,d=a.getSymbolRecord(c.target);if(d.isValueHolder){var e=d.value[d.index];b?(a=a.getValue(b)+a.getValue(f),d.value[d.index]={type:"constant",numeric:!0,content:a}):(!e.numeric&&isNaN(e.content)&&a.nonNumericValueError(c.lino),a=parseInt(e.content)+ 26 parseInt(a.getValue(f)),d.value[d.index]={type:"constant",numeric:!0,content:a})}else a.variableDoesNotHoldAValueError(c.lino,d.name);return c.pc+1}},Alias:{compile:function(a){var c=a.getLino();a.next();if(a.isSymbol()){var f=a.getToken();a.next();if(a.tokenIs("to")&&(a.next(),a.isSymbol())){var b=a.getSymbolRecord();b.used=!0;a.next();a.addCommand({domain:"core",keyword:"alias",lino:c,alias:f,symbol:b.name});return!0}}return!1},run:function(a){var c=a[a.pc],f=a.symbols[c.alias].pc,b=a[f],d=a.getSymbolRecord(c.symbol); 27 a[f]={pc:b.pc,domain:d.domain,keyword:d.keyword,lino:b.lino,name:b.name,alias:c.symbol};return c.pc+1}},Begin:{compile:function(a){a.next();a.compileFromHere(["end"]);return!0},run:function(a){return a[a.pc].pc+1}},Callback:{compile:function(a){a.compileVariable("core","callback");return!0},run:function(a){return a[a.pc].pc+1}},Clear:{compile:function(a){var c=a.getLino();a.next();if(a.isSymbol()){var f=a.getSymbolRecord();if(f.isValueHolder)return f=a.getToken(),a.next(),a.addCommand({domain:"core", 28 keyword:"clear",lino:c,symbol:f}),!0;a.warning("'Variable '"+f.name+"' does not hold a value")}return!1},run:function(a){var c=a[a.pc],f=a.getSymbolRecord(c.symbol);f.isValueHolder?(a.domain[f.domain].value.put(f,{type:"boolean",content:!1}),c.numeric=!1):a.variableDoesNotHoldAValueError(c.lino,f.name);return c.pc+1}},Close:{compile:function(a){var c=a.getLino();if(a.nextIsSymbol()){var f=a.getSymbolRecord();if("module"===f.keyword)return a.next(),a.addCommand({domain:"core",keyword:"close",lino:c, 29 module:f.name}),!0}return!1},run:function(a){var c=a[a.pc];a=a.getSymbolRecord(c.module).program;a.run(a.onClose);return c.pc+1}},Debug:{compile:function(a){var c=a.getLino();if(a.nextTokenIs("program")){a.next();if(["item","pc"].includes(a.getToken())){var f=a.getNextValue();a.addCommand({domain:"core",keyword:"debug",lino:c,item:f});return!0}a.addCommand({domain:"core",keyword:"debug",lino:c,item:"program"});return!0}return a.tokenIs("symbols")?(a.next(),a.addCommand({domain:"core",keyword:"debug", 30 lino:c,item:"symbols"}),!0):a.tokenIs("symbol")?(f=a.nextToken(),a.next(),a.addCommand({domain:"core",keyword:"debug",lino:c,item:"symbol",name:f}),!0):a.tokenIs("step")?(a.next(),a.addCommand({domain:"core",keyword:"debug",lino:c,item:"step"}),!0):!1},run:function(a){var c=a[a.pc],f=c.item;switch(f){case "symbols":console.log("Symbols: "+JSON.stringify(a.symbols,null,2));break;case "symbol":a=a.getSymbolRecord(c.name);f=a.exporter;delete a.exporter;console.log("Symbol: "+JSON.stringify(a,null,2)); 31 a.exporter=f;break;case "step":a.debugStep=!0;break;case "program":console.log("Debug program: "+JSON.stringify(a,null,2));break;default:0<=f.content&&console.log("Debug item "+f.content+": "+JSON.stringify(a[f.content],null,2))}return c.pc+1}},Decode:{compile:function(a){var c=a.getLino();if(a.nextIsSymbol()){var f=a.getToken();a.next();a.addCommand({domain:"core",keyword:"decode",lino:c,symbol:f});return!0}return!1},run:function(a){var c=a[a.pc],f=a.getSymbolRecord(c.symbol);if(f.isValueHolder){var b= 32 a.getValue(f.value[f.index]);f.value[f.index]={type:"constant",numeric:!1,content:a.decode(b)};c.numeric=!1}else a.variableDoesNotHoldAValueError(c.lino,f.name);return c.pc+1}},Divide:{compile:function(a){var c=a.getLino();if(a.nextIsSymbol()){var f=a.getSymbol();var b=a.getCommandAt(f.pc).name}f=a.getValue();a.tokenIs("by")&&a.next();var d=a.getValue();if(a.tokenIs("giving")){a.next();if(a.isSymbol())return b=a.getSymbol(),b=a.getCommandAt(b.pc).name,a.next(),a.addCommand({domain:"core",keyword:"divide", 33 lino:c,value1:f,value2:d,target:b}),!0;a.warning("core "+e.name+": Expected value holder")}else return"undefined"===typeof b&&a.warning("core "+e.name+": No target variable given"),a.addCommand({domain:"core",keyword:"divide",lino:c,value2:d,target:b}),!0;return!1},run:function(a){var c=a[a.pc],f=c.value1,b=c.value2,d=a.getSymbolRecord(c.target);if(d.isValueHolder){var e=d.value[d.index];f?(a=a.getValue(f)/a.getValue(b),d.value[d.index]={type:"constant",numeric:!0,content:Math.trunc(a)}):(!e.numeric&& 34 isNaN(e.content)&&a.nonNumericValueError(c,lino),a=parseInt(e.content)/parseInt(a.getValue(b)),d.value[d.index]={type:"constant",numeric:!0,content:Math.trunc(a)})}else a.variableDoesNotHoldAValueError(c.lino,d.name);return c.pc+1}},Encode:{compile:function(a){var c=a.getLino();a.next();if(a.isSymbol()){var f=a.getToken();a.next();a.addCommand({domain:"core",keyword:"encode",lino:c,symbol:f});return!0}return!1},run:function(a){var c=a[a.pc],f=a.getSymbolRecord(c.symbol);if(f.isValueHolder){var b= 35 a.getValue(f.value[f.index]);f.value[f.index]={type:"constant",numeric:!1,content:a.encode(b)};c.numeric=!1}else a.variableDoesNotHoldAValueError(c.lino,f.name);return c.pc+1}},End:{compile:function(a){a.next();return!0},run:function(){return 0}},Exit:{compile:function(a){a.next();a.addCommand({domain:"core",keyword:"exit"});return!0},run:function(a){a.exit();return 0}},Fork:{compile:function(a){var c=a.getLino();a.next();a.nextTokenIs("to")&&a.next();var f=a.getToken();a.next();a.addCommand({domain:"core", 36 keyword:"fork",lino:c,label:f});return!0},run:function(a){var c=a[a.pc];try{a.run(a.symbols[c.label].pc)}catch(f){console.log(f.message),alert(f.message)}return c.pc+1}},Go:{compile:function(a){var c=a.getLino();a.nextTokenIs("to")&&a.next();var f=a.getToken();a.next();a.addCommand({domain:"core",keyword:"go",lino:c,label:f});return!0},run:function(a){var c=a[a.pc];if(c.label){if(a.verifySymbol(c.label)){var f=a.symbols[c.label];if(f)return f.pc}a.runtimeError(c.lino,"Unknown symbol '"+c.label+"'"); 37 return 0}return c.goto}},Gosub:{compile:function(a){var c=a.getLino();a.nextTokenIs("to")&&a.next();var f=a.getToken();a.next();a.addCommand({domain:"core",keyword:"gosub",lino:c,label:f});return!0},run:function(a){var c=a[a.pc];if(a.verifySymbol(c.label))return a.stack.push(a.pc+1),a.symbols[c.label].pc;a.runtimeError(c.lino,"Unknown symbol '"+c.label+"'");return 0}},If:{compile:function(a){var c=a.getLino();a.next();var f=a.condition.compile(a),b=a.getPc();a.addCommand({domain:"core",keyword:"if", 38 lino:c,condition:f});a.compileOne();if(!a.getToken())return a.getCommandAt(b).else=a.getPc(),!0;a.tokenIs("else")?(c=a.getPc(),a.addCommand({domain:"core",keyword:"goto",goto:0}),a.getCommandAt(b).else=a.getPc(),a.next(),a.compileOne(!0),a.getCommandAt(c).goto=a.getPc()):a.getCommandAt(b).else=a.getPc();return!0},run:function(a){var c=a[a.pc];return a.condition.test(a,c.condition)?c.pc+1:c.else}},Import:{compile:function(a){var c=a.imports,f=a.getProgram();c=$jscomp.makeIterator(c);for(var b=c.next();!b.done;b= 39 c.next()){b=b.value;var d=a.nextToken(),e=b.keyword;if(d===e){if(d=a.compileVariable(b.domain,e,!0),d=f[a.getSymbols()[d.name].pc],d.element=b.element,d.exporter=b.exporter,d.exportedName=b.name,d.extra=b.extra,d.isValueHolder=b.isValueHolder,d.imported=!0,!a.tokenIs("and"))break}else throw Error("Mismatched import variable type for '"+b.name+"'");}if(a.tokenIs("and"))throw Error("Imports do not match exports");return!0},run:function(a){return a[a.pc].pc+1}},Index:{compile:function(a){var c=a.getLino(); 40 if(a.nextIsSymbol(!0)){var b=a.getToken();if(a.nextTokenIs("to")){var d=a.getNextValue();a.addCommand({domain:"core",keyword:"index",lino:c,symbol:b,value:d});return!0}}return!1},run:function(a){var c=a[a.pc],b=a.getSymbolRecord(c.symbol),d=a.getValue(c.value);d>=b.elements&&a.runtimeError(c.lino,"Array index "+d+" is out of range for '"+b.name+"'");b.index=d;b.imported&&(b.exporter.getSymbolRecord(b.exportedName).index=d);return c.pc+1}},Load:{compile:function(a){var c=a.getLino();switch(a.nextToken()){case "plugin":var b= 41 a.getNextValue();a.addCommand({domain:"core",keyword:"load",lino:c,name:b});return!0}return!1},run:function(a){var c=a[a.pc],b=a.getValue(c.name);switch(c.keyword){case "load":if(a.checkPlugin(b))return c.pc+1;EasyCoder_Plugins.getLocalPlugin(a.getPluginsPath,b,a.getPlugin,a.addLocalPlugin,function(){a.run(c.pc+1)});return 0}}},Module:{compile:function(a){a.compileVariable("core","module");return!0},run:function(a){a=a[a.pc];a.program=null;return a.pc+1}},Multiply:{compile:function(a){var c=a.getLino(); 42 a.next();if(a.isSymbol()){var b=a.getSymbol();var d=a.getCommandAt(b.pc).name}b=a.getValue();a.tokenIs("by")&&a.next();var e=a.getValue();if(a.tokenIs("giving")){a.next();if(a.isSymbol())return d=a.getSymbol(),d=a.getCommandAt(d.pc).name,a.next(),a.addCommand({domain:"core",keyword:"multiply",lino:c,value1:b,value2:e,target:d}),!0;a.warning("core multiply: Expected value holder")}else return"undefined"===typeof d&&a.warning("core multiply: No target variable given"),a.addCommand({domain:"core",keyword:"multiply", 43 lino:c,value2:e,target:d}),!0;return!1},run:function(a){var c=a[a.pc],b=c.value1,d=c.value2,e=a.getSymbolRecord(c.target);if(e.isValueHolder){var g=e.value[e.index];b?(a=a.getValue(b)*a.getValue(d),e.value[e.index]={type:"constant",numeric:!0,content:a}):(!g.numeric&&isNaN(g.content)&&a.nonNumericValueError(c,lino),a=parseInt(g.content)*parseInt(a.getValue(d)),e.value[e.index]={type:"constant",numeric:!0,content:a})}else a.variableDoesNotHoldAValueError(c.lino,e.name);return c.pc+1}},Negate:{compile:function(a){var c= 44 a.getLino();a.next();if(a.isSymbol()){var b=a.getToken();a.next();a.addCommand({domain:"core",keyword:"negate",lino:c,symbol:b});return!0}return!1},run:function(a){var c=a[a.pc],b=a.getSymbolRecord(c.symbol);b.isValueHolder?b.value[b.index]={type:"constant",numeric:!0,content:-b.value[b.index].content}:a.variableDoesNotHoldAValueError(c.lino,b.name);return c.pc+1}},On:{compile:function(a){var c=a.getLino(),b=a.nextToken();switch(b){case "close":case "restore":case "message":return a.next(),a.addCommand({domain:"core", 45 keyword:"on",lino:c,action:b}),a.completeHandler()}return a.isSymbol()&&(b=a.getSymbolRecord(),"callback"===b.keyword)?(a.next(),a.addCommand({domain:"core",keyword:"on",lino:c,action:b.name}),a.completeHandler()):!1},run:function(a){var c=a[a.pc],b=c.pc+2;switch(c.action){case "close":a.onClose=b;break;case "restore":a.onRestore=b;break;case "message":a.onMessage=b;break;default:var d=a.getSymbolRecord(c.action);if(d)d.cb=b;else return a.runtimeError(c.lino,"Unknown action '"+c.action+"'"),0}return c.pc+ 46 1}},Print:{compile:function(a){var c=a.getLino();a.next();var b=a.getValue();a.addCommand({domain:"core",keyword:"print",lino:c,value:b});return!0},run:function(a){var c=a[a.pc];a=a.getFormattedValue(c.value);console.log("-> "+a);return c.pc+1}},Put:{compile:function(a){var c=a.getLino(),b=a.getNextValue();if(a.tokenIs("into")){if(a.nextIsSymbol()){var d=a.getToken();a.next();a.addCommand({domain:"core",keyword:"put",lino:c,value:b,target:d});return!0}a.warning("core:put: No such variable: '"+a.getToken()+ 47 "'")}return!1},run:function(a){var c=a[a.pc],b=a.getSymbolRecord(c.target);b.isValueHolder||a.variableDoesNotHoldAValueError(c.lino,b.name);a=a.evaluate(c.value);b.value[b.index]=a;b.imported&&(b=b.exporter.getSymbolRecord(b.exportedName),b.value[b.index]=a);return c.pc+1}},Replace:{compile:function(a){var c=a.getLino(),b=a.getNextValue();if(a.tokenIs("with")){var d=a.getNextValue();if(a.tokenIs("in")&&a.nextIsSymbol()){var e=a.getSymbolRecord();a.next();if(e.isValueHolder)return a.addCommand({domain:"core", 48 keyword:"replace",lino:c,original:b,replacement:d,target:e.name}),!0;throw Error("'"+e.name+"' does not hold a value");}}return!1},run:function(a){var c=a[a.pc],b=a.getValue(c.original),d=a.getValue(c.replacement),e=a.getSymbolRecord(c.target);a=a.getValue(e.value[e.index]).split(b).join(d);e.value[e.index]={type:"constant",numeric:!1,content:a};return c.pc+1}},Require:{compile:function(a){var c=a.getLino(),b=a.nextToken();if(["css","js"].includes(b)){var d=a.getNextValue();a.addCommand({domain:"core", 49 keyword:"require",lino:c,type:b,url:d});return!0}throw Error("File type must be 'css' or 'js'");},run:function(a){var c=a[a.pc];a.require(c.type,a.getValue(c.url),function(){a.run(c.pc+1)});return 0}},Return:{compile:function(a){var c=a.getLino();a.next();a.addCommand({domain:"core",keyword:"return",lino:c});return!0},run:function(a){return a.stack.pop()}},Run:{compile:function(a){var c=a.getLino(),b=a.getNextValue(),d=[];if(a.tokenIs("with"))for(;;)if(a.nextIsSymbol(!0)){var e=a.getSymbolRecord(); 50 e.exporter=a.getProgram();d.push(e);a.next();if(!a.tokenIs("and"))break}if(a.tokenIs("as")&&a.nextIsSymbol(!0)){var g=a.getSymbolRecord();a.next();if("module"!==g.keyword)throw Error("'"+g.name+"' is not a module");g=g.name}var l=!1;a.tokenIs("nowait")&&(a.next(),l=!0);e=a.getPc();a.addCommand({domain:"core",keyword:"run",lino:c,script:b,imports:d,module:g,nowait:l,then:0});a.tokenIs("then")&&(c=a.getPc(),a.addCommand({domain:"core",keyword:"goto",goto:0}),a.getCommandAt(e).then=a.getPc(),a.next(), 51 a.compileOne(!0),a.addCommand({domain:"core",keyword:"stop"}),a.getCommandAt(c).goto=a.getPc());return!0},run:function(a){a.nextPc=a.pc+1;a.runScript(a);return 0}},Sanitize:{compile:function(a){var c=a.getLino();if(a.nextIsSymbol()){var b=a.getToken();a.next();a.addCommand({domain:"core",keyword:"sanitize",lino:c,name:b});return!0}return!1},run:function(a){var c=a[a.pc];a=a.getSymbolRecord(c.name);a=a.value[a.index];a.content=JSON.stringify(JSON.parse(a.content));return c.pc+1}},Script:{compile:function(a){var c= 52 a.getLino(),b=a.nextToken();a.next();a.addCommand({domain:"core",keyword:"script",lino:c,name:b});return!0},run:function(a){var c=a[a.pc];a.script=c.name;EasyCoder.scripts[c.name]=a;console.log(Date.now()-EasyCoder.timestamp+" ms: Script: "+c.name);return c.pc+1}},Send:{compile:function(a){var c=a.getLino(),b="";a.nextTokenIs("to")||(b=a.getValue());if(a.tokenIs("to")){if(a.nextTokenIs("parent"))var d="parent";else if(a.isSymbol){d=a.getSymbolRecord();if("module"!==d.keyword)throw Error("'"+d.name+ 53 "' is not a module");d=d.name}a.next();a.addCommand({domain:"core",keyword:"send",lino:c,message:b,recipient:d})}return!0},run:function(a){var c=a[a.pc],b=a.getValue(c.message);if("parent"===c.recipient){var d=a.parent;d&&a.parent.onMessage&&(d.message=b,d.run(d.onMessage))}else a=a.getSymbolRecord(c.recipient),a.program&&(a.program.message=b,a.program.run(a.program.onMessage));return c.pc+1}},Set:{compile:function(a){var c=a.getLino();if(a.nextIsSymbol()){var b=a.getSymbolRecord();if(!b.isValueHolder)return!1; 54 if(a.nextTokenIs("to")){a.next();for(var d=[];;){a.mark();try{d.push(a.getValue())}catch(k){a.rewind();break}}a.addCommand({domain:"core",keyword:"set",lino:c,request:"setArray",target:b.name,value:d});return!0}a.addCommand({domain:"core",keyword:"set",lino:c,request:"setBoolean",target:b.name});return!0}if(a.tokenIs("ready"))return a.next(),a.addCommand({domain:"core",keyword:"set",lino:c,request:"setReady"}),!0;if(a.tokenIs("property")&&(b=a.getNextValue(),a.tokenIs("of")&&a.nextIsSymbol()&&(d= 55 a.getSymbolRecord(),"variable"===d.keyword&&a.nextTokenIs("to")))){var e=a.getNextValue();a.addCommand({domain:"core",keyword:"set",lino:c,request:"setProperty",target:d.name,name:b,value:e});return!0}a.tokenIs("the")&&a.next();if(a.tokenIs("elements")&&(a.next(),a.tokenIs("of"))){a.next();if(!a.isSymbol())throw Error("Unknown variable '"+a.getToken()+"'");b=a.getToken();a.next();if(a.tokenIs("to"))return a.next(),d=a.getValue(),a.addCommand({domain:"core",keyword:"set",lino:c,request:"setElements", 56 symbol:b,value:d}),!0}if(a.tokenIs("encoding")){if(a.nextTokenIs("to"))return b=a.getNextValue(),a.addCommand({domain:"core",keyword:"set",request:"encoding",lino:c,encoding:b}),!0;a.addWarning("Unknown encoding option");return!1}return a.tokenIs("payload")&&a.nextTokenIs("of")&&a.nextIsSymbol()&&(b=a.getSymbolRecord(),"callback"===b.keyword&&a.nextTokenIs("to"))?(d=a.getNextValue(),a.addCommand({domain:"core",keyword:"set",request:"setPayload",lino:c,callback:b.name,payload:d}),!0):!1},run:function(a){var c= 57 a[a.pc];switch(c.request){case "setBoolean":var b=a.getSymbolRecord(c.target);b.isValueHolder?(b.value[b.index]={type:"boolean",content:!0},c.numeric=!1):a.variableDoesNotHoldAValueError(c.lino,b.name);break;case "setReady":a.parent.run(a.parent.nextPc);a.parent.nextPc=0;break;case "setElements":b=a.getSymbolRecord(c.symbol);b.elements=a.getValue(c.value);b.index=0;b.value=[];b.element=[];for(a=0;a<b.elements;a++)b.value.push({}),b.element.push({});break;case "setArray":b=a.getSymbolRecord(c.target); 58 b.elements=c.value.length;b.value=c.value;break;case "encoding":a.encoding=a.getValue(c.encoding);break;case "setProperty":b=a.getSymbolRecord(c.target);var d=a.getValue(b.value[b.index]);d||(d="{}");var e="";try{e=JSON.parse(d)}catch(k){return a.runtimeError(c.lino,"Can't parse "+b.name),0}d=a.getValue(c.name);if(a=a.evaluate(c.value))e[d]=a.content instanceof Array?JSON.stringify(a.content):"boolean"===a.type?a.content:a.numeric?a.content:'{"'===a.content.substr(0,2)?JSON.parse(a.content):a.content.split('"').join('\\"'), 59 b.value[b.index]={type:"constant",numeric:!1,content:JSON.stringify(e)};break;case "setPayload":a.getSymbolRecord(c.callback).payload=a.getValue(c.payload)}return c.pc+1}},Stop:{compile:function(a){var c=a.getLino();a.next();if(a.more()&&a.isSymbol()){var b=a.getSymbolRecord();return"module"===b.keyword?(a.next(),a.addCommand({domain:"core",keyword:"stop",lino:c,name:b.name}),!0):!1}a.addCommand({domain:"core",keyword:"stop",lino:c,next:0});return!0},run:function(a){var c=a[a.pc];if(c.name)a.getSymbolRecord(c.name).program.exit(); 60 else return 0;return c.pc+1}},Take:{compile:function(a){var c=a.getLino();a.next();var b=a.getValue();if(a.tokenIs("from"))if(a.next(),a.isSymbol()){var d=a.getSymbol();if(a.getCommandAt(d.pc).isValueHolder){if("giving"===a.peek()){d=a.getValue();a.next();var g=a.getToken();a.next();a.addCommand({domain:"core",keyword:"take",lino:c,value1:b,value2:d,target:g})}else d=a.getToken(),a.next(),a.addCommand({domain:"core",keyword:"take",lino:c,value1:b,target:d});return!0}a.warning("core "+e.name+": Expected value holder")}else{d= 61 a.getValue();if(a.tokenIs("giving"))return a.next(),g=a.getToken(),a.next(),a.addCommand({domain:"core",keyword:"take",lino:c,value1:b,value2:d,target:g}),!0;a.warning("core "+e.name+': Expected "giving"')}return!1},run:function(a){var c=a[a.pc],b=c.value1,d=c.value2,e=a.getSymbolRecord(c.target);if(e.isValueHolder){var g=e.value[e.index];d?(a=a.getValue(d)-a.getValue(b),e.value[e.index]={type:"constant",numeric:!0,content:a}):(!g.numeric&&isNaN(g.content)&&a.nonNumericValueError(c.lino),a=parseInt(a.getValue(g))- 62 parseInt(a.getValue(b)),e.value[e.index]={type:"constant",numeric:!0,content:a})}else a.variableDoesNotHoldAValueError(c.lino,e.name);return c.pc+1}},Toggle:{compile:function(a){var c=a.getLino();a.next();if(a.isSymbol()){var b=a.getSymbolPc();a.next();a.addCommand({domain:"core",keyword:"toggle",lino:c,symbol:b});return!0}return!1},run:function(a){var c=a[a.pc],b=a[c.symbol];if(b.isValueHolder){var d=a.domain[b.domain];a=d.value.get(a,b.value[b.index]).content;d.value.put(b,{type:"boolean",content:!a})}else a.variableDoesNotHoldAValueError(c.lino, 63 b.name);return c.pc+1}},Variable:{compile:function(a){a.compileVariable("core","variable",!0);return!0},run:function(a){return a[a.pc].pc+1}},Wait:{compile:function(a){var c=a.getLino();a.next();var b=a.getValue(a),d=1E3;switch(a.getToken()){case "milli":case "millis":a.next();d=1;break;case "tick":case "ticks":a.next();d=10;break;case "second":case "seconds":a.next();d=1E3;break;case "minute":case "minutes":a.next(),d=6E4}a.addCommand({domain:"core",keyword:"wait",lino:c,value:b,multiplier:d});return!0}, 64 run:function(a){var c=a[a.pc],b=a.getValue(c.value);setTimeout(function(){a.run(c.pc+1)},b*c.multiplier);return 0}},While:{compile:function(a){var c=a.getLino();a.next();var b=a.getCondition(),d=a.getPc();a.addCommand({domain:"core",keyword:"while",lino:c,condition:b});c=a.getPc();a.addCommand({domain:"core",keyword:"goto",goto:0});a.compileOne();a.addCommand({domain:"core",keyword:"goto",goto:d});a.getCommandAt(c).goto=a.getPc();return!0},run:function(a){return a.condition.test(a,a[a.pc].condition)? 65 a.pc+2:a.pc+1}},getHandler:function(a){switch(a){case "add":return b.Add;case "alias":return b.Alias;case "begin":return b.Begin;case "callback":return b.Callback;case "clear":return b.Clear;case "close":return b.Close;case "debug":return b.Debug;case "decode":return b.Decode;case "divide":return b.Divide;case "encode":return b.Encode;case "end":return b.End;case "exit":return b.Exit;case "fork":return b.Fork;case "go":case "goto":return b.Go;case "gosub":return b.Gosub;case "if":return b.If;case "import":return b.Import; 66 case "index":return b.Index;case "load":return b.Load;case "module":return b.Module;case "multiply":return b.Multiply;case "negate":return b.Negate;case "on":return b.On;case "print":return b.Print;case "put":return b.Put;case "replace":return b.Replace;case "require":return b.Require;case "return":return b.Return;case "run":return b.Run;case "sanitize":return b.Sanitize;case "script":return b.Script;case "send":return b.Send;case "set":return b.Set;case "stop":return b.Stop;case "take":return b.Take; 67 case "toggle":return b.Toggle;case "variable":return b.Variable;case "wait":return b.Wait;case "while":return b.While;default:return!1}},run:function(a){var c=a[a.pc],d=b.getHandler(c.keyword);d||a.runtimeError(c.lino,"Unknown keyword '"+c.keyword+"' in 'core' package");return d.run(a)},isNegate:function(a){return"not"===a.getToken()?(a.next(),!0):!1},value:{compile:function(a){if(a.isSymbol()){var c=a.getToken();switch(a.getSymbolRecord().keyword){case "module":return a.next(),{domain:"core",type:"module", 68 name:c};case "variable":var b=a.nextToken();return["format","modulo"].includes(b)?(a=a.getNextValue(),{domain:"core",type:b,name:c,value:a}):{domain:"core",type:"symbol",name:c}}return null}c=a.getToken();if("true"===c)return a.next(),{domain:"core",type:"boolean",content:!0};if("false"===c)return a.next(),{domain:"core",type:"boolean",content:!1};if("random"===c)return a.next(),{domain:"core",type:"random",range:a.getValue()};if("cos"===c)return a.next(),c=a.getValue(),a.skip("radius"),a=a.getValue(), 69 {domain:"core",type:"cos",angle_c:c,radius_c:a};if("sin"===c)return a.next(),c=a.getValue(),a.skip("radius"),a=a.getValue(),{domain:"core",type:"sin",angle_s:c,radius_s:a};if("tan"===c)return a.next(),c=a.getValue(),a.skip("radius"),a=a.getValue(),{domain:"core",type:"tan",angle_t:c,radius_t:a};if("empty"===c)return a.next(),{domain:"core",type:"empty"};if(["now","today"].includes(c))return a.next(),{domain:"core",type:c};if("newline"===c)return a.next(),{domain:"core",type:"newline"};if("break"=== 70 c)return a.next(),{domain:"core",type:"break"};if(["encode","decode","lowercase","hash"].includes(c))return a.next(),a=a.getValue(),{domain:"core",type:c,value:a};if("element"===c)return c=a.getNextValue(),a.tokenIs("of")&&a.nextIsSymbol()&&(b=a.getSymbolRecord(),a.next(),"variable"===b.keyword)?{domain:"core",type:"element",element:c,symbol:b.name}:null;if("property"===c)return c=a.getNextValue(),a.tokenIs("of")&&a.nextIsSymbol()&&(b=a.getSymbolRecord(),a.next(),"variable"===b.keyword)?{domain:"core", 71 type:"property",property:c,symbol:b.name}:null;a.tokenIs("the")&&a.next();c=a.getToken();switch(c){case "elements":case "index":if(a.nextTokenIs("of")&&a.nextIsSymbol())return b=a.getToken(),a.next(),{domain:"core",type:c,name:b};break;case "value":if(a.nextTokenIs("of"))return a.next(),{domain:"core",type:"valueOf",value:a.getValue()};break;case "length":if(a.nextTokenIs("of"))return a.next(),{domain:"core",type:"lengthOf",value:a.getValue()};break;case "left":case "right":b=a.getNextValue();if(a.tokenIs("of"))return a= 72 a.getNextValue(),{domain:"core",type:c,count:b,value:a};break;case "from":b=a.getNextValue();var d=a.tokenIs("to")?a.getNextValue():null;if(a.tokenIs("of"))return a=a.getNextValue(),{domain:"core",type:c,from:b,to:d,value:a};break;case "position":if(a.nextTokenIs("of")&&(c=!1,a.nextTokenIs("the")&&a.nextTokenIs("last")&&(a.next(),c=!0),b=a.getValue(),a.tokenIs("in")))return a=a.getNextValue(),{domain:"core",type:"position",needle:b,haystack:a,last:c};break;case "payload":if(a.nextTokenIs("of")&&a.nextIsSymbol()&& 73 (c=a.getSymbolRecord(),"callback"===c.keyword))return a.next(),{domain:"core",type:"payload",callback:c.name};break;case "message":case "error":return a.next(),{domain:"core",type:c}}return null},get:function(a,c){switch(c.type){case "boolean":return{type:"boolean",numeric:!1,content:c.content};case "elements":return{type:"constant",numeric:!0,content:a.getSymbolRecord(c.name).elements};case "index":return{type:"constant",numeric:!0,content:a.getSymbolRecord(c.name).index};case "random":return a= 74 a.evaluate(c.range),{type:"constant",numeric:!0,content:Math.floor(Math.random()*a.content)};case "cos":var b=a.getValue(c.angle_c);a=a.getValue(c.radius_c);return{type:"constant",numeric:!0,content:parseInt(Math.cos(.01745329*parseFloat(b))*a,10)};case "sin":return b=a.getValue(c.angle_s),a=a.getValue(c.radius_s),{type:"constant",numeric:!0,content:parseInt(Math.sin(.01745329*parseFloat(b))*a,10)};case "tan":return b=a.getValue(c.angle_t),a=a.getValue(c.radius_t),{type:"constant",numeric:!0,content:parseInt(Math.tan(.01745329* 75 parseFloat(b))*a,10)};case "valueOf":return a=parseInt(a.getValue(c.value)),{type:"constant",numeric:!0,content:a?a:0};case "lengthOf":return{type:"constant",numeric:!0,content:a.getValue(c.value).length};case "left":return{type:"constant",numeric:!1,content:a.getValue(c.value).substr(0,a.getValue(c.count))};case "right":return b=a.getValue(c.value),{type:"constant",numeric:!1,content:b.substr(b.length-a.getValue(c.count))};case "from":b=a.getValue(c.from);var d=c.to?a.getValue(c.to):null;a=a.getValue(c.value); 76 return{type:"constant",numeric:!1,content:d?a.substr(b,d):a.substr(b)};case "position":return b=a.getValue(c.needle),a=a.getValue(c.haystack),{type:"constant",numeric:!0,content:c.last?a.lastIndexOf(b):a.indexOf(b)};case "payload":return{type:"constant",numeric:!1,content:a.getSymbolRecord(c.callback).payload};case "modulo":return b=a.getSymbolRecord(c.name),a=a.evaluate(c.value),{type:"constant",numeric:!0,content:b.value[b.index].content%a.content};case "format":d=a.getSymbolRecord(c.name);d=1E3* 77 a.getValue(d.value[d.index]);try{switch(b=JSON.parse(a.getValue(c.value)),b.mode){case "time":return{type:"constant",numeric:!0,content:(new Date(d)).toLocaleTimeString(b.locale,b.options)};default:return{type:"constant",numeric:!0,content:(new Date(d)).toLocaleDateString(b.locale,b.options)}}}catch(p){a.runtimeError(a[a.pc].lino,"Can't parse "+c.value);break}case "empty":return{type:"constant",numeric:!1,content:""};case "now":return{type:"constant",numeric:!0,content:Math.floor(Date.now()/1E3)}; 78 case "today":return a=new Date,a.setHours(0,0,0,0),{type:"constant",numeric:!0,content:Math.floor(a.getTime()/1E3)};case "newline":return{type:"constant",numeric:!1,content:"\n"};case "break":return{type:"constant",numeric:!1,content:"<br />"};case "encode":return{type:"constant",numeric:!1,content:a.encode(a.getValue(c.value))};case "decode":return{type:"constant",numeric:!1,content:a.decode(a.getValue(c.value))};case "lowercase":return{type:"constant",numeric:!1,content:a.getValue(c.value).toLowerCase()}; 79 case "hash":a=a.getValue(c.value);c=0;if(0===a.length)return c;for(b=0;b<a.length;b++)d=a.charCodeAt(b),c=(c<<5)-c+d;return{type:"constant",numeric:!0,content:c};case "element":b=a.getValue(c.element);c=a.getSymbolRecord(c.symbol);d="";try{d=JSON.parse(a.getValue(c.value[c.index]))[b]}catch(p){a.runtimeError(command.lino,"Can't parse JSON");break}return{type:"constant",numeric:!1,content:"object"===typeof d?JSON.stringify(d):d};case "property":b=a.getValue(c.property);c=a.getSymbolRecord(c.symbol); 80 a=a.getValue(c.value[c.index]);c="";if(b&&a)if("object"===typeof a)c=a[b];else if("{"===a.charAt(0))try{c=JSON.parse(a)[b]}catch(p){console.log("Can't parse '"+a+"': "+p.message)}return{type:"constant",numeric:!isNaN(c),content:"object"===typeof c?JSON.stringify(c):c};case "module":return{type:"boolean",numeric:!1,content:a.getSymbolRecord(c.name).program};case "message":return c=a.message,{type:"constant",numeric:!1,content:c};case "error":return c=a.errorMessage,{type:"constant",numeric:!1,content:c}}return null}, 81 put:function(a,c){a.value[a.index]=c}},condition:{compile:function(a){if(a.isSymbol()){var c=a.getSymbolRecord();if("module"===c.keyword){if(a.nextTokenIs("is")){var d=!0;a.nextTokenIs("not")&&(a.next(),d=!1);if(a.tokenIs("running"))return a.next(),{domain:"core",type:"moduleRunning",name:c.name,sense:d}}return null}}if(a.tokenIs("not"))return{domain:"core",type:"not",value:a.getNextValue()};try{if(d=a.getValue(),"is"===a.getToken()){a.next();var e=b.isNegate(a);switch(a.getToken()){case "numeric":return a.next(), 82 {domain:"core",type:"numeric",value1:d};case "even":return a.next(),{domain:"core",type:"even",value1:d};case "odd":return a.next(),{domain:"core",type:"odd",value1:d};case "greater":a.next();if(a.tokenIs("than")){a.next();var g=a.getValue();return{domain:"core",type:"greater",value1:d,value2:g,negate:e}}break;case "less":a.next();if(a.tokenIs("than")){a.next();var h=a.getValue();return{domain:"core",type:"less",value1:d,value2:h,negate:e}}break;default:var l=a.getValue();return{domain:"core",type:"is", 83 value1:d,value2:l,negate:e}}}else if(d)return{domain:"core",type:"boolean",value:d}}catch(n){return a.warning("Can't get a value"),0}return null},test:function(a,c){switch(c.type){case "boolean":return a.getValue(c.value);case "numeric":return!isNaN(a.getValue(c.value1));case "even":return 0===a.getValue(c.value1)%2;case "odd":return 1===a.getValue(c.value1)%2;case "is":return a=a.compare(a,c.value1,c.value2),c.negate?0!==a:0===a;case "greater":return a=a.compare(a,c.value1,c.value2),c.negate?0>= 84 a:0<a;case "less":return a=a.compare(a,c.value1,c.value2),c.negate?0<=a:0>a;case "not":return!a.getValue(c.value);case "moduleRunning":return a=a.getSymbolRecord(c.name).program,c.sense?a:!a}return!1}}};h.exports=b},{}],6:[function(d,h,g){var e=this,b=d("./Tokenise"),a=d("./Compile"),c=d("./Run"),f=d("./Value"),m=d("./Condition"),p=d("./Compare"),k={domain:{core:d("./Core")},setupTracer:function(){var a=document.getElementById("easycoder-tracer");a&&(a.innerHTML='<div><input id="easycoder-run-button" type="button" value="Run" /><input id="easycoder-step-button" type="button" value="Step" /><div id="easycoder-tracer-content" style="border:1px solid black;padding:4px";width:100%></div>', 85 a.style.display="none")},runtimeError:function(a,c){this.lino=a;this.reportError({message:"Line "+(0<=a?a:"")+": "+c},k.program);program.aborted=!0},nonNumericValueError:function(a){this.runtimeError(a,"Non-numeric value")},variableDoesNotHoldAValueError:function(a,c){this.runtimeError(a,"Variable '"+c+"' does not hold a value")},reportError:function(c,b,d){if(c.message)if(this.compiling||b){d=d?d:b.source;var e=d.tokens;d=d.scriptLines;e=this.compiling?e[a.getIndex()].lino:b[b.pc].lino;b=this.compiling? 86 "Compile error":"Runtime error in '"+b.script+"'";b+=":\n";var f=e-5;for(f=0>f?0:f;f<e;f++){var l=(""+(f+1)).padStart(4," ");b+=l+" "+d[f].line.split("\\s").join(" ")+"\n"}b+=c.message+"\n";c=a.getWarnings();if(c.length)for(b+="Warnings:\n",c=$jscomp.makeIterator(c),d=c.next();!d.done;d=c.next())b+=d.value+"\n";console.log(b);alert(b)}else c="Error: "+c.message,alert(c),console.log(c);else console.log("An error occurred - origin was "+c.path[0])},getSymbolRecord:function(a){a=this[this.symbols[a].pc]; 87 return a.alias?this.getSymbolRecord(a.alias):a.exporter&&a.exporter!=this?a.exporter.getSymbolRecord(a.exportedName):a},verifySymbol:function(a){return this.symbols.hasOwnProperty(a)},encode:function(a){return f.encode(a,this.encoding)},decode:function(a){return f.decode(a,this.encoding)},evaluate:function(a){return f.evaluate(this,a)},getValue:function(a){return f.getValue(this,a)},getFormattedValue:function(a){a=f.evaluate(this,a);return a.numeric?a.content:'{"'===a.content.substr(0,2)||"["===a.content.charAt(0)? 88 JSON.stringify(JSON.parse(a.content),null,2):a.content},getSimpleValue:function(a){return!0===a||!1===a?{type:"boolean",content:a}:{type:"constant",numeric:Number.isInteger(a),content:a}},run:function(a){a&&(k.program=this,c.run(this,a))},exit:function(){c.exit(this)},register:function(a){k.program=a},require:function(a,c,b){var d=document.createElement("css"===a?"link":"script");switch(a){case "css":d.type="text/css";d.href=c;d.rel="stylesheet";break;case "js":d.type="text/javascript";d.src=c;break; 89 default:return}d.onload=function(){console.log(Date.now()-k.timestamp+" ms: Library "+c+" loaded");b()};document.head.appendChild(d)},isUndefined:function(a){return"undefined"===typeof a},runScript:function(a){var c=a[a.pc],b=a.getValue(c.script),d=c.imports,e=c.module?a.getSymbolRecord(c.module):null;k.tokeniseScript(b.split("\n"),d,e,this,c.then);c.nowait&&this.run(a.nextPc)},close:function(){},compileScript:function(c,b,d,e){var g=c.tokens;this.compiling=!0;var h=Date.now();a.value=f;a.condition= 90 m;a.domain=k.domain;a.imports=b;b=a.compile(g);var l=Date.now();console.log(l-k.timestamp+" ms: Compiled "+g.length+" tokens in "+(l-h+" ms"));this.compiling=!1;b.EasyCoder=k;b.value=f;b.condition=m;b.compare=p;b.source=c;b.run=this.run;b.exit=this.exit;b.runScript=this.runScript;b.evaluate=this.evaluate;b.getValue=this.getValue;b.getFormattedValue=this.getFormattedValue;b.getSimpleValue=this.getSimpleValue;b.encode=this.encode;b.decode=this.decode;b.domain=this.domain;b.require=this.require;b.isUndefined= 91 this.isUndefined;b.checkPlugin=this.checkPlugin;b.getPlugin=this.getPlugin;b.addLocalPlugin=this.addLocalPlugin;b.getPluginsPath=this.getPluginsPath;b.getSymbolRecord=this.getSymbolRecord;b.verifySymbol=this.verifySymbol;b.runtimeError=this.runtimeError;b.nonNumericValueError=this.nonNumericValueError;b.variableDoesNotHoldAValueError=this.variableDoesNotHoldAValueError;b.reportError=this.reportError;b.register=this.register;b.symbols=a.getSymbols();b.encoding="ec";b.popups=[];b.stack=[];b.queue=[0]; 92 b.module=d;b.parent=e;d&&(d.program=b);return b},tokeniseScript:function(a,d,e,f,g){var h=null,l=Date.now();a=b.tokenise(a);var m=Date.now();console.log(m-k.timestamp+" ms: Tokenised "+a.scriptLines.length+" lines in "+(m-l+" ms"));try{h=k.compileScript(a,d,e,f)}catch(u){"stop"!==u.message&&this.reportError(u,k.program,a)}this.setupTracer();h&&(h.onExit=g,c.run(h,0))},tokenize:function(a){var b=a.split("\n");if(!e.tokenising){try{k.tokeniseScript(b)}catch(q){k.reportError(q,null,a)}e.tokenising=!0}}, 93 setPluginCount:function(a){e.plugins=[];e.pluginCount=a},checkPlugin:function(a){return k.domain[a]},getPlugin:function(a,b,c){k.domain[a]?c():(a=document.createElement("script"),a.type="text/javascript",a.src=b+"?ver="+k.version,a.onload=function(){console.log(Date.now()-k.timestamp+" ms: Plugin "+b+" loaded");c()},document.head.appendChild(a))},addGlobalPlugin:function(a,b){e.plugins.push({name:a,handler:b});e.plugins.length===e.pluginCount&&(e.plugins.forEach(function(a){k.domain[a.name]=a.handler}), 94 k.tokenize(e.source))},addLocalPlugin:function(a,b,c){k.domain[a]=b;c()},getPluginsPath:function(){return k.pluginsPath},loadPluginJs:function(a){console.log(Date.now()-k.timestamp+" ms: Load "+a+"/easycoder/plugins.js");var b=document.createElement("script");b.src=""+window.location.origin+a+"/easycoder/plugins.js?ver="+k.version;b.type="text/javascript";b.onload=function(){EasyCoder_Plugins.getGlobalPlugins(k.timestamp,a,k.setPluginCount,k.getPlugin,k.addGlobalPlugin)};b.onerror=function(){a?k.loadPluginJs(a.slice(0, 95 a.lastIndexOf("/"))):k.reportError({message:"Can't load plugins.js"},k.program,e.source)};document.head.appendChild(b);k.pluginsPath=a},start:function(a){e.source=a;a=window.location.pathname;a=a.endsWith("/")?a.slice(0,-1):"";k.loadPluginJs(a)}};h.exports=k},{"./Compare":2,"./Compile":3,"./Condition":4,"./Core":5,"./Run":7,"./Tokenise":8,"./Value":9}],7:[function(d,h,g){var e={run:function(b,a){var c=[],d=function(a){var b=9999;a.forEach(function(a){a=a.line;for(var c=0;c<a.length&&" "===a[c];)c++; 96 0<c&&c<b&&(b=c)});return 0};if(c.length)c.push(a);else for(b.register(b),c.push(a);0<c.length;)for(b.pc=c.shift(),b.watchdog=0,a={};;){if(1E6<b.watchdog){b.lino=b[b.pc].lino;b.reportError(Error("Program runaway intercepted.\nHave you forgotten to increment a loop counter?",b),b);break}b.watchdog++;var g=b[b.pc].domain;b.debugStep&&console.log(b.script+" "+b.pc+" "+g+":"+b[b.pc].keyword);var h=b.domain[g];if(!h){b.runtimeError(b[b.pc].lino,"Unknown domain '"+g+"'");break}b.pc=h.run(b);if(!b.pc)break; 97 if(b.stop){b.tracing=!1;break}if(b.tracing){g=b[b.pc];h=b.source.scriptLines;var k=d(h),l=document.getElementById("easycoder-tracer");if(!l){b.runtimeError(g.lino,"Element 'easycoder-tracer' was not found");return}l.style.display="block";l.style.visibility="visible";var n="";if(b.tracer){if(l=document.getElementById("easycoder-tracer-content")){b.tracer.variables.forEach(function(a,c,d){var e=b.getSymbolRecord(a);if(1<e.elements)for(n+=a+": "+e.index+"/"+e.elements+": ",a=0;a<e.elements;a++){var f= 98 e.value[a];n=f?n+(f.content+" "):n+"undefined "}else n=(e=e.value[e.index])?n+(a+": "+e.content):n+(a+": undefined");switch(b.tracer.alignment){case "horizontal":c<d.length-1&&(n+=", ");break;case "vertical":n+="<br>"}});n+="<hr>";for(var q="",r=5;0<r;r--)g.lino&&(q+='<input type="text" name="'+r+'"'+('value="'+h[g.lino-r].line.substr(k)+'"')+'style="width:100%;border:none;enabled:false">'),q+="<br>";l.innerHTML=n+" "+q;l.style.display="block";a.run=document.getElementById("easycoder-run-button"); 99 a.step=document.getElementById("easycoder-step-button");a.run.onclick=function(a){return function(){a.run.blur();b.tracing=!1;document.getElementById("easycoder-tracer-content").style.display="none";try{e.run(b,b.resume)}catch(t){var c="Error in run handler: "+t.message;console.log(c);alert(c)}}}(a);a.step.onclick=function(a){return function(){console.log("step");a.step.blur();b.tracing=!0;document.getElementById("easycoder-tracer-content").style.display="block";try{b.run(b.resume)}catch(t){var c= 100 "Error in step handler: "+t.message;console.log(c);alert(c)}}}(a)}b.resume=b.pc;b.pc=0}break}a={run:a.run,step:a.step}}},exit:function(b){b.onExit&&(b.parent.run(b.onExit),b.module.program=null)}};h.exports=e},{}],8:[function(d,h,g){var e={markComments:function(b){var a=b.list,c=void 0===b.index?0:b.index,d=void 0===b.inComment?!1:b.inComment,g=void 0===b.newList?[]:b.newList;if(c>=a.length)return g;var h=a[c];b=h.lino;h=h.token;var k={list:a,index:c+1,inComment:!1,newList:g.concat({lino:b,index:c, 101 token:h})};g={list:a,index:c+1,inComment:!0,newList:g.concat({lino:b,index:c,comment:!0,token:h})};return d&&0<c&&b===a[c-1].lino?e.markComments(g):"!"===h.charAt(0)?e.markComments(g):e.markComments(k)},findStrings:function(b){var a=b.original,c=b.line,d=void 0===b.inComment?!1:b.inComment;b=void 0===b.inQuote?!1:b.inQuote;var g=c.charAt(0),h=b&&[" ","\\t"].includes(g)?"\\s":g;if(1===c.length)return h;c=c.substring(1);if("!"===g&&!b)return g+e.findStrings({original:a,line:c,inComment:!0,inQuote:!1}); 102 if("`"===g&&!d&&!b)return g+e.findStrings({original:a,line:c,inComment:d,inQuote:!0});if("`"===g&&b)return g+e.findStrings({original:a,line:c,inComment:d,inQuote:!1});if(!d&&!b&&!g.match(/[A-z0-9_\-+*/\- \t]/)){if(["'",'"'].includes(g))throw Error('Bad syntax in "'+a+'":\nStrings in EasyCoder must be enclosed in backticks.');throw Error('Unrecognised character "'+g+'" in\n"'+a+'".');}return h+e.findStrings({original:a,line:c,inComment:d,inQuote:b})},tokenise:function(b){b=b.map(function(a){var b= 103 a.trim();return b.length?e.findStrings({original:a,line:b}):""}).map(function(a,b){return{lino:b+1,line:a}});var a=b.map(function(a){return a.line.trim().split(/\s+/).map(function(b,c){return{lino:a.lino,index:c,token:b}})});a=[].concat.apply([],a).filter(function(a){return a.token}).map(function(a){return{lino:a.lino,index:a.index,token:a.token.split("\\s").join(" ")}});a=e.markComments({list:a}).filter(function(a){return!a.comment});return{scriptLines:b,tokens:a}}};h.exports=e},{}],9:[function(d, 104 h,g){var e={getItem:function(b){var a=b.getToken();if(!a)return null;if("true"===a)return b.next(),{type:"boolean",content:!0};if("false"===a)return b.next(),{type:"boolean",content:!1};if("`"===a.charAt(0))return b.next(),{type:"constant",numeric:!1,content:a.substring(1,a.length-1)};if(a.charAt(0).match(/[0-9-]/)){var c=eval(a);if(Number.isInteger(c))return b.next(),{type:"constant",numeric:!0,content:c};throw Error("'"+a+"' is not an integer");}a=b.getIndex();c=$jscomp.makeIterator(Object.keys(b.domain)); 105 for(var d=c.next();!d.done;d=c.next())if(d=d.value,b.rewindTo(a),d=b.domain[d].value.compile(b))return d;return null},compile:function(b){var a=b.getToken(),c=e.getItem(b);if(!c)throw Error("Undefined value: '"+a+"'");if("cat"===b.getToken()){for(a={type:"cat",numeric:!1,parts:[c]};b.tokenIs("cat");)b.next(),a.parts.push(b.value.getItem(b));return a}return c},doValue:function(b,a){if("undefined"===typeof a.type)return b.runtimeError(b[b.pc].lino,"Undefined value (variable not initialized?)"),null; 106 switch(a.type){case "cat":return{type:"constant",numeric:!1,content:a.parts.reduce(function(a,c){return a+e.doValue(b,c).content},"")};case "boolean":case "constant":return a;case "symbol":var c=b.getSymbolRecord(a.name);if(c.isValueHolder){if(a=c.value[c.index]){c=a.content;if(null===c||"undefined"===typeof c)a.content=a.numeric?0:"";return a}return null}return b.domain[c.domain].value.get(b,a)}return b.domain[a.domain].value.get(b,a)},constant:function(b,a){return{type:"constant",numeric:a,content:b}}, 107 evaluate:function(b,a){if(!a)return{type:"constant",numeric:!1,content:""};var c=e.doValue(b,a);if(c)return c;b.runtimeError(b[b.pc].lino,"Can't decode value: "+a)},getValue:function(b,a){return e.evaluate(b,a).content},encode:function(b,a){if(b)switch(a){case "ec":return b.replace(/'/g,"~sq~").replace(/"/g,"~dq~").replace(/\n/g,"%0a").replace(/\r/g,"%0d");case "url":return encodeURIComponent(b.replace(/\s/g,"+"));case "sanitize":return b.normalize("NFD").replace(/[\u0300-\u036f]/g,"")}return b}, 108 decode:function(b,a){if(b)switch(a){case "ec":return b.replace(/~dq~/g,'"').replace(/~sq~/g,"'").replace(/%0a/g,"\n").replace(/%0d/g,"\r");case "url":return decodeURIComponent(b).replace(/\+/g," ")}return b}};h.exports=e},{}]},{},[1]); -
easycoder/trunk/easycoder.js
r2089142 r2102119 4 4 const EasyCoder = require(`./easycoder/Main`); 5 5 6 EasyCoder.version = `2.3. 0`;6 EasyCoder.version = `2.3.1`; 7 7 EasyCoder.timestamp = Date.now(); 8 8 console.log(`EasyCoder loaded; waiting for page`); … … 91 91 }, 92 92 93 more: () => { 94 return _this.index < _this.tokens.length; 95 }, 96 93 97 getToken: () => { 94 98 if (_this.index >= _this.tokens.length) { … … 356 360 EasyCoder_Compiler.addCommand({ 357 361 domain: `core`, 358 keyword: ` stop`,362 keyword: `exit`, 359 363 lino: EasyCoder_Compiler.getLino(), 360 364 next: 0 … … 490 494 }; 491 495 } else { 492 if (!value.numeric ) {496 if (!value.numeric && isNaN(value.content)) { 493 497 program.nonNumericValueError(command.lino); 494 498 } 495 const result = value.content + program.getValue(value1);499 const result = parseInt(value.content) + parseInt(program.getValue(value1)); 496 500 target.value[target.index] = { 497 501 type: `constant`, … … 576 580 } 577 581 }, 582 578 583 Clear: { 579 584 … … 665 670 keyword: `debug`, 666 671 lino, 667 item: -1672 item: `program` 668 673 }); 669 674 return true; … … 718 723 program.debugStep = true; 719 724 break; 725 case `program`: 726 console.log(`Debug program: ${JSON.stringify(program, null, 2)}`); 727 break; 720 728 default: 721 729 if (item.content >= 0) { 722 730 console.log(`Debug item ${item.content}: ${JSON.stringify(program[item.content], null, 2)}`); 723 } else {724 console.log(`Debug program: ${JSON.stringify(program, null, 2)}`);725 731 } 726 732 break; … … 834 840 }; 835 841 } else { 836 if (!value.numeric ) {842 if (!value.numeric && isNaN(value.content)) { 837 843 program.nonNumericValueError(command, lino); 838 844 } 839 const result = value.content / program.getValue(value2);845 const result = parseInt(value.content) / parseInt(program.getValue(value2)); 840 846 target.value[target.index] = { 841 847 type: `constant`, … … 896 902 897 903 run: () => { 904 return 0; 905 } 906 }, 907 908 Exit: { 909 910 compile: compiler => { 911 compiler.next(); 912 compiler.addCommand({ 913 domain: `core`, 914 keyword: `exit` 915 }); 916 return true; 917 }, 918 919 run: program => { 920 program.exit(); 898 921 return 0; 899 922 } … … 1240 1263 }; 1241 1264 } else { 1242 if (!value.numeric ) {1265 if (!value.numeric && isNaN(value.content)) { 1243 1266 program.nonNumericValueError(command, lino); 1244 1267 } 1245 const result = value.content * program.getValue(value2);1268 const result = parseInt(value.content) * parseInt(program.getValue(value2)); 1246 1269 target.value[target.index] = { 1247 1270 type: `constant`, … … 1298 1321 const action = compiler.nextToken(); 1299 1322 switch (action) { 1300 case `trigger`:1301 1323 case `close`: 1302 1324 case `restore`: … … 1331 1353 const cb = command.pc + 2; 1332 1354 switch (command.action) { 1333 case `trigger`:1334 program.onTrigger = cb;1335 break;1336 1355 case `close`: 1337 1356 program.onClose = cb; … … 1383 1402 compile: compiler => { 1384 1403 const lino = compiler.getLino(); 1385 compiler.next();1386 1404 // Get the value 1387 const value = compiler.get Value();1405 const value = compiler.getNextValue(); 1388 1406 if (compiler.tokenIs(`into`)) { 1389 compiler.next(); 1390 if (compiler.isSymbol()) { 1407 if (compiler.nextIsSymbol()) { 1391 1408 const target = compiler.getToken(); 1392 1409 compiler.next(); … … 1444 1461 }); 1445 1462 return true; 1463 } else { 1464 throw new Error(`'${targetRecord.name}' does not hold a value`); 1446 1465 } 1447 1466 } … … 1539 1558 } 1540 1559 } 1541 varmodule;1560 let module; 1542 1561 if (compiler.tokenIs(`as`)) { 1543 1562 if (compiler.nextIsSymbol(true)) { … … 1550 1569 } 1551 1570 } 1571 let nowait = false; 1572 if (compiler.tokenIs(`nowait`)) { 1573 compiler.next(); 1574 nowait = true; 1575 } 1576 const pc = compiler.getPc(); 1552 1577 compiler.addCommand({ 1553 1578 domain: `core`, … … 1556 1581 script, 1557 1582 imports, 1558 module 1583 module, 1584 nowait, 1585 then: 0 1559 1586 }); 1587 // Get the 'then' code, if any 1588 if (compiler.tokenIs(`then`)) { 1589 const goto = compiler.getPc(); 1590 // Add a 'goto' to skip the 'then' 1591 compiler.addCommand({ 1592 domain: `core`, 1593 keyword: `goto`, 1594 goto: 0 1595 }); 1596 // Fixup the link to the 'then' branch 1597 compiler.getCommandAt(pc).then = compiler.getPc(); 1598 // Process the 'then' branch 1599 compiler.next(); 1600 compiler.compileOne(true); 1601 compiler.addCommand({ 1602 domain: `core`, 1603 keyword: `stop` 1604 }); 1605 // Fixup the 'goto' 1606 compiler.getCommandAt(goto).goto = compiler.getPc(); 1607 } 1560 1608 return true; 1561 1609 }, … … 1833 1881 case `setReady`: 1834 1882 program.parent.run(program.parent.nextPc); 1883 program.parent.nextPc = 0; 1835 1884 break; 1836 1885 case `setElements`: … … 1869 1918 const itemValue = program.evaluate(command.value); 1870 1919 if (itemValue) { 1871 if (itemValue.type === `boolean`) { 1920 if (itemValue.content instanceof Array) { 1921 targetJSON[itemName] = JSON.stringify(itemValue.content); 1922 } else if (itemValue.type === `boolean`) { 1872 1923 targetJSON[itemName] = itemValue.content; 1873 1924 } else { … … 1896 1947 const lino = compiler.getLino(); 1897 1948 compiler.next(); 1949 if (compiler.more() && compiler.isSymbol()) { 1950 const symbolRecord = compiler.getSymbolRecord(); 1951 if (symbolRecord.keyword === `module`) { 1952 compiler.next(); 1953 compiler.addCommand({ 1954 domain: `core`, 1955 keyword: `stop`, 1956 lino, 1957 name: symbolRecord.name 1958 }); 1959 return true; 1960 } else { 1961 return false; 1962 } 1963 } 1898 1964 compiler.addCommand({ 1899 1965 domain: `core`, … … 1905 1971 }, 1906 1972 1907 run: () => { 1908 return 0; 1973 run: program => { 1974 const command = program[program.pc]; 1975 if (command.name) { 1976 const symbolRecord = program.getSymbolRecord(command.name); 1977 symbolRecord.program.exit(); 1978 } else { 1979 return 0; 1980 } 1981 return command.pc + 1; 1909 1982 } 1910 1983 }, … … 1992 2065 }; 1993 2066 } else { 1994 if (!value.numeric ) {1995 program.nonNumericValueError(command ,lino);1996 } 1997 const result = p rogram.getValue(value) - program.getValue(value1);2067 if (!value.numeric && isNaN(value.content)) { 2068 program.nonNumericValueError(command.lino); 2069 } 2070 const result = parseInt(program.getValue(value)) - parseInt(program.getValue(value1)); 1998 2071 target.value[target.index] = { 1999 2072 type: `constant`, … … 2175 2248 case `end`: 2176 2249 return EasyCoder_Core.End; 2250 case `exit`: 2251 return EasyCoder_Core.Exit; 2177 2252 case `fork`: 2178 2253 return EasyCoder_Core.Fork; … … 2379 2454 }; 2380 2455 } 2381 if ( token === `encode`) {2456 if ([`encode`, `decode`, `lowercase`, `hash`].includes(token)) { 2382 2457 compiler.next(); 2383 2458 const value = compiler.getValue(); 2384 2459 return { 2385 2460 domain: `core`, 2386 type: `encode`, 2387 value 2388 }; 2389 } 2390 if (token === `decode`) { 2391 compiler.next(); 2392 const value = compiler.getValue(); 2393 return { 2394 domain: `core`, 2395 type: `decode`, 2396 value 2397 }; 2398 } 2399 if (token === `lowercase`) { 2400 compiler.next(); 2401 const value = compiler.getValue(); 2402 return { 2403 domain: `core`, 2404 type: `lowercase`, 2461 type: token, 2405 2462 value 2406 2463 }; … … 2740 2797 content: program.getValue(value.value).toLowerCase() 2741 2798 }; 2799 case `hash`: 2800 const hashval = program.getValue(value.value); 2801 let hash = 0; 2802 if (hashval.length === 0) return hash; 2803 for (let i = 0; i < hashval.length; i++) { 2804 const chr = hashval.charCodeAt(i); 2805 hash = (hash << 5) - hash + chr; 2806 // hash |= 0; // Convert to 32bit integer 2807 } 2808 return { 2809 type: `constant`, 2810 numeric: true, 2811 content: hash 2812 }; 2742 2813 case `element`: 2743 2814 const element = program.getValue(value.element); … … 2773 2844 return { 2774 2845 type: `constant`, 2775 numeric: Number.isInteger(content),2846 numeric: !isNaN(content), 2776 2847 content: typeof content === `object` ? JSON.stringify(content) : content 2777 2848 }; … … 2808 2879 2809 2880 compile: compiler => { 2881 if (compiler.isSymbol()) { 2882 const symbolRecord = compiler.getSymbolRecord(); 2883 if (symbolRecord.keyword === `module`) { 2884 if (compiler.nextTokenIs(`is`)) { 2885 let sense = true; 2886 if (compiler.nextTokenIs(`not`)) { 2887 compiler.next(); 2888 sense = false; 2889 } 2890 if (compiler.tokenIs(`running`)) { 2891 compiler.next(); 2892 return { 2893 domain: `core`, 2894 type: `moduleRunning`, 2895 name: symbolRecord.name, 2896 sense 2897 }; 2898 } 2899 } 2900 return null; 2901 } 2902 } 2810 2903 if (compiler.tokenIs(`not`)) { 2811 compiler.next(); 2812 const value = compiler.getValue(); 2904 const value = compiler.getNextValue(); 2813 2905 return { 2814 2906 domain: `core`, … … 2905 2997 return program.getValue(condition.value); 2906 2998 case `numeric`: 2907 return Number.isInteger(program.getValue(condition.value1));2999 return !isNaN(program.getValue(condition.value1)); 2908 3000 case `even`: 2909 3001 return program.getValue(condition.value1) % 2 === 0; … … 2921 3013 case `not`: 2922 3014 return !program.getValue(condition.value); 3015 case `moduleRunning`: 3016 const running = program.getSymbolRecord(condition.name).program; 3017 return condition.sense ? running : !running; 2923 3018 } 2924 3019 return false; … … 2958 3053 message: `Line ${lino >= 0 ? lino : ``}: ${message}` 2959 3054 }, EasyCoder.program); 3055 program.aborted = true; 2960 3056 }, 2961 3057 nonNumericValueError: function (lino) { … … 3001 3097 console.log(errString); 3002 3098 alert(errString); 3003 EasyCoder.aborted = true;3004 3099 }, 3005 3100 … … 3065 3160 if (pc) { 3066 3161 EasyCoder.program = this; 3067 EasyCoder_Run(this, pc); 3068 } 3069 }, 3070 3071 trigger: function () { 3072 if (this.onTrigger) { 3073 EasyCoder_Run(this, this.onTrigger); 3074 } 3162 EasyCoder_Run.run(this, pc); 3163 } 3164 }, 3165 3166 exit: function () { 3167 EasyCoder_Run.exit(this); 3075 3168 }, 3076 3169 … … 3109 3202 const script = program.getValue(command.script); 3110 3203 const imports = command.imports; 3111 const module = command.module ? program.getSymbolRecord(command.module) : null; 3112 EasyCoder.tokeniseScript(script.split(`\n`), imports, module, this); 3204 const moduleRecord = command.module ? program.getSymbolRecord(command.module) : null; 3205 EasyCoder.tokeniseScript(script.split(`\n`), imports, moduleRecord, this, command.then); 3206 if (command.nowait) { 3207 this.run(program.nextPc); 3208 } 3113 3209 }, 3114 3210 … … 3138 3234 program.source = source; 3139 3235 program.run = this.run; 3236 program.exit = this.exit; 3140 3237 program.runScript = this.runScript; 3141 3238 program.evaluate = this.evaluate; … … 3146 3243 program.decode = this.decode; 3147 3244 program.domain = this.domain; 3148 program.trigger = this.trigger;3149 3245 program.require = this.require; 3150 3246 program.isUndefined = this.isUndefined; … … 3173 3269 }, 3174 3270 3175 tokeniseScript: function (file, imports, module, parent ) {3271 tokeniseScript: function (file, imports, module, parent, then) { 3176 3272 // console.log('Tokenise script: '); 3177 3273 let program = null; … … 3189 3285 } 3190 3286 this.setupTracer(); 3191 // console.log('Run the script');3192 3287 if (program) { 3193 // console.log('Program: '+ JSON.stringify(program, null, 2));3194 EasyCoder_Run (program, 0);3288 program.onExit = then; 3289 EasyCoder_Run.run(program, 0); 3195 3290 } 3196 3291 }, … … 3277 3372 start: source => { 3278 3373 _this.source = source; 3279 varpathname = window.location.pathname;3374 let pathname = window.location.pathname; 3280 3375 if (pathname.endsWith(`/`)) { 3281 3376 pathname = pathname.slice(0, -1); 3377 } else { 3378 pathname = ``; 3282 3379 } 3283 3380 EasyCoder.loadPluginJs(pathname); … … 3287 3384 module.exports = EasyCoder; 3288 3385 },{"./Compare":2,"./Compile":3,"./Condition":4,"./Core":5,"./Run":7,"./Tokenise":8,"./Value":9}],7:[function(require,module,exports){ 3289 const EasyCoder_Run = (program, pc) => { 3290 3291 const queue = []; 3292 3293 const minIndent = scriptLines => { 3294 var count = 9999; 3295 scriptLines.forEach(function (element) { 3296 const item = element.line; 3297 var n = 0; 3298 while (n < item.length) { 3299 if (item[n] !== ` `) { 3386 const EasyCoder_Run = { 3387 3388 run: (program, pc) => { 3389 3390 const queue = []; 3391 3392 const minIndent = scriptLines => { 3393 var count = 9999; 3394 scriptLines.forEach(function (element) { 3395 const item = element.line; 3396 var n = 0; 3397 while (n < item.length) { 3398 if (item[n] !== ` `) { 3399 break; 3400 } 3401 n++; 3402 } 3403 if (n > 0 && n < count) { 3404 count = n; 3405 } 3406 }); 3407 return 0; 3408 }; 3409 3410 if (queue.length) { 3411 queue.push(pc); 3412 return; 3413 } 3414 program.register(program); 3415 queue.push(pc); 3416 while (queue.length > 0) { 3417 program.pc = queue.shift(); 3418 program.watchdog = 0; 3419 while (true) { 3420 if (program.watchdog > 1000000) { 3421 program.lino = program[program.pc].lino; 3422 program.reportError(new Error(`Program runaway intercepted.\nHave you forgotten to increment a loop counter?`, program), program); 3300 3423 break; 3301 3424 } 3302 n++; 3303 } 3304 if (n > 0 && n < count) { 3305 count = n; 3306 } 3307 }); 3308 return 0; 3309 // return count; 3310 }; 3311 3312 if (queue.length) { 3313 queue.push(pc); 3314 return; 3315 } 3316 program.register(program); 3317 queue.push(pc); 3318 while (queue.length > 0) { 3319 if (EasyCoder.aborted) { 3320 break; 3321 } 3322 program.pc = queue.shift(); 3323 program.watchdog = 0; 3324 while (true) { 3325 if (program.watchdog > 1000000) { 3326 program.lino = program[program.pc].lino; 3327 program.reportError(new Error(`Program runaway intercepted.\nHave you forgotten to increment a loop counter?`, program), program); 3328 break; 3329 } 3330 program.watchdog++; 3331 const domain = program[program.pc].domain; 3332 if (program.debugStep) { 3333 console.log(`${program.script} ${program.pc} ${domain}:${program[program.pc].keyword}`); 3334 // console.log(`${program.script} ${program.pc} ${domain}:${program.source.scriptLines[program[program.pc].lino].line}`); 3335 } 3336 const handler = program.domain[domain]; 3337 if (!handler) { 3338 program.runtimeError(program[program.pc].lino, `Unknown domain '${domain}'`); 3339 break; 3340 } 3341 program.pc = handler.run(program); 3342 if (!program.pc) { 3343 break; 3344 } 3345 if (program.stop) { 3346 program.tracing = false; 3347 return; 3348 } 3349 if (program.tracing) { 3350 const command = program[program.pc]; 3351 const scriptLines = program.source.scriptLines; 3352 const minSpace = minIndent(scriptLines); 3353 const tracer = document.getElementById(`easycoder-tracer`); 3354 if (!tracer) { 3355 program.runtimeError(command.lino, `Element 'easycoder-tracer' was not found`); 3356 return; 3357 } 3358 tracer.style.display = `block`; 3359 tracer.style.visibility = `visible`; 3360 var variables = ``; 3361 if (program.tracer) { 3362 const content = document.getElementById(`easycoder-tracer-content`); 3363 if (content) { 3364 program.tracer.variables.forEach(function (name, index, array) { 3365 const symbol = program.getSymbolRecord(name); 3366 if (symbol.elements > 1) { 3367 variables += `${name}: ${symbol.index}/${symbol.elements}: `; 3368 for (var n = 0; n < symbol.elements; n++) { 3369 const value = symbol.value[n]; 3425 program.watchdog++; 3426 const domain = program[program.pc].domain; 3427 if (program.debugStep) { 3428 console.log(`${program.script} ${program.pc} ${domain}:${program[program.pc].keyword}`); 3429 } 3430 const handler = program.domain[domain]; 3431 if (!handler) { 3432 program.runtimeError(program[program.pc].lino, `Unknown domain '${domain}'`); 3433 break; 3434 } 3435 program.pc = handler.run(program); 3436 if (!program.pc) { 3437 break; 3438 } 3439 if (program.stop) { 3440 program.tracing = false; 3441 break; 3442 } 3443 if (program.tracing) { 3444 const command = program[program.pc]; 3445 const scriptLines = program.source.scriptLines; 3446 const minSpace = minIndent(scriptLines); 3447 const tracer = document.getElementById(`easycoder-tracer`); 3448 if (!tracer) { 3449 program.runtimeError(command.lino, `Element 'easycoder-tracer' was not found`); 3450 return; 3451 } 3452 tracer.style.display = `block`; 3453 tracer.style.visibility = `visible`; 3454 var variables = ``; 3455 if (program.tracer) { 3456 const content = document.getElementById(`easycoder-tracer-content`); 3457 if (content) { 3458 program.tracer.variables.forEach(function (name, index, array) { 3459 const symbol = program.getSymbolRecord(name); 3460 if (symbol.elements > 1) { 3461 variables += `${name}: ${symbol.index}/${symbol.elements}: `; 3462 for (var n = 0; n < symbol.elements; n++) { 3463 const value = symbol.value[n]; 3464 if (value) { 3465 variables += `${value.content} `; 3466 } else { 3467 variables += `undefined `; 3468 } 3469 } 3470 } else { 3471 const value = symbol.value[symbol.index]; 3370 3472 if (value) { 3371 variables += `${ value.content}`;3473 variables += `${name}: ${value.content}`; 3372 3474 } else { 3373 variables += ` undefined`;3475 variables += `${name}: undefined`; 3374 3476 } 3375 3477 } 3376 } else { 3377 const value = symbol.value[symbol.index]; 3378 if (value) { 3379 variables += `${name}: ${value.content}`; 3380 } else { 3381 variables += `${name}: undefined`; 3478 switch (program.tracer.alignment) { 3479 case `horizontal`: 3480 if (index < array.length - 1) { 3481 variables += `, `; 3482 } 3483 break; 3484 case `vertical`: 3485 variables += `<br>`; 3486 break; 3382 3487 } 3488 }); 3489 variables += `<hr>`; 3490 var trace = ``; 3491 for (var n = 5; n > 0; n--) { 3492 if (command.lino) { 3493 trace += `<input type="text" name="${n}"` + `value="${scriptLines[command.lino - n].line.substr(minSpace)}"` + `style="width:100%;border:none;enabled:false">`; 3494 } 3495 trace += `<br>`; 3383 3496 } 3384 switch (program.tracer.alignment) { 3385 case `horizontal`: 3386 if (index < array.length - 1) { 3387 variables += `, `; 3388 } 3389 break; 3390 case `vertical`: 3391 variables += `<br>`; 3392 break; 3393 } 3394 }); 3395 variables += `<hr>`; 3396 var trace = ``; 3397 for (var n = 5; n > 0; n--) { 3398 if (command.lino) { 3399 trace += `<input type="text" name="${n}"` + `value="${scriptLines[command.lino - n].line.substr(minSpace)}"` + `style="width:100%;border:none;enabled:false">`; 3400 } 3401 trace += `<br>`; 3497 content.innerHTML = `${variables} ${trace}`; 3498 content.style.display = `block`; 3499 const run = document.getElementById(`easycoder-run-button`); 3500 const step = document.getElementById(`easycoder-step-button`); 3501 3502 run.onclick = function () { 3503 run.blur(); 3504 program.tracing = false; 3505 const content = document.getElementById(`easycoder-tracer-content`); 3506 content.style.display = `none`; 3507 try { 3508 EasyCoder_Run.run(program, program.resume); 3509 } catch (err) { 3510 const message = `Error in run handler: ` + err.message; 3511 console.log(message); 3512 alert(message); 3513 } 3514 }; 3515 3516 step.onclick = function () { 3517 console.log(`step`); 3518 step.blur(); 3519 program.tracing = true; 3520 const content = document.getElementById(`easycoder-tracer-content`); 3521 content.style.display = `block`; 3522 try { 3523 program.run(program.resume); 3524 } catch (err) { 3525 const message = `Error in step handler: ` + err.message; 3526 console.log(message); 3527 alert(message); 3528 } 3529 }; 3402 3530 } 3403 content.innerHTML = `${variables} ${trace}`; 3404 content.style.display = `block`; 3405 const run = document.getElementById(`easycoder-run-button`); 3406 const step = document.getElementById(`easycoder-step-button`); 3407 3408 run.onclick = function () { 3409 run.blur(); 3410 program.tracing = false; 3411 const content = document.getElementById(`easycoder-tracer-content`); 3412 content.style.display = `none`; 3413 try { 3414 EasyCoder_Run(program, program.resume); 3415 } catch (err) { 3416 const message = `Error in run handler: ` + err.message; 3417 console.log(message); 3418 alert(message); 3419 } 3420 }; 3421 3422 step.onclick = function () { 3423 console.log(`step`); 3424 step.blur(); 3425 program.tracing = true; 3426 const content = document.getElementById(`easycoder-tracer-content`); 3427 content.style.display = `block`; 3428 try { 3429 EasyCoder_Run(program, program.resume); 3430 } catch (err) { 3431 const message = `Error in step handler: ` + err.message; 3432 console.log(message); 3433 alert(message); 3434 } 3435 }; 3436 } 3437 3438 program.resume = program.pc; 3439 program.pc = 0; 3440 } 3441 break; 3442 } 3531 3532 program.resume = program.pc; 3533 program.pc = 0; 3534 } 3535 break; 3536 } 3537 } 3538 } 3539 }, 3540 3541 exit: program => { 3542 if (program.onExit) { 3543 program.parent.run(program.onExit); 3544 program.module.program = null; 3545 program = null; 3443 3546 } 3444 3547 } -
easycoder/trunk/easycoder.php
r2089142 r2102119 4 4 * Plugin URI: https://easycoder.software 5 5 * Description: Control the appearance and behavior of your posts and pages by embedding simple English-like scripts, without the need to learn JavaScript. 6 * Version: 2.3. 06 * Version: 2.3.1 7 7 * Author: EasyCoder Software 8 8 * Author URI: https://easycoder.software … … 17 17 function easycoder_enqueue_script() { 18 18 wp_enqueue_script('easycoder_script', plugin_dir_url( __FILE__ ) 19 . 'easycoder-min.js', array(), '2. 2.6');19 . 'easycoder-min.js', array(), '2.3.1'); 20 20 } 21 21 -
easycoder/trunk/plugins-sample.js
r2089142 r2102119 99 99 break; 100 100 } 101 }, 102 103 rest: () => { 104 return `wp-content/plugins/easycoder/rest.php`; 101 105 } 102 106 }; -
easycoder/trunk/plugins/browser.js
r2086338 r2102119 45 45 const symbol = compiler.getSymbolRecord(); 46 46 switch (symbol.keyword) { 47 case `a`: 48 case `blockquote`: 49 case `button`: 50 case `div`: 51 case `fieldset`: 52 case `file`: 53 case `form`: 54 case `h1`: 55 case `h2`: 56 case `h3`: 57 case `h4`: 58 case `h5`: 59 case `h6`: 60 case `img`: 61 case `input`: 62 case `label`: 63 case `legend`: 64 case `li`: 65 case `p`: 66 case `pre`: 67 case `select`: 68 case `span`: 69 case `table`: 70 case `td`: 71 case `text`: 72 case `textarea`: 73 case `tr`: 74 case `ul`: 75 symbol.used = true; 76 compiler.next(); 77 if (compiler.tokenIs(`to`)) { 78 const cssId = compiler.getNextValue(); 79 compiler.addCommand({ 80 domain: `browser`, 81 keyword: `attach`, 82 lino, 83 type: symbol.keyword, 84 symbol: symbol.name, 85 cssId 86 }); 87 return true; 88 } 89 break; 90 default: 91 compiler.addWarning(`type '${symbol.keyword}' not recognized in browser 'attach'`); 92 return false; 47 case `a`: 48 case `blockquote`: 49 case `button`: 50 case `div`: 51 case `fieldset`: 52 case `file`: 53 case `form`: 54 case `h1`: 55 case `h2`: 56 case `h3`: 57 case `h4`: 58 case `h5`: 59 case `h6`: 60 case `image`: 61 case `img`: 62 case `input`: 63 case `label`: 64 case `legend`: 65 case `li`: 66 case `p`: 67 case `pre`: 68 case `select`: 69 case `span`: 70 case `table`: 71 case `td`: 72 case `text`: 73 case `textarea`: 74 case `tr`: 75 case `ul`: 76 symbol.used = true; 77 compiler.next(); 78 if (compiler.tokenIs(`to`)) { 79 const cssId = compiler.getNextValue(); 80 compiler.addCommand({ 81 domain: `browser`, 82 keyword: `attach`, 83 lino, 84 type: symbol.keyword, 85 symbol: symbol.name, 86 cssId 87 }); 88 return true; 89 } 90 break; 91 default: 92 compiler.addWarning(`type '${symbol.keyword}' not recognized in browser 'attach'`); 93 return false; 93 94 } 94 95 } … … 225 226 let value = content; 226 227 switch (command.mode) { 227 case `print`:228 value = value.split(`%0a`).join(`\n`).split(`%0A`).join(`\n`).split(`%0d`).join(``).split(`$0D`).join(``);229 break;230 case `html`:231 value = value.split(`%0a`).join(`<br />`).split(`%0A`).join(`<br />`).split(`%0d`).join(``).split(`$0D`).join(``);232 break;228 case `print`: 229 value = value.split(`%0a`).join(`\n`).split(`%0A`).join(`\n`).split(`%0d`).join(``).split(`$0D`).join(``); 230 break; 231 case `html`: 232 value = value.split(`%0a`).join(`<br />`).split(`%0A`).join(`<br />`).split(`%0d`).join(``).split(`$0D`).join(``); 233 break; 233 234 } 234 235 targetRecord.value[targetRecord.index].content = value; … … 260 261 } 261 262 if ([`a`, 262 `blockquote`, 263 `button`, 264 `div`, 265 `fieldset`, 266 `file`, 267 `form`, 268 `h1`, 269 `h2`, 270 `h3`, 271 `h4`, 272 `h5`, 273 `h6`, 274 `hr`, 275 `img`, 276 `input`, 277 `label`, 278 `legend`, 279 `li`, 280 `p`, 281 `pre`, 282 `progress`, 283 `select`, 284 `span`, 285 `table`, 286 `tr`, 287 `td`, 288 `text`, 289 `textarea`, 290 `ul` 291 ].includes(keyword)) { 263 `blockquote`, 264 `button`, 265 `div`, 266 `fieldset`, 267 `file`, 268 `form`, 269 `h1`, 270 `h2`, 271 `h3`, 272 `h4`, 273 `h5`, 274 `h6`, 275 `hr`, 276 `image`, 277 `img`, 278 `input`, 279 `label`, 280 `legend`, 281 `li`, 282 `p`, 283 `pre`, 284 `progress`, 285 `select`, 286 `span`, 287 `table`, 288 `tr`, 289 `td`, 290 `text`, 291 `textarea`, 292 `ul` 293 ].includes(keyword)) { 292 294 if (compiler.nextTokenIs(`in`)) { 293 if (compiler.nextTokenIs(`body`)) { 294 compiler.next(); 295 compiler.addCommand({ 296 domain: `browser`, 297 keyword: `create`, 298 lino, 299 name: symbolRecord.name, 300 parent: `body` 301 }); 302 return true; 303 } 304 if (compiler.isSymbol()) { 295 if (compiler.nextIsSymbol()) { 305 296 const parentRecord = compiler.getSymbolRecord(); 306 297 compiler.next(); … … 314 305 return true; 315 306 } 307 } else { 308 const imports = compiler.imports; 309 if (imports.length > 0) { 310 const parent = imports[0].name; 311 compiler.addCommand({ 312 domain: `browser`, 313 keyword: `create`, 314 lino, 315 name: symbolRecord.name, 316 parent, 317 imported: true 318 }); 319 return true; 320 } else { 321 compiler.addCommand({ 322 domain: `browser`, 323 keyword: `create`, 324 lino, 325 name: symbolRecord.name, 326 parent: `body` 327 }); 328 return true; 329 } 316 330 } 317 331 } … … 324 338 const targetRecord = program.getSymbolRecord(command.name); 325 339 switch (command.type) { 326 case `audioclip`: 327 targetRecord.value[targetRecord.index] = command.value; 328 break; 329 default: 330 let parent; 331 if (command.parent === `body`) { 332 parent = document.body; 333 } else { 334 const parentRecord = program.getSymbolRecord(command.parent); 335 if (!parentRecord.element[parentRecord.index]) { 336 program.runtimeError(command.pc, `Element ${parentRecord.name} does not exist.`); 337 } 338 parent = parentRecord.element[parentRecord.index]; 339 } 340 targetRecord.element[targetRecord.index] = document.createElement(targetRecord.keyword); 341 if (!this.elementId) { 342 this.elementId = 0; 343 } 344 targetRecord.element[targetRecord.index].id = `ec-${targetRecord.name}-${targetRecord.index}-${this.elementId++}`; 345 if (targetRecord.keyword === `a`) { 346 targetRecord.element[targetRecord.index].setAttribute(`href`, `#`); 347 } 348 parent.appendChild(targetRecord.element[targetRecord.index]); 349 break; 340 case `audioclip`: 341 targetRecord.value[targetRecord.index] = command.value; 342 break; 343 default: 344 let parent; 345 if (command.parent === `body`) { 346 parent = document.body; 347 } else { 348 const p = command.imported ? program.parent : program; 349 const parentRecord = p.getSymbolRecord(command.parent); 350 if (!parentRecord.element[parentRecord.index]) { 351 program.runtimeError(command.pc, `Element ${parentRecord.name} does not exist.`); 352 } 353 parent = parentRecord.element[parentRecord.index]; 354 } 355 targetRecord.element[targetRecord.index] = document.createElement(targetRecord.keyword); 356 if (!this.elementId) { 357 this.elementId = 0; 358 } 359 targetRecord.element[targetRecord.index].id = `ec-${targetRecord.name}-${targetRecord.index}-${this.elementId++}`; 360 if (targetRecord.keyword === `a`) { 361 targetRecord.element[targetRecord.index].setAttribute(`href`, `#`); 362 } 363 parent.appendChild(targetRecord.element[targetRecord.index]); 364 break; 350 365 } 351 366 return command.pc + 1; … … 476 491 }); 477 492 return true; 493 } else { 494 compiler.addCommand({ 495 domain: `browser`, 496 keyword: `get`, 497 action: `listStorage`, 498 lino, 499 target 500 }); 501 return true; 478 502 } 479 503 } … … 504 528 const targetRecord = program.getSymbolRecord(command.target); 505 529 switch (command.action) { 506 case `getForm`: 507 const formRecord = program.getSymbolRecord(command.form); 508 const form = document.getElementById(formRecord.value[formRecord.index].content); 509 const data = new FormData(form); 510 const content = {}; 511 for (const entry of data) { 512 content[entry[0]] = entry[1].replace(/\r/g, ``).replace(/\n/g, `%0a`); 513 } 514 targetRecord.value[targetRecord.index] = { 515 type: `constant`, 516 numeric: false, 517 content: JSON.stringify(content) 518 }; 519 break; 520 case `getStorage`: 521 let value = window.localStorage.getItem(program.getValue(command.key)); 522 if (typeof value === `undefined`) { 523 value = null; 524 } 525 targetRecord.value[targetRecord.index] = { 526 type: `constant`, 527 numeric: false, 528 content: value 529 }; 530 break; 530 case `getForm`: 531 const formRecord = program.getSymbolRecord(command.form); 532 const form = document.getElementById(formRecord.value[formRecord.index].content); 533 const data = new FormData(form); 534 const content = {}; 535 for (const entry of data) { 536 content[entry[0]] = entry[1].replace(/\r/g, ``).replace(/\n/g, `%0a`); 537 } 538 targetRecord.value[targetRecord.index] = { 539 type: `constant`, 540 numeric: false, 541 content: JSON.stringify(content) 542 }; 543 break; 544 case `listStorage`: 545 const items = []; 546 for (let i = 0, len = window.localStorage.length; i < len; i++) { 547 items.push(localStorage.key(i)); 548 } 549 targetRecord.value[targetRecord.index] = { 550 type: `constant`, 551 numeric: false, 552 content: JSON.stringify(items) 553 }; 554 break; 555 case `getStorage`: 556 let value = window.localStorage.getItem(program.getValue(command.key)); 557 if (typeof value === `undefined`) { 558 value = null; 559 } 560 targetRecord.value[targetRecord.index] = { 561 type: `constant`, 562 numeric: false, 563 content: value 564 }; 565 break; 531 566 } 532 567 return command.pc + 1; … … 612 647 const type = compiler.nextToken(); 613 648 switch (type) { 614 case `push`:615 case `set`:616 case `replace`:617 compiler.next();618 let url = ``;619 let state = ``;620 while (true) {621 const token = compiler.getToken();622 if (token === `url`) {623 url = compiler.getNextValue();624 } else if (token === `state`) {625 state = compiler.getNextValue();626 } else {627 break;628 }629 }630 compiler.addCommand({631 domain: `browser`,632 keyword: `history`,633 lino,634 type,635 url,636 state637 });638 return true;639 case `pop`:640 case `back`:641 case `forward`:642 compiler.next();643 compiler.addCommand({644 domain: `browser`,645 keyword: `history`,646 lino,647 type648 });649 return true;649 case `push`: 650 case `set`: 651 case `replace`: 652 compiler.next(); 653 let url = ``; 654 let state = ``; 655 while (true) { 656 const token = compiler.getToken(); 657 if (token === `url`) { 658 url = compiler.getNextValue(); 659 } else if (token === `state`) { 660 state = compiler.getNextValue(); 661 } else { 662 break; 663 } 664 } 665 compiler.addCommand({ 666 domain: `browser`, 667 keyword: `history`, 668 lino, 669 type, 670 url, 671 state 672 }); 673 return true; 674 case `pop`: 675 case `back`: 676 case `forward`: 677 compiler.next(); 678 compiler.addCommand({ 679 domain: `browser`, 680 keyword: `history`, 681 lino, 682 type 683 }); 684 return true; 650 685 } 651 686 return false; … … 663 698 const url = program.getValue(command.url); 664 699 switch (command.type) { 665 case `push`:666 if (!window.history.state) {667 program.runtimeError(command.lino, `No state history; you need to call 'history set' on the parent`);668 return 0;669 }670 window.history.pushState(state, ``, url);671 break;672 case `set`:673 case `replace`:674 window.history.replaceState(state, ``, url);675 break;676 case `pop`:677 case `back`:678 window.history.back();679 break;680 case `forward`:681 window.history.forward();682 break;700 case `push`: 701 if (!window.history.state) { 702 program.runtimeError(command.lino, `No state history; you need to call 'history set' on the parent`); 703 return 0; 704 } 705 window.history.pushState(state, ``, url); 706 break; 707 case `set`: 708 case `replace`: 709 window.history.replaceState(state, ``, url); 710 break; 711 case `pop`: 712 case `back`: 713 window.history.back(); 714 break; 715 case `forward`: 716 window.history.forward(); 717 break; 683 718 } 684 719 return command.pc + 1; … … 690 725 compile: (compiler) => { 691 726 compiler.compileVariable(`browser`, `hr`, false, `dom`); 727 return true; 728 }, 729 730 run: (program) => { 731 return program[program.pc].pc + 1; 732 } 733 }, 734 735 IMAGE: { 736 737 compile: (compiler) => { 738 compiler.compileVariable(`browser`, `image`, false, `dom`); 692 739 return true; 693 740 }, … … 835 882 const action = compiler.nextToken(); 836 883 switch (action) { 837 case `change`: 884 case `change`: 885 compiler.next(); 886 if (compiler.isSymbol()) { 887 const symbol = compiler.getSymbolRecord(); 838 888 compiler.next(); 839 if (compiler.isSymbol()) { 840 const symbol = compiler.getSymbolRecord(); 841 compiler.next(); 842 if (symbol.extra !== `dom`) { 843 return false; 844 } 845 compiler.addCommand({ 846 domain: `browser`, 847 keyword: `on`, 848 lino, 849 action, 850 symbol: symbol.name 851 }); 852 return compiler.completeHandler(); 853 } 854 break; 855 case `click`: 856 if (compiler.nextTokenIs(`document`)) { 857 compiler.next(); 858 compiler.addCommand({ 859 domain: `browser`, 860 keyword: `on`, 861 lino, 862 action: `clickDocument` 863 }); 864 return compiler.completeHandler(); 865 } 866 if (compiler.isSymbol()) { 867 const symbol = compiler.getSymbolRecord(); 868 compiler.next(); 869 if (symbol.extra !== `dom`) { 870 return false; 871 } 872 compiler.addCommand({ 873 domain: `browser`, 874 keyword: `on`, 875 lino, 876 action, 877 symbol: symbol.name 878 }); 879 return compiler.completeHandler(); 880 } 881 break; 882 case `key`: 883 case `leave`: 889 if (symbol.extra !== `dom`) { 890 return false; 891 } 892 compiler.addCommand({ 893 domain: `browser`, 894 keyword: `on`, 895 lino, 896 action, 897 symbol: symbol.name 898 }); 899 return compiler.completeHandler(); 900 } 901 break; 902 case `click`: 903 if (compiler.nextTokenIs(`document`)) { 884 904 compiler.next(); 885 905 compiler.addCommand({ … … 887 907 keyword: `on`, 888 908 lino, 889 action 909 action: `clickDocument` 890 910 }); 891 911 return compiler.completeHandler(); 892 case `browser`: 893 if (compiler.nextTokenIs(`back`)) { 894 compiler.next(); 895 compiler.addCommand({ 896 domain: `browser`, 897 keyword: `on`, 898 lino, 899 action: `browserBack` 900 }); 901 return compiler.completeHandler(); 902 } 903 return false; 904 case `swipe`: 905 if ([`left`, `right`].includes(compiler.nextToken())) { 906 const direction = compiler.getToken(); 907 compiler.next(); 908 compiler.addCommand({ 909 domain: `browser`, 910 keyword: `on`, 911 lino, 912 action: `swipe`, 913 direction 914 }); 915 return compiler.completeHandler(); 916 } 912 } 913 if (compiler.isSymbol()) { 914 const symbol = compiler.getSymbolRecord(); 915 compiler.next(); 916 if (symbol.extra !== `dom`) { 917 return false; 918 } 919 compiler.addCommand({ 920 domain: `browser`, 921 keyword: `on`, 922 lino, 923 action, 924 symbol: symbol.name 925 }); 926 return compiler.completeHandler(); 927 } 928 break; 929 case `key`: 930 case `leave`: 931 compiler.next(); 932 compiler.addCommand({ 933 domain: `browser`, 934 keyword: `on`, 935 lino, 936 action 937 }); 938 return compiler.completeHandler(); 939 case `browser`: 940 if (compiler.nextTokenIs(`back`)) { 941 compiler.next(); 942 compiler.addCommand({ 943 domain: `browser`, 944 keyword: `on`, 945 lino, 946 action: `browserBack` 947 }); 948 return compiler.completeHandler(); 949 } 950 return false; 951 case `swipe`: 952 if ([`left`, `right`].includes(compiler.nextToken())) { 953 const direction = compiler.getToken(); 954 compiler.next(); 955 compiler.addCommand({ 956 domain: `browser`, 957 keyword: `on`, 958 lino, 959 action: `swipe`, 960 direction 961 }); 962 return compiler.completeHandler(); 963 } 917 964 } 918 965 compiler.addWarning(`Unrecognised syntax in 'on'`); … … 923 970 const command = program[program.pc]; 924 971 switch (command.action) { 925 case `change`: 926 const changeItem = program.getSymbolRecord(command.symbol); 927 if (changeItem.keyword === `select`) { 928 const target = changeItem.element[changeItem.index]; 929 target.targetPc = command.pc + 2; 930 target.addEventListener(`change`, function () { 931 try { 932 program.run(target.targetPc); 933 } catch (err) { 934 console.log(err.message); 935 alert(err.message); 972 case `change`: 973 const changeItem = program.getSymbolRecord(command.symbol); 974 if (changeItem.keyword === `select`) { 975 const target = changeItem.element[changeItem.index]; 976 target.targetPc = command.pc + 2; 977 target.addEventListener(`change`, function () { 978 try { 979 program.run(target.targetPc); 980 } catch (err) { 981 console.log(err.message); 982 alert(err.message); 983 } 984 return false; 985 }); 986 } 987 break; 988 case `click`: 989 const targetRecord = program.getSymbolRecord(command.symbol); 990 targetRecord.element.forEach(function (target, index) { 991 target.targetRecord = targetRecord; 992 target.targetIndex = index; 993 target.targetPc = command.pc + 2; 994 target.onclick = function (event) { 995 event.stopPropagation(); 996 if (program.length > 0) { 997 const eventTarget = event.target; 998 eventTarget.blur(); 999 if (typeof eventTarget.targetRecord !== `undefined`) { 1000 eventTarget.targetRecord.index = eventTarget.targetIndex; 1001 setTimeout(function () { 1002 EasyCoder.timestamp = Date.now(); 1003 program.run(eventTarget.targetPc); 1004 }, 1); 936 1005 } 937 return false; 938 }); 939 } 1006 } 1007 return false; 1008 }; 1009 }); 1010 break; 1011 case `clickDocument`: 1012 program.targetPc = command.pc + 2; 1013 const interceptClickEvent = (e) => { 1014 EasyCoder.timestamp = Date.now(); 1015 let target = e.target || e.srcElement; 1016 let href = ``; 1017 while (target.parentNode) { 1018 if (target.tagName === `A`) { 1019 href = target.href; 1020 program.docPath = href.slice(-(href.length - window.location.href.length)); 1021 break; 1022 } 1023 target = target.parentNode; 1024 } 1025 while (target.parentNode) { 1026 if (target.id.indexOf(`ec-`) === 0) { 1027 let id = target.id.slice(3); 1028 let pos = id.indexOf(`-`); 1029 program.varName = id.slice(0, pos); 1030 id = id.slice(pos + 1); 1031 pos = id.indexOf(`-`); 1032 program.varIndex = parseInt(id.slice(0, pos)); 1033 break; 1034 } 1035 target = target.parentNode; 1036 } 1037 if (href.indexOf(window.location.href) === 0) { 1038 program.run(program.targetPc); 1039 e.preventDefault(); 1040 } 1041 }; 1042 if (document.addEventListener) { 1043 document.addEventListener(`click`, interceptClickEvent); 1044 } else if (document.attachEvent) { 1045 document.attachEvent(`onclick`, interceptClickEvent); 1046 } 1047 break; 1048 case `swipe`: 1049 let xDown; 1050 const getTouches = (evt) => { 1051 return evt.touches || // browser API 1052 evt.originalEvent.touches; // jQuery 1053 }; 1054 const handleTouchStart = (evt) => { 1055 const firstTouch = getTouches(evt)[0]; 1056 xDown = firstTouch.clientX; 1057 }; 1058 const handleTouchMove = (evt) => { 1059 evt.stopImmediatePropagation(); 1060 if (!xDown) { 1061 return; 1062 } 1063 const xUp = evt.touches[0].clientX; 1064 const xDiff = xDown - xUp; 1065 if (Math.abs(xDiff) > 150) { 1066 xDown = null; 1067 if (xDiff > 0 && program.onSwipeLeft) { 1068 program.run(program.onSwipeLeft); 1069 } else if (xDiff < 0 && program.onSwipeRight) { 1070 program.run(program.onSwipeRight); 1071 } 1072 } 1073 }; 1074 switch (command.direction) { 1075 case `left`: 1076 program.onSwipeLeft = command.pc + 2; 940 1077 break; 941 case `click`: 942 const targetRecord = program.getSymbolRecord(command.symbol); 943 targetRecord.element.forEach(function (target, index) { 944 target.targetRecord = targetRecord; 945 target.targetIndex = index; 946 target.targetPc = command.pc + 2; 947 target.onclick = function (event) { 948 event.stopPropagation(); 949 if (program.length > 0) { 950 const eventTarget = event.target; 951 eventTarget.blur(); 952 if (typeof eventTarget.targetRecord !== `undefined`) { 953 eventTarget.targetRecord.index = eventTarget.targetIndex; 954 setTimeout(function () { 955 EasyCoder.timestamp = Date.now(); 956 program.run(eventTarget.targetPc); 957 }, 1); 958 } 959 } 960 return false; 961 }; 962 }); 1078 case `right`: 1079 program.onSwipeRight = command.pc + 2; 963 1080 break; 964 case `clickDocument`: 965 program.targetPc = command.pc + 2; 966 const interceptClickEvent = (e) => { 967 EasyCoder.timestamp = Date.now(); 968 let target = e.target || e.srcElement; 969 let href = ``; 970 while (target.parentNode) { 971 if (target.tagName === `A`) { 972 href = target.href; 973 program.docPath = href.slice(-(href.length - window.location.href.length)); 974 break; 975 } 976 target = target.parentNode; 977 } 978 while (target.parentNode) { 979 if (target.id.indexOf(`ec-`) === 0) { 980 let id = target.id.slice(3); 981 let pos = id.indexOf(`-`); 982 program.varName = id.slice(0, pos); 983 id = id.slice(pos + 1); 984 pos = id.indexOf(`-`); 985 program.varIndex = parseInt(id.slice(0, pos)); 986 break; 987 } 988 target = target.parentNode; 989 } 990 if (href.indexOf(window.location.href) === 0) { 991 program.run(program.targetPc); 992 e.preventDefault(); 993 } 994 }; 995 if (document.addEventListener) { 996 document.addEventListener(`click`, interceptClickEvent); 997 } else if (document.attachEvent) { 998 document.attachEvent(`onclick`, interceptClickEvent); 999 } 1000 break; 1001 case `swipe`: 1002 let xDown; 1003 const getTouches = (evt) => { 1004 return evt.touches || // browser API 1005 evt.originalEvent.touches; // jQuery 1006 }; 1007 const handleTouchStart = (evt) => { 1008 const firstTouch = getTouches(evt)[0]; 1009 xDown = firstTouch.clientX; 1010 }; 1011 const handleTouchMove = (evt) => { 1012 evt.stopImmediatePropagation(); 1013 if (!xDown) { 1014 return; 1015 } 1016 const xUp = evt.touches[0].clientX; 1017 const xDiff = xDown - xUp; 1018 if (Math.abs(xDiff) > 150) { 1019 xDown = null; 1020 if (xDiff > 0 && program.onSwipeLeft) { 1021 program.run(program.onSwipeLeft); 1022 } else if (xDiff < 0 && program.onSwipeRight) { 1023 program.run(program.onSwipeRight); 1024 } 1025 } 1026 }; 1027 switch (command.direction) { 1028 case `left`: 1029 program.onSwipeLeft = command.pc + 2; 1030 break; 1031 case `right`: 1032 program.onSwipeRight = command.pc + 2; 1033 break; 1034 } 1035 document.addEventListener(`touchstart`, handleTouchStart, false); 1036 document.addEventListener(`touchmove`, handleTouchMove, false); 1037 break; 1038 case `key`: 1039 if (typeof document.onKeyListeners === `undefined`) { 1040 document.onKeyListeners = []; 1041 } 1042 if (!document.onKeyListeners.includes(program)) { 1043 document.onKeyListeners.push(program); 1044 } 1045 program.onKeyPc = command.pc + 2; 1046 document.onkeypress = function (event) { 1047 for (const program of document.onKeyListeners) { 1048 program.key = event.key; 1049 try { 1050 setTimeout(function () { 1051 program.run(program.onKeyPc); 1052 }, 1); 1053 } catch (err) { 1054 console.log(`Error: ${err.message}`); 1055 } 1056 } 1057 return true; 1058 }; 1059 break; 1060 case `browserBack`: 1061 program.onBrowserBack = command.pc + 2; 1062 break; 1063 case `leave`: 1064 window.addEventListener(`beforeunload`, function () { 1065 program.run(command.pc + 2); 1066 }); 1067 break; 1068 default: 1069 break; 1081 } 1082 document.addEventListener(`touchstart`, handleTouchStart, false); 1083 document.addEventListener(`touchmove`, handleTouchMove, false); 1084 break; 1085 case `key`: 1086 if (typeof document.onKeyListeners === `undefined`) { 1087 document.onKeyListeners = []; 1088 } 1089 if (!document.onKeyListeners.includes(program)) { 1090 document.onKeyListeners.push(program); 1091 } 1092 program.onKeyPc = command.pc + 2; 1093 document.onkeypress = function (event) { 1094 for (const program of document.onKeyListeners) { 1095 program.key = event.key; 1096 try { 1097 setTimeout(function () { 1098 program.run(program.onKeyPc); 1099 }, 1); 1100 } catch (err) { 1101 console.log(`Error: ${err.message}`); 1102 } 1103 } 1104 return true; 1105 }; 1106 break; 1107 case `browserBack`: 1108 program.onBrowserBack = command.pc + 2; 1109 break; 1110 case `leave`: 1111 window.addEventListener(`beforeunload`, function () { 1112 program.run(command.pc + 2); 1113 }); 1114 break; 1115 default: 1116 break; 1070 1117 } 1071 1118 return command.pc + 1; … … 1175 1222 compile: (compiler) => { 1176 1223 const lino = compiler.getLino(); 1177 if (compiler.nextIsSymbol()) { 1178 const child = compiler.getSymbolRecord(); 1179 if (child.extra != `dom`) { 1180 compiler.warning(`'${child.name}' is not a DOM element`); 1181 return false; 1182 } 1183 if (compiler.nextTokenIs(`from`)) { 1184 if (compiler.nextIsSymbol()) { 1185 const parent = compiler.getSymbolRecord(); 1186 if (parent.extra != `dom`) { 1187 compiler.warning(`'${parent.name}' is not a DOM element`); 1188 return false; 1189 } 1190 compiler.next(); 1191 compiler.addCommand({ 1192 domain: `browser`, 1193 keyword: `remove`, 1194 type: `removeElement`, 1195 lino, 1196 child: child.name, 1197 parent: parent.name 1198 }); 1199 return true; 1200 } 1201 } 1202 return false; 1224 if (compiler.nextTokenIs(`element`)) { 1225 if (compiler.nextIsSymbol()) { 1226 const element = compiler.getSymbolRecord(); 1227 if (element.extra != `dom`) { 1228 compiler.warning(`'${element.name}' is not a DOM element`); 1229 return false; 1230 } 1231 compiler.next(); 1232 compiler.addCommand({ 1233 domain: `browser`, 1234 keyword: `remove`, 1235 type: `removeElement`, 1236 lino, 1237 element: element.name 1238 }); 1239 return true; 1240 } 1203 1241 } 1204 1242 if (compiler.tokenIs(`attribute`)) { … … 1223 1261 } 1224 1262 } 1263 const key = compiler.getValue(); 1264 if (compiler.tokenIs(`from`)) { 1265 if (compiler.nextTokenIs(`storage`)) { 1266 compiler.next(); 1267 compiler.addCommand({ 1268 domain: `browser`, 1269 keyword: `remove`, 1270 type: `removeStorage`, 1271 key 1272 }); 1273 return true; 1274 } 1275 } 1225 1276 return false; 1226 1277 }, … … 1231 1282 const command = program[program.pc]; 1232 1283 switch (command.type) { 1233 case `removeAttribute`: 1234 const attribute = program.getValue(command.attribute); 1235 const targetRecord = program.getSymbolRecord(command.target); 1236 target = targetRecord.element[targetRecord.index]; 1237 target.removeAttribute(attribute); 1238 break; 1239 case `removeElement`: 1240 const childRecord = program.getSymbolRecord(command.child); 1241 const parentRecord = program.getSymbolRecord(command.parent); 1242 const child = childRecord.element[childRecord.index]; 1243 const parent = parentRecord.element[parentRecord.index]; 1244 parent.removeChild(child); 1245 break; 1284 case `removeAttribute`: 1285 const attribute = program.getValue(command.attribute); 1286 const targetRecord = program.getSymbolRecord(command.target); 1287 target = targetRecord.element[targetRecord.index]; 1288 target.removeAttribute(attribute); 1289 break; 1290 case `removeElement`: 1291 const elementRecord = program.getSymbolRecord(command.element); 1292 const element = elementRecord.element[elementRecord.index]; 1293 element.parentElement.removeChild(element); 1294 break; 1295 case `removeStorage`: 1296 const key = program.getValue(command.key); 1297 window.localStorage.removeItem(key); 1298 break; 1246 1299 } 1247 1300 return command.pc + 1; … … 1264 1317 1265 1318 compile: (compiler) => { 1266 if (compiler.nextTokenIs(`to`)) { 1319 let name = null; 1320 if (compiler.nextIsSymbol()) { 1321 const symbolRecord = compiler.getSymbolRecord(); 1322 name = symbolRecord.name; 1323 compiler.next(); 1324 } 1325 if (compiler.tokenIs(`to`)) { 1267 1326 const to = compiler.getNextValue(); 1268 1327 compiler.addCommand({ 1269 1328 domain: `browser`, 1270 1329 keyword: `scroll`, 1330 name, 1271 1331 to 1272 1332 }); … … 1279 1339 const command = program[program.pc]; 1280 1340 const to = program.getValue(command.to); 1281 window.scrollTo(0, to); 1282 // document.documentElement.pageYOffset = to; 1341 if (command.name) { 1342 const symbolRecord = program.getSymbolRecord(command.name); 1343 symbolRecord.element[symbolRecord.index].scrollTo(0, to); 1344 } else { 1345 window.scrollTo(0, to); 1346 } 1283 1347 return command.pc + 1; 1284 1348 } … … 1394 1458 const symbol = compiler.getSymbolRecord(); 1395 1459 switch (symbol.keyword) { 1396 case `button`:1397 case `input`:1398 case `span`:1399 case `label`:1400 case `legend`:1401 if (compiler.nextTokenIs(`to`)) {1402 const value = compiler.getNextValue();1403 compiler.addCommand({1404 domain: `browser`,1405 keyword: `set`,1406 lino,1407 type: `setText`,1408 symbolName: symbol.name,1409 value1410 });1411 return true;1412 }1413 break;1414 default:1415 break;1460 case `button`: 1461 case `input`: 1462 case `span`: 1463 case `label`: 1464 case `legend`: 1465 if (compiler.nextTokenIs(`to`)) { 1466 const value = compiler.getNextValue(); 1467 compiler.addCommand({ 1468 domain: `browser`, 1469 keyword: `set`, 1470 lino, 1471 type: `setText`, 1472 symbolName: symbol.name, 1473 value 1474 }); 1475 return true; 1476 } 1477 break; 1478 default: 1479 break; 1416 1480 } 1417 1481 } … … 1422 1486 const symbol = compiler.getSymbolRecord(); 1423 1487 switch (symbol.keyword) { 1424 case `input`:1425 if (compiler.nextTokenIs(`to`)) {1426 const value = compiler.getNextValue();1427 compiler.addCommand({1428 domain: `browser`,1429 keyword: `set`,1430 lino,1431 type: `setSize`,1432 symbolName: symbol.name,1433 value1434 });1435 return true;1436 }1488 case `input`: 1489 if (compiler.nextTokenIs(`to`)) { 1490 const value = compiler.getNextValue(); 1491 compiler.addCommand({ 1492 domain: `browser`, 1493 keyword: `set`, 1494 lino, 1495 type: `setSize`, 1496 symbolName: symbol.name, 1497 value 1498 }); 1499 return true; 1500 } 1437 1501 } 1438 1502 } … … 1558 1622 let cssId; 1559 1623 switch (command.type) { 1560 case `setContentVar`: 1561 const sourceVar = program.getSymbolRecord(command.source); 1562 targetVar = program.getSymbolRecord(command.target); 1563 const source = document.getElementById(sourceVar.value[sourceVar.index].content); 1564 target = targetVar.element[targetVar.index]; 1565 if (!target) { 1566 targetId = program.getValue(targetVar.value[targetVar.index]); 1567 target = document.getElementById(targetId); 1568 } 1569 target.innerHTML = source.innerHTML; 1624 case `setContentVar`: 1625 const sourceVar = program.getSymbolRecord(command.source); 1626 targetVar = program.getSymbolRecord(command.target); 1627 const source = document.getElementById(sourceVar.value[sourceVar.index].content); 1628 target = targetVar.element[targetVar.index]; 1629 if (!target) { 1630 targetId = program.getValue(targetVar.value[targetVar.index]); 1631 target = document.getElementById(targetId); 1632 } 1633 target.innerHTML = source.innerHTML; 1634 break; 1635 case `setContent`: 1636 value = program.getValue(command.value); 1637 targetVar = program.getSymbolRecord(command.target); 1638 target = targetVar.element[targetVar.index]; 1639 if (!target) { 1640 cssId = targetVar.value[targetVar.index].content; 1641 if (!cssId) { 1642 program.runtimeError(command.lino, 1643 `Variable '${targetVar.name}' has not been attached to a DOM element.`); 1644 return 0; 1645 } 1646 target = document.getElementById(cssId); 1647 } 1648 targetVar.element[targetVar.index] = target; 1649 switch (targetVar.keyword) { 1650 case `text`: 1651 case `textarea`: 1652 target.value = value; 1570 1653 break; 1571 case `setContent`: 1572 value = program.getValue(command.value); 1573 targetVar = program.getSymbolRecord(command.target); 1574 target = targetVar.element[targetVar.index]; 1575 if (!target) { 1576 cssId = targetVar.value[targetVar.index].content; 1577 if (!cssId) { 1578 program.runtimeError(command.lino, 1579 `Variable '${targetVar.name}' has not been attached to a DOM element.`); 1580 return 0; 1581 } 1582 target = document.getElementById(cssId); 1583 } 1584 targetVar.element[targetVar.index] = target; 1585 switch (targetVar.keyword) { 1586 case `text`: 1587 case `textarea`: 1588 target.value = value; 1589 break; 1590 case `input`: 1591 target.value = value; 1592 break; 1593 default: 1594 target.innerHTML = value; 1595 break; 1596 } 1654 case `input`: 1655 target.value = value; 1597 1656 break; 1598 case `setId`: 1599 symbol = program.getSymbolRecord(command.symbolName); 1657 default: 1658 target.innerHTML = value; 1659 break; 1660 } 1661 break; 1662 case `setId`: 1663 symbol = program.getSymbolRecord(command.symbolName); 1664 target = symbol.element[symbol.index]; 1665 if (!target) { 1666 targetId = program.getValue(symbol.value[symbol.index]); 1667 target = document.getElementById(targetId); 1668 } 1669 target.id = program.getValue(command.value); 1670 break; 1671 case `setText`: 1672 symbol = program.getSymbolRecord(command.symbolName); 1673 target = symbol.element[symbol.index]; 1674 if (!target) { 1675 targetId = program.getValue(symbol.value[symbol.index]); 1676 target = document.getElementById(targetId); 1677 } 1678 value = program.getValue(command.value); 1679 switch (symbol.keyword) { 1680 case `button`: 1681 case `span`: 1682 case `label`: 1683 case `legend`: 1684 target.innerHTML = value; 1685 break; 1686 case `input`: 1687 target.value = value; 1688 break; 1689 default: 1690 break; 1691 } 1692 break; 1693 case `setSize`: 1694 symbol = program.getSymbolRecord(command.symbolName); 1695 if (symbol.keyword === `input`) { 1600 1696 target = symbol.element[symbol.index]; 1601 1697 if (!target) { … … 1603 1699 target = document.getElementById(targetId); 1604 1700 } 1605 target.id = program.getValue(command.value); 1701 target.size = program.getValue(command.value); 1702 } else { 1703 program.runtimeError(command.lino, `Inappropriate variable type '${symbol.name}'`); 1704 } 1705 break; 1706 case `setAttribute`: 1707 symbol = program.getSymbolRecord(command.symbolName); 1708 target = symbol.element[symbol.index]; 1709 if (!target) { 1710 targetId = program.getValue(symbol.value[symbol.index]); 1711 target = document.getElementById(targetId); 1712 } 1713 const attributeName = program.getValue(command.attributeName); 1714 if (command.attributeValue.type === `boolean`) { 1715 target.setAttribute(attributeName, command.attributeValue.content); 1716 } else { 1717 target.setAttribute(attributeName, program.getValue(command.attributeValue)); 1718 } 1719 break; 1720 case `setStyle`: 1721 case `setStyles`: 1722 symbol = program.getSymbolRecord(command.symbolName); 1723 target = symbol.element[symbol.index]; 1724 if (!target) { 1725 const symbolElement = symbol.value[symbol.index]; 1726 if (!symbolElement.type) { 1727 program.runtimeError(command.lino, `Variable '${symbol.name}' is not attached to a DOM element.`); 1728 return 0; 1729 } 1730 targetId = program.getValue(symbolElement); 1731 target = document.getElementById(targetId); 1732 } 1733 const styleValue = program.getValue(command.styleValue); 1734 if (!symbol.value[symbol.index]) { 1735 program.runtimeError(command.lino, `Variable '${symbol.name}' has not been assigned.`); 1736 return 0; 1737 } 1738 switch (command.type) { 1739 case `setStyle`: 1740 target.style[command.styleName.content] = styleValue; 1606 1741 break; 1607 case `setText`: 1608 symbol = program.getSymbolRecord(command.symbolName); 1609 target = symbol.element[symbol.index]; 1610 if (!target) { 1611 targetId = program.getValue(symbol.value[symbol.index]); 1612 target = document.getElementById(targetId); 1613 } 1614 value = program.getValue(command.value); 1615 switch (symbol.keyword) { 1616 case `button`: 1617 case `span`: 1618 case `label`: 1619 case `legend`: 1620 target.innerHTML = value; 1621 break; 1622 case `input`: 1623 target.value = value; 1624 break; 1625 default: 1626 break; 1627 } 1742 case `setStyles`: 1743 target.style.cssText = styleValue; 1628 1744 break; 1629 case `setSize`: 1630 symbol = program.getSymbolRecord(command.symbolName); 1631 if (symbol.keyword === `input`) { 1632 target = symbol.element[symbol.index]; 1633 if (!target) { 1634 targetId = program.getValue(symbol.value[symbol.index]); 1635 target = document.getElementById(targetId); 1636 } 1637 target.size = program.getValue(command.value); 1638 } else { 1639 program.runtimeError(command.lino, `Inappropriate variable type '${symbol.name}'`); 1640 } 1641 break; 1642 case `setAttribute`: 1643 symbol = program.getSymbolRecord(command.symbolName); 1644 target = symbol.element[symbol.index]; 1645 if (!target) { 1646 targetId = program.getValue(symbol.value[symbol.index]); 1647 target = document.getElementById(targetId); 1648 } 1649 const attributeName = program.getValue(command.attributeName); 1650 if (command.attributeValue.type === `boolean`) { 1651 target.setAttribute(attributeName, command.attributeValue.content); 1652 } else { 1653 target.setAttribute(attributeName, program.getValue(command.attributeValue)); 1654 } 1655 break; 1656 case `setStyle`: 1657 case `setStyles`: 1658 symbol = program.getSymbolRecord(command.symbolName); 1659 target = symbol.element[symbol.index]; 1660 if (!target) { 1661 const symbolElement = symbol.value[symbol.index]; 1662 if (!symbolElement.type) { 1663 program.runtimeError(command.lino, `Variable '${symbol.name}' is not attached to a DOM element.`); 1664 return 0; 1665 } 1666 targetId = program.getValue(symbolElement); 1667 target = document.getElementById(targetId); 1668 } 1669 const styleValue = program.getValue(command.styleValue); 1670 if (!symbol.value[symbol.index]) { 1671 program.runtimeError(command.lino, `Variable '${symbol.name}' has not been assigned.`); 1672 return 0; 1673 } 1674 switch (command.type) { 1675 case `setStyle`: 1676 target.style[command.styleName.content] = styleValue; 1677 break; 1678 case `setStyles`: 1679 target.style.cssText = styleValue; 1680 break; 1681 } 1682 break; 1683 case `setBodyStyle`: 1684 const bodyStyleValue = program.getValue(command.styleValue); 1685 document.body.style[command.styleName.content] = bodyStyleValue.content; 1686 break; 1687 case `setTitle`: 1688 document.title = program.getValue(command.value); 1689 break; 1690 case `setDefault`: 1691 const selectRecord = program.getSymbolRecord(command.name); 1692 value = program.getValue(command.value); 1693 const element = selectRecord.element[selectRecord.index]; 1694 for (let n = 0; n < element.options.length; n++) { 1695 if (element.options[n].value === value) { 1696 element.selectedIndex = n; 1697 break; 1698 } 1699 } 1700 break; 1701 default: 1702 break; 1745 } 1746 break; 1747 case `setBodyStyle`: 1748 const bodyStyleValue = program.getValue(command.styleValue); 1749 document.body.style[command.styleName.content] = bodyStyleValue.content; 1750 break; 1751 case `setTitle`: 1752 document.title = program.getValue(command.value); 1753 break; 1754 case `setDefault`: 1755 const selectRecord = program.getSymbolRecord(command.name); 1756 value = program.getValue(command.value); 1757 const element = selectRecord.element[selectRecord.index]; 1758 for (let n = 0; n < element.options.length; n++) { 1759 if (element.options[n].value === value) { 1760 element.selectedIndex = n; 1761 break; 1762 } 1763 } 1764 break; 1765 default: 1766 break; 1703 1767 } 1704 1768 return command.pc + 1; … … 1803 1867 const command = program[program.pc]; 1804 1868 switch (command.variant) { 1805 case `setup`: 1806 console.log(`Set up tracer`); 1869 case `setup`: 1870 console.log(`Set up tracer`); 1871 program.tracer = { 1872 variables: command.variables, 1873 alignment: command.alignment 1874 }; 1875 break; 1876 case `run`: 1877 console.log(`Run tracer`); 1878 if (!program.tracer) { 1807 1879 program.tracer = { 1808 variables: command.variables,1809 alignment: command.alignment1880 variables: [], 1881 alignment: `horizontal` 1810 1882 }; 1811 break; 1812 case `run`: 1813 console.log(`Run tracer`); 1814 if (!program.tracer) { 1815 program.tracer = { 1816 variables: [], 1817 alignment: `horizontal` 1818 }; 1819 } 1820 program.tracing = true; 1821 program.stop = false; 1822 break; 1883 } 1884 program.tracing = true; 1885 program.stop = false; 1886 break; 1823 1887 } 1824 1888 return program.pc + 1; … … 1923 1987 const command = program.ajaxCommand; 1924 1988 switch (this.status) { 1925 case 200:1926 program.run(command.pc + 1);1927 break;1928 case 0:1929 break;1930 default:1931 let error = ``;1932 try {1933 error = JSON.parse(this.responseText ? this.responseText : `{}`);1934 } catch (err) {1935 program.runtimeError(command.lino, `Can't parse JSON`);1936 return 0;1937 }1938 try {1939 program.runtimeError(command.lino, error.message);1940 } catch (err) {1941 program.reportError(err, program);1942 }1943 break;1989 case 200: 1990 program.run(command.pc + 1); 1991 break; 1992 case 0: 1993 break; 1994 default: 1995 let error = ``; 1996 try { 1997 error = JSON.parse(this.responseText ? this.responseText : `{}`); 1998 } catch (err) { 1999 program.runtimeError(command.lino, `Can't parse JSON`); 2000 return 0; 2001 } 2002 try { 2003 program.runtimeError(command.lino, error.message); 2004 } catch (err) { 2005 program.reportError(err, program); 2006 } 2007 break; 1944 2008 } 1945 2009 } … … 1955 2019 getHandler: (name) => { 1956 2020 switch (name) { 1957 case `a`: 1958 return EasyCoder_Browser.A; 1959 case `alert`: 1960 return EasyCoder_Browser.Alert; 1961 case `attach`: 1962 return EasyCoder_Browser.Attach; 1963 case `audioclip`: 1964 return EasyCoder_Browser.Audioclip; 1965 case `blockquote`: 1966 return EasyCoder_Browser.BLOCKQUOTE; 1967 case `button`: 1968 return EasyCoder_Browser.BUTTON; 1969 case `clear`: 1970 return EasyCoder_Browser.Clear; 1971 case `convert`: 1972 return EasyCoder_Browser.Convert; 1973 case `create`: 1974 return EasyCoder_Browser.Create; 1975 case `disable`: 1976 return EasyCoder_Browser.Disable; 1977 case `div`: 1978 return EasyCoder_Browser.DIV; 1979 case `enable`: 1980 return EasyCoder_Browser.Enable; 1981 case `fieldset`: 1982 return EasyCoder_Browser.FIELDSET; 1983 case `file`: 1984 return EasyCoder_Browser.FILE; 1985 case `form`: 1986 return EasyCoder_Browser.FORM; 1987 case `get`: 1988 return EasyCoder_Browser.Get; 1989 case `h1`: 1990 return EasyCoder_Browser.H1; 1991 case `h2`: 1992 return EasyCoder_Browser.H2; 1993 case `h3`: 1994 return EasyCoder_Browser.H3; 1995 case `h4`: 1996 return EasyCoder_Browser.H4; 1997 case `h5`: 1998 return EasyCoder_Browser.H5; 1999 case `h6`: 2000 return EasyCoder_Browser.H6; 2001 case `history`: 2002 return EasyCoder_Browser.History; 2003 case `hr`: 2004 return EasyCoder_Browser.HR; 2005 case `img`: 2006 return EasyCoder_Browser.IMG; 2007 case `input`: 2008 return EasyCoder_Browser.INPUT; 2009 case `label`: 2010 return EasyCoder_Browser.LABEL; 2011 case `legend`: 2012 return EasyCoder_Browser.LEGEND; 2013 case `li`: 2014 return EasyCoder_Browser.LI; 2015 case `location`: 2016 return EasyCoder_Browser.Location; 2017 case `mail`: 2018 return EasyCoder_Browser.Mail; 2019 case `on`: 2020 return EasyCoder_Browser.On; 2021 case `p`: 2022 return EasyCoder_Browser.P; 2023 case `play`: 2024 return EasyCoder_Browser.Play; 2025 case `pre`: 2026 return EasyCoder_Browser.PRE; 2027 case `progress`: 2028 return EasyCoder_Browser.PROGRESS; 2029 case `put`: 2030 return EasyCoder_Browser.Put; 2031 case `remove`: 2032 return EasyCoder_Browser.Remove; 2033 case `select`: 2034 return EasyCoder_Browser.SELECT; 2035 case `scroll`: 2036 return EasyCoder_Browser.Scroll; 2037 case `section`: 2038 return EasyCoder_Browser.SECTION; 2039 case `set`: 2040 return EasyCoder_Browser.Set; 2041 case `span`: 2042 return EasyCoder_Browser.SPAN; 2043 case `table`: 2044 return EasyCoder_Browser.TABLE; 2045 case `tr`: 2046 return EasyCoder_Browser.TR; 2047 case `td`: 2048 return EasyCoder_Browser.TD; 2049 case `textarea`: 2050 return EasyCoder_Browser.TEXTAREA; 2051 case `trace`: 2052 return EasyCoder_Browser.Trace; 2053 case `ul`: 2054 return EasyCoder_Browser.UL; 2055 case `upload`: 2056 return EasyCoder_Browser.Upload; 2057 default: 2058 return false; 2021 case `a`: 2022 return EasyCoder_Browser.A; 2023 case `alert`: 2024 return EasyCoder_Browser.Alert; 2025 case `attach`: 2026 return EasyCoder_Browser.Attach; 2027 case `audioclip`: 2028 return EasyCoder_Browser.Audioclip; 2029 case `blockquote`: 2030 return EasyCoder_Browser.BLOCKQUOTE; 2031 case `button`: 2032 return EasyCoder_Browser.BUTTON; 2033 case `clear`: 2034 return EasyCoder_Browser.Clear; 2035 case `convert`: 2036 return EasyCoder_Browser.Convert; 2037 case `create`: 2038 return EasyCoder_Browser.Create; 2039 case `disable`: 2040 return EasyCoder_Browser.Disable; 2041 case `div`: 2042 return EasyCoder_Browser.DIV; 2043 case `enable`: 2044 return EasyCoder_Browser.Enable; 2045 case `fieldset`: 2046 return EasyCoder_Browser.FIELDSET; 2047 case `file`: 2048 return EasyCoder_Browser.FILE; 2049 case `form`: 2050 return EasyCoder_Browser.FORM; 2051 case `get`: 2052 return EasyCoder_Browser.Get; 2053 case `h1`: 2054 return EasyCoder_Browser.H1; 2055 case `h2`: 2056 return EasyCoder_Browser.H2; 2057 case `h3`: 2058 return EasyCoder_Browser.H3; 2059 case `h4`: 2060 return EasyCoder_Browser.H4; 2061 case `h5`: 2062 return EasyCoder_Browser.H5; 2063 case `h6`: 2064 return EasyCoder_Browser.H6; 2065 case `history`: 2066 return EasyCoder_Browser.History; 2067 case `hr`: 2068 return EasyCoder_Browser.HR; 2069 case `image`: 2070 return EasyCoder_Browser.IMAGE; 2071 case `img`: 2072 return EasyCoder_Browser.IMG; 2073 case `input`: 2074 return EasyCoder_Browser.INPUT; 2075 case `label`: 2076 return EasyCoder_Browser.LABEL; 2077 case `legend`: 2078 return EasyCoder_Browser.LEGEND; 2079 case `li`: 2080 return EasyCoder_Browser.LI; 2081 case `location`: 2082 return EasyCoder_Browser.Location; 2083 case `mail`: 2084 return EasyCoder_Browser.Mail; 2085 case `on`: 2086 return EasyCoder_Browser.On; 2087 case `p`: 2088 return EasyCoder_Browser.P; 2089 case `play`: 2090 return EasyCoder_Browser.Play; 2091 case `pre`: 2092 return EasyCoder_Browser.PRE; 2093 case `progress`: 2094 return EasyCoder_Browser.PROGRESS; 2095 case `put`: 2096 return EasyCoder_Browser.Put; 2097 case `remove`: 2098 return EasyCoder_Browser.Remove; 2099 case `select`: 2100 return EasyCoder_Browser.SELECT; 2101 case `scroll`: 2102 return EasyCoder_Browser.Scroll; 2103 case `section`: 2104 return EasyCoder_Browser.SECTION; 2105 case `set`: 2106 return EasyCoder_Browser.Set; 2107 case `span`: 2108 return EasyCoder_Browser.SPAN; 2109 case `table`: 2110 return EasyCoder_Browser.TABLE; 2111 case `tr`: 2112 return EasyCoder_Browser.TR; 2113 case `td`: 2114 return EasyCoder_Browser.TD; 2115 case `textarea`: 2116 return EasyCoder_Browser.TEXTAREA; 2117 case `trace`: 2118 return EasyCoder_Browser.Trace; 2119 case `ul`: 2120 return EasyCoder_Browser.UL; 2121 case `upload`: 2122 return EasyCoder_Browser.Upload; 2123 default: 2124 return false; 2059 2125 } 2060 2126 }, … … 2086 2152 } 2087 2153 switch (symbolRecord.keyword) { 2088 case `file`:2089 case `input`:2090 case `select`:2091 case `textarea`:2092 return {2093 domain: `browser`,2094 type: symbolRecord.keyword,2095 value: symbolRecord.name2096 };2154 case `file`: 2155 case `input`: 2156 case `select`: 2157 case `textarea`: 2158 return { 2159 domain: `browser`, 2160 type: symbolRecord.keyword, 2161 value: symbolRecord.name 2162 }; 2097 2163 } 2098 2164 return null; … … 2139 2205 return null; 2140 2206 } 2207 if (type === `style`) { 2208 const style = compiler.getNextValue(); 2209 if (compiler.tokenIs(`of`)) { 2210 if (compiler.nextIsSymbol()) { 2211 const symbolRecord = compiler.getSymbolRecord(); 2212 if (symbolRecord.extra === `dom`) { 2213 compiler.next(); 2214 return { 2215 domain: `browser`, 2216 type, 2217 style, 2218 target: symbolRecord.name 2219 }; 2220 } 2221 } 2222 } 2223 return null; 2224 } 2141 2225 if (type === `confirm`) { 2142 2226 const text = compiler.getNextValue(); … … 2211 2295 } 2212 2296 switch (type) { 2213 case `scroll`:2214 if (compiler.nextTokenIs(`position`)) {2215 compiler.next();2216 return {2217 domain: `browser`,2218 type: `scrollPosition`2219 };2220 }2221 return null;2222 case `document`:2223 if (compiler.nextTokenIs(`path`)) {2224 compiler.next();2225 return {2226 domain: `browser`,2227 type: `docPath`2228 };2229 }2230 return null;2231 case `parent`:2232 switch (compiler.nextToken()) {2233 case `name`:2234 compiler.next();2235 return {2236 domain: `browser`,2237 type: `varName`2238 };2239 case `index`:2240 compiler.next();2241 return {2242 domain: `browser`,2243 type: `varIndex`2244 };2245 }2246 return null;2247 case `history`:2248 if (compiler.nextTokenIs(`state`)) {2249 compiler.next();2250 return {2251 domain: `browser`,2252 type: `historyState`2253 };2254 }2255 return null;2297 case `scroll`: 2298 if (compiler.nextTokenIs(`position`)) { 2299 compiler.next(); 2300 return { 2301 domain: `browser`, 2302 type: `scrollPosition` 2303 }; 2304 } 2305 return null; 2306 case `document`: 2307 if (compiler.nextTokenIs(`path`)) { 2308 compiler.next(); 2309 return { 2310 domain: `browser`, 2311 type: `docPath` 2312 }; 2313 } 2314 return null; 2315 case `parent`: 2316 switch (compiler.nextToken()) { 2317 case `name`: 2318 compiler.next(); 2319 return { 2320 domain: `browser`, 2321 type: `varName` 2322 }; 2323 case `index`: 2324 compiler.next(); 2325 return { 2326 domain: `browser`, 2327 type: `varIndex` 2328 }; 2329 } 2330 return null; 2331 case `history`: 2332 if (compiler.nextTokenIs(`state`)) { 2333 compiler.next(); 2334 return { 2335 domain: `browser`, 2336 type: `historyState` 2337 }; 2338 } 2339 return null; 2256 2340 } 2257 2341 return null; … … 2264 2348 let content; 2265 2349 switch (value.type) { 2266 case `file`: 2350 case `file`: 2351 case `input`: 2352 case `select`: 2353 case `textarea`: 2354 symbolRecord = program.getSymbolRecord(value.value); 2355 target = symbolRecord.element[symbolRecord.index]; 2356 return { 2357 type: `constant`, 2358 numeric: false, 2359 content: target.value 2360 }; 2361 case `exists`: 2362 symbolRecord = program.getSymbolRecord(value.value); 2363 return { 2364 domain: `browser`, 2365 type: `boolean`, 2366 content: typeof symbolRecord.element[symbolRecord.index] !== `undefined` 2367 }; 2368 case `mobile`: 2369 return { 2370 domain: `browser`, 2371 type: `boolean`, 2372 content: (typeof window.orientation !== `undefined`) || (navigator.userAgent.indexOf(`IEMobile`) !== -1) 2373 }; 2374 case `portrait`: 2375 return { 2376 domain: `browser`, 2377 type: `boolean`, 2378 content: document.documentElement.clientWidth < document.documentElement.clientHeight 2379 }; 2380 case `landscape`: 2381 return { 2382 domain: `browser`, 2383 type: `boolean`, 2384 content: document.documentElement.clientWidth >= document.documentElement.clientHeight 2385 }; 2386 case `br`: 2387 return { 2388 type: `constant`, 2389 numeric: false, 2390 content: decodeURIComponent(`%3Cbr%20%2F%3E`) 2391 }; 2392 case `attributeOf`: 2393 symbolRecord = program.getSymbolRecord(value.symbol); 2394 const attribute = program.getValue(value.attribute); 2395 target = symbolRecord.element[symbolRecord.index]; 2396 if (attribute.indexOf(`data-`) === 0) { 2397 return program.getSimpleValue(target.dataset[attribute.substr(5)]); 2398 } 2399 return program.getSimpleValue(target[attribute]); 2400 case `style`: 2401 symbolRecord = program.getSymbolRecord(value.target); 2402 const style = program.getValue(value.style); 2403 target = symbolRecord.element[symbolRecord.index]; 2404 return program.getSimpleValue(target.style[style]); 2405 case `confirm`: 2406 return { 2407 type: `boolean`, 2408 content: window.confirm(program.getValue(value.text)) 2409 }; 2410 case `prompt`: 2411 const text = program.getValue(value.text); 2412 const pre = program.getValue(value.pre); 2413 return { 2414 type: `constant`, 2415 numeric: false, 2416 content: window.prompt(text, pre) 2417 }; 2418 case `contentOf`: 2419 symbolRecord = program.getSymbolRecord(value.symbol); 2420 target = symbolRecord.element[symbolRecord.index]; 2421 switch (symbolRecord.keyword) { 2267 2422 case `input`: 2268 case `select`:2269 2423 case `textarea`: 2270 symbolRecord = program.getSymbolRecord(value.value); 2271 target = symbolRecord.element[symbolRecord.index]; 2272 return { 2273 type: `constant`, 2274 numeric: false, 2275 content: target.value 2276 }; 2277 case `exists`: 2278 symbolRecord = program.getSymbolRecord(value.value); 2279 return { 2280 domain: `browser`, 2281 type: `boolean`, 2282 content: typeof symbolRecord.element[symbolRecord.index] !== `undefined` 2283 }; 2284 case `mobile`: 2285 return { 2286 domain: `browser`, 2287 type: `boolean`, 2288 content: (typeof window.orientation !== `undefined`) || (navigator.userAgent.indexOf(`IEMobile`) !== -1) 2289 }; 2290 case `portrait`: 2291 return { 2292 domain: `browser`, 2293 type: `boolean`, 2294 content: document.documentElement.clientWidth < document.documentElement.clientHeight 2295 }; 2296 case `landscape`: 2297 return { 2298 domain: `browser`, 2299 type: `boolean`, 2300 content: document.documentElement.clientWidth >= document.documentElement.clientHeight 2301 }; 2302 case `br`: 2303 return { 2304 type: `constant`, 2305 numeric: false, 2306 content: decodeURIComponent(`%3Cbr%20%2F%3E`) 2307 }; 2308 case `attributeOf`: 2309 symbolRecord = program.getSymbolRecord(value.symbol); 2310 const attribute = program.getValue(value.attribute); 2311 target = symbolRecord.element[symbolRecord.index]; 2312 if (attribute.indexOf(`data-`) === 0) { 2313 return program.getSimpleValue(target.dataset[attribute.substr(5)]); 2314 } 2315 return program.getSimpleValue(target[attribute]); 2316 case `confirm`: 2317 return { 2318 type: `boolean`, 2319 content: window.confirm(program.getValue(value.text)) 2320 }; 2321 case `prompt`: 2322 const text = program.getValue(value.text); 2323 const pre = program.getValue(value.pre); 2324 return { 2325 type: `constant`, 2326 numeric: false, 2327 content: window.prompt(text, pre) 2328 }; 2329 case `contentOf`: 2330 symbolRecord = program.getSymbolRecord(value.symbol); 2331 target = symbolRecord.element[symbolRecord.index]; 2332 switch (symbolRecord.keyword) { 2333 case `input`: 2334 case `textarea`: 2335 content = target.value; 2336 break; 2337 case `pre`: 2338 content = target.innerHTML; 2339 break; 2340 default: 2341 content = target.innerHTML.split(`\n`).join(``); 2342 break; 2343 } 2344 return { 2345 type: `constant`, 2346 numeric: false, 2347 content 2348 }; 2349 case `selectedItem`: 2350 symbolRecord = program.getSymbolRecord(value.symbol); 2351 element = symbolRecord.value[symbolRecord.index].content; 2352 target = document.getElementById(element); 2353 return { 2354 type: `constant`, 2355 numeric: false, 2356 content: target.options[target.selectedIndex].text 2357 }; 2358 case `widthOf`: 2359 symbolRecord = program.getSymbolRecord(value.symbol); 2360 content = symbolRecord.element[symbolRecord.index].offsetWidth; 2361 return { 2362 type: `constant`, 2363 numeric: true, 2364 content 2365 }; 2366 case `heightOf`: 2367 symbolRecord = program.getSymbolRecord(value.symbol); 2368 content = symbolRecord.element[symbolRecord.index].offsetHeight; 2369 return { 2370 type: `constant`, 2371 numeric: true, 2372 content 2373 }; 2374 case `color`: 2375 const styleValue = program.value.evaluate(program, value.value).content; 2376 const hex = styleValue.toString(16).padStart(6, `0`); 2377 return { 2378 type: `constant`, 2379 numeric: false, 2380 content: `#${hex}` 2381 }; 2382 case `docPath`: 2383 return { 2384 type: `constant`, 2385 numeric: false, 2386 content: program.docPath 2387 }; 2388 case `location`: 2389 return { 2390 type: `constant`, 2391 numeric: false, 2392 content: window.location.href 2393 }; 2394 case `historyState`: 2395 return { 2396 type: `constant`, 2397 numeric: false, 2398 content: window.history.state 2399 }; 2400 case `scrollPosition`: 2401 return { 2402 type: `constant`, 2403 numeric: true, 2404 content: scrollPosition 2405 }; 2406 case `varName`: 2407 return { 2408 type: `constant`, 2409 numeric: false, 2410 content: program.varName 2411 }; 2412 case `varIndex`: 2413 return { 2414 type: `constant`, 2415 numeric: true, 2416 content: program.varIndex 2417 }; 2418 case `key`: 2419 return { 2420 type: `constant`, 2421 numeric: false, 2422 content: program.key 2423 }; 2424 content = target.value; 2425 break; 2426 case `pre`: 2427 content = target.innerHTML; 2428 break; 2429 default: 2430 content = target.innerHTML.split(`\n`).join(``); 2431 break; 2432 } 2433 return { 2434 type: `constant`, 2435 numeric: false, 2436 content 2437 }; 2438 case `selectedItem`: 2439 symbolRecord = program.getSymbolRecord(value.symbol); 2440 element = symbolRecord.value[symbolRecord.index].content; 2441 target = document.getElementById(element); 2442 return { 2443 type: `constant`, 2444 numeric: false, 2445 content: target.options[target.selectedIndex].text 2446 }; 2447 case `widthOf`: 2448 symbolRecord = program.getSymbolRecord(value.symbol); 2449 content = symbolRecord.element[symbolRecord.index].offsetWidth; 2450 return { 2451 type: `constant`, 2452 numeric: true, 2453 content 2454 }; 2455 case `heightOf`: 2456 symbolRecord = program.getSymbolRecord(value.symbol); 2457 content = symbolRecord.element[symbolRecord.index].offsetHeight; 2458 return { 2459 type: `constant`, 2460 numeric: true, 2461 content 2462 }; 2463 case `color`: 2464 const styleValue = program.value.evaluate(program, value.value).content; 2465 const hex = styleValue.toString(16).padStart(6, `0`); 2466 return { 2467 type: `constant`, 2468 numeric: false, 2469 content: `#${hex}` 2470 }; 2471 case `docPath`: 2472 return { 2473 type: `constant`, 2474 numeric: false, 2475 content: program.docPath 2476 }; 2477 case `location`: 2478 return { 2479 type: `constant`, 2480 numeric: false, 2481 content: window.location.href 2482 }; 2483 case `historyState`: 2484 return { 2485 type: `constant`, 2486 numeric: false, 2487 content: window.history.state 2488 }; 2489 case `scrollPosition`: 2490 return { 2491 type: `constant`, 2492 numeric: true, 2493 content: scrollPosition 2494 }; 2495 case `varName`: 2496 return { 2497 type: `constant`, 2498 numeric: false, 2499 content: program.varName 2500 }; 2501 case `varIndex`: 2502 return { 2503 type: `constant`, 2504 numeric: true, 2505 content: program.varIndex 2506 }; 2507 case `key`: 2508 return { 2509 type: `constant`, 2510 numeric: false, 2511 content: program.key 2512 }; 2424 2513 } 2425 2514 } … … 2461 2550 test: (program, condition) => { 2462 2551 switch (condition.type) { 2463 case `confirm`:2464 return confirm(program.getValue(condition.value));2465 case `focus`:2466 const elementRecord = program.getSymbolRecord(condition.element);2467 return elementRecord.element[elementRecord.index] === document.activeElement;2552 case `confirm`: 2553 return confirm(program.getValue(condition.value)); 2554 case `focus`: 2555 const elementRecord = program.getSymbolRecord(condition.element); 2556 return elementRecord.element[elementRecord.index] === document.activeElement; 2468 2557 } 2469 2558 } -
easycoder/trunk/plugins/codemirror.js
r2089142 r2102119 9 9 case `init`: 10 10 const mode = compiler.nextToken(); 11 compiler.next(); 11 let profile = ``; 12 if (compiler.nextTokenIs(`profile`)) { 13 profile = compiler.getNextValue(); 14 } 12 15 compiler.addCommand({ 13 16 domain: `codemirror`, … … 15 18 lino, 16 19 action, 17 mode 20 mode, 21 profile 18 22 }); 19 23 return true; … … 91 95 program.require(`js`, `https://codemirror.net/lib/codemirror.js`, 92 96 function () { 93 program.require(`js`, `/wp-content/plugins/easycoder/plugins/codemirror-ecs.js`, 94 function () { 95 program.run(command.pc + 1); 96 }); 97 if (command.profile) { 98 program.require(`js`, program.getValue(command.profile), 99 function () { 100 program.run(command.pc + 1); 101 }); 102 } else { 103 program.run(command.pc + 1); 104 } 97 105 }); 98 106 }); -
easycoder/trunk/plugins/json.js
r2089142 r2102119 6 6 const lino = compiler.getLino(); 7 7 const request = compiler.nextToken(); 8 let item; 8 9 switch (request) { 9 10 case `set`: … … 139 140 break; 140 141 case `add`: 141 constitem = compiler.getNextValue();142 item = compiler.getNextValue(); 142 143 if (compiler.tokenIs(`to`)) { 143 144 if (compiler.nextIsSymbol()) { … … 158 159 } 159 160 break; 161 case `split`: 162 item = compiler.getNextValue(); 163 if (compiler.tokenIs(`into`)){ 164 if (compiler.nextIsSymbol()) { 165 const targetRecord = compiler.getSymbolRecord(); 166 if (targetRecord.keyword === `variable`) { 167 compiler.next(); 168 compiler.addCommand({ 169 domain: `json`, 170 keyword: `json`, 171 lino, 172 request, 173 item, 174 target: targetRecord.name 175 }); 176 return true; 177 } 178 } 179 } 180 break; 160 181 } 161 compiler.addWarning(`Unrecognised syntax in json`);182 compiler.addWarning(`Unrecognised json command syntax`); 162 183 return false; 163 184 }, … … 211 232 case `sort`: 212 233 targetRecord = program.getSymbolRecord(command.target); 213 let a = JSON.parse(program.getValue(targetRecord.value[targetRecord.index])).sort(); 234 const list = program.getValue(targetRecord.value[targetRecord.index]); 235 content = list ? JSON.stringify(JSON.parse(list).sort()) : list; 214 236 targetRecord.value[targetRecord.index] = { 215 237 type: `constant`, 216 238 numeric: false, 217 content : JSON.stringify(a)239 content 218 240 }; 219 241 break; … … 288 310 content = program.getValue(command.item); 289 311 targetRecord = program.getSymbolRecord(command.target); 290 record = JSON.parse(targetRecord.value[targetRecord.index].content); 312 const existing = targetRecord.value[targetRecord.index].content; 313 record = existing ? JSON.parse(existing) : []; 291 314 record.push(content); 292 315 targetRecord.value[targetRecord.index].content = JSON.stringify(record); 316 break; 317 case `split`: 318 content = program.getValue(command.item); 319 targetRecord = program.getSymbolRecord(command.target); 320 targetRecord.value[targetRecord.index].content = content.split(`\n`); 293 321 break; 294 322 } -
easycoder/trunk/plugins/rest.js
r2089142 r2102119 46 46 } 47 47 const url = compiler.getValue(); 48 if (!url) { 49 throw new Error(command.lino, `No URL present`); 50 } 48 51 let target = null; 49 52 if (compiler.tokenIs(`giving`)) { … … 82 85 const command = program[program.pc]; 83 86 const url = program.getValue(command.url); 84 const ajax = new XMLHttpRequest(); 85 ajax.command = command; 86 ajax.onreadystatechange = function () { 87 // console.log(`readyState:${ajax.readyState}, status:${ajax.status}`); 88 if (ajax.readyState === 4) { 89 const command = ajax.command; 90 switch (this.status) { 91 case 200: 92 case 201: 93 var content = this.responseText; 94 if (content.length > 0 && ![`[`, `{`].includes(content.charAt(0))) { 95 content = program.decode(content); 96 } 97 if (command.target) { 98 const targetRecord = program.getSymbolRecord(command.target); 99 targetRecord.value[targetRecord.index] = { 100 type: `constant`, 101 numeric: false, 102 content 103 }; 104 } 105 program.run(command.pc + 1); 106 break; 107 case 0: 108 break; 109 default: 110 if (command.onError) { 111 program.errorMessage = this.responseText; 112 program.run(command.onError); 113 } else { 114 const error = this.responseText; 115 program.runtimeError(command.lino, error); 116 } 117 break; 118 } 87 const request = new XMLHttpRequest(); 88 request.command = command; 89 90 request.onload = function () { 91 var content = request.responseText; 92 if (content.length > 0 && ![`[`, `{`].includes(content.charAt(0))) { 93 content = program.decode(content); 94 } 95 if (command.target) { 96 const targetRecord = program.getSymbolRecord(command.target); 97 targetRecord.value[targetRecord.index] = { 98 type: `constant`, 99 numeric: false, 100 content 101 }; 102 } 103 program.run(command.pc + 1); 104 }; 105 106 request.onerror = function () { 107 if (command.onError) { 108 program.errorMessage = this.responseText; 109 program.run(command.onError); 110 } else { 111 const error = this.responseText; 112 program.runtimeError(command.lino, error); 119 113 } 120 114 }; 121 if (!url) { 122 program.runtimeError(command.lino, `No URL present`); 123 } 124 const path = url.startsWith(`http`) ? url : 125 `${window.location.origin}/wp-content/plugins/easycoder/rest.php/${url}`; 115 116 const path = url.startsWith(`http`) ? url : `${window.location.origin}/${EasyCoder_Plugins.rest()}/${url}`; 126 117 switch (command.request) { 127 118 case `get`: 128 119 // console.log(`GET from ${path}`); 129 ajax.open(`GET`, path);130 ajax.send();120 request.open(`GET`, path); 121 request.send(); 131 122 break; 132 123 case `post`: 133 124 const value = program.getValue(command.value); 134 125 console.log(`POST to ${path}`); 135 ajax.open(`POST`, path);126 request.open(`POST`, path); 136 127 if (value.charAt(0) === `{` || !isNaN(value)) { 137 ajax.setRequestHeader(`Content-Type`, `application/json; charset=UTF-8`);128 request.setRequestHeader(`Content-Type`, `application/json; charset=UTF-8`); 138 129 // console.log(`value=${value}`); 139 ajax.send(value.charAt(0) === `{` ? value : value.toString());130 request.send(value.charAt(0) === `{` ? value : value.toString()); 140 131 } else { 141 ajax.setRequestHeader(`Content-Type`, `application/text; charset=UTF-8`);132 request.setRequestHeader(`Content-Type`, `application/text; charset=UTF-8`); 142 133 // console.log(`value=${program.encode(value)}`); 143 ajax.send(program.encode(value));134 request.send(program.encode(value)); 144 135 } 145 136 break; -
easycoder/trunk/plugins/svg.js
r2052097 r2102119 157 157 } 158 158 } 159 const container = document.getElementById(parentRecord.value[parentRecord.index].content);159 const container = parentRecord.element[parentRecord.index]; 160 160 const element = document.createElementNS(ns, command.type); 161 161 symbolRecord.element[symbolRecord.index] = element; -
easycoder/trunk/readme.txt
r2089142 r2102119 53 53 54 54 == Changelog == 55 56 = 2.3.1 7-jun-2019 = 57 * Bug fixes & updates to support learn-to-code 55 58 56 59 = 2.3.0 16-may-2019 = -
easycoder/trunk/rest.php
r2038748 r2102119 70 70 foreach ($files as $file) { 71 71 if (strpos($file, '.') !== 0) { 72 if (!is_dir("$path/$file")) { 73 if ($flag) { 74 print ','; 75 } else { 76 $flag = true; 77 } 78 $ext = substr($file, strrpos($file, '.') + 1); 79 $type = $ext; 80 switch (strtolower($ext)) { 81 case 'jpg': 82 case 'png': 83 case 'gif': 84 $type = 'img'; 85 break; 86 } 87 print "{\"name\":\"$file\",\"type\":\"$type\"}"; 88 } 89 } 72 if (!is_dir("$path/$file")) { 73 if ($flag) { 74 print ','; 75 } else { 76 $flag = true; 77 } 78 $type = 'file'; 79 $p = strrpos($file, '.'); 80 if ($p > 0) { 81 $ext = substr($file, $p + 1); 82 $type = $ext; 83 switch (strtolower($ext)) { 84 case 'jpg': 85 case 'png': 86 case 'gif': 87 $type = 'img'; 88 break; 89 } 90 } 91 } 92 print "{\"name\":\"$file\",\"type\":\"$type\"}"; 93 } 90 94 } 91 95 print ']';
Note: See TracChangeset
for help on using the changeset viewer.