Mercurial > hg > Members > kono > compiler-examples
view s-tree-compile.c @ 17:e5c8532ab38d
fix for Mountain lion
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 18 Oct 2013 15:51:35 +0900 |
parents | 745c62bbc200 |
children | 06763fed18e4 |
line wrap: on
line source
/* Very Simple Compiler (Parser part, Tree Genertor) $Id$ */ #include "s-compile.h" #include <stdlib.h> // for malloc static int optimize = 0; #define NEW(type) ((type *)malloc(sizeof(type))) typedef struct node { struct node *left; struct node *right; int type; int value; } node, *node_ptr; static node *expr(); static node *aexpr(); static node *mexpr(); static node *term(); static node *new_node(); static node_ptr new_node(int type,int value,node_ptr left,node_ptr right) { node *d; if (optimize && (left && left->type =='0') && (right && right->type =='0')) { switch(type) { case '>': right->value = (left->value > right->value); free(left); return right; break; case '+': right->value = left->value + right->value; free(left); return right; break; case '-': right->value = left->value - right->value; free(left); return right; break; case '*': right->value = right->value * left->value; free(left); return right; break; case '/': if(right->value==0) { error("zero divide in compile time"); } else { right->value = left->value / right->value; } free(left); return right; } } // d = (node *)malloc(sizeof(node)); d = NEW(node); d->type = type; d->value = value; d->left = left; d->right = right; return d; } static void free_node(d) node_ptr d; { if(d->left) { free_node(d->left); } if(d->right) { free_node(d->right); } free(d); } static void code_generate(d) node_ptr d; { int assign; switch(d->type) { case '0': emit_value(d->value); return; case 'v': emit_load(d->value); return; case '=': if(!d->left || d->left->type != 'v') { error("Bad assignment"); code_generate(d->right); return; } assign = d->left->value; code_generate(d->right); emit_store(assign); return; case '>': code_generate(d->left); emit_push(); code_generate(d->right); emit_compare(); break; default: /* calculation */ code_generate(d->right); emit_push(); code_generate(d->left); switch(d->type) { case '+': emit_calc(O_ADD); break; case '-': emit_calc(O_SUB_R); break; case '/': emit_calc(O_DIV_R); break; case '*': emit_calc(O_MUL); break; default: error("Internal Error, unknown opecode"); } return; } } static node_ptr expr() { node *d; d = aexpr(); while(last_token!=EOF) { switch(last_token) { case '>': d = new_node('>',0,d,aexpr()); break; case '=': d = new_node('=',0,d,aexpr()); break; case ')': return d; default: error("Bad expression"); return d; } } return d; } static node_ptr aexpr() { node *d; d = mexpr(); while(last_token!=EOF) { switch(last_token) { case '-': d = new_node('-',0,d,mexpr()); break; case '+': d = new_node('+',0,d,mexpr()); break; default: return d; } } return d; } static node_ptr mexpr() { node *d; d = term(); while(last_token!=EOF) { switch(last_token) { case '*': d = new_node('*',0,d,term()); break; case '/': d = new_node('/',0,d,term()); break; default: return d; } } return d; } static node_ptr term() { node *d; lvalue= -1; token(); if(last_token==EOF) { error("Term expected"); } switch(last_token) { case '0': d = new_node('0',value,NULL,NULL); token(); return d; case 'v': d = new_node('v',value,NULL,NULL); token(); return d; case '(': d = expr(); if(last_token != ')') { error("Unbalanced parenthsis"); } token(); return d; default: token(); error("Unknown term"); return 0; } } int main() { node *d; char buf[BUFSIZ]; emit_intro(); while (fgets(buf,BUFSIZ,stdin)) { ptr = buf; before = buf; printf("%s %s",comments,buf); d = expr(); code_generate(d); free_node(d); emit_print(); emit_comment(); } emit_ending(); return 0; } /* end */