Files
moxa/_gi_c/run_cfg.c
Sebastien Binet 476a31322d Go get ellipsis (#1)
* gi: rename gi_c into _gi_c

* gi: rename test into _test

* gi: fix README syntax
2018-06-26 10:17:01 +02:00

187 lines
3.7 KiB
C

#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include "node.h"
#include "trace.h"
#define FALSE 0
#define TRUE 1
void nop(node_t *n)
{
return;
}
void assign(node_t *n)
{
*n->pv = *n->child[0]->pv = *n->child[1]->pv;
}
void cond_branch(node_t *n)
{
n->snext = n->pv->u.num ? n->next[TRUE] : n->next[FALSE];
}
void inc(node_t *n)
{
n->child[0]->pv->u.num++;
}
void bprintf_val(val_t *pv)
{
switch((int)pv->type) {
case VINT:
printf("%ld", pv->u.num);
break;
case VFLOAT:
printf("%g", pv->u.fnum);
case VSTR:
printf("%s", pv->u.str);
default:
break;
}
}
void bprint_val(bip_t *ip, val_t *pv, int quote)
{
char s[100];
switch ((int)pv->type) {
case VINT:
snprintf(s, sizeof(s), "%ld", pv->u.num);
break;
case VFLOAT:
snprintf(s, sizeof(s), "%g", pv->u.fnum);
break;
case VSTR:
snprintf(s, sizeof(s), "%s", pv->u.str);
break;
if (quote == 0)
snprintf(s, sizeof(s), "\\\"%s\\\"", pv->u.str);
else if (quote == 2)
snprintf(s, sizeof(s), "\"%s\"", pv->u.str);
else
snprintf(s, sizeof(s), "%s", pv->u.str);
break;
default:
break;
}
strcat(ip->out, s);
}
void bprint_node_label(bip_t *ip, node_t *node, int flow)
{
char s[100];
switch ((int)node->type) {
case TERM:
strcat(ip->out, " ");
bprint_val(ip, node->pv, flow);
break;
case SL:
snprintf(s, sizeof(s), " %s", nodetype[node->type]);
strcat(ip->out, s);
break;
case VAR:
snprintf(s, sizeof(s), " %s", node->sym->name);
strcat(ip->out, s);
break;
default:
if (flow)
snprintf(s, sizeof(s), " $%d", node->num);
else
snprintf(s, sizeof(s), " %s", node->sym->name);
strcat(ip->out, s);
break;
}
}
void echo(node_t *n)
{
int i;
for (i = 0; i < n->nchild; i++)
bprintf_val(n->child[i]->pv);
printf("\n");
//bprint_val(ip, n->child[i]->pv, 1);
//strcat(ip->out, "\n");
}
void trace(FILE *fd, bip_t *ip, node_t *node, int tid)
{
int i, start = 0;
char s[100];
if (node->sym->f == nop || node->type == SL)
return;
snprintf(s, sizeof(s), "[%d] $%d:", tid, node->num);
strcat(ip->out, s);
if (node->type == OP) {
bprint_node_label(ip, node->child[0], 2);
start = 1;
}
bprint_node_label(ip, node, 0);
for (i = start; i < node->nchild; i++)
bprint_node_label(ip, node->child[i], 2);
strcat(ip->out, ": ");
bprint_val(ip, node->pv, 2);
strcat(ip->out, "\n");
}
void run_cfg(bip_t *ip)
{
node_t *n = ip->entry[0];
while (n) {
n->f(n);
n = n->snext;
}
}
#define define_arithmetic_opfun(name, op) \
void name(node_t *n) \
{ \
val_t *v0, *v1; \
const static val_t v = {0}; \
if (n->nchild == 1) { \
v0 = (val_t *)&v; \
v1 = n->child[0]->pv; \
} else { \
v0 = n->child[0]->pv; \
v1 = n->child[1]->pv; \
} \
n->pv->u.num = v0->u.num op v1->u.num; \
}
#define define_comparison_opfun(name, op) \
void name(node_t *n) \
{ \
n->pv->u.num = n->child[0]->pv->u.num op n->child[1]->pv->u.num;\
}
#define define_bitwise_opfun(name, op) \
void name(node_t *n) \
{ \
n->pv->u.num = n->child[0]->pv->u.num op n->child[1]->pv->u.num;\
}
/* Generate code for common operators */
#define check_zero_div(v) \
{if (v == 0) fprintf(stderr, "run error: divide by zero\n"); return;}
define_arithmetic_opfun(fdiv, /)
#undef check_zero_div
#define check_zero_div(v)
define_arithmetic_opfun(add, +)
define_arithmetic_opfun(sub, -)
define_arithmetic_opfun(mul, *)
define_bitwise_opfun(band, &)
define_bitwise_opfun(bor, |)
define_bitwise_opfun(lshift, <<)
define_bitwise_opfun(rshift, >>)
define_bitwise_opfun(mod, %)
define_comparison_opfun(eq, ==)
define_comparison_opfun(neq, !=)
define_comparison_opfun(ge, >=)
define_comparison_opfun(gt, >)
define_comparison_opfun(le, <=)
define_comparison_opfun(lt, <)