#include #include #include #include "bind.h" #include "tree.h" #include "qc.h" #define OBJ_STACK_SIZE 1024 /* stringf.c で定義 */ void freeStrings(); /* Stringf() で確保された文字列領域を全て開放 */ /********************************/ /* オブジェクト構造体関係 */ /********************************/ /* オブジェクト構造体のスタック */ struct object ObjStack[OBJ_STACK_SIZE]; int OSp=0, lastGobjIndex=-1; /* 大域オブジェクトの登録 */ Obj pushGobj(ObjType type, char *name, int size) { Obj p = &ObjStack[OSp]; p->type = type; p->name = name; p->size = size; p->argc = 0; p->offset = 0; p->scope = NUL; lastGobjIndex = OSp++; return p; } Obj pushFunc(char *name) { return pushGobj(objFUNC, name, 0); } Obj pushGvar(char *name) { return pushGobj(objGVAR, name, 1); } Obj pushGarr(char *name, int size) { return pushGobj(objGARR, name, size); } /* 局所オブジェクトの登録 */ Obj pushLobj(ObjType type, char *name, int size) { Obj p = &ObjStack[OSp++]; p->type = type; p->name = name; p->size = size; p->argc = 0; p->scope = &ObjStack[lastGobjIndex]; return p; } Obj pushLarg(char *name) { Obj p = pushLobj(objLVAR, name, 1); p->scope->argc++; p->offset = p->scope->argc + 1; return p; } Obj pushLvar(char *name) { Obj p = pushLobj(objLVAR, name, 1); p->scope->size++; p->offset = -(p->scope->size); return p; } Obj pushLarr(char *name, int size) { Obj p = pushLobj(objLARR, name, size); p->scope->size += size; p->offset = -(p->scope->size); return p; } /* オブジェクト構造体の検索 */ Obj getObj(char *name) { int i; for (i = OSp-1; i >= 0; i--) { if (strcmp(ObjStack[i].name, name)==0) return &ObjStack[i]; } /* 見つからなかった場合 */ return NUL; } /* 局所オブジェクトの解放 */ void popLocals() { OSp = lastGobjIndex + 1; } /********************************/ /* 意味解析と結果の出力 */ /********************************/ /* 意味解析 */ void bindObj(Node t) { Node s, v; Obj o; if (t == NUL) return; switch (t->type) { case Fdef: /* 関数定義 */ s = t->left->left; /* SYM ノード */ s->right = (Node)(o = pushFunc((char *)s->left)); for (s=t->left->right; s!=NUL; s=s->right) s->left->right = (Node)pushLarg((char *)s->left->left); bindObj(t->right); return; case Gvar: /* 大域変数の宣言 */ for (s=t->left; s!=NUL; s=s->right) { v = s->left; if (v->type==Sclr) { v->left->right = (Node)pushGvar((char *)v->left->left); } else /* v->type==Arry */ { v->left->right = (Node)pushGarr((char *)v->left->left, (int)v->right->left); } } return; case Lvar: /* 局所変数の宣言 */ for (s=t->left; s!=NUL; s=s->right) { v = s->left; if (v->type==Sclr) { v->left->right = (Node)pushLvar((char *)v->left->left); } else /* v->type==Arry */ { v->left->right = (Node)pushLarr((char *)v->left->left, (int)v->right->left); } } return; case Func: /* 関数の使用 */ o = getObj((char *)t->left->left); if (o==NUL) { fprintf(stderr, "undefined function (%s) in %s()\n", (char *)t->left->left, ObjStack[lastGobjIndex].name); o = pushLobj(objFUNC, (char *)t->left->left, 0); } t->left->right = (Node)o; bindObj(t->right); return; case Arry: /* 配列の使用 */ o = getObj((char *)t->left->left); if (o==NUL) { fprintf(stderr, "undefined array (%s) in %s().\n", (char *)t->left->left, ObjStack[lastGobjIndex].name); freeStrings(); /* Stringf() で確保された文字列領域を全て開放 */ exit(1); } t->left->right = (Node)o; bindObj(t->right); return; case Sclr: /* 変数の使用 */ o = getObj((char *)t->left->left); if (o==NUL) { fprintf(stderr, "undefined variable (%s) in %s().\n", (char *)t->left->left, ObjStack[lastGobjIndex].name); o = pushLvar((char *)t->left->left); } t->left->right = (Node)o; return; case STR: case NUM: return; default: bindObj(t->left); bindObj(t->right); } } /* オブジェクト構造体スタックの出力 */ char *objType[] = { "GARR", "GVAR", "LARR", "LVAR", "FUNC" }; void putObjs() { int i; printf("Address Name Type Argc Size Offset Scope\n"); printf("---------------------------------------------------------\n"); for (i=0; i