Skip to content

Instantly share code, notes, and snippets.

@semahawk
Last active December 29, 2015 02:59
Show Gist options
  • Save semahawk/7604599 to your computer and use it in GitHub Desktop.
Save semahawk/7604599 to your computer and use it in GitHub Desktop.
Just me trying to get some grasp around the execution order of an AST. Huh.... Nevermind that crap..
/*
*
* exec_order.c
*
* Created at: Fri 22 Nov 16:52:08 2013 16:52:08
*
* Author: Szymon Urbaś <szymon.urbas@aol.com>
*
* License: MIT (X11)
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <err.h>
/* current node's id */
static unsigned currid;
/* {{{ type defs */
enum type {
VARIABLE, INT,
ASSIGNMENT, ADDITION, SUBSTRACTION
};
#define NODE_BASE \
enum type type; \
struct node *next; \
void (*dumpf)(struct node *); \
void (*execf)(struct node *); \
unsigned id; \
int value;
struct node {
NODE_BASE
};
struct node_binop {
NODE_BASE
struct node *left, *right;
};
/* }}} */
/* {{{ nodes 'line' */
static struct node *nodes[16];
static struct node **nodes_curr = nodes;
/* }}} */
/* {{{ the arguments stack */
static int stack[16];
static int *stack_curr = stack;
static void push(int value)
{
*stack_curr = value;
stack_curr++;
}
static int pop(void)
{
int save = *stack_curr;
stack_curr--;
return save;
}
static void dump_stack(void)
{
int i = 0;
printf("\nStack Dump:\n");
for (; i < sizeof(stack) / sizeof(stack[0]); i++){
printf(" %x - %d\n", i, stack[i]);
}
}
/* }}} */
/* {{{ some debugging/macros stuff */
static unsigned sw;
#define INDENT do { sw += 2; } while (0)
#define DEDENT do { sw -= 2; } while (0)
#define TABS do { int i = 0; for (; i < sw; i++){ putchar(' ');} } while (0)
/* two handy macros */
#define DUMP(node) (node)->dumpf(node)
#define EXEC(node) (node)->execf(node)
/* macro to print the node's id */
#define ID(node) printf("%d. %p ", (node)->id, (void *)(node))
const char *ttos(enum type type)
{
switch (type){
case VARIABLE: return "variable";
case INT: return "integer";
case ASSIGNMENT: return "op '='";
case ADDITION: return "op '+'";
case SUBSTRACTION: return "op '-'";
}
return "#unknown#";
}
/* }}} */
/* {{{ dumping functions */
void dump(struct node *node)
{
ID(node);
TABS;
printf("- %s (%d)\n", ttos(node->type), node->value);
}
void dump_binop(struct node *n)
{
struct node_binop *node = (struct node_binop *)n;
ID(node);
TABS;
printf("= %s\n", ttos(node->type));
INDENT;
DUMP(node->left);
DUMP(node->right);
DEDENT;
}
/* }}} */
/* {{{ executing functions */
/* constant (integer) */
void cons(struct node *n)
{
static int currval = 1;
printf("push %d (integer)\n", n->value);
push(n->value);
}
/* variable */
void var(struct node *n)
{
printf("push %d (variable)\n", n->value);
push(n->value);
}
/* assignment */
void assign(struct node *n)
{
int FOS = pop();
int SOS = pop();
printf("push %d (assign)\n", SOS);
push(SOS);
}
/* addition */
void add(struct node *n)
{
int FOS = pop();
int SOS = pop();
printf("push %d (add)\n", SOS + FOS);
push(SOS + FOS);
}
/* substraction */
void sub(struct node *n)
{
int FOS = pop();
int SOS = pop();
printf("push %d (sub)\n", SOS - FOS);
push(SOS - FOS);
}
/* }}} */
/* {{{ new node functions */
#define PUSH_NODE(node) do { \
*nodes_curr = node; \
nodes_curr++; \
} while (0);
struct node *new(enum type type, int value)
{
struct node *n = malloc(sizeof(struct node));
if (!n)
err(1, "malloc");
PUSH_NODE(n);
n->id = currid++;
n->type = type;
n->value = value;
n->next = NULL;
n->dumpf = dump;
if (type == INT)
n->execf = cons;
else if (type == VARIABLE)
n->execf = var;
else
n->execf = NULL;
return n;
}
struct node *new_binop(enum type type, struct node *left, struct node *right)
{
struct node_binop *n = malloc(sizeof(struct node_binop));
if (!n)
err(1, "malloc");
PUSH_NODE((struct node *)n);
n->id = currid++;
n->type = type;
n->value = -1;
n->left = left;
n->right = right;
n->dumpf = dump_binop;
if (type == ASSIGNMENT)
n->execf = assign;
else if (type == ADDITION)
n->execf = add;
else if (type == SUBSTRACTION)
n->execf = sub;
else
n->execf = NULL;
return (struct node *)n;
}
/* }}} */
int main(void)
{
struct node *n =
new_binop(ADDITION,
new(VARIABLE, 1),
new_binop(ADDITION,
new_binop(ADDITION,
new(INT, 2),
new(VARIABLE, 3)),
new(INT, 4)));
struct node *p;
struct node **pp;
printf("The 'Code' (a = 1, b = 3):\n\n");
printf(" a + ((2 + b) + 4)\n\n");
printf("The Tree:\n");
for (p = n; p != NULL; p = p->next){
DUMP(p);
}
printf("\nThe Execution Order:\n");
for (pp = nodes; *pp != NULL; pp++){
ID(*pp);
printf("%s\n", ttos((*pp)->type));
}
printf("\nExecuting Nodes:\n");
for (pp = nodes; *pp != NULL; pp++){
ID(*pp);
EXEC(*pp);
}
return 0;
}
/*
* vi: ft=c:ts=2:sw=2:expandtab
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment