Plugin Directory

Changeset 2052097


Ignore:
Timestamp:
03/17/2019 03:29:26 PM (7 years ago)
Author:
gtanyware
Message:

Version 2.2.1, with various updates & bug fixes

Location:
easycoder/trunk
Files:
1 added
10 edited

Legend:

Unmodified
Added
Removed
  • easycoder/trunk/easycoder-min.js

    r2038748 r2052097  
    4444a.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;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=
    4545a.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();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},
    46 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();a.next();var b=a.getValue();if(a.tokenIs("with")){a.next();var d=a.getValue();if(a.tokenIs("in")&&(a.next(),a.isSymbol())){var e=a.getSymbolRecord();a.next();if(e.isValueHolder)return a.addCommand({domain:"core",
    47 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]={type:"constant",numeric:!1,content:a};return c.pc+1}},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=
    48 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 f=e.name}a.addCommand({domain:"core",keyword:"run",lino:c,script:b,imports:d,module:f});return!0},run:function(a){a.nextPc=a.pc+1;a.runScript(a);return 0}},Script:{compile:function(a){var c=
    49 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.getNextValue();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=
    50 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.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();
    51 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=a.getSymbolRecord(),"variable"===
    52 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",symbol:b,value:d}),!0}if(a.tokenIs("encoding")){if(a.nextTokenIs("to"))return b=
    53 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=a[a.pc];switch(c.request){case "setBoolean":var b=a.getSymbolRecord(c.target);
    54 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);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);
    55 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]="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=
    56 a.getValue(c.payload)}return c.pc+1}},Stop:{compile:function(a){var c=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 f=a.getToken();a.next();a.addCommand({domain:"core",keyword:"take",lino:c,value1:b,value2:d,
    57 target:f})}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=a.getValue();if(a.tokenIs("giving"))return a.next(),f=a.getToken(),a.next(),a.addCommand({domain:"core",keyword:"take",lino:c,value1:b,value2:d,target:f}),!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 f=
    58 e.value[e.index];d?(a=a.getValue(d)-a.getValue(b),e.value[e.index]={type:"constant",numeric:!0,content:a}):(f.numeric||a.nonNumericValueError(c,lino),a=a.getValue(f)-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=
    59 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,b.name);return c.pc+1}},Trigger:{compile:function(a){var c=a.getLino();a.next();return a.tokenIs("parent")?(a.next(),a.addCommand({domain:"core",keyword:"trigger",lino:c,module:"parent"}),!0):a.isSymbol()&&(moduleRecord=a.getSymbolRecord(),a.next(),"module"===moduleRecord.keyword)?(h=moduleRecord.name,a.addCommand({domain:"core",
    60 keyword:"trigger",lino:c,module:h}),!0):!1},run:function(a){var c=a[a.pc];if("parent"===c.module)a.parent&&a.parent.trigger(!0);else{var b=a.getSymbolRecord(c.module);if(b.exporter){exporterRecord=b.exporter.getSymbolRecord(c.module);var d=exporterRecord.program}else d=b.program;d?d.trigger():a.runtimeError(c.lino,b.name+" has not been initialized")}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=
    61 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},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();
    62 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)?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;
    63 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;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;
    64 case "put":return b.Put;case "replace":return b.Replace;case "return":return b.Return;case "run":return b.Run;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;case "toggle":return b.Toggle;case "trigger":return b.Trigger;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 '"+
    65 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",name:c};case "variable":return a.nextTokenIs("modulo")?(a=a.getNextValue(),{domain:"core",type:"modulo",name:c,value:a}):{domain:"core",type:"symbol",name:c}}return null}c=a.getToken();if("true"===c)return a.next(),{domain:"core",
    66 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(),{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(),
    67 {domain:"core",type:"tan",angle_t:c,radius_t:a};if("empty"===c)return a.next(),{domain:"core",type:"empty"};if("now"===c)return a.next(),{domain:"core",type:"now"};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",
    68 value:a.getValue()};if("element"===c){c=a.getNextValue();if(a.tokenIs("of")&&a.nextIsSymbol()){var b=a.getSymbolRecord();a.next();if("variable"===b.keyword)return{domain:"core",type:"element",element:c,symbol:b.name}}return 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")&&
    69 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=a.getNextValue(),{domain:"core",type:c,count:b,value:a};break;case "from":b=a.getNextValue();var d=a.tokenIs("to")?a.getNextValue():
    70 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()&&(c=a.getSymbolRecord(),"callback"===c.keyword))return a.next(),{domain:"core",type:"payload",callback:c.name};break;
    71 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=a.evaluate(c.range),{type:"constant",numeric:!0,content:Math.floor(Math.random()*a.content)};case "cos":var b=a.getValue(c.angle_c);
    72 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*parseFloat(b))*a,10)};case "valueOf":return a=parseInt(a.getValue(c.value)),{type:"constant",numeric:!0,
    73 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{type:"constant",numeric:!1,content:a.getValue(c.value).substr(rstr.length-a.getValue(c.count))};case "from":b=a.getValue(c.from);var d=c.to?a.getVaue(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=
    74 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 "empty":return{type:"constant",numeric:!1,content:""};case "now":return{type:"constant",numeric:!0,content:Date.now()/1E3};case "newline":return{type:"constant",
    75 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()};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,
    76 "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);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,
    77 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},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",
    78 value1:c};case "even":return a.next(),{domain:"core",type:"even",value1:c};case "odd":return a.next(),{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 f=a.getValue();return{domain:"core",type:"less",value1:c,value2:f,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",
    79 type:"boolean",value:c}}catch(l){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 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),
    80 c.negate?0<=a:0>a;case "not":return!a.getValue(c.value)}return!1}}};h.exports=b},{}],6:[function(d,h,f){var e=this,b=d("./Tokenise"),a=d("./Compile"),c=d("./Run"),g=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>',
    81 a.style.display="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":
    82 "Runtime error in '"+b.script+"'";b+=":\n";var g=e-5;for(g=0>g?0:g;g<e;g++){var l=(""+(g+1)).padStart(4," ");b+=l+" "+d[g].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];
    83 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 g.encode(a,this.encoding)},decode:function(a){return g.decode(a,this.encoding)},evaluate:function(a){return g.evaluate(this,a)},getValue:function(a){return g.getValue(this,a)},getFormattedValue:function(a){a=g.evaluate(this,a);return a.numeric?a.content:'{"'===a.content.substr(0,2)||"["===a.content.charAt(0)?
    84 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(this,a))},trigger:function(){this.onTrigger&&c(this,this.onTrigger)},register:function(a){k.program=a},require:function(a,c,b){a=document.createElement("script");a.type="text/javascript";a.src=c;a.onload=function(){console.log(Date.now()-k.timestamp+" ms: Library "+c+" loaded");
    85 b()};document.head.appendChild(a)},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 f=c.tokens;this.compiling=!0;var h=Date.now();a.value=g;a.condition=m;a.domain=k.domain;a.imports=b;b=a.compile(f);var l=Date.now();console.log(l-k.timestamp+" ms: Compiled "+f.length+" tokens in "+(l-
    86 h+" ms"));this.compiling=!1;b.EasyCoder=k;b.value=g;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;b.getPlugin=this.getPlugin;b.addLocalPlugin=this.addLocalPlugin;b.getPluginsPath=
    87 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},tokeniseScript:function(a,d,e,g){var f=null,h=Date.now();a=b.tokenise(a);var l=
    88 Date.now();console.log(l-k.timestamp+" ms: Tokenised "+a.scriptLines.length+" lines in "+(l-h+" ms"));try{f=k.compileScript(a,d,e,g)}catch(u){"stop"!==u.message&&this.reportError(u,k.program,a)}this.setupTracer();f&&c(f,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]},getPlugin:function(a,b,c){k.domain[a]?c():
    89 (a=document.createElement("script"),a.type="text/javascript",a.src=b,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},loadPluginJs:function(a){console.log(Date.now()-
    90 k.timestamp+" ms: Load "+a+"/easycoder/plugins.js");var b=document.createElement("script");b.src=""+window.location.origin+a+"/easycoder/plugins.js";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);k.pluginsPath=a},start:function(a){e.source=
    91 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,f){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=c.shift(),b.watchdog=0,a={};;){if(1E6<b.watchdog){b.lino=
    92 b[b.pc].lino;b.reportError(Error("Program runaway intercepted.\nHave you forgotten to increment a loop counter?",b),b);break}b.watchdog++;var f=b[b.pc].domain;b.debugStep&&console.log(b.script+" "+b.pc+" "+f+":"+b[b.pc].keyword);var h=b.domain[f];if(!h){b.runtimeError(b[b.pc].lino,"Unknown domain '"+f+"'");break}b.pc=h.run(b);if(!b.pc)break;if(b.stop){b.tracing=!1;return}if(b.tracing){f=b[b.pc];h=b.source.scriptLines;var k=d(h),l=document.getElementById("easycoder-tracer");if(!l){b.runtimeError(f.lino,
    93 "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 g=e.value[a];n=g?n+(g.content+" "):n+"undefined "}else n=(e=e.value[e.index])?n+(a+": "+e.content):n+(a+": undefined");switch(b.tracer.alignment){case "horizontal":c<
    94 d.length-1&&(n+=", ");break;case "vertical":n+="<br>"}});n+="<hr>";for(var q="",r=5;0<r;r--)f.lino&&(q+='<input type="text" name="'+r+'"'+('value="'+h[f.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=
    95 "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,f){var e={markComments:function(b){var a=b.list,
    96 c=void 0===b.index?0:b.index,d=void 0===b.inComment?!1:b.inComment,f=void 0===b.newList?[]:b.newList;if(c>=a.length)return f;var h=a[c];b=h.lino;h=h.token;var k={list:a,index:c+1,inComment:!1,newList:f.concat({lino:b,index:c,token:h})};f={list:a,index:c+1,inComment:!0,newList:f.concat({lino:b,index:c,comment:!0,token:h})};return d&&0<c&&b===a[c-1].lino?e.markComments(f):"!"===h.charAt(0)?e.markComments(f):e.markComments(k)},findStrings:function(b){var a=b.original,c=b.line,d=void 0===b.inComment?
    97 !1:b.inComment;b=void 0===b.inQuote?!1:b.inQuote;var f=c.charAt(0),h=b&&[" ","\\t"].includes(f)?"\\s":f;if(1===c.length)return h;c=c.substring(1);if("!"===f&&!b)return f+e.findStrings({original:a,line:c,inComment:!0,inQuote:!1});if("`"===f&&!d&&!b)return f+e.findStrings({original:a,line:c,inComment:d,inQuote:!0});if("`"===f&&b)return f+e.findStrings({original:a,line:c,inComment:d,inQuote:!1});if(!d&&!b&&!f.match(/[A-z0-9_\-+*/\- \t]/)){if(["'",'"'].includes(f))throw Error('Bad syntax in "'+a+'":\nStrings in EasyCoder must be enclosed in backticks.');
    98 throw Error('Unrecognised character "'+f+'" in "'+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,
    99 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,f){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);
    100 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));
    101 return a}return c},doValue:function(b,a){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,
    102 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,"+"));case "sanitize":return b.normalize("NFD").replace(/[\u0300-\u036f]/g,
    103 "")}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]);
     46run: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",keyword:"replace",
     47lino: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]={type:"constant",numeric:!1,content:a};return c.pc+1}},Require:{compile:function(a){var c=a.getLino(),b=a.getNextValue();a.addCommand({domain:"core",keyword:"require",lino:c,url:b});return!0},run:function(a){var c=a[a.pc];a.require(a,a.getValue(c.url),function(){a.run(c.pc+
     481)});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();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("'"+
     49e.name+"' is not a module");var f=e.name}a.addCommand({domain:"core",keyword:"run",lino:c,script:b,imports:d,module:f});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+
     501}},Script:{compile:function(a){var c=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"!==
     51d.keyword)throw Error("'"+d.name+"' 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.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();
     52if(!b.isValueHolder)return!1;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")&&
     53a.nextIsSymbol()&&(d=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,
     54request:"setElements",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}),
     55!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]={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);
     56b.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]="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",
     57numeric:!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();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();
     58a.next();var f=a.getToken();a.next();a.addCommand({domain:"core",keyword:"take",lino:c,value1:b,value2:d,target:f})}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=a.getValue();if(a.tokenIs("giving"))return a.next(),f=a.getToken(),a.next(),a.addCommand({domain:"core",keyword:"take",lino:c,value1:b,value2:d,target:f}),!0;a.warning("core "+e.name+': Expected "giving"')}return!1},run:function(a){var c=
     59a[a.pc],b=c.value1,d=c.value2,e=a.getSymbolRecord(c.target);if(e.isValueHolder){var f=e.value[e.index];d?(a=a.getValue(d)-a.getValue(b),e.value[e.index]={type:"constant",numeric:!0,content:a}):(f.numeric||a.nonNumericValueError(c,lino),a=a.getValue(f)-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",
     60keyword:"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,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();
     61d=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},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});
     62c=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)?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;
     63case "divide":return b.Divide;case "encode":return b.Encode;case "end":return b.End;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;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;
     64case "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;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)},
     65isNegate: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",name:c};case "variable":return a.nextTokenIs("modulo")?(a=a.getNextValue(),{domain:"core",type:"modulo",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(),
     66{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(),{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"===
     67c)return a.next(),{domain:"core",type:"empty"};if("now"===c)return a.next(),{domain:"core",type:"now"};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){c=a.getNextValue();
     68if(a.tokenIs("of")&&a.nextIsSymbol()){var b=a.getSymbolRecord();a.next();if("variable"===b.keyword)return{domain:"core",type:"element",element:c,symbol:b.name}}return 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(),
     69a.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=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(),
     70{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()&&(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",
     71type: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=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",
     72numeric:!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*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",
     73numeric:!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{type:"constant",numeric:!1,content:a.getValue(c.value).substr(rstr.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",
     74numeric:!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 "empty":return{type:"constant",numeric:!1,content:""};case "now":return{type:"constant",numeric:!0,content:Date.now()/1E3};case "newline":return{type:"constant",numeric:!1,content:"\n"};case "break":return{type:"constant",
     75numeric:!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()};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",
     76numeric:!1,content:"object"===typeof d?JSON.stringify(d):d};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=
     77a.message,{type:"constant",numeric:!1,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",
     78type:"even",value1:c};case "odd":return a.next(),{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 f=a.getValue();return{domain:"core",type:"less",value1:c,value2:f,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"),
     790}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}}};
     80h.exports=b},{}],6:[function(d,h,f){var e=this,b=d("./Tokenise"),a=d("./Compile"),c=d("./Run"),g=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=
     81"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 '"+
     82b.script+"'";b+=":\n";var g=e-5;for(g=0>g?0:g;g<e;g++){var l=(""+(g+1)).padStart(4," ");b+=l+" "+d[g].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):
     83a.exporter&&a.exporter!=this?a.exporter.getSymbolRecord(a.exportedName):a},verifySymbol:function(a){return this.symbols.hasOwnProperty(a)},encode:function(a){return g.encode(a,this.encoding)},decode:function(a){return g.decode(a,this.encoding)},evaluate:function(a){return g.evaluate(this,a)},getValue:function(a){return g.getValue(this,a)},getFormattedValue:function(a){a=g.evaluate(this,a);return a.numeric?a.content:'{"'===a.content.substr(0,2)||"["===a.content.charAt(0)?JSON.stringify(JSON.parse(a.content),
     84null,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){a=document.createElement("script");a.type="text/javascript";a.src=c;a.onload=function(){console.log(Date.now()-k.timestamp+" ms: Library "+c+" loaded");b()};document.head.appendChild(a)},
     85isUndefined: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 f=c.tokens;this.compiling=!0;var h=Date.now();a.value=g;a.condition=m;a.domain=k.domain;a.imports=b;b=a.compile(f);var l=Date.now();console.log(l-k.timestamp+" ms: Compiled "+f.length+" tokens in "+(l-h+" ms"));this.compiling=!1;b.EasyCoder=
     86k;b.value=g;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;b.getPlugin=this.getPlugin;b.addLocalPlugin=this.addLocalPlugin;b.getPluginsPath=this.getPluginsPath;b.getSymbolRecord=
     87this.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},tokeniseScript:function(a,d,e,g){var f=null,h=Date.now();a=b.tokenise(a);var l=Date.now();console.log(l-k.timestamp+
     88" ms: Tokenised "+a.scriptLines.length+" lines in "+(l-h+" ms"));try{f=k.compileScript(a,d,e,g)}catch(u){"stop"!==u.message&&this.reportError(u,k.program,a)}this.setupTracer();f&&c(f,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]},getPlugin:function(a,b,c){k.domain[a]?c():(a=document.createElement("script"),a.type=
     89"text/javascript",a.src=b,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},loadPluginJs:function(a){console.log(Date.now()-k.timestamp+" ms: Load "+a+"/easycoder/plugins.js");
     90var b=document.createElement("script");b.src=""+window.location.origin+a+"/easycoder/plugins.js";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);k.pluginsPath=a},start:function(a){e.source=a;a=window.location.pathname;a.endsWith("/")&&(a=a.slice(0,
     91-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,f){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=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?",
     92b),b);break}b.watchdog++;var f=b[b.pc].domain;b.debugStep&&console.log(b.script+" "+b.pc+" "+f+":"+b[b.pc].keyword);var h=b.domain[f];if(!h){b.runtimeError(b[b.pc].lino,"Unknown domain '"+f+"'");break}b.pc=h.run(b);if(!b.pc)break;if(b.stop){b.tracing=!1;return}if(b.tracing){f=b[b.pc];h=b.source.scriptLines;var k=d(h),l=document.getElementById("easycoder-tracer");if(!l){b.runtimeError(f.lino,"Element 'easycoder-tracer' was not found");return}l.style.display="block";l.style.visibility="visible";var n=
     93"";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 g=e.value[a];n=g?n+(g.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--)f.lino&&(q+='<input type="text" name="'+
     94r+'"'+('value="'+h[f.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="none";try{e(b,b.resume)}catch(t){var c="Error in run handler: "+t.message;console.log(c);alert(c)}}}(a);
     95a.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,f){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,f=void 0===b.newList?[]:b.newList;
     96if(c>=a.length)return f;var h=a[c];b=h.lino;h=h.token;var k={list:a,index:c+1,inComment:!1,newList:f.concat({lino:b,index:c,token:h})};f={list:a,index:c+1,inComment:!0,newList:f.concat({lino:b,index:c,comment:!0,token:h})};return d&&0<c&&b===a[c-1].lino?e.markComments(f):"!"===h.charAt(0)?e.markComments(f):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 f=c.charAt(0),h=b&&[" ","\\t"].includes(f)?"\\s":
     97f;if(1===c.length)return h;c=c.substring(1);if("!"===f&&!b)return f+e.findStrings({original:a,line:c,inComment:!0,inQuote:!1});if("`"===f&&!d&&!b)return f+e.findStrings({original:a,line:c,inComment:d,inQuote:!0});if("`"===f&&b)return f+e.findStrings({original:a,line:c,inComment:d,inQuote:!1});if(!d&&!b&&!f.match(/[A-z0-9_\-+*/\- \t]/)){if(["'",'"'].includes(f))throw Error('Bad syntax in "'+a+'":\nStrings in EasyCoder must be enclosed in backticks.');throw Error('Unrecognised character "'+f+'" in\n"'+
     98a+'".');}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,token:a.token.split("\\s").join(" ")}});a=e.markComments({list:a}).filter(function(a){return!a.comment});
     99return{scriptLines:b,tokens:a}}};h.exports=e},{}],9:[function(d,h,f){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");
     100}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));return a}return c},doValue:function(b,a){switch(a.type){case "cat":return{type:"constant",numeric:!1,
     101content: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}},evaluate:function(b,a){if(!a)return{type:"constant",
     102numeric:!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},decode:function(b,a){if(b)switch(a){case "ec":return b.replace(/~dq~/g,
     103'"').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

    r2038748 r2052097  
    14151415        compile: compiler => {
    14161416            const lino = compiler.getLino();
    1417             compiler.next();
    1418             const original = compiler.getValue();
     1417            const original = compiler.getNextValue();
    14191418            if (compiler.tokenIs(`with`)) {
    1420                 compiler.next();
    1421                 const replacement = compiler.getValue();
     1419                const replacement = compiler.getNextValue();
    14221420                if (compiler.tokenIs(`in`)) {
    1423                     compiler.next();
    1424                     if (compiler.isSymbol()) {
     1421                    if (compiler.nextIsSymbol()) {
    14251422                        const targetRecord = compiler.getSymbolRecord();
    14261423                        compiler.next();
     
    14611458    },
    14621459
     1460    Require: {
     1461
     1462        compile: compiler => {
     1463            const lino = compiler.getLino();
     1464            const url = compiler.getNextValue();
     1465            compiler.addCommand({
     1466                domain: `core`,
     1467                keyword: `require`,
     1468                lino,
     1469                url
     1470            });
     1471            return true;
     1472        },
     1473
     1474        // runtime
     1475
     1476        run: program => {
     1477            const command = program[program.pc];
     1478            program.require(program, program.getValue(command.url), function () {
     1479                program.run(command.pc + 1);
     1480            });
     1481            return 0;
     1482        }
     1483    },
     1484
    14631485    Return: {
    14641486
     
    15311553    },
    15321554
     1555    Sanitize: {
     1556
     1557        compile: compiler => {
     1558            const lino = compiler.getLino();
     1559            if (compiler.nextIsSymbol()) {
     1560                const name = compiler.getToken();
     1561                compiler.next();
     1562                compiler.addCommand({
     1563                    domain: `core`,
     1564                    keyword: `sanitize`,
     1565                    lino,
     1566                    name
     1567                });
     1568                return true;
     1569            }
     1570            return false;
     1571        },
     1572
     1573        run: program => {
     1574            const command = program[program.pc];
     1575            const symbolRecord = program.getSymbolRecord(command.name);
     1576            const value = symbolRecord.value[symbolRecord.index];
     1577            value.content = JSON.stringify(JSON.parse(value.content));
     1578            return command.pc + 1;
     1579        }
     1580    },
     1581
    15331582    Script: {
    15341583
     
    15591608        compile: compiler => {
    15601609            const lino = compiler.getLino();
    1561             const message = compiler.getNextValue();
    1562             var recipient;
     1610            let message = ``;
     1611            if (!compiler.nextTokenIs(`to`)) {
     1612                message = compiler.getValue();
     1613            }
    15631614            if (compiler.tokenIs(`to`)) {
     1615                var recipient;
    15641616                if (compiler.nextTokenIs(`parent`)) {
    15651617                    recipient = `parent`;
     
    19692021            } else {
    19702022                program.VariableDoesNotHoldAValueError(command.lino, symbol.name);
    1971             }
    1972             return command.pc + 1;
    1973         }
    1974     },
    1975 
    1976     Trigger: {
    1977 
    1978         compile: compiler => {
    1979             const lino = compiler.getLino();
    1980             compiler.next();
    1981             if (compiler.tokenIs(`parent`)) {
    1982                 compiler.next();
    1983                 compiler.addCommand({
    1984                     domain: `core`,
    1985                     keyword: `trigger`,
    1986                     lino,
    1987                     module: `parent`
    1988                 });
    1989                 return true;
    1990             }
    1991             if (compiler.isSymbol()) {
    1992                 moduleRecord = compiler.getSymbolRecord();
    1993                 compiler.next();
    1994                 if (moduleRecord.keyword === `module`) {
    1995                     module = moduleRecord.name;
    1996                     compiler.addCommand({
    1997                         domain: `core`,
    1998                         keyword: `trigger`,
    1999                         lino,
    2000                         module
    2001                     });
    2002                     return true;
    2003                 }
    2004             }
    2005             return false;
    2006         },
    2007 
    2008         // runtime
    2009 
    2010         run: program => {
    2011             const command = program[program.pc];
    2012             if (command.module === `parent`) {
    2013                 if (program.parent) {
    2014                     program.parent.trigger(true);
    2015                 }
    2016             } else {
    2017                 const moduleRecord = program.getSymbolRecord(command.module);
    2018                 var p;
    2019                 if (moduleRecord.exporter) {
    2020                     exporterRecord = moduleRecord.exporter.getSymbolRecord(command.module);
    2021                     p = exporterRecord.program;
    2022                 } else {
    2023                     p = moduleRecord.program;
    2024                 }
    2025                 if (p) {
    2026                     p.trigger();
    2027                 } else {
    2028                     program.runtimeError(command.lino, `${moduleRecord.name} has not been initialized`);
    2029                 }
    20302023            }
    20312024            return command.pc + 1;
     
    21922185            case `replace`:
    21932186                return EasyCoder_Core.Replace;
     2187            case `require`:
     2188                return EasyCoder_Core.Require;
    21942189            case `return`:
    21952190                return EasyCoder_Core.Return;
    21962191            case `run`:
    21972192                return EasyCoder_Core.Run;
     2193            case `sanitize`:
     2194                return EasyCoder_Core.Sanitize;
    21982195            case `script`:
    21992196                return EasyCoder_Core.Script;
     
    22082205            case `toggle`:
    22092206                return EasyCoder_Core.Toggle;
    2210             case `trigger`:
    2211                 return EasyCoder_Core.Trigger;
    22122207            case `variable`:
    22132208                return EasyCoder_Core.Variable;
     
    26212616                case `from`:
    26222617                    const from = program.getValue(value.from);
    2623                     const to = value.to ? program.getVaue(value.to) : null;
     2618                    const to = value.to ? program.getValue(value.to) : null;
    26242619                    const fstr = program.getValue(value.value);
    26252620                    return {
     
    27102705                    const property = program.getValue(value.property);
    27112706                    const propertyRecord = program.getSymbolRecord(value.symbol);
    2712                     const propertyContent = program.getValue(propertyRecord.value[propertyRecord.index]);
     2707                    let propertyContent = program.getValue(propertyRecord.value[propertyRecord.index]);
    27132708                    var content = ``;
    27142709                    if (property && propertyContent) {
     
    34523447                    throw new Error(`Bad syntax in "${original}":\nStrings in EasyCoder must be enclosed in backticks.`);
    34533448                } else {
    3454                     throw new Error(`Unrecognised character "${c}" in "${original}".`);
     3449                    throw new Error(`Unrecognised character "${c}" in\n"${original}".`);
    34553450                }
    34563451            }
  • easycoder/trunk/easycoder.php

    r2038748 r2052097  
    44  * Plugin URI: https://easycoder.software
    55  * 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.2.0
     6  * Version: 2.2.1
    77  * Author: EasyCoder Software
    88  * Author URI: https://easycoder.software
     
    1717  function easycoder_enqueue_script() {   
    1818    wp_enqueue_script('easycoder_script', plugin_dir_url( __FILE__ )
    19             . 'easycoder-min.js', array(), '2.2.0');
     19            . 'easycoder-min.js', array(), '2.2.1');
    2020  }
    2121 
  • easycoder/trunk/plugins-sample.js

    r2038748 r2052097  
    22
    33    getGlobalPlugins: (timestamp, path, setPluginCount, getPlugin, addPlugin) => {
    4      
     4
    55        console.log(`${Date.now() - timestamp} ms: Load plugins`);
    6    
     6
    77        /*
    8     * To include EasyCoder global plugins in your site, add them here.
    9     * It adds the selected plugins to every page of your site that uses EasyCoder.
    10     * You can also dynamically load plugins before launching a script; see getLocalPlugin() below.
    11     *
    12     * setPluginCount() sets the number of plugins to add.
    13     * getPlugin() loads a plugin from any URL.
    14     * addPlugin() adds it to the EasyCoder system.
    15     * When all the plugins have been added, EasyCoder starts up.
    16     */
     8        * To include EasyCoder global plugins in your site, add them here.
     9        * It adds the selected plugins to every page of your site that uses EasyCoder.
     10        * You can also dynamically load plugins before launching a script; see getLocalPlugin() below.
     11        *
     12        * setPluginCount() sets the number of plugins to add.
     13        * getPlugin() loads a plugin from any URL.
     14        * addPlugin() adds it to the EasyCoder system.
     15        * When all the plugins have been added, EasyCoder starts up.
     16        */
    1717
    18         setPluginCount(3); // *** IMPORTANT *** the number of plugins you will be adding
    19    
     18        setPluginCount(2); // *** IMPORTANT *** the number of plugins you will be adding
     19
    2020        getPlugin(`browser`,
    2121            `${window.location.origin}${path}/wp-content/plugins/easycoder/plugins/browser.js`,
    22             function() {
     22            function () {
    2323                addPlugin(`browser`, EasyCoder_Browser);
    2424            });
    25    
     25
    2626        getPlugin(`json`,
    2727            `${window.location.origin}${path}/wp-content/plugins/easycoder/plugins/json.js`,
    28             function() {
     28            function () {
    2929                addPlugin(`json`, EasyCoder_Json);
    3030            });
    31    
    32         getPlugin(`svg`,
    33             `${window.location.origin}${path}/wp-content/plugins/easycoder/plugins/svg.js`,
    34             function() {
    35                 addPlugin(`svg`, EasyCoder_SVG);
    36             });
    37    
     31
    3832    },
    39  
     33
    4034    getLocalPlugin: (path, name, getPlugin, addPlugin, callback) => {
    41    
     35
    4236        /*
    43     * This lets you add a plugin before launching a script, using the 'plugin' command.
    44     * You must provide a case for every plugin you will be adding;
    45     * use any one of them as the pattern to follow.
    46     */
    47    
     37        * This lets you add a plugin before launching a script, using the 'plugin' command.
     38        * You must provide a case for every plugin you will be adding;
     39        * use any one of them as the pattern to follow.
     40        */
     41
    4842        switch (name) {
    4943        case `ckeditor`:
    5044            getPlugin(name,
    5145                `${window.location.origin}${path()}/wp-content/plugins/easycoder/plugins/ckeditor.js`,
    52                 function() {
     46                function () {
    5347                    addPlugin(name, EasyCoder_CKEditor, callback);
    5448                });
     
    5852            getPlugin(name,
    5953                `${window.location.origin}${path()}/wp-content/plugins/easycoder/plugins/ui.js`,
    60                 function() {
     54                function () {
    6155                    addPlugin(name, EasyCoder_UI, callback);
    6256                });
     
    6660            getPlugin(name,
    6761                `${window.location.origin}${path()}/wp-content/plugins/easycoder/plugins/gmap.js`,
    68                 function() {
     62                function () {
    6963                    addPlugin(name, EasyCoder_GMap, callback);
    7064                });
     
    7468            getPlugin(name,
    7569                `${window.location.origin}${path()}/wp-content/plugins/easycoder/plugins/showdown.js`,
    76                 function() {
     70                function () {
    7771                    addPlugin(name, EasyCoder_Showdown, callback);
     72                });
     73            break;
     74
     75        case `svg`:
     76            getPlugin(name,
     77                `${window.location.origin}${path()}/wp-content/plugins/easycoder/plugins/svg.js`,
     78                function () {
     79                    addPlugin(name, EasyCoder_SVG, callback);
    7880                });
    7981            break;
  • easycoder/trunk/plugins/browser.js

    r2038748 r2052097  
    11const EasyCoder_Browser = {
     2
    23
    34    A: {
     
    171172    },
    172173
     174    Convert: {
     175
     176        compile: (compiler) => {
     177            const lino = compiler.getLino();
     178            if (compiler.nextTokenIs(`whitespace`)) {
     179                if (compiler.nextTokenIs(`in`)) {
     180                    if (compiler.nextIsSymbol()) {
     181                        const symbolRecord = compiler.getSymbolRecord();
     182                        if (symbolRecord.isValueHolder) {
     183                            if (compiler.nextTokenIs(`to`)) {
     184                                const mode = compiler.nextToken();
     185                                compiler.next();
     186                                compiler.addCommand({
     187                                    domain: `browser`,
     188                                    keyword: `convert`,
     189                                    lino,
     190                                    name: symbolRecord.name,
     191                                    mode
     192                                });
     193                                return true;
     194                            }
     195                        }
     196                    }
     197                }
     198            }
     199            return false;
     200        },
     201
     202        run: (program) => {
     203            const command = program[program.pc];
     204            const targetRecord = program.getSymbolRecord(command.name);
     205            const content = targetRecord.value[targetRecord.index].content;
     206            let value = content;
     207            switch (command.mode) {
     208            case `print`:
     209                value = value.split(`%0a`).join(`\n`).split(`%0A`).join(`\n`).split(`%0d`).join(``).split(`$0D`).join(``);
     210                break;
     211            case `html`:
     212                value = value.split(`%0a`).join(`<br />`).split(`%0A`).join(`<br />`).split(`%0d`).join(``).split(`$0D`).join(``);
     213                break;
     214            }
     215            targetRecord.value[targetRecord.index].content = value;
     216            return command.pc + 1;
     217        }
     218    },
     219
    173220    Create: {
    174221
     
    426473                const content = {};
    427474                for (const entry of data) {
    428                     content[entry[0]] = entry[1].replace(/\r/g, ``).replace(/\n/g, `%0d%0a`);
     475                    content[entry[0]] = entry[1].replace(/\r/g, ``).replace(/\n/g, `%0a`);
    429476                }
    430477                targetRecord.value[targetRecord.index] = {
     
    10091056    },
    10101057
    1011     Popup: {
    1012 
    1013         compile: (compiler) => {
    1014             compiler.compileVariable(`browser`, `popup`);
    1015             return true;
    1016         },
    1017 
    1018         run: (program) => {
    1019             return program[program.pc].pc + 1;
    1020         }
    1021     },
    1022 
    10231058    PRE: {
    10241059
     
    10421077        run: (program) => {
    10431078            return program[program.pc].pc + 1;
    1044         }
    1045     },
    1046 
    1047     Prompt: {
    1048 
    1049         compile: (compiler) => {
    1050             const text = compiler.getNextValue();
    1051             if (compiler.tokenIs(`with`)) {
    1052                 const pre = compiler.getNextValue();
    1053                 compiler.addCommand({
    1054                     domain: `browser`,
    1055                     keyword: `prompt`,
    1056                     text,
    1057                     pre
    1058                 });
    1059                 return true;
    1060             }
    1061             return false;
    1062         },
    1063 
    1064         run: (program) => {
    1065             const command = program[program.pc];
    1066             const text = program.getValue(command.text);
    1067             const pre = program.getValue(command.pre);
    1068             window.prompt(text, pre);
    1069             return command.pc + 1;
    10701079        }
    10711080    },
     
    12151224            // document.documentElement.pageYOffset = to;
    12161225            return command.pc + 1;
     1226        }
     1227    },
     1228
     1229    SECTION: {
     1230
     1231        compile: (compiler) => {
     1232            compiler.compileVariable(`browser`, `section`, false, `dom`);
     1233            return true;
     1234        },
     1235
     1236        run: (program) => {
     1237            return program[program.pc].pc + 1;
    12171238        }
    12181239    },
     
    16291650        compile: (compiler) => {
    16301651            compiler.compileVariable(`browser`, `span`, false, `dom`);
    1631             return true;
    1632         },
    1633 
    1634         run: (program) => {
    1635             return program[program.pc].pc + 1;
    1636         }
    1637     },
    1638 
    1639     TEXT: {
    1640 
    1641         compile: (compiler) => {
    1642             compiler.compileVariable(`browser`, `text`, false, `dom`);
    16431652            return true;
    16441653        },
     
    18621871        case `clear`:
    18631872            return EasyCoder_Browser.Clear;
     1873        case `convert`:
     1874            return EasyCoder_Browser.Convert;
    18641875        case `create`:
    18651876            return EasyCoder_Browser.Create;
     
    19101921        case `play`:
    19111922            return EasyCoder_Browser.Play;
    1912         case `popup`:
    1913             return EasyCoder_Browser.Popup;
    19141923        case `pre`:
    19151924            return EasyCoder_Browser.PRE;
    19161925        case `progress`:
    19171926            return EasyCoder_Browser.PROGRESS;
    1918         case `prompt`:
    1919             return EasyCoder_Browser.Prompt;
    19201927        case `put`:
    19211928            return EasyCoder_Browser.Put;
     
    19261933        case `scroll`:
    19271934            return EasyCoder_Browser.Scroll;
     1935        case `section`:
     1936            return EasyCoder_Browser.SECTION;
    19281937        case `set`:
    19291938            return EasyCoder_Browser.Set;
    19301939        case `span`:
    19311940            return EasyCoder_Browser.SPAN;
    1932         case `text`:
    1933             return EasyCoder_Browser.TEXT;
    19341941        case `textarea`:
    19351942            return EasyCoder_Browser.TEXTAREA;
     
    19591966            if (compiler.isSymbol()) {
    19601967                const symbolRecord = compiler.getSymbolRecord();
    1961                 if (compiler.nextTokenIs(`is`)) {
    1962                     if (compiler.nextTokenIs(`defined`)) {
    1963                         if (symbolRecord.extra === `dom`) {
    1964                             compiler.next();
    1965                             return {
    1966                                 domain: `browser`,
    1967                                 type: `defined`,
    1968                                 value: symbolRecord.name
    1969                             };
    1970                         }
    1971                         return null;
    1972                     } else {
    1973                         compiler.prev();
    1974                     }
     1968                if (compiler.nextTokenIs(`exists`)) {
     1969                    if (symbolRecord.extra === `dom`) {
     1970                        compiler.next();
     1971                        return {
     1972                            domain: `browser`,
     1973                            type: `exists`,
     1974                            value: symbolRecord.name
     1975                        };
     1976                    }
     1977                    return null;
    19751978                }
    19761979                switch (symbolRecord.keyword) {
     
    21772180                    content: target.value
    21782181                };
    2179             case `defined`:
     2182            case `exists`:
    21802183                symbolRecord = program.getSymbolRecord(value.value);
    21812184                return {
     
    22012204                const attribute = program.getValue(value.attribute);
    22022205                target = symbolRecord.element[symbolRecord.index];
     2206                if (attribute.indexOf(`data-`) === 0) {
     2207                    return program.getSimpleValue(target.dataset[attribute.substr(5)]);
     2208                }
    22032209                return program.getSimpleValue(target[attribute]);
    22042210            case `confirm`:
     
    23182324        compile: (compiler) => {
    23192325            if (compiler.tokenIs(`confirm`)) {
    2320                 compiler.next();
    2321                 const value = compiler.getValue();
     2326                const value = compiler.getNextValue();
    23222327                return {
    23232328                    domain: `browser`,
  • easycoder/trunk/plugins/json.js

    r2038748 r2052097  
    77            const request = compiler.nextToken();
    88            switch (request) {
    9             case `get`:
    10                 compiler.next();
    11                 if (compiler.tokenIs(`property`)) {
    12                     const item = compiler.getNextValue();
    13                     if (compiler.tokenIs(`of`)) {
    14                         if (compiler.nextIsSymbol()) {
    15                             const source = compiler.getToken();
    16                             if (compiler.nextTokenIs(`as`)) {
    17                                 if (compiler.nextIsSymbol()) {
    18                                     const targetRecord = compiler.getSymbolRecord();
    19                                     if (targetRecord.keyword === `variable`) {
    20                                         compiler.next();
    21                                         compiler.addCommand({
    22                                             domain: `json`,
    23                                             keyword: `json`,
    24                                             lino,
    25                                             request: `getProperty`,
    26                                             target: targetRecord.name,
    27                                             item,
    28                                             source
    29                                         });
    30                                         return true;
    31                                     }
    32                                 }
    33                             }
    34                         }
    35                     }
    36                     throw new Error(`Expected '${`of`}' but saw '${compiler.getToken()}`);
    37                 } else if (compiler.tokenIs(`element`)) {
    38                     const element = compiler.getNextValue();
    39                     if (compiler.tokenIs(`of`)) {
    40                         if (compiler.nextIsSymbol()) {
    41                             const source = compiler.getToken();
    42                             if (compiler.nextTokenIs(`as`)) {
    43                                 if (compiler.nextIsSymbol()) {
    44                                     const targetRecord = compiler.getSymbolRecord();
    45                                     if (targetRecord.keyword === `variable`) {
    46                                         compiler.next();
    47                                         compiler.addCommand({
    48                                             domain: `json`,
    49                                             keyword: `json`,
    50                                             lino,
    51                                             request: `getElement`,
    52                                             target: targetRecord.name,
    53                                             element,
    54                                             source
    55                                         });
    56                                         return true;
    57                                     }
    58                                 }
    59                             }
    60                         }
    61                     }
    62                     throw new Error(`Expected '${`of`}' but saw '${compiler.getToken()}`);
    63                 }
    64                 break;
    659            case `set`:
    6610                compiler.next();
     
    11054                }
    11155                break;
     56            case `sort`:
    11257            case `shuffle`:
    11358            case `format`:
     
    14893                    }
    14994                }
     95                break;
     96            case `delete`:
     97                const name = compiler.getNextValue();
     98                if (compiler.tokenIs(`from`)) {
     99                    if (compiler.nextIsSymbol()) {
     100                        const targetRecord = compiler.getSymbolRecord();
     101                        if (targetRecord.keyword === `variable`) {
     102                            compiler.next();
     103                            compiler.addCommand({
     104                                domain: `json`,
     105                                keyword: `json`,
     106                                lino,
     107                                request,
     108                                name,
     109                                target: targetRecord.name
     110                            });
     111                            return true;
     112                        }
     113                    }
     114                }
     115                break;
     116            case `rename`:
     117                const oldName = compiler.getNextValue();
     118                if (compiler.tokenIs(`to`)) {
     119                    const newName = compiler.getNextValue();
     120                    if (compiler.tokenIs(`in`)) {
     121                        if (compiler.nextIsSymbol()) {
     122                            const targetRecord = compiler.getSymbolRecord();
     123                            if (targetRecord.keyword === `variable`) {
     124                                compiler.next();
     125                                compiler.addCommand({
     126                                    domain: `json`,
     127                                    keyword: `json`,
     128                                    lino,
     129                                    request,
     130                                    oldName,
     131                                    newName,
     132                                    target: targetRecord.name
     133                                });
     134                                return true;
     135                            }
     136                        }
     137                    }
     138                }
     139                break;
     140            case `add`:
     141                const item = compiler.getNextValue();
     142                if (compiler.tokenIs(`to`)) {
     143                    if (compiler.nextIsSymbol()) {
     144                        const targetRecord = compiler.getSymbolRecord();
     145                        if (targetRecord.keyword === `variable`) {
     146                            compiler.next();
     147                            compiler.addCommand({
     148                                domain: `json`,
     149                                keyword: `json`,
     150                                lino,
     151                                request,
     152                                item,
     153                                target: targetRecord.name
     154                            });
     155                            return true;
     156                        }
     157                    }
     158                }
     159                break;
    150160            }
    151161            compiler.addWarning(`Unrecognised syntax in json`);
     
    155165        run: (program) => {
    156166            const command = program[program.pc];
    157             var sourceRecord;
    158             var targetRecord;
    159             var content;
     167            let sourceRecord;
     168            let targetRecord;
     169            let record;
     170            let content;
     171            let array;
    160172            switch (command.request) {
    161             case `getProperty`:
    162                 sourceRecord = program.getSymbolRecord(command.source);
    163                 var itemData = ``;
    164                 try {
    165                     itemData = JSON.parse(sourceRecord.value[sourceRecord.index].content);
    166                 } catch (err) {
    167                     program.runtimeError(command.lino, `Can't parse JSON`);
    168                     return 0;
    169                 }
    170                 const item = program.getValue(command.item);
    171                 if (typeof itemData[item] === `undefined`) {
    172                     program.runtimeError(command.lino, `No such property '${item}'`);
    173                 }
    174                 const itemContent = itemData[item];
    175                 targetRecord = program.getSymbolRecord(command.target);
    176                 targetRecord.value[targetRecord.index] = {
    177                     type: `constant`,
    178                     numeric: false,
    179                     content: typeof itemContent === `object` ?
    180                         JSON.stringify(itemContent) : itemContent
    181                 };
    182                 break;
    183             case `getElement`:
    184                 sourceRecord = program.getSymbolRecord(command.source);
    185                 var elementData = ``;
    186                 try {
    187                     elementData = JSON.parse(sourceRecord.value[sourceRecord.index].content);
    188                 } catch (err) {
    189                     program.runtimeError(command.lino, `Can't parse JSON`);
    190                     return 0;
    191                 }
    192                 const elementContent = elementData[program.getValue(command.element)];
    193                 targetRecord = program.getSymbolRecord(command.target);
    194                 targetRecord.value[targetRecord.index] = {
    195                     type: `constant`,
    196                     numeric: false,
    197                     content: typeof elementContent === `object` ?
    198                         JSON.stringify(elementContent) : elementContent
    199                 };
    200                 break;
    201173            case `setVariable`:
    202174                targetRecord = program.getSymbolRecord(command.target);
     
    237209                target.selectedIndex = -1;
    238210                break;
    239             case `shuffle`:
    240                 targetRecord = program.getSymbolRecord(command.target);
    241                 var a = JSON.parse(program.getValue(targetRecord.value[targetRecord.index]));
    242                 for (let i = a.length - 1; i > 0; i--) {
    243                     const j = Math.floor(Math.random() * (i + 1));
    244                     [a[i], a[j]] = [a[j], a[i]];
    245                 }
     211            case `sort`:
     212                targetRecord = program.getSymbolRecord(command.target);
     213                let a = JSON.parse(program.getValue(targetRecord.value[targetRecord.index])).sort();
    246214                targetRecord.value[targetRecord.index] = {
    247215                    type: `constant`,
    248216                    numeric: false,
    249217                    content: JSON.stringify(a)
     218                };
     219                break;
     220            case `shuffle`:
     221                targetRecord = program.getSymbolRecord(command.target);
     222                array = JSON.parse(program.getValue(targetRecord.value[targetRecord.index]));
     223                for (let i = array.length - 1; i > 0; i--) {
     224                    const j = Math.floor(Math.random() * (i + 1));
     225                    [array[i], array[j]] = [array[j], array[i]];
     226                }
     227                targetRecord.value[targetRecord.index] = {
     228                    type: `constant`,
     229                    numeric: false,
     230                    content: JSON.stringify(array)
    250231                };
    251232                break;
     
    286267                    content: JSON.stringify(content, null, 2)
    287268                };
     269                break;
     270            case `delete`:
     271                const name = program.getValue(command.name);
     272                targetRecord = program.getSymbolRecord(command.target);
     273                record = JSON.parse(targetRecord.value[targetRecord.index].content);
     274                delete record[name];
     275                targetRecord.value[targetRecord.index].content = JSON.stringify(record);
     276                break;
     277            case `rename`:
     278                const oldName = program.getValue(command.oldName);
     279                const newName = program.getValue(command.newName);
     280                targetRecord = program.getSymbolRecord(command.target);
     281                record = JSON.parse(targetRecord.value[targetRecord.index].content);
     282                content = record[oldName];
     283                delete record[oldName];
     284                record[newName] = content;
     285                targetRecord.value[targetRecord.index].content = JSON.stringify(record);
     286                break;
     287            case `add`:
     288                content = program.getValue(command.item);
     289                targetRecord = program.getSymbolRecord(command.target);
     290                record = JSON.parse(targetRecord.value[targetRecord.index].content);
     291                record.push(content);
     292                targetRecord.value[targetRecord.index].content = JSON.stringify(record);
    288293                break;
    289294            }
  • easycoder/trunk/plugins/showdown.js

    r2038748 r2052097  
    2929                                callback.payload = group;
    3030                                program.run(callback.cb);
    31                                 const payload = JSON.parse(callback.payload);
    32                                 switch (payload.type) {
    33                                 case `span`:
    34                                     return `<span style="${payload.styles}">${payload.content}</span>`;
    35                                 case `link`:
    36                                     return `<a href="#" id="${payload.id}">${payload.content}</a>`;
    37                                 }
    38                                 return payload.content;
     31                                return callback.payload;
    3932                            });
    40 
    41 
    4233                        }
    4334                    });
  • easycoder/trunk/plugins/svg.js

    r2016526 r2052097  
    11const EasyCoder_SVG = {
    2 
    3     Attach: {
    4 
    5         compile: (compiler) => {
    6             const lino = compiler.getLino();
    7             if (compiler.nextIsSymbol()) {
    8                 const symbol = compiler.getProgram()[compiler.getSymbol().pc];
    9                 switch (symbol.keyword) {
    10                 case `shape`:
    11                 case `svg`:
    12                     if (compiler.nextTokenIs(`to`)) {
    13                         const cssId = compiler.getNextValue();
    14                         compiler.addCommand({
    15                             domain: `svg`,
    16                             keyword: `attach`,
    17                             lino,
    18                             type: symbol.keyword,
    19                             symbol: symbol.name,
    20                             cssId
    21                         });
    22                         return true;
    23                     }
    24                     break;
    25                 default:
    26                     compiler.addWarning(`type '${symbol.keyword}' not recognized in svg 'attach'`);
    27                     break;
    28                 }
    29             }
    30             compiler.addWarning(`Unrecognised syntax in 'attach'`);
    31             return false;
    32         },
    33 
    34         run: (program) => {
    35             const command = program[program.pc];
    36             const cssId = program.value.evaluate(program, command.cssId).content;
    37             const element = document.getElementById(cssId);
    38             if (!element) {
    39                 program.runtimeError(command.lino, `No such element: ` + cssId);
    40             }
    41             const target = program.getSymbolRecord(command.symbol);
    42             target.value[target.index] = {
    43                 type: `constant`,
    44                 numeric: false,
    45                 content: cssId
    46             };
    47             return command.pc + 1;
    48         }
    49     },
    502
    513    Circle: {
     
    526478                    }
    527479                }
    528                 // } else if (token === 'attribute') {
    529                 //   compiler.next();
    530                 //   const attributeName = compiler.getValue();
    531                 //   if (compiler.tokenIs('of')) {
    532                 //     if (compiler.nextIsSymbol(true)) {
    533                 //       const symbolRecord = compiler.getSymbolRecord();
    534                 //       if (symbolRecord.domain !== 'svg') {
    535                 //         return false;
    536                 //       }
    537                 //       const symbolName = symbolRecord.name;
    538                 //       compiler.next();
    539                 //       var attributeValue = {
    540                 //         type: 'boolean',
    541                 //         content: true
    542                 //       };
    543                 //       if (compiler.tokenIs('to')) {
    544                 //         attributeValue = compiler.getNextValue();
    545                 //       }
    546                 //       compiler.addCommand({
    547                 //         domain: 'svg',
    548                 //         keyword: 'set',
    549                 //         lino,
    550                 //         type: 'setAttribute',
    551                 //         symbolName,
    552                 //         attributeName,
    553                 //         attributeValue
    554                 //       });
    555                 //       return true;
    556                 //     }
    557                 //   }
    558480            }
    559481            return false;
     
    611533    getHandler: (name) => {
    612534        switch (name) {
    613         case `attach`:
    614             return EasyCoder_SVG.Attach;
    615535        case `circle`:
    616536            return EasyCoder_SVG.Circle;
  • easycoder/trunk/plugins/ui.js

    r2038748 r2052097  
    9797                                const token = compiler.getToken();
    9898                                if (token === `second`) {
    99                                     compiler.next();
    100                                     second = compiler.getValue();
     99                                    second = compiler.getNextValue();
    101100                                } else if (token === `minute`) {
    102                                     compiler.next();
    103                                     minute = compiler.getValue();
     101                                    minute = compiler.getNextValue();
    104102                                } else if (token === `hour`) {
    105                                     compiler.next();
    106                                     hour = compiler.getValue();
     103                                    hour = compiler.getNextValue();
    107104                                } else if (token === `day`) {
    108                                     compiler.next();
    109                                     day = compiler.getValue();
     105                                    day = compiler.getNextValue();
    110106                                } else if (token === `month`) {
    111                                     compiler.next();
    112                                     month = compiler.getValue();
     107                                    month = compiler.getNextValue();
    113108                                } else if (token === `year`) {
    114                                     compiler.next();
    115                                     year = compiler.getValue();
     109                                    year = compiler.getNextValue();
    116110                                } else {
    117111                                    break;
  • easycoder/trunk/readme.txt

    r2038748 r2052097  
    2424* Retrieve content from web services using REST and JSON
    2525* Draw and animate simple graphics
    26 * Create a Google Map, put markers on it and interct with the map and the markers
     26* Create a Google Map, put markers on it and intearct with the map and the markers
    2727* Include the CKEditor rich text editor in your pages
    2828* Include the Showdown markdown converter in your pages
     
    5353
    5454== Changelog ==
     55
     56= 2.2.1 17-mar-2019 =
     57* New plugin: anagrams. Various changes/optimisations/bugfixes
    5558
    5659= 2.2.0 25-feb-2019 =
Note: See TracChangeset for help on using the changeset viewer.