Blame simple/bytebeat/parser.c

744572
744572
744572
#include "funcs.c"
744572
744572
744572
enum {
744572
  K_NONE = 0,
744572
  K_POPEN,
744572
  K_PCLOSE,
744572
  K_BPOPEN,
744572
  K_BCLOSE,
744572
  K_COMMA,
744572
  K_COLON,
744572
};
744572
const char *baseKeys[] = { "", "(", ")", "[", "]", ",", ":" };
744572
744572
744572
typedef struct Op {
744572
  const OpDesc *desc;
744572
  Var v;
744572
  struct Op *a, *b, *c;
744572
} Op;
744572
744572
744572
744572
void prepareKeys() {
744572
  if (keys) return;
744572
  keys = (const char**)calloc(1, sizeof(baseKeys) + sizeof(char*)*opsCnt);
744572
  if (!keys) { fprintf(stderr, "out of memory\n"); exit(1); }
744572
  memcpy(keys, baseKeys, sizeof(baseKeys));
744572
  keysCnt = sizeof(baseKeys)/sizeof(*baseKeys);
744572
744572
  for(int i = 0; i < opsCnt; ++i) {
744572
    OpDesc *d = &ops[i];
744572
    d->k = 0;
744572
    if (!d->key || !*d->key) continue;
744572
    for(int j = 1; j < keysCnt; ++j)
744572
      if (0 == strcmp(keys[j], d->key)) { d->k = j; break; }
744572
    if (!d->k) {
744572
      d->k = keysCnt;
744572
      keys[keysCnt++] = d->key;
744572
    }
744572
  }
744572
}
744572
744572
744572
744572
Op* opCreate(const OpDesc *d) {
744572
  Op *op = (Op*)calloc(1, sizeof(*op));
744572
  if (!op) { fprintf(stderr, "out of memory\n"); exit(1); }
744572
  op->desc = d;
744572
  return op;
744572
}
744572
744572
744572
void opDestroy(Op *op) {
744572
  if (!op) return;
744572
  opDestroy(op->a);
744572
  opDestroy(op->b);
744572
  opDestroy(op->c);
744572
  free(op);
744572
}
744572
744572
744572
Var opCall(Op *op, U32 t);
744572
744572
744572
Op* opSubItem(Op *op, U32 t, U32 idx) {
744572
  while(op && op->desc) {
744572
    if (op->desc->mode == M_ARRAY) {
744572
      while(op && idx) { op = op->b; --idx; }
744572
      return op ? op->a : op;
744572
    } else
744572
    if (op->desc->mode == M_INDEX) {
744572
      U32 i = asint(opCall(op->b, t));
744572
      op = opSubItem(op->a, t, i);
744572
    } else {
744572
      return op;
744572
    }
744572
  }
744572
  return NULL;
744572
}
744572
744572
744572
Var opCall(Op *op, U32 t) {
744572
  if (!op || !op->desc) return vari(0);
744572
  if (!op->desc->func) {
744572
    if (op->desc->mode == M_INDEX) {
744572
      U32 idx = asint(opCall(op->b, t));
744572
      Op *o = opSubItem(op->a, t, idx);
744572
      return opCall(o, t);
744572
    }
744572
    if (op->desc->mode == M_ARRAY)
744572
      return opCall(op->a, t);
744572
    return op->v;
744572
  }
744572
  Params p = { t, opCall(op->a, t), opCall(op->b, t), opCall(op->c, t) };
744572
  return op->desc->func(p);
744572
}
744572
744572
744572
void opPrint(Op *op, FILE *f, int level) {
744572
  if (!f) f = stdout;
744572
  for(int i = 0; i < level; ++i)
744572
    fprintf(f, "  ");
744572
  if (!op || !op->desc)
744572
    { fprintf(f, "nop\n"); return; }
744572
  if (!op->desc->func && op->desc->mode != M_ARRAY && op->desc->mode != M_INDEX)
744572
    { fprintf(f, "value: %d, %d, %g\n", op->v.type, op->v.u, op->v.f); return; }
744572
  fprintf(f, "%d:%d:%s:\n", op->desc->mode, op->desc->priority, op->desc->key);
744572
  ++level;
744572
  opPrint(op->a, f, level);
744572
  opPrint(op->b, f, level);
744572
  opPrint(op->c, f, level);
744572
}
744572
744572
744572
Op* opParsePart(const Lex **l, int priority);
744572
744572
744572
Op* opParseParentheses(const Lex **p) {
744572
  const Lex *l = *p;
744572
  if (iskey(l++, K_POPEN)) {
744572
    Op *op = opParsePart(&l, INT_MAX);
744572
    if (op && iskey(l++, K_PCLOSE))
744572
      return *p = l, op;
744572
    opDestroy(op);
744572
  }
744572
  return NULL;
744572
}
744572
744572
744572
Op* opParseValue(const Lex **p, const OpDesc *d) {
744572
  const Lex *l = *p;
744572
  if ( d->k ? iskey(l, d->k) : (l->type == LT_INT || l->type == LT_FLOAT) ) {
744572
    Op *op = opCreate(d);
744572
    op->v.type = l->type == LT_FLOAT ? T_F32 : T_U32;
744572
    op->v.u = l->u;
744572
    return *p = l + 1, op;
744572
  }
744572
  return NULL;
744572
}
744572
744572
9e60e5
Op* opParseFunc(const Lex **p, const OpDesc *d) {
9e60e5
  const Lex *l = *p;
9e60e5
  if (iskey(l++, d->k) && iskey(l++, K_POPEN)) {
9e60e5
    Op *sub = opParsePart(&l, INT_MAX);
9e60e5
    if (sub && iskey(l++, K_PCLOSE)) {
9e60e5
      Op *op = opCreate(d);
9e60e5
      op->a = sub;
9e60e5
      return *p = l, op;
9e60e5
    }
9e60e5
    opDestroy(sub);
9e60e5
  }
9e60e5
  return NULL;
9e60e5
}
9e60e5
9e60e5
9e60e5
Op* opParseFunc2(const Lex **p, const OpDesc *d) {
9e60e5
  const Lex *l = *p;
9e60e5
  if (iskey(l++, d->k) && iskey(l++, K_POPEN)) {
9e60e5
    Op *a = opParsePart(&l, INT_MAX);
9e60e5
    if (a && iskey(l++, K_COMMA)) {
9e60e5
      Op *b = opParsePart(&l, INT_MAX);
9e60e5
      if (b && iskey(l++, K_PCLOSE)) {
9e60e5
        Op *op = opCreate(d);
9e60e5
        op->a = a;
9e60e5
        op->b = b;
9e60e5
        return *p = l, op;
9e60e5
      }
9e60e5
      opDestroy(b);
9e60e5
    }
9e60e5
    opDestroy(a);
9e60e5
  }
9e60e5
  return NULL;
9e60e5
}
9e60e5
9e60e5
744572
Op* opParseArray(const Lex **p, const OpDesc *d) {
744572
  const Lex *l = *p;
744572
  if (iskey(l++, d->k)) {
744572
    Op *op = opCreate(d), *o = op;
744572
    while(1) {
744572
      o->a = opParsePart(&l, INT_MAX);
744572
      if (iskey(l, K_BCLOSE)) return *p = l + 1, op;
744572
      if (!iskey(l++, K_COMMA)) break;
744572
      o->b = opCreate(d);
744572
      o = o->b;
744572
    };
744572
    opDestroy(op);
744572
  }
744572
  return NULL;
744572
}
744572
744572
744572
Op* opParseIndex(const Lex **p, Op *a, const OpDesc *d) {
744572
  const Lex *l = *p;
744572
  if (iskey(l++, d->k)) {
744572
    Op *b = opParsePart(&l, INT_MAX);
744572
    if (b && iskey(l++, K_BCLOSE)) {
744572
      Op *op = opCreate(d);
744572
      op->a = a;
744572
      op->b = b;
744572
      return *p = l, op;
744572
    }
744572
    opDestroy(b);
744572
  }
744572
  return NULL;
744572
}
744572
744572
744572
Op* opParsePrefix(const Lex **p, const OpDesc *d) {
744572
  const Lex *l = *p;
744572
  if (iskey(l++, d->k)) {
744572
    Op *sub = opParsePart(&l, d->priority);
744572
    if (sub) {
744572
      Op *op = opCreate(d);
744572
      op->a = sub;
744572
      return *p = l, op;
744572
    }
744572
  }
744572
  return NULL;
744572
}
744572
744572
744572
Op* opParseBinary(const Lex **p, Op *a, const OpDesc *d) {
744572
  const Lex *l = *p;
744572
  if (iskey(l++, d->k)) {
744572
    Op *b = opParsePart(&l, d->priority);
744572
    if (b) {
744572
      Op *op = opCreate(d);
744572
      if (b->desc->priority == d->priority) {
744572
        op->a = a;
744572
        op->b = b->a;
744572
        b->a = op;
744572
        op = b;
744572
      } else {
744572
        op->a = a;
744572
        op->b = b;
744572
      }
744572
      return *p = l, op;
744572
    }
744572
  }
744572
  return NULL;
744572
}
744572
744572
744572
Op* opParseTernary(const Lex **p, Op *a, const OpDesc *d) {
744572
  const Lex *l = *p;
744572
  if (iskey(l++, d->k)) {
744572
    Op *b = opParsePart(&l, d->priority - 1);
744572
    if (b && iskey(l++, K_COLON)) {
744572
      Op *c = opParsePart(&l, d->priority);
744572
      if (c) {
744572
        Op *op = opCreate(d);
744572
        op->a = a;
744572
        op->b = b;
744572
        op->c = c;
744572
        return *p = l, op;
744572
      }
744572
    }
744572
    opDestroy(b);
744572
  }
744572
  return NULL;
744572
}
744572
744572
744572
Op* opParsePart(const Lex **p, int priority) {
744572
  //static int level = 0;
744572
  //printf("opParsePart:%d:%d:", level, priority);
744572
  //lexChainPrint(*p, NULL);
744572
  //printf("\n");
744572
  //++level;
744572
744572
  const Lex *l = *p;
744572
  Op *op = opParseParentheses(&l);
744572
  for(int i = 0; i < opsCnt; ++i) {
744572
    //printf("  i = %d\n", i);
744572
    const OpDesc *d = &ops[i];
744572
    if (d->priority > priority) break;
744572
    switch(d->mode) {
744572
    case M_VALUE:
744572
      if (!op) op = opParseValue(&l, d);
744572
      break;
9e60e5
    case M_FUNC:
9e60e5
      if (!op) op = opParseFunc(&l, d);
9e60e5
      break;
9e60e5
    case M_FUNC2:
9e60e5
      if (!op) op = opParseFunc2(&l, d);
9e60e5
      break;
744572
    case M_ARRAY:
744572
      if (!op) op = opParseArray(&l, d);
744572
      break;
744572
    case M_INDEX:
744572
      if (op) {
744572
        Op *o = opParseIndex(&l, op, d);
744572
        if (o) { op = o; i = 0; }
744572
      }
744572
      break;
744572
    case M_PREFIX:
744572
      if (!op) op = opParsePrefix(&l, d);
744572
      break;
744572
    case M_BINARY:
744572
      if (op) {
744572
        Op *o = opParseBinary(&l, op, d);
744572
        if (o) { op = o; i = 0; }
744572
      }
744572
      break;
744572
    case M_TERNARY:
744572
      if (op) {
744572
        Op *o = opParseTernary(&l, op, d);
744572
        if (o) { op = o; i = 0; }
744572
      }
744572
      break;
744572
    }
744572
  }
744572
  if (op) *p = l;
744572
744572
  //--level;
744572
  return op;
744572
}
744572
744572
744572
Op* opParse(const Lex *l) {
744572
  Op *op = opParsePart(&l, INT_MAX);
744572
  if (!op || l->type != LT_NONE)
744572
    { fprintf(stderr, "parse error at: "); lexChainPrint(l, stderr); fprintf(stderr, "\n"); }
744572
  return op;
744572
}
744572