www.pudn.com > ANSI_C_OOP.rar > postfix.c
#include#include #include #include #include "parse.h" #include "value.h" /* * postfix driver */ struct Type { const char * name; /* node's name */ void * (* new) (va_list ap); void (* exec) (const void * tree); void (* delete) (void * tree); }; void * new (const void * type, ...) { va_list ap; void * result; assert(type && ((struct Type *) type) -> new); va_start(ap, type); result = ((struct Type *) type) -> new(ap); * (const struct Type **) result = type; va_end(ap); return result; } static void exec (const void * tree) { assert(tree && * (struct Type **) tree && (* (struct Type **) tree) -> exec); (* (struct Type **) tree) -> exec(tree); } void process (const void * tree) { putchar('\t'); exec(tree); putchar('\n'); } void delete (void * tree) { assert(tree && * (struct Type **) tree && (* (struct Type **) tree) -> delete); (* (struct Type **) tree) -> delete(tree); } /* * NUMBER */ struct Val { const void * type; double value; }; static void * mkVal (va_list ap) { struct Val * node = malloc(sizeof(struct Val)); assert(node); node -> value = va_arg(ap, double); return node; } static void doVal (const void * tree) { printf(" %g", ((struct Val *) tree) -> value); } /* * unary operators */ struct Un { const void * type; void * arg; }; static void * mkUn (va_list ap) { struct Un * node = malloc(sizeof(struct Un)); assert(node); node -> arg = va_arg(ap, void *); return node; } static void doUn (const void * tree) { exec(((struct Un *) tree) -> arg); printf(" %s", (* (struct Type **) tree) -> name); } static void freeUn (void * tree) { delete(((struct Un *) tree) -> arg); free(tree); } /* * binary operators */ struct Bin { const void * type; void * left, * right; }; static void * mkBin (va_list ap) { struct Bin * node = malloc(sizeof(struct Bin)); assert(node); node -> left = va_arg(ap, void *); node -> right = va_arg(ap, void *); return node; } static void doBin (const void * tree) { exec(((struct Bin *) tree) -> left); exec(((struct Bin *) tree) -> right); printf(" %s", (* (struct Type **) tree) -> name); } static void freeBin (void * tree) { delete(((struct Bin *) tree) -> left); delete(((struct Bin *) tree) -> right); free(tree); } /* * Types */ static struct Type _Add = { "+", mkBin, doBin, freeBin }; static struct Type _Sub = { "-", mkBin, doBin, freeBin }; static struct Type _Mult = { "*", mkBin, doBin, freeBin }; static struct Type _Div = { "/", mkBin, doBin, freeBin }; static struct Type _Minus = { "minus", mkUn, doUn, freeUn }; static struct Type _Value = { "", mkVal, doVal, free }; const void * Add = & _Add; const void * Sub = & _Sub; const void * Mult = & _Mult; const void * Div = & _Div; const void * Minus = & _Minus; const void * Value = & _Value;