/* * File : chiaa.c * Last Modified: 14 December 2002 * * */ typeptr empty_node (){ // returns an empty node with its left and right pointers as NULL typeptr t1 = (typeptr) malloc(sizeof(typenode)); t1->left = NULL; t1->right = NULL; return t1; } typeptr new_node(char *info, myType t){ //returns a new node of type t typeptr t1 = empty_node(); t1->info.c = (char*)malloc(strlen(info)+1); strcpy(t1->info.c,info); t1->type = t; return t1; } typeptr new_int_node(int info) { //returns a new node of type NUMBER typeptr t1 = empty_node(); t1->info.i = info; t1->type = NUMBER; return t1; } typeptr new_dummy_node() { //returns a new dummy node with "." filled in its info field typeptr t1= empty_node(); t1->type = DUMMY; t1->info.c = "."; } typeptr join_child_node(typeptr t1, typeptr t2, typeptr t3) { //return pointer to the root node that points the left subtree t2 and right subtree t3 t1->left = t2; t1->right = t3; return t1; } void print_tree (typeptr t) { //prints the abstract syntax tree formed if (t != NULL) { if ((t->type == STR) || (t->type == NUMOPER) || (t->type == TYPE) || (t->type == LOGOPER) || (t->type == ASSIGNOPER) || (t->type == DUMMY) || (t->type == RESWORD)) printf("%s ", t->info.c); if (t->type == NUMBER) printf("%d ", t->info.i); if (t->left != NULL || t->right != NULL) { printf("\n( "); print_tree(t->left); print_tree(t->right); printf(")"); } } return ; } int isLeaf(typeptr t){ //return 1 if the node is leaf node, otherwise 0 if (t->left==NULL && t->right==NULL) return 1; else return 0; } void generate(typeptr t){ //generate equivalent interpreted code from the abstract syntax tree int leftCount,rightCount; int leftlabel, rightlabel, slabel,scount; if (t == NULL) return; switch(t->type) { case DUMMY: generate(t->left); generate(t->right); break; case TYPE: //printf("Procedure %s: \n",t->left->info.c); if (t->left->type == ASSIGNOPER) generate(t->left); generate(t->right); break; case ASSIGNOPER: generate(t->right); printf("STORE R1, %s\n",t->left->info.c); break; case STR: if (isLeaf(t)) printf("LOAD %s, R1\n",t->info.c); break; case NUMBER: if (isLeaf(t)) printf("LOAD #%d, R1\n",t->info.i); break; case LOGOPER: if (strcmp(t->info.c,"<") == 0) { scount = count++; generate(t->left); printf("STORE R1, temp%d\n",scount); generate(t->right); printf("L temp%d, R1\n",scount); } if (strcmp(t->info.c,"<=") == 0) { scount = count++; generate(t->left); printf("STORE R1, temp%d\n",scount); generate(t->right); printf("LE temp%d, R1\n",scount); } if (strcmp(t->info.c,">") == 0) { scount = count++; generate(t->left); printf("STORE R1, temp%d\n",scount); generate(t->right); printf("G temp%d, R1\n",scount); } if (strcmp(t->info.c,">=") == 0) { scount = count++; generate(t->left); printf("STORE R1, temp%d\n",scount); generate(t->right); printf("GE temp%d, R1\n",scount); } if (strcmp(t->info.c,"!=") == 0) { scount = count++; generate(t->left); printf("STORE R1, temp%d\n",scount); generate(t->right); printf("NE temp%d, R1\n",scount); } if (strcmp(t->info.c,"==") == 0) { scount = count++; generate(t->left); printf("STORE R1, temp%d\n",scount); generate(t->right); printf("CMP temp%d, R1\n",scount); } if (strcmp(t->info.c,"AND") == 0) { scount = count++; generate(t->left); printf("STORE R1, temp%d\n",scount); generate(t->right); printf("AND R1, temp%d\n",scount); } if (strcmp(t->info.c,"OR") == 0) { scount = count++; generate(t->left); printf("STORE R1, temp%d\n",scount); generate(t->right); printf("OR R1, temp%d\n",scount); } if (strcmp(t->info.c,"NOT") == 0) { scount = count++; generate(t->left); printf("NOT R1\n"); } break; case RESWORD: slabel = label; if (strcmp(t->info.c,"IF") == 0) { if (t->right->type == DUMMY){ if (t->right->left != NULL){ leftlabel = label++; slabel = leftlabel; } if (t->right->right != NULL) rightlabel = label++; } generate(t->left); printf("IFFALSE GOTO Label%d\n",slabel); if (t->right->type != DUMMY){ generate(t->right); printf("Label%d:\n",slabel); } else{ generate(t->right->left); printf("GOTO Label%d\n",rightlabel); printf("Label%d:\n",leftlabel); generate(t->right->right); printf("Label%d:\n",rightlabel); } } if (strcmp(t->info.c,"WHILE") == 0) { leftlabel = label++; rightlabel = label++; printf("LABEL%d:\n",leftlabel); generate(t->left); printf("IFFALSE GOTO Label%d\n",rightlabel); generate(t->right); printf("GOTO Label%d\n",leftlabel); printf("LABEL%d:\n",rightlabel); } if (strcmp(t->info.c,"DO") == 0) { slabel = label++; printf("LABEL%d:\n",slabel); generate(t->right); generate(t->left); printf("IFTRUE GOTO Label%d\n",slabel); } if (strcmp(t->info.c,"FOR") == 0) { slabel = label++; if (t->left->left != NULL) generate(t->left->left); printf("Label%d:\n",slabel); generate(t->right); if (t->left->type == DUMMY){ if (t->left->right != NULL){ if (t->left->right->right != NULL) generate(t->left->right->right); if (t->left->right->left != NULL){ generate(t->left->right->left); printf("IFTRUE GOTO Label%d\n",slabel); } else { printf("GOTO Label%d\n",slabel); } } } } break; case NUMOPER: if (!isLeaf(t->left) || !isLeaf(t->right)) leftCount = count++; if (!isLeaf(t->right)) rightCount = count++; generate(t->left); if (!isLeaf(t->left) || !isLeaf(t->right)) printf("STORE R1, Temp%d\n",leftCount); if (!isLeaf(t->right)){ generate(t->right); printf("STORE R1, Temp%d\n",rightCount); } if (!isLeaf(t->left) || !isLeaf(t->right)) printf("LOAD Temp%d, R1\n",leftCount); if (strcmp(t->info.c,"+") == 0) if (!isLeaf(t->right)) printf("ADD Temp%d, R1\n",rightCount); else if (t->right->type == STR) printf("ADD %s, R1\n",t->right->info.c); else printf("ADD #%d, R1\n",t->right->info.i); if (strcmp(t->info.c,"-") == 0){ if (!isLeaf(t->right)){ printf("NEG Temp%d\n",rightCount); printf("ADD Temp%d, R1\n",rightCount); } else if (t->right->type == STR){ printf("NEG %s\n",t->right->info.c); printf("ADD %s, R1\n",t->right->info.c); } else{ printf("NEG #%d\n",t->right->info.i); printf("ADD #%d, R1\n",t->right->info.i); } } if (strcmp(t->info.c,"*") == 0) if (!isLeaf(t->right)) printf("MULT Temp%d, R1\n",rightCount); else if (t->right->type == STR) printf("MULT %s, R1\n",t->right->info.c); else printf("MULT #%d, R1\n",t->right->info.i); if (strcmp(t->info.c,"/") == 0) if (!isLeaf(t->right)) printf("DIV R1, Temp%d\n",rightCount); else if (t->right->type == STR) printf("DIV R1, %s\n",t->right->info.c); else printf("DIV R1, #%d\n",t->right->info.i); if (strcmp(t->info.c,"%") == 0) if (!isLeaf(t->right)) printf("MOD R1, Temp%d\n",rightCount); else if (t->right->type == STR) printf("MOD R1, %s\n",t->right->info.c); else printf("MOD R1, #%d\n",t->right->info.i); break; } return; }