Mercurial > repo
view src/ploki/compile.c @ 4335:c3083517f99c
<int-e> revert
author | HackBot |
---|---|
date | Thu, 16 Jan 2014 23:12:02 +0000 |
parents | ac0403686959 |
children |
line wrap: on
line source
#include "config.h" #include "Str.h" #include "compile.h" #include "expr.h" #include "main_var.h" #include "op.h" #include "text.h" #include "zz.h" #include <assert.h> static struct op *end_if(struct text *code, size_t *n) { for (; *n < code->length; ++*n) { struct op *const p = code->start[*n]; switch (p->type) { case OP_IF: ++*n; p->arh.op = code->start[*n]; p->next = end_if(code, n); break; case OP_ELSE: { size_t tmp; tmp = ++*n; p->next = end_if(code, n); p->type = OP_NOP; if (tmp < code->length) { return code->start[tmp]; } return p; } case OP_FI: p->type = OP_NOP; return p; default: break; } } return code->start[0]; } static void resolve(struct expr *e) { if (!e) { return; } switch (e->type) { case literE: break; case varE: e->v.val = vr_data(Var_plain, e->v.tent); assert(e->v.val != NULL); break; case varhashE: e->v.hash = vr_data(Var_hash, e->v.tent); resolve(e->right); break; case symbolE: if (e->op == S_ARGV) { resolve(e->right); } break; case unopE: resolve(e->right); break; case binopE: resolve(e->left.expr); resolve(e->right); break; case listE: resolve(e->right); resolve(e->left.expr); break; } } static void op_resolve(struct op *o) { switch (o->type) { case OP_NOP: case OP_GOBACK: case OP_GOTO: case OP_HANG: break; case OP_ASSIGN: case OP_CALL_BACK: case OP_MODIFY: case OP_PRINT: case OP_PUTC: case OP_TEMP: resolve(o->arh.expr); resolve(o->arg); break; case OP_CALL: case OP_CALL_DYN: case OP_CLOSE: case OP_EXIT: case OP_IF: case OP_RETURN: case OP_SYSTEM: case OP_THROW: resolve(o->arg); break; default: NOTREACHED; break; } } void compile(struct text *code) { size_t i; for (i = 0; i < code->length; ++i) { struct op *const p = code->start[i]; op_getop(p); if (!p->next && p->type != OP_EXIT && i + 1 < code->length) { p->next = code->start[i + 1]; } } if (!i) { struct op tmp; op_init(&tmp); text_push(code, &tmp); } vr_freeze(Var_plain); vr_freeze(Var_hash); for (i = 0; i < code->length; ++i) { struct op *const p = code->start[i]; switch (p->type) { case OP_IF: ++i; p->arh.op = code->start[i]; p->next = end_if(code, &i); break; case OP_ELSE: ++i; p->next = end_if(code, &i); p->type = OP_NOP; break; case OP_FI: p->type = OP_NOP; break; default: break; } } for (i = 0; i < code->length; ++i) { op_resolve(code->start[i]); } }