Mercurial > repo
view src/ploki/op.c @ 8916:0234daffd946
<oerjan> addquote <int-e> I couldn\'t help thinking that maybe if one considers the ramifications in full detail it will turn out that overthinking is often not helpful and therefore, not something to be proud of.
author | HackBot |
---|---|
date | Sun, 14 Aug 2016 02:31:47 +0000 |
parents | ac0403686959 |
children |
line wrap: on
line source
#include "IO.h" #include "Str.h" #include "expr.h" #include "main_label.h" #include "mars.h" #include "op.h" #include <ctype.h> #include <stddef.h> #include <string.h> void op_init(struct op *op) { St_init(&op->txt); op->type = OP_NOP; op->arg = NULL; op->arh.expr = NULL; op->next = NULL; op->line = 0; } void op_end(struct op *op) { St_clear(&op->txt); free_expr(op->arg); switch (op->type) { case OP_ASSIGN: case OP_CALL_BACK: case OP_MODIFY: case OP_PRINT: case OP_PUTC: case OP_SET_VAL: case OP_TEMP: free_expr(op->arh.expr); break; default: break; } } void op_getop(struct op *p) { p->next = NULL; switch (ST_FIRSTCHAR(&p->txt)) { case '#': if (ST_INDEX(&p->txt, 1) == '!') { p->type = OP_NOP; break; } p->type = OP_SYSTEM; St_shift(&p->txt); p->arg = get_expr(p); break; case 'A': switch (ST_INDEX(&p->txt, 1)) { case 'B': if (St_len(&p->txt) < 5 || St_ncmp_m(&p->txt, "ABRUF", 5)) { goto defualt; } p->type = OP_CALL_BACK; St_del(&p->txt, 0, 5); p->arh.expr = get_iobj(p); p->arg = get_expr(p); break; case 'N': if (St_len(&p->txt) < 5 || St_ncmp_m(&p->txt, "ANRUF", 5)) { goto defualt; } p->type = OP_CALL_DYN; St_del(&p->txt, 0, 5); p->arg = get_expr(p); break; default: goto defualt; } break; case 'C': if (St_len(&p->txt) < 6 || St_ncmp_m(&p->txt, "CLAUDS", 6)) { goto defualt; } p->type = OP_CLOSE; St_del(&p->txt, 0, 6); p->arg = get_expr(p); break; case 'E': switch (ST_INDEX(&p->txt, 1)) { case 'L': if (St_len(&p->txt) < 4 || St_ncmp_m(&p->txt, "ELSE", 4)) { goto defualt; } p->type = OP_ELSE; St_del(&p->txt, 0, 4); break; case 'N': if (St_len(&p->txt) >= 6 && St_ncmp_m(&p->txt, "END IF", 6) == 0) { p->type = OP_FI; break; } if (St_len(&p->txt) < 3 || St_ncmp_m(&p->txt, "END", 3)) { goto defualt; } p->type = OP_EXIT; St_del(&p->txt, 0, 3); p->arg = get_expr(p); break; default: goto defualt; } break; case 'F': switch (ST_INDEX(&p->txt, 1)) { case 'I': p->type = OP_FI; break; case 'L': if (St_len(&p->txt) < 5 || St_ncmp_m(&p->txt, "FLUSH", 5)) { goto defualt; } p->type = OP_FLUSH; St_del(&p->txt, 0, 5); p->arg = get_expr(p); break; default: goto defualt; } break; case 'G': if (ST_INDEX(&p->txt, 1) != 'O') { goto defualt; } switch (ST_INDEX(&p->txt, 2)) { case 'F': if (St_len(&p->txt) < 5 || St_ncmp_m(&p->txt, "GOFOR", 5)) { goto defualt; } p->type = OP_GOBACK; St_del(&p->txt, 0, 5); p->arg = get_expr(p); break; case 'T': if (St_len(&p->txt) < 4 || St_ncmp_m(&p->txt, "GOTO", 4)) { goto defualt; } p->type = OP_GOTO; St_del(&p->txt, 0, 4); p->arg = get_expr(p); break; default: goto defualt; } break; case 'I': switch (ST_INDEX(&p->txt, 1)) { case 'A': if (St_len(&p->txt) < 4 || St_ncmp_m(&p->txt, "IACS", 4)) { goto defualt; } p->type = OP_THROW; St_del(&p->txt, 0, 4); p->arg = get_expr(p); break; case 'F': p->type = OP_IF; St_del(&p->txt, 0, 2); p->arg = get_expr(p); break; default: goto defualt; } break; case 'K': if (St_len(&p->txt) < 4 || St_ncmp_m(&p->txt, "KTHX", 4)) { goto defualt; } p->type = OP_RETURN; St_del(&p->txt, 0, 4); p->arg = get_expr(p); break; case 'L': if (ST_INDEX(&p->txt, 1) != 'E') { goto defualt; } switch (ST_INDEX(&p->txt, 2)) { case 'E': if (ST_INDEX(&p->txt, 3) != 'T') { goto defualt; } p->type = OP_TEMP; St_del(&p->txt, 0, 4); p->arh.expr = get_lval(p); p->arg = get_expr(p); break; case 'T': p->type = OP_ASSIGN; St_del(&p->txt, 0, 3); p->arh.expr = get_lval(p); St_shiftws(&p->txt); if (p->arh.expr && ST_INDEX(&p->txt, 1) == '=' && OPERATOR_P(ST_FIRSTCHAR(&p->txt))) { p->arh.expr->op = expr_binop(ST_FIRSTCHAR(&p->txt)); St_del(&p->txt, 0, 2); p->type = OP_MODIFY; } p->arg = get_expr(p); break; default: goto defualt; } break; case 'N': if (St_len(&p->txt) < 4 || St_ncmp_m(&p->txt, "NEXT", 4)) { goto defualt; } else { size_t tmp; p->type = OP_NOP; St_del(&p->txt, 0, 4); tmp = St_shiftws(&p->txt); if (!(p->next = ma_find(&Mars, &p->txt))) { St_tac_m(&p->txt, "NEXT ", 4 + !!tmp); p->arg = get_expr(p); p->arh.expr = NULL; p->type = OP_PRINT; } } break; case 'R': if (ST_INDEX(&p->txt, 1) != 'E') { goto defualt; } switch (ST_INDEX(&p->txt, 2)) { case 'M': p->type = OP_NOP; break; case 'S': if (St_len(&p->txt) < 5 || St_ncmp_m(&p->txt, "RESET", 5)) { goto defualt; } p->type = OP_RESET; St_del(&p->txt, 0, 5); p->arg = get_expr(p); break; default: goto defualt; } break; case 'S': if (St_len(&p->txt) < 3 || St_ncmp_m(&p->txt, "SET", 3)) { goto defualt; } p->type = OP_PUTC; St_del(&p->txt, 0, 3); p->arg = get_iobj(p); p->arh.expr = NULL; St_shiftws(&p->txt); if (ST_FIRSTCHAR(&p->txt) == ',') { St_shift(&p->txt); p->arh.expr = p->arg; p->arg = get_expr(p); } break; case 'W': if (St_len(&p->txt) < 4 || St_ncmp_m(&p->txt, "WUNT", 4)) { goto defualt; } p->type = OP_PRINT; St_del(&p->txt, 0, 4); p->arg = get_iobj(p); p->arh.expr = NULL; St_shiftws(&p->txt); if (ST_FIRSTCHAR(&p->txt) != EOF) { p->arh.expr = p->arg; p->arg = get_expr(p); } break; defualt: default: if ((p->arh.op = ma_find(&Mars, &p->txt))) { p->type = OP_CALL; p->arg = get_expr(p); } else { p->type = OP_PRINT; p->arg = get_expr(p); p->arh.expr = NULL; } break; } St_clear(&p->txt); }