aboutsummaryrefslogtreecommitdiff
path: root/sys/cmd/rc/code.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/cmd/rc/code.c')
-rw-r--r--sys/cmd/rc/code.c277
1 files changed, 0 insertions, 277 deletions
diff --git a/sys/cmd/rc/code.c b/sys/cmd/rc/code.c
deleted file mode 100644
index 786f284..0000000
--- a/sys/cmd/rc/code.c
+++ /dev/null
@@ -1,277 +0,0 @@
-#include "rc.h"
-#include "parse.h"
-#include "exec.h"
-
-// -----------------------------------------------------------------------
-// types
-
-struct Interpreter
-{
- int i, cap;
- Code *code;
-};
-
-Code *compiled = nil;
-static struct Interpreter interpreter;
-#define emiti(x) ((void)(interpreter.i != interpreter.cap || grow()), interpreter.code[interpreter.i].i = (x), interpreter.i++)
-#define emitf(x) ((void)(interpreter.i != interpreter.cap || grow()), interpreter.code[interpreter.i].f = (x), interpreter.i++)
-#define emits(x) ((void)(interpreter.i != interpreter.cap || grow()), interpreter.code[interpreter.i].s = (x), interpreter.i++)
-
-static
-int
-grow(void)
-{
- interpreter.cap += 100;
- interpreter.code = erealloc(interpreter.code, sizeof(*interpreter.code)*interpreter.cap);
- memset(interpreter.code+interpreter.cap-100, 0, 100*sizeof(*interpreter.code));
-
- return 0;
-}
-
-static
-void
-storepc(int a)
-{
- if(interpreter.i <= a || a < 0)
- fatal("bad address %d in interpreter", a);
-
- interpreter.code[a].i = interpreter.i;
-}
-
-static
-void
-walk(Tree *node)
-{
- Tree *n;
- int addr1, addr2;
-
- if(!node)
- return;
-
- switch(node->type){
- default:
- print(shell.err, "bad type %d in interpreter walk\n", node->type);
- fatal("crashing\n");
- break;
-
- case '$':
- emitf(Xmark);
- walk(node->child[0]);
- emitf(Xdollar);
- break;
-
- case Tcount:
- emitf(Xmark);
- walk(node->child[0]);
- emitf(Xcount);
- break;
-
- case Tjoin:
- emitf(Xmark);
- walk(node->child[0]);
- emitf(Xjoin);
- break;
-
- case Tindex:
- emitf(Xmark);
- walk(node->child[1]);
- emitf(Xmark);
- walk(node->child[0]);
- emitf(Xindex);
- break;
-
- case ';':
- walk(node->child[0]);
- walk(node->child[1]);
- break;
-
- case '^':
- emitf(Xmark);
- walk(node->child[1]);
- emitf(Xmark);
- walk(node->child[0]);
- emitf(Xconcatenate);
- break;
-
- case Tandand:
- walk(node->child[0]);
- emitf(Xtrue);
- addr1 = emiti(0);
- walk(node->child[1]);
- storepc(addr1);
- break;
-
- case Toror:
- walk(node->child[0]);
- emitf(Xfalse);
- addr1 = emiti(0);
- walk(node->child[1]);
- storepc(addr1);
- break;
-
- case Targs:
- walk(node->child[1]);
- walk(node->child[0]);
- break;
-
- case Tparen: case Tblock:
- walk(node->child[0]);
- break;
-
- case Tbasic:
- emitf(Xmark);
- walk(node->child[0]);
- emitf(Xbasic);
- break;
-
- case Tbang:
- walk(node->child[0]);
- emitf(Xbang);
-
- case Tword:
- emitf(Xword);
- emits(strdup(node->str));
- break;
-
- case Twords:
- walk(node->child[1]);
- walk(node->child[0]);
- break;
-
- case '=':
- for(n=node; node && node->type == '='; node = node->child[2])
- ;
- if(node){
- for(node=n; node->type=='='; node = node->child[2]){
- emitf(Xmark);
- walk(node->child[1]);
- emitf(Xmark);
- walk(node->child[0]);
- emitf(Xlocal);
- }
- walk(node);
- for(node=n; node->type=='='; node = node->child[2])
- emitf(Xunlocal);
- }else{
- for(node=n; node; node=node->child[2]){
- emitf(Xmark);
- walk(node->child[1]);
- emitf(Xmark);
- walk(node->child[0]);
- emitf(Xassign);
- }
- }
- node = n;
- break;
- /* control structures */
- case Twhile:
- addr1 = interpreter.i; // head of loop
- walk(node->child[0]);
- if(addr1 == interpreter.i)
- fatal("TODO");
- emitf(Xtrue);
- addr2 = emiti(0); // goto end of loop
-
- walk(node->child[1]);
- emitf(Xgoto);
- emiti(addr1); // goto top of loop
- storepc(addr2);
- break;
-
- case Tfor:
- emitf(Xmark);
- if(node->child[1]){ // for( x in X )
- walk(node->child[1]);
- // emitf(Xglob)
- }else{ // for(X)
- fatal("TODO");
- }
- emitf(Xmark); // null initial value for Xlocal
- emitf(Xmark);
- walk(node->child[0]);
- emitf(Xlocal);
-
- addr1 = emitf(Xfor);
- addr2 = emiti(0);
-
- walk(node->child[2]);
- emitf(Xgoto);
- emiti(addr1);
- storepc(addr2);
- emitf(Xunlocal);
- break;
-
- /* forks */
- case '&':
- emitf(Xasync);
- addr1 = emiti(0);
- walk(node->child[0]);
- emitf(Xexit);
- storepc(addr1);
- break;
-
- case Tsubshell:
- emitf(Xsubshell);
- addr1 = emiti(0);
- walk(node->child[0]);
- emitf(Xexit);
- storepc(addr1);
- break;
-
- case Tpipe:
- emitf(Xpipe);
-
- emiti(node->redir.fd[0]);
- emiti(node->redir.fd[1]);
- addr1 = emiti(0);
- addr2 = emiti(0);
-
- walk(node->child[0]);
- emitf(Xexit);
- storepc(addr1);
-
- walk(node->child[1]);
- emitf(Xreturn);
- storepc(addr2);
-
- emitf(Xpipewait);
-
- break;
- }
-}
-
-// -----------------------------------------------------------------------
-// main exports
-
-void
-freecode(Code *c)
-{
- if(--c[0].i!=0)
- return;
- efree(c);
-}
-
-Code *
-copycode(Code *c)
-{
- c[0].i++;
- return c;
-}
-
-int
-compile(Tree *node)
-{
- flush(shell.err);
-
- interpreter.i = 0;
- interpreter.code = emalloc(100*sizeof(*interpreter.code));
- emiti(0); // reference count: no thread owns code yet
-
- walk(node);
-
- emitf(Xreturn);
- emitf(nil);
-
- compiled = interpreter.code;
- return 0;
-}