Blame simple/bytebeat/funcs.c

744572
744572
#include "lexer.c"
744572
744572
744572
typedef enum {
744572
  T_U32,
744572
  T_F32,
744572
} Type;
744572
744572
typedef enum {
744572
  M_VALUE = 0,
744572
  M_ARRAY,
744572
  M_INDEX,
744572
  M_PREFIX,
744572
  M_BINARY,
744572
  M_TERNARY,
744572
  M_FUNC,
744572
  M_FUNC2,
744572
} Mode;
744572
744572
typedef struct {
744572
  Type type;
744572
  union {
744572
    U32 u;
744572
    F32 f;
744572
  };
744572
} Var;
744572
744572
typedef struct {
744572
  U32 t;
744572
  Var a, b, c;
744572
} Params;
744572
744572
typedef Var (*Func)(Params p);
744572
744572
typedef struct {
744572
  Mode mode;
744572
  int priority;
744572
  const char *key;
744572
  Func func;
744572
  U32 k;
744572
} OpDesc;
744572
744572
744572
744572
static inline Var vari(U32 u)
744572
  { Var v; v.type = T_U32; v.u = u; return v; }
744572
static inline Var varf(F32 f)
744572
  { Var v; v.type = T_F32; v.f = f; return v; }
744572
744572
static inline int isint(Var v)
744572
  { return v.type == T_U32; }
744572
static inline int isflt(Var v)
744572
  { return v.type == T_F32; }
744572
static inline int isflt2(Var a, Var b)
744572
  { return isflt(a) || isflt(b); }
744572
744572
static inline U32 asint(Var v)
744572
  { return isflt(v) ? (U32)v.f : v.u; }
744572
static inline F32 asflt(Var v)
744572
  { return isflt(v) ? v.f : (F32)v.u; }
744572
744572
744572
744572
Var f_var(Params p)
744572
  { return vari(p.t); }
744572
744572
Var f_neg(Params p)
744572
  { return isflt(p.a) ? varf(-p.a.f) : vari(-p.a.u); }
744572
Var f_pos(Params p)
744572
  { return p.a; }
744572
Var f_not(Params p)
744572
  { return vari(~p.a.u); }
744572
Var f_boolnot(Params p)
744572
  { return vari(!p.a.u); }
744572
Var f_casti(Params p)
744572
  { return vari(asint(p.a)); }
744572
Var f_castf(Params p)
744572
  { return vari(asflt(p.a)); }
744572
744572
Var f_mul(Params p)
744572
  { return isflt2(p.a, p.b) ? varf(asflt(p.a) * asflt(p.b)) : vari(asint(p.a) * asint(p.b)); }
744572
Var f_div(Params p)
744572
  { F32 a = asflt(p.a), b = asflt(p.b); return varf(b ? a/b : a); }
744572
Var f_mod(Params p)
744572
  { U32 a = asint(p.a), b = asint(p.b); return vari(b ? a%b : a); }
744572
744572
Var f_add(Params p)
744572
  { return isflt2(p.a, p.b) ? varf(asflt(p.a) + asflt(p.b)) : vari(asint(p.a) + asint(p.b)); }
744572
Var f_sub(Params p)
744572
  { return isflt2(p.a, p.b) ? varf(asflt(p.a) - asflt(p.b)) : vari(asint(p.a) - asint(p.b)); }
744572
744572
Var f_shl(Params p)
744572
  { return vari(asint(p.a) << asint(p.b)); }
744572
Var f_shr(Params p)
744572
  { return vari(asint(p.a) >> asint(p.b)); }
744572
744572
Var f_lt(Params p)
744572
  { return isflt2(p.a, p.b) ? vari(asflt(p.a) < asflt(p.b)) : vari(asint(p.a) < asint(p.b)); }
744572
Var f_gt(Params p)
744572
  { return isflt2(p.a, p.b) ? vari(asflt(p.a) > asflt(p.b)) : vari(asint(p.a) > asint(p.b)); }
744572
Var f_leq(Params p)
744572
  { return isflt2(p.a, p.b) ? vari(asflt(p.a) <= asflt(p.b)) : vari(asint(p.a) <= asint(p.b)); }
744572
Var f_geq(Params p)
744572
  { return isflt2(p.a, p.b) ? vari(asflt(p.a) >= asflt(p.b)) : vari(asint(p.a) >= asint(p.b)); }
744572
744572
Var f_eq(Params p)
744572
  { return vari(p.a.u == p.b.u); }
744572
Var f_neq(Params p)
744572
  { return vari(p.a.u != p.b.u); }
744572
744572
Var f_and(Params p)
744572
  { return vari(asint(p.a) & asint(p.b)); }
744572
Var f_xor(Params p)
744572
  { return vari(asint(p.a) ^ asint(p.b)); }
744572
Var f_or(Params p)
744572
  { return vari(asint(p.a) | asint(p.b)); }
744572
744572
Var f_booland(Params p)
744572
  { return vari(p.a.u && p.b.u); }
744572
Var f_boolor(Params p)
744572
  { return vari(p.a.u || p.b.u); }
744572
744572
Var f_cond(Params p)
744572
  { return isflt2(p.b, p.c) ? (p.a.u ? varf(asflt(p.b)) : varf(asflt(p.c))) : (p.a.u ? vari(asint(p.b)) : vari(asint(p.c))); }
744572
744572
744572
OpDesc ops[] = {
744572
  { M_VALUE, 0, "" },
744572
  { M_VALUE, 0, "t", f_var },
744572
744572
  { M_ARRAY, 0, "[" },
744572
  { M_INDEX, 1, "[" },
744572
744572
  { M_PREFIX, 2, "+", f_pos },
744572
  { M_PREFIX, 2, "-", f_neg },
744572
  { M_PREFIX, 2, "~", f_not },
744572
  { M_PREFIX, 2, "!", f_boolnot },
744572
  { M_PREFIX, 2, "(U32)", f_casti },
744572
  { M_PREFIX, 2, "(int)", f_casti },
744572
  { M_PREFIX, 2, "(unsigned)", f_casti },
744572
  { M_PREFIX, 2, "(unsigned int)", f_casti },
744572
  { M_PREFIX, 2, "(F32)", f_castf },
744572
  { M_PREFIX, 2, "(float)", f_castf },
744572
  { M_PREFIX, 2, "(double)", f_castf },
744572
744572
  { M_BINARY, 3, "*", f_mul },
744572
  { M_BINARY, 3, "/", f_div },
744572
  { M_BINARY, 3, "%", f_mod },
744572
744572
  { M_BINARY, 4, "+", f_add },
744572
  { M_BINARY, 4, "-", f_sub },
744572
744572
  { M_BINARY, 5, "<<", f_shl },
744572
  { M_BINARY, 5, ">>", f_shr },
744572
744572
  { M_BINARY, 6, "<", f_lt },
744572
  { M_BINARY, 6, ">", f_gt },
744572
  { M_BINARY, 6, "<=", f_leq },
744572
  { M_BINARY, 6, ">=", f_geq },
744572
744572
  { M_BINARY, 7, "==", f_eq },
744572
  { M_BINARY, 7, "!=", f_neq },
744572
744572
  { M_BINARY, 8, "&", f_and },
744572
  { M_BINARY, 9, "^", f_xor },
744572
  { M_BINARY, 10, "|", f_or },
744572
  { M_BINARY, 11, "&&", f_booland },
744572
  { M_BINARY, 12, "||", f_boolor },
744572
744572
  { M_TERNARY, 13, "?", f_cond },
744572
};
744572
int opsCnt = sizeof(ops)/sizeof(*ops);
744572
744572
744572
744572