diff interps/glass/builtins.cc @ 996:859f9b4339e6

<Gregor> tar xf egobot.tar.xz
author HackBot
date Sun, 09 Dec 2012 19:30:08 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/interps/glass/builtins.cc	Sun Dec 09 19:30:08 2012 +0000
@@ -0,0 +1,338 @@
+/*
+ * Copyright (c) 2005  Gregor Richards
+ *
+ * This file is part of Glass.
+ * 
+ * Glass is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * Glass is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Glass; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <cstdio>
+#include <iostream>
+#include <sstream>
+using namespace std;
+
+#include "builtins.h"
+#include "func.h"
+#include "glass.h"
+#include "klass.h"
+#include "klassi.h"
+#include "parseq.h"
+#include "variable.h"
+
+#define POP \
+{ \
+    if (mainStack.size() != 0) { \
+        delete mainStack[0]; \
+        mainStack.pop_front(); \
+    } \
+}
+
+char builtinDefinitions[] = "{A \
+[a~A.a~] \
+[s~A.s~] \
+[m~A.m~] \
+[d~A.d~] \
+[(mod)~A.mod~] \
+[f~A.f~] \
+[e~A.e~] \
+[(ne)~A.ne~] \
+[(lt)~A.lt~] \
+[(le)~A.le~] \
+[(gt)~A.gt~] \
+[(ge)~A.ge~] \
+} \
+{S \
+[l~S.l~] \
+[i~S.i~] \
+[(si)~S.si~] \
+[a~S.a~] \
+[d~S.d~] \
+[e~S.e~] \
+[(ns)~S.ns~] \
+[(sn)~S.sn~] \
+} \
+{V \
+[n~V.n~] \
+[d~V.d~] \
+} \
+{O \
+[o~O.o~] \
+[(on)~O.on~] \
+} \
+{I \
+[l~I.l~] \
+[c~I.c~] \
+[e~I.e~] \
+[n~I.n~] \
+} \
+{(Debug) \
+[(cl)~Debug.cl~] \
+[(fl)~Debug.fl~] \
+[(fc)~Debug.fc~] \
+[s~Debug.s~] \
+}";
+
+
+#define BUILTIN(A, B) else if (which == A && mainStack.size() >= B)
+void doBuiltin(string which)
+{
+    if (0) {
+    } BUILTIN("A.a", 2) {
+        mainStack[1]->nval = mainStack[1]->nval + mainStack[0]->nval;
+        POP;
+    } BUILTIN("A.s", 2) {
+        mainStack[1]->nval = mainStack[1]->nval - mainStack[0]->nval;
+        POP;
+    } BUILTIN("A.m", 2) {
+        mainStack[1]->nval = mainStack[1]->nval * mainStack[0]->nval;
+        POP;
+    } BUILTIN("A.d", 2) {
+        if (mainStack[0]->nval != 0)
+            mainStack[1]->nval = mainStack[1]->nval / mainStack[0]->nval;
+        POP;
+    } BUILTIN("A.mod", 2) {
+        long long a = (long long) mainStack[1]->nval;
+        long long b = (long long) mainStack[0]->nval;
+        if (b != 0)
+            mainStack[1]->nval = a % b;
+        POP;
+    } BUILTIN("A.f", 1) {
+        mainStack[0]->nval = (long long) mainStack[0]->nval;
+    } BUILTIN("A.e", 2) {
+        mainStack[1]->nval = mainStack[1]->nval == mainStack[0]->nval;
+        POP;
+    } BUILTIN("A.ne", 2) {
+        mainStack[1]->nval = mainStack[1]->nval != mainStack[0]->nval;
+        POP;
+    } BUILTIN("A.lt", 2) {
+        mainStack[1]->nval = mainStack[1]->nval < mainStack[0]->nval;
+        POP;
+    } BUILTIN("A.le", 2) {
+        mainStack[1]->nval = mainStack[1]->nval <= mainStack[0]->nval;
+        POP;
+    } BUILTIN("A.gt", 2) {
+        mainStack[1]->nval = mainStack[1]->nval > mainStack[0]->nval;
+        POP;
+    } BUILTIN("A.ge", 2) {
+        mainStack[1]->nval = mainStack[1]->nval >= mainStack[0]->nval;
+        POP;
+    } BUILTIN("S.l", 1) {
+        mainStack[0]->nval = mainStack[0]->sval.length();
+        mainStack[0]->type = VAR_NUMBER;
+        mainStack[0]->sval = "";
+    } BUILTIN("S.i", 2) {
+        if (mainStack[0]->nval >= 0 &&
+            mainStack[0]->nval < mainStack[1]->sval.length()) {
+            mainStack[1]->sval = mainStack[1]->sval[(int) mainStack[0]->nval];
+        } else {
+            mainStack[1]->sval = "";
+        }
+        POP;
+    } BUILTIN("S.si", 3) {
+        if (mainStack[1]->nval >= 0 &&
+            mainStack[1]->nval < mainStack[2]->sval.length() &&
+            mainStack[0]->sval.length() > 0) {
+            mainStack[2]->sval[(int) mainStack[1]->nval] = mainStack[0]->sval[0];
+        }
+        POP; POP;
+    } BUILTIN("S.a", 2) {
+        mainStack[1]->sval += mainStack[0]->sval;
+        POP;
+    } BUILTIN("S.d", 2) {
+        mainStack[0]->sval = mainStack[1]->sval.substr((int) mainStack[0]->nval);
+        mainStack[0]->type = VAR_STRING;
+        mainStack[1]->sval = mainStack[1]->sval.substr(0, (int) mainStack[0]->nval);
+    } BUILTIN("S.e", 2) {
+        mainStack[1]->nval = (mainStack[1]->sval == mainStack[0]->sval);
+        mainStack[1]->type = VAR_NUMBER;
+        mainStack[1]->sval = "";
+        POP;
+    } BUILTIN("S.ns", 1) {
+        mainStack[0]->sval = (char) mainStack[0]->nval;
+        mainStack[0]->type = VAR_STRING;
+    } BUILTIN("S.sn", 1) {
+        if (mainStack[0]->sval.length() > 0) {
+            mainStack[0]->nval = mainStack[0]->sval[0];
+        } else {
+            mainStack[0]->nval = 0;
+        }
+        mainStack[0]->type = VAR_NUMBER;
+        mainStack[0]->sval = "";
+    } BUILTIN("V.n", 0) {
+        // find one
+        unsigned int i;
+        stringstream nm;
+        for (i = 1; i != 0; i++) {
+            // check this name ...
+            nm.str("");
+            nm << "Anonymous" << i;
+            if (globalVars.find(nm.str()) == globalVars.end()) {
+                // it's free
+                globalVars[nm.str()] = new Variable();
+                mainStack.push_front(new Variable(VAR_VARIABLEP, nm.str()));
+                return;
+            }
+        }
+        // uh oh!
+        mainStack.push_front(new Variable());
+    } BUILTIN("V.d", 1) {
+        // TODO
+#ifndef IRC
+    } BUILTIN("O.o", 1) {
+        cout << mainStack[0]->sval;
+        fflush(stdout);
+        POP;
+    } BUILTIN("O.on", 1) {
+        cout << mainStack[0]->nval;
+        fflush(stdout);
+        POP;
+#else
+    } BUILTIN("O.o", 1) {
+        IRC_o += mainStack[0]->sval;
+        POP;
+    } BUILTIN("O.on", 1) {
+        stringstream IRC_os;
+        IRC_os << mainStack[0]->nval;
+        IRC_o += IRC_os.str();
+        POP;
+#endif
+#ifndef IRC
+    } BUILTIN("I.l", 0) {
+        char line[1025];
+        string sline;
+        
+        line[1024] = '\0';
+        line[0] = '\0';
+        fgets(line, 1024, stdin); // ignore errors purposely
+        sline = line;
+        
+        mainStack.push_front(new Variable(VAR_STRING, sline));
+
+    } BUILTIN("I.c", 0) {
+        int ic = getchar();
+        string ics;
+        
+        if (ic == EOF) ic = 0;
+        ics = ic;
+        
+        mainStack.push_front(new Variable(VAR_STRING, ics));
+
+    } BUILTIN ("I.n", 0) {
+        int in;
+        int inn;
+        scanf ("%d",&in);
+        inn = in;
+        mainStack.push_front(new Variable(VAR_NUMBER, inn));
+
+    } BUILTIN("I.e", 0) {
+        if (feof(stdin) || ferror(stdin)) {
+            mainStack.push_front(new Variable(VAR_NUMBER, 1.0));
+        } else {
+            mainStack.push_front(new Variable(VAR_NUMBER, 0.0));
+        }
+#else
+    } BUILTIN("I.l", 0) {
+        mainStack.push_front(new Variable(VAR_STRING, ""));
+    } BUILTIN("I.c", 0) {
+        mainStack.push_front(new Variable(VAR_STRING, ""));
+    } BUILTIN("I.e", 0) {
+        mainStack.push_front(new Variable(VAR_NUMBER, 1.0));
+#endif
+    } BUILTIN("Debug.cl", 0) {
+        map<string,Variable *>::iterator svari;
+        for (svari = globalVars.begin(); svari != globalVars.end(); svari++) {
+            if (svari->second->type == VAR_KLASS) {
+#ifndef IRC
+                cout << svari->first << " ";
+#else
+                IRC_o += svari->first + " ";
+#endif
+            }
+        }
+    } BUILTIN("Debug.fl", 1) {
+        if (mainStack[0]->type != VAR_STRING) { POP; return; }
+        if (globalVars.find(mainStack[0]->sval) != globalVars.end()) {
+            Klass *tolist = globalVars[mainStack[0]->sval]->kval;
+            map<string,Func *>::iterator sfuni;
+            for (sfuni = tolist->functions.begin(); sfuni != tolist->functions.end(); sfuni++) {
+#ifndef IRC
+                cout << sfuni->first << " ";
+#else
+                IRC_o += sfuni->first + " ";
+#endif
+            }
+        }
+        POP;
+    } BUILTIN("Debug.fc", 2) {
+        if (mainStack[0]->type != VAR_STRING ||
+            mainStack[1]->type != VAR_STRING) { POP; POP; return; }
+        
+        if (globalVars.find(mainStack[1]->sval) != globalVars.end()) {
+            Klass *tolist = globalVars[mainStack[1]->sval]->kval;
+            if (tolist->functions.find(mainStack[0]->sval) != tolist->functions.end()) {
+                Func *ftolist = tolist->functions[mainStack[0]->sval];
+                
+                // now output it all
+                string cont = ftolist->contents->dump();
+#ifndef IRC
+                cout << cont;
+#else
+                IRC_o += cont;
+#endif
+            }
+        }
+        POP; POP;
+    } BUILTIN("Debug.s", 0) {
+        unsigned int ui;
+        stringstream dso;
+        for (ui = 0; ui < mainStack.size(); ui++) {
+            switch (mainStack[ui]->type) {
+                case VAR_VARIABLEP:
+                    dso << "(" << mainStack[ui]->sval << ")";
+                    break;
+                    
+                case VAR_NUMBER:
+                    dso << "<" << mainStack[ui]->nval << ">";
+                    break;
+                    
+                case VAR_STRING:
+                    dso << "\"" << mainStack[ui]->sval << "\"";
+                    break;
+                    
+                case VAR_KLASS:
+                    dso << "(" << mainStack[ui]->kval->name << "*:c)";
+                    break;
+                    
+                case VAR_KLASSI:
+                    dso << "(" << mainStack[ui]->kival->of->name << "*:ci)";
+                    break;
+                    
+                case VAR_FUNC:
+                    dso << "(" << mainStack[ui]->fval->name << "*:f)";
+                    break;
+                    
+                case VAR_FUNCI:
+                    dso << "(" << mainStack[ui]->kival->of->name << "." <<
+                    mainStack[ui]->fval->name << "*:f)";
+                    break;
+            }
+        }
+#ifndef IRC
+        cout << dso.str();
+#else
+        IRC_o += dso.str();
+#endif
+    }
+}