Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //okay, lets do this
- //keywords, so I dont forget any
- //unsummon, summon, summonhold, conjure, enchant, dispel, bind, bindself, with, empty, print, set, skip
- //a spirit is something summoned and running, a spell is the scroll, or the recipe
- //spirits hold variables, spells don't
- //THIS ONE WITH ONE INSTRUCTION PER TIME
- function parseline(s){
- s = "("+s+")"; //the fuck? is this lisp?
- s = s.replace(/\(/g," ( ").replace(/\)/g," ) ").replace(/ +/g, " ");
- s = s.substring(1,s.length-1); //remove the border spaces
- var t = s.split(" ");
- return read_from(t);
- }
- function read_from(tokens) {
- if (tokens.length == 0) {
- throw ( "unexpected EOF while reading" );
- }
- var token = tokens[0];
- tokens.shift();
- if ("(" == token) {
- var L = [];
- while (tokens[0] != ")") {
- L.push(read_from(tokens));
- }
- tokens.shift(); //pop off ")"
- return L;
- } else if (")" == token) {
- throw("unexpected )");
- } else {
- return token;
- }
- }
- function parsefile(s){
- s = s.replace(/\n+/g,"\n");
- return map(parseline,s.split("\n"));
- }
- function map(func,t){
- var t2 = [];
- for (var x=0;x<t.length;x++) {
- t2[x] = func(t[x]);
- }
- return t2;
- }
- function conjureempty(){
- return {spells:[]};
- }
- function enchant(form,t){ //of course a syntax check must be done first, right??
- form.spells.push(t);
- }
- function setat(form,n,v){ //a form that isn't summoned is just a list
- form.spells[n]=v;
- }
- /*
- function slice(t,start)
- var t2 = []
- for x=start,#t do
- table.insert(t2,t[x])
- }
- return t2
- }*/
- function slice(t,start) { return t.slice(start);}
- function copy(t){
- return t.slice(0);
- }
- var spiritlist = [];
- var spiritcount = 0;
- function summon(form,bindings){
- var spirit = {spells:copy(form.spells),bindings:bindings,p:0} //must be a copy cuz it might be altered at runtime
- spiritlist[spiritcount] = spirit;
- spirit.id = spiritcount;
- spiritcount=spiritcount+1;
- spirit.bindings.self = spirit; //not a special word, but a common var that can be changed with set! U WOOT!!
- spirit.bindings.selfform = form;
- spirit.bindings.firstloop = true; //a useful(?) boolean
- return spirit;
- }
- function unsummon(spirit){ //need to remove it from the spirit list, and put a tag on it saying "dead"
- spiritlist[spirit.id] = false;
- spirit.dead=true;
- if (spirit.bindings.summoner) {
- spirit.bindings.summoner.halt=false; //this unhalts the summoner
- }
- }
- //function summonhold(form,bindings)
- // var spirit = summon(form,bindings)
- // while not spirit.dead do
- // evalspirit(spirit)
- // }
- // return spirit
- //}
- var mymath2 = {"+":function (a,b) { return a+b; },
- "-":function (a,b){ return a-b; },
- "*":function (a,b){ return a*b; },
- "/":function (a,b){ return a/b; },
- "%":function (a,b){ return a%b; },
- "=":function (a,b){ return a==b; },
- "!=":function (a,b){ return a!=b; },
- ">":function (a,b){ return a>b; },
- "<":function (a,b){ return a<b; },
- ">=":function (a,b){ return a>=b; },
- "<=":function (a,b){ return a<=b; },
- "and":function (a,b){ return a && b; }, //yea, and as a function it's no good, I kno
- "concat":function (a,b){ return a.toString()+b.toString(); }}
- var mymath1 = {"not" : function (a){ return !a; },
- "sin" : function (a){ return Math.sin(a); },
- "cos" : function (a){ return Math.cos(a); },
- "tan" : function (a){ return Math.tan(a); }}
- function processwith(t,spirit){
- var bindings = {};
- var count = 0;
- while (true) {
- bindings[t[count]] = evalline(t[count+1],spirit);
- //print(t[count],bindings[t[count]])
- if (t[count+2] == "and") {
- count = count + 3;
- } else {
- break;
- }
- }
- return bindings;
- }
- function evalline(t,spirit){ //a spirit holds its variables, aka bindings
- if (!isNaN(parseInt(t))) {
- return parseInt(t);
- } else if (typeof t == "string") {
- if (t.charAt(0) === '"' && t.charAt(t.length-1) === '"') {
- return t.substring(1,t.length-1);
- } else if (typeof spirit.bindings[t] != "undefined") {
- return spirit.bindings[t];
- } else {
- //for k,v in pairs(spirit.bindings) do print(k,v) }
- //throw("unknown binding "+t+t.length);
- }
- } else if (typeof t != "object") {
- throw("wrong type "+(typeof t));
- } else if (t[0] == "conjure") {
- if (t[1] == "empty") {
- return conjureempty();
- } else {
- var spell = evalline(t[1],spirit);
- return conjurecopy(spell); //you might make a copy of a spell, for some reason
- }
- } else if (t[0] == "enchant") {
- var spell = evalline(t[1],spirit);
- enchant(spell, slice(t,2)); //the line ain't checked? only when executed? u avin a giggle m8?
- } else if (t[0] == "bindself") {
- /*var exists = spirit.bindings[t[1]]
- if (exists) {
- throw("bindself: "..t[1].." already binded")
- }*/
- spirit.bindings[t[1]] = evalline(slice(t,2),spirit)
- } else if (t[0] == "bind") {
- var spr = evalline(t[1],spirit);
- /*var exists = spr.bindings[t[2]]; //exists considered harmful
- if (exists) {
- throw("bind: "..t[2].." already binded")
- }*/
- spr.bindings[t[2]] = evalline(slice(t,3),spirit)
- } else if (t[0] == "from") { //you can get the value of a bind from a different spirit
- var spr = evalline(t[1],spirit);
- return spr.bindings[t[2]];
- } else if (t[0] == "at") { //to be used with forms, which are also the listguys (why??)
- var sprorform = evalline(t[1],spirit);
- var n = evalline(t[2],spirit);
- return sprorform.spells[n]; //changed numbers so far
- } else if (t[0] == "setat") {
- var sprorform = evalline(t[1],spirit);
- var n = evalline(t[2],spirit);
- var v = evalline(t[3],spirit);
- setat(sprorform,n,v);
- } else if (mymath2[t[0]]) {
- var a = evalline(t[1],spirit);
- var b = evalline(t[2],spirit);
- return mymath2[t[0]](a,b)
- } else if (mymath1[t[0]]) {
- var a = evalline(t[1],spirit);
- return mymath1[t[0]](a);
- } else if (t[0] == "set") { //just.. why? DEPRECATED, BIND CAN CHANGE VALUES TOO
- // this aint scheme fuk u
- //var exists = spirit.bindings[t[2]]
- //if not exists {
- // throw("set: "..t[2].." not already binded")
- //}
- spirit.bindings[t[1]] = evalline(slice(t,2),spirit);
- } else if (t[0] == "summon") {
- var spell = evalline(t[1],spirit);
- var bindings = {};
- if (t[2] == "with") {
- bindings = processwith(slice(t,3),spirit);
- }
- var spr = summon(spell,bindings) //summon only adds it to the list, but doesnt do anything yet
- bindings.summoner = spirit;
- spirit.halt=true; //when you summon, you're halted
- return spr
- //elseif t[1] == "summonhold" {
- // var spell = evalline(t[2],spirit)
- // var bindings = {summoner=spirit}
- // if t[3] == "with" {
- // bindings = processwith(slice(t,4),spirit)
- // bindings.summoner=spirit
- // }
- // var spr = summonhold(spell,bindings) //summonhold halts everything, evaling the spirit continuously until it is unsummoned
- // return spr.rturn
- } else if (t[0] == "unsummon") {
- var spr = evalline(t[1],spirit)
- unsummon(spr);
- if (t[2] == "with") { //this only has meaning if its a "unsummon self"
- spr.rturn = evalline(t[3],spirit)
- }
- } else if (t[0] == "return") {
- var spr = evalline(t[1],spirit);
- return spr.rturn;
- } else if (t[0] == "if") { //oh god, if wont work without parentheses and =,>,<,etc
- var cond = evalline(t[1],spirit)
- if (cond) {
- return evalline(slice(t,2),spirit)
- }
- } else if (t[0] == "print") { //dunno how i'll do this, eval t[2] or slice(t,2)? for now i'll use slice
- var s
- if (t.length == 2) {
- s = evalline(t[1],spirit);
- } else {
- s = evalline(slice(t,1),spirit);
- }
- //print(s);
- alert(s);
- } else if (t[0] == "read") {
- //return io.read()
- return 10;
- } else if (t[0] == "skip") {
- var n
- if (t.length == 2) {
- n = evalline(t[1],spirit)
- } else {
- n = evalline(slice(t,1),spirit)
- }
- spirit.p = (spirit.p+n)%spirit.spells.length
- } else if (t[0] && !t[1]) { //something went wrong, sliced instead of using t[x]? quickfix
- return evalline(t[0],spirit);
- }
- }
- function mydofile(s) {
- spiritlist=[]; //need to clear it
- spiritcount=0;
- var spells = parsefile(s);
- var mainform = conjureempty(); //spells are forms but I should call spells' spells enchantments dunno
- mainform.spells = spells;
- enchant(mainform,["unsummon","self"]); //so it will only run once
- summon(mainform,{});
- dospirits();
- return "hehe";
- }
- /*
- function mydofilename(filename){
- spiritlist=[]; //need to clear it
- spiritcount=0;
- var file = io.open(filename,"r")
- var s = file:read("*a")
- mydofile(s)
- }*/
- function dospirits(){ //here's where the shit gets done
- while (true) {
- var sprcount = 0; //it's different from spiritcount up there /\, that other is like an id count
- for (var k in spiritlist) {
- var spirit = spiritlist[k];
- if (spirit){
- if (!spirit.halt) {
- evalspirit(spirit);
- }
- sprcount = sprcount+1;
- }
- }
- if (sprcount == 0) { //no more spirits alive, why should we keep running?
- break;
- }
- }
- }
- function evalspirit(spirit){
- //while spirit.p <= #spirit.spells do
- if (spirit.dead) { //todo:unhalt summoner //nvm, i do that in the unsummon in evalline
- //break
- }
- evalline(spirit.spells[spirit.p],spirit);
- spirit.p = spirit.p+1;
- //}
- if (spirit.p >= spirit.spells.length) {
- spirit.p=0;
- }
- //spirit.bindings.firstloop = false
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement