Mercurial > hg > CbC > old > device
changeset 9:65f01a63de9c
*** empty log message ***
author | kono |
---|---|
date | Fri, 14 Jan 2000 12:21:10 +0900 |
parents | e714bcee688b |
children | 9f0593d7295a |
files | ansi/mc-nop-386.c ansi/mc-nop-386.c.save ansi/mc-parse.c ansi/mc-parse.c.save ansi/mc-tree.c ansi/mc-tree.c.save ansi/mc.h ansi/mc.h.save ansi/stdio.h ansi/stdio.h.save |
diffstat | 10 files changed, 0 insertions(+), 9274 deletions(-) [+] |
line wrap: on
line diff
--- a/ansi/mc-nop-386.c Fri Jan 14 12:10:42 2000 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1586 +0,0 @@ -/* Micro-C Code Generatation Part for intel386 */ - -#define EXTERN extern -#include "mc.h" - -#define REGISTERS6 0 - -void code_init(); -void free_register(); -void emit_init(); -void emit_push(); -void gexpr(); -void g_expr(); -void bexpr(); -void b_expr(); -void string(); -void function(); -void machinop(); -void rindirect(); -void assign(); -void sassign(); -void assop(); -void tosop(); -char *div_setup() ; -void shift() ; -void ld_indexx(); -void st_indexx(); -void indexy(); -void cmpdimm(); -void global_table() ; -void local_table() ; -void opening(); -void closing(); -void gen_gdecl() ; -void jmp_label(); -void jmp_eq_label(); -void rexpr(); -void jcond(); -void jmp(); -void def_label() ; -void gen_comment(); -void gen_source(); -void code_enter() ; -void code_leave() ; -void enter() ; -void enter1() ; -void ret(); -void emit_data(); -void text_mode(); -void data_mode(); -int get_register_var(); -void jump(); -int lvar(); - -int cadr(); -int car(); -int caddr(); -int fwdlabel(); -void fwddef(); -int cadddr(); -int backdef(); -int error(); -int size(); -int list3(); - -#define TEXT_EMIT_MODE 0 -#define DATA_EMIT_MODE 1 -#define RODATA_EMIT_MODE 2 - -static output_mode = TEXT_EMIT_MODE; -static data_alignment = 0; - -/* - local1 <----24 local variable - %esi -20 <- disp_offset - %edi -16 - %edx -12 - %ecx -8 - %ebx -4 - %ebp = %esp 0 - %eip 4 <- arg_offset - arg1 8 - see enter/enter1/leave - */ -int arg_offset = 8; -int disp_offset = -20; -int func_disp_offset = -20; -int code_disp_offset = 0; -int int_size = 4; -int endian = 0; -int MAX_REGISTER=6; /* intel386のレジスタを4つまで使う*/ -int REAL_MAX_REGISTER=8; /* intel386のレジスタが8つということ*/ -int MAX_DATA_REG=4; -int MAX_POINTER=3; -int MAX_REGISTGER_VAR=2; - -static int creg; /* current register */ -static char *crn; /* current register name */ -static int lreg; /* operand register */ -static char *lrn; /* operand register name */ -static int dreg; /* temporary register */ -static char *drn; /* temporary register name */ -static int xreg; /* pointer register */ -static int reg_sp; /* REGister Stack-Pointer */ - - -#define REG_EAX 0 -#define REG_EBX 1 -#define REG_ECX 2 -#define REG_EDX 3 -#define REG_ESI 4 -#define REG_EDI 5 -#define REG_EBP 6 -#define REG_ESP 7 - - -#define DATA_REG 0 -#define POINTER_REG 3 -static char *reg_name[8]; -static char *reg_name_l[4]; - -/* - creg currrent virtual register - lreg operand virtual register - dreg spare virtual register - - rname[creg] currrent real register - rname[lreg] operand real register - rname[dreg] spare real register - - regs[] virtual register usage - - reg_name[rname[creg]] - */ - -#define MAX_MAX 10 -static int rname[MAX_MAX]; -static int regs[MAX_MAX]; /* 使われているレジスタを示すフラグ */ -static int reg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ - -void -code_init() -{ - if (REGISTERS6) { - arg_offset = 8; - func_disp_offset = -20; - int_size = 4; - endian = 0; - MAX_REGISTER=6; - MAX_DATA_REG=4; - MAX_POINTER=3; - } else { - arg_offset = 8; - func_disp_offset = -12; - int_size = 4; - endian = 0; - MAX_REGISTER=4; - MAX_DATA_REG=4; - MAX_POINTER=1; - } - MAX_REGISTER_VAR=2; - - reg_name[REG_EAX] = "%eax"; - reg_name[REG_EBX] = "%ebx"; - reg_name[REG_ECX] = "%ecx"; - reg_name[REG_EDX] = "%edx"; - reg_name[REG_ESI] = "%esi"; - reg_name[REG_EDI] = "%edi"; - reg_name[REG_EBP] = "%ebp"; - reg_name[REG_ESP] = "%esp"; - reg_name_l[REG_EAX] = "%al"; - reg_name_l[REG_EBX] = "%bl"; - reg_name_l[REG_ECX] = "%cl"; - reg_name_l[REG_EDX] = "%dl"; - -} - -char * -register_name(i) - int i; -{ - return reg_name[rname[i]]; -} - -int -get_register() -{ /* 使われていないレジスタを調べる */ - int i; - for(i=0;i<MAX_REGISTER;i++) { - if (! regs[i]) { /* 使われていないなら */ - regs[i]=1; /* そのレジスタを使うことを宣言し */ - return i; /* その場所を表す番号を返す */ - } - } - return -1; /* 空いている場所がないなら、それを表す -1 を返す */ -} - -void -free_register(i) - int i; - { /* いらなくなったレジスタを開放 */ - regs[i]=0; -} - -int -register_full() -{ - int i; - for(i=0;i<MAX_REGISTER;i++) { - if (! regs[i]) { - return 0; - } - } - return 1; -} - -void -gexpr_init() -{ - int i; - while(reg_sp > 0) { - free_register(reg_stack[--reg_sp]); - } - text_mode(); -} - -void -emit_init() -{ - int i; - for(i=0;i<REAL_MAX_REGISTER;i++) regs[i]=0; - for(i=0;i<REAL_MAX_REGISTER;i++) rname[i]=i; - creg = get_register(); - crn = reg_name[rname[creg]]; - dreg = get_register(); - drn = reg_name[rname[dreg]]; - reg_sp = 0; - text_mode(); -} - -void -set_crn(i) - int i; -{ - creg = i; - crn = reg_name[rname[creg]]; -} - -void -set_drn(i) - int i; -{ - dreg = i; - drn = reg_name[rname[dreg]]; -} - -int -virtual(real) - int real; -{ - int real_v,i; - real_v = -1; - for(i=0;i<MAX_REGISTER;i++) { - if (rname[i]==real) { - real_v=i; - break; - } - } - if (real_v == -1) - error(-1); - return real_v; -} - -void -use_register(virt, real, move) - int virt; - int real; - int move; -{ - int real_v; - char *move_op; - if (rname[virt]==real) - return; - real_v = virtual(real); - move_op = regs[real_v]?"\txchg %s,%s\n":"\tmovl %s,%s\n"; - if (move || regs[real_v]) { - printf(move_op,reg_name[rname[virt]],reg_name[real]); - } - rname[real_v] = rname[virt]; - rname[virt] = real; - crn = reg_name[rname[creg]]; - drn = reg_name[rname[dreg]]; - lrn = reg_name[rname[lreg]]; -} - -void -use_pointer(virt, move) - int virt; - int move; -{ - int i; - if (rname[virt]>=POINTER_REG) - return; - for(i=POINTER_REG;i<MAX_REGISTER;i++) { - if (!regs[virtual(i)]) { - use_register(virt,i,move); - return; - } - } - /* we prefer EBX */ - use_register(virt,REG_EBX,move); -} - -void -use_data_reg(virt, move) - int virt; - int move; -{ - int i; - if (rname[virt]<MAX_DATA_REG) - return; - for(i=0;i<MAX_DATA_REG;i++) { - if (!regs[virtual(i)]) { - use_register(virt,i,move); - return; - } - } - /* we prefer EBX */ - use_register(virt,REG_EBX,move); -} - -int -pop_register() -{ /* レジスタから値を取り出す */ - int i,j; - - j = creg; - i = reg_stack[--reg_sp]; - - if(i<0) { - return i; - } else { - free_register(i); - lreg = i; - lrn = reg_name[rname[lreg]]; - regs[i]=0; - return lreg; - } -} - -int -stack_used() - { - return reg_stack[--reg_sp]<0; -} - -void -emit_push() -{ - int new_reg; - new_reg = get_register(); - if(new_reg<0) { /* もうレジスタがない */ - reg_stack[reg_sp++] = -1; - printf("\tpushl %s\n",crn); - } else { - reg_stack[reg_sp++] = creg; /* push するかわりにレジスタを使う */ - set_crn(new_reg); - } -} - -char * -emit_pop(type) - int type; -{ - char *xrn; - if (pop_register()==-1) { - if (type==POINTER_REG) - use_pointer(dreg,0); - else if (type==DATA_REG) - use_data_reg(dreg,0); - printf("\tpopl %s\n",drn); - xrn = drn; - xreg = dreg; - } else { - xrn = lrn; - xreg = lreg; - } - return xrn; -} - -int -get_register_var() -{ - int i; - for(i=REG_ESI;i<REG_ESP;i++) { - if (! regs[i]) { /* 使われていないなら */ - regs[i]=1; /* そのレジスタを使うことを宣言し */ - return i; /* その場所を表す番号を返す */ - } - } - return -1; -} - -void -gexpr(e1) - int e1; -{ - gexpr_init(); - g_expr(e1); - csvalue = rname[creg]; /* for siwtch value */ -} - -void -g_expr(e1) - int e1; -{ - int e2,e3,e4; - char *xrn; - NMTBL *n; - - if (chk) return; - e2 = cadr(e1); - switch (car(e1)){ - case GVAR: - /* use_pointer(creg,0); */ - printf("\tmovl $%s,%s\n",caddr(e1),crn); - return; - case RGVAR: - /* use_pointer(creg,0); */ - printf("\tmovl %s,%s\n",caddr(e1),crn); - return; - case CRGVAR: - printf("\tmovsbl %s,%s\n",caddr(e1),crn); - return; - case LVAR: - /* use_pointer(creg,0); */ - printf("\tlea %d(%%ebp),%s\n",lvar(e2),crn); - return; - case REGISTER: - /* this is of course redundant... */ - printf("\tmovl %s,%s\n",register_name(e2),crn); - return; - case RLVAR: - printf("\tmovl %d(%%ebp),%s\n",lvar(e2),crn); - return; - case CRLVAR: - printf("\tmovsbl %d(%%ebp),%s\n",lvar(e2),crn); - return; - case FNAME: - printf("\tmovl $%s,%s\n",((NMTBL *)e2)->nm,crn); - return; - case CONST: /* 代入する値が0でも特別な処理はしない */ - printf("\tmovl $%d,%s\n",e2,crn); - return; - case STRING: - string(e1); - return; - case FUNCTION: - function(e1); - return; - case CODE: - jump(e2,caddr(e1)); - return; - case INDIRECT: - g_expr(e2); - return; - case RINDIRECT: case CRINDIRECT: - rindirect(e1); - return; - case ADDRESS: - g_expr(e2); - return; - case MINUS: /* レジスタに対し、neglを実行すれば実現可能 */ - g_expr(e2); - /* use_data_reg(creg,1); */ - printf("\tnegl %s\n", crn); - return; - case BNOT: /* ~ */ - g_expr(e2); - /* use_data_reg(creg,1); */ - printf("\tnotl %s\n", crn); - return; - case LNOT: /* ! */ - g_expr(e2); - use_data_reg(creg,1); - printf("\tcmpl $0,%s\n", crn); - printf("\tsete %s\n", reg_name_l[rname[creg]]); - printf("\tmovzbl %s,%s\n", reg_name_l[rname[creg]],crn); - return; - case PREINC: - if (car(e2)==REGISTER) { - printf("\taddl $%d,%s\n",caddr(e1),register_name(cadr(e2))); - printf("\tmovl %s,%s\n",register_name(cadr(e2)),crn); - return; - } - g_expr(e2); - printf("\taddl $%d,(%s)\n",caddr(e1),crn); - printf("\tmovl (%s),%s\n",crn,crn); - return; - case POSTINC: - if (car(e2)==REGISTER) { - printf("\tmovl %s,%s\n",register_name(cadr(e2)),crn); - printf("\taddl $%d,%s\n",caddr(e1),register_name(cadr(e2))); - return; - } - g_expr(e2); - emit_push(); -/* in case of register full we should copy crn to drn */ - xrn = emit_pop(0); - printf("\tmovl (%s),%s\n",xrn,crn); - printf("\taddl $%d,(%s)\n",caddr(e1),xrn); - return; - case CPOSTINC: - /* char *p; *p++ */ - if (car(e2)==REGISTER) { - printf("\tmovl %s,%s\n",register_name(cadr(e2)),crn); - printf("\taddl $%d,%s\n",caddr(e1),register_name(cadr(e2))); - return; - } - g_expr(e2); - emit_push(); /* in case of register full we should copy crn to drn */ - xrn = emit_pop(0); - printf("\tmovsbl (%s),%s\n",xrn,crn); - printf("\tincl (%s)\n",xrn); - return; - case CPREINC: - if (car(e2)==REGISTER) { - printf("\taddl $%d,%s\n",caddr(e1),register_name(cadr(e2))); - printf("\tmovl %s,%s\n",register_name(cadr(e2)),crn); - return; - } - g_expr(e2); - printf("\tincl (%s)\n",crn); - printf("\tmovsbl (%s),%s\n",crn,crn); - return; - case CPOSTDEC: - if (car(e2)==REGISTER) { - printf("\tmovl %s,%s\n",register_name(cadr(e2)),crn); - printf("\tdecl %s\n",register_name(cadr(e2))); - return; - } - g_expr(e2); - printf("\tmovsbl (%s),%s\n",crn,crn); - printf("\tdecl (%s)\n",crn); - return; - case CPREDEC: - if (car(e2)==REGISTER) { - printf("\tdecl %s\n",register_name(cadr(e2))); - printf("\tmovl %s,%s\n",register_name(cadr(e2)),crn); - return; - } - g_expr(e2); - emit_push(); - xrn = emit_pop(0); - printf("\tdecl (%s)\n",xrn); - printf("\tmovsbl (%s),%s\n",xrn,crn); - return; - case MUL: case UMUL: - case DIV: case UDIV: - case MOD: case UMOD: - case LSHIFT: case ULSHIFT: case RSHIFT: case URSHIFT: - case ADD: case SUB: case BAND: case EOR: case BOR: - machinop(e1); - return; - case COND: - e2=fwdlabel(); - b_expr(cadr(e1),0,e2); - g_expr(caddr(e1)); - e4 = rname[creg]; - jmp(e3=fwdlabel()); - fwddef(e2); - g_expr(cadddr(e1)); - use_register(creg,e4,1); - fwddef(e3); - return; - case SASS: - sassign(e1); - return; - case ASS: case CASS: - assign(e1); - return; - case ASSOP: case CASSOP: - assop(e1); - return; - case COMMA: - g_expr(e2); - g_expr(caddr(e1)); - return; - case RETURN: - n = (NMTBL *)e2; - if (retcont==0) - retcont=fwdlabel(); - printf("\tleal _%d,%s\n",retcont,crn); - return; - case ENVIRONMENT: - printf("\tmovl %%ebp,%s\n",crn); - return; - default: - b_expr(e1,1,e2=fwdlabel()); /* including > < ... */ - printf("\txorl %s,%s\n",crn,crn); - jmp(e3=fwdlabel()); - fwddef(e2); - printf("\tmovl $1,%s\n",crn); - fwddef(e3); - } -} - -void -bexpr(e1, cond, l1) - int e1; - char cond; - int l1; -{ - gexpr_init(); - b_expr(e1,cond,l1); -} - -void -b_expr(e1, cond, l1) - int e1; - char cond; - int l1; -{ - int e2,l2; - if (chk) return; - e2=cadr(e1); - switch(car(e1)) { - case LNOT: - b_expr(e2,!cond,l1); - return; - case GT: - rexpr(e1,l1,cond?"g":"le"); - return; - case UGT: - rexpr(e1,l1,cond?"a":"be"); - return; - case GE: - rexpr(e1,l1,cond?"ge":"l"); - return; - case UGE: - rexpr(e1,l1,cond?"ae":"b"); - return; - case LT: - rexpr(e1,l1,cond?"l":"ge"); - return; - case ULT: - rexpr(e1,l1,cond?"b":"ae"); - return; - case LE: - rexpr(e1,l1,cond?"le":"g"); - return; - case ULE: - rexpr(e1,l1,cond?"be":"a"); - return; - case EQ: - rexpr(e1,l1,cond?"e":"ne"); - return; - case NEQ: - rexpr(e1,l1,cond?"ne":"e"); - return; - case LAND: - b_expr(e2,0,cond?(l2=fwdlabel()):l1); - b_expr(caddr(e1),cond,l1); - if(cond) fwddef(l2); - return; - case LOR: - b_expr(e2,1,cond?l1:(l2=fwdlabel())); - b_expr(caddr(e1),cond,l1); - if(!cond) fwddef(l2); - return; - case CRGVAR: - printf("\tcmpb $0,%s\n",caddr(e1)); - jcond(l1,cond); - return; - case CRLVAR: - printf("\tcmpb $0,%d(%%ebp)\n",lvar(e2)); - jcond(l1,cond); - return; - case RGVAR: - printf("\tcmpl $0,%s\n",caddr(e1)); - jcond(l1,cond); - return; - case RLVAR: - printf("\tcmpl $0,%d(%%ebp)\n",lvar(e2)); - jcond(l1,cond); - return; - case REGISTER: - printf("\tcmpl $0,%s\n",register_name(e2)); - jcond(l1,cond); - return; - case CONST: - if((cond&&e2)||(!cond&&!e2)) jmp(l1); - return; - default: - g_expr(e1); - printf("\tcmpl $0,%s\n",crn); - jcond(l1,cond); - return; - } -} - -void -ascii(s) - char *s; -{ - printf("\t.string \""); - while(*s) { - if (*s=='\n') - printf("%cn",92); - else if (*s<' ') - printf("%c%03o",92,*s); - else if (*s==34) - printf("%c%c",92,34); - else - printf("%c",*s); - s++; - } - printf("%c\n",34); -} - -void -string(e1) - int e1; -{ - char *s; - int i,lb; - - if (0) { - s=(char *)cadr(e1); - lb=fwdlabel(); - printf("\tjmp _%d\n",lb); - i=backdef(); - ascii(s); - printf("\t.align 2\n"); - fwddef(lb); - printf("\tlea _%d,%s\n",i,crn); - } else { - s=(char *)cadr(e1); - printf(".section\t.rodata\n"); - lb=fwdlabel(); - printf("_%d:\n",lb); - ascii(s); - if (output_mode==TEXT_EMIT_MODE) { - printf(".text\n"); - } else { - text_mode(); - } - printf("\tlea _%d,%s\n",lb,crn); - } -} - -void -function(e1) - int e1; -{ - int e2,e3,e4,e5,nargs; - NMTBL *n; - - e2 = cadr(e1); - nargs = 0; - for (e3 = caddr(e1); e3; e3 = cadr(e3)) { - n=(NMTBL *)(e5=(cadr(e4 = car(e3)))); - switch(car(e4)) { - case FNAME: - printf("\tlea %s,%s\n",n->nm,crn); - printf("\tpushl %s\n",crn); - break; - case ADDRESS: - g_expr(e5); - printf("\tpushl %s\n",crn); - break; - default:g_expr(e4); - printf("\tpushl %s\n",crn); - } - ++nargs; - } - if (car(e2) == FNAME) { - n=(NMTBL *)cadr(e2); - use_register(creg,REG_EAX,0); - printf("\tcall\t%s\n",n->nm); - } else { - g_expr(e2); - use_register(creg,REG_EAX,0); - printf("\tcall\t*%s\n",crn); - } - if (nargs) printf("\taddl $%d,%%esp\n",4*nargs); -} - -void -jump(e1, env) - int e1; - int env; -{ - int i,e2,e3,e4,e5,nargs,regs; - NMTBL *n,*code0; - int new_disp; - char *xrn; - - /* count number of args */ - nargs = 0; - for (e3 = caddr(e1); e3;e3 =cadr(e3)) nargs++; - new_disp = -(nargs-MAX_REGISTER_VAR)*int_size; - if (new_disp > 0) - new_disp=0; -/* printf("# new_disp %d,disp %d\n",new_disp,disp); */ - if (new_disp < disp) { - printf("\tlea %d(%%ebp),%%esp\n",new_disp+disp_offset); - } - /* compute jump address */ - e2 = cadr(e1); - if (car(e2) == FNAME) { - code0=(NMTBL *)cadr(e2); - if (code0->sc!=CODE) { - error(STERR); return; - } - } else { /* indirect */ - g_expr(e2); - emit_push(); - } - /* compute arguments */ - regs = nargs-1; - i=0; - for (e3 = caddr(e1); e3;e3 =cadr(e3),i++) { - n=(NMTBL *)(e5=(cadr(e4 = car(e3)))); - switch(car(e4)) { - case FNAME: - printf("\tlea %s,%s\n",n->nm,crn); - emit_push(); - break; - case ADDRESS: - g_expr(e5); - emit_push(); - break; -/* -printf("# cadr(e4) %d ==disp_offset+(-1-i)*int_size %d\n", cadr(e4), disp_offset+(-2-i)*int_size); - */ - case RLVAR: - case CRLVAR: - if (env==0 && cadr(e4)==disp_offset+(-1-i)*int_size) { - /* Same positioned local variable. No need to copy */ - reg_stack[reg_sp++] = -2; - --regs; - continue; - } - case REGISTER: - if (rname[cadr(e4)]==REG_ESI+regs) { - /* Same register variable. No need to copy */ - reg_stack[reg_sp++] = cadr(e4); - --regs; - continue; - } - default: - g_expr(e4); - emit_push(); - } - --regs; - } - /* save frame pointer before jump in fuction */ - if (fnptr->sc==FUNCTION) { - printf("\tmovl %%ebp,%d(%%ebp)\n",disp_offset); - } - if (env) { - /* change frame pointer */ - g_expr(env); - printf("\tmovl %s,%%ebp\n",crn); - } - /* copy arguments to destination environment if necessary */ - for(i=0;i<nargs;i++) { - if (i>=MAX_REGISTGER_VAR) { - if (reg_stack[reg_sp-1]== -2) { - /* same positioned variable */ - reg_sp--; - } else { - xrn=emit_pop(0); - printf("\tmovl %s,%d(%%ebp)\n",xrn, - disp_offset+(-(nargs-i))*int_size); - } - } else if (reg_stack[--reg_sp]>=REG_ESI) { - /* the same registger */ - ; - } else { - if(reg_stack[reg_sp]<0) { - printf("\tpopl %s\n",reg_name[rname[REG_ESI+i]]); - } else { - printf("\tmovl %s,%s\n", - reg_name[rname[reg_stack[reg_sp]]], - reg_name[rname[REG_ESI+i]]); - free_register(reg_stack[reg_sp]); - } - } - } - if (car(e2) != FNAME) { - xrn=emit_pop(0); - } -/* printf("# new_disp %d,disp %d\n",new_disp,disp); */ - if (new_disp>disp) { - /* shrink stack if necessary */ - printf("\tlea %d(%%ebp),%%esp\n",new_disp+disp_offset); - } - if (fnptr->sc==FUNCTION) { - /* link operation for leave, %ebp must point saved old %ebp */ - printf("\tlea %d(%%ebp),%%ebp\n",disp_offset); - } - if (car(e2) == FNAME) { - printf("\tjmp %s\n",code0->nm); - } else { - printf("\tjmp *%s\n",xrn); - } -} - - -void -machinop(e1) - int e1; -{ - int e2,e3,op; - - e2 = cadr(e1); - op = car(e1); - e3 = caddr(e1); - g_expr(e3); - emit_push(); - g_expr(e2); - tosop(car(e1)); - return; -} - - -void -rindirect(e1) - int e1; /* *(p +5 ) */ - -{ - char *op; - int e2,e3,byte; - - op = ((byte = (car(e1) == CRINDIRECT)) ? "movsbl" : "movl"); - e3 = cadr(e2 = cadr(e1)); - g_expr(e2); - printf("\t%s (%s),%s\n",op,crn,crn); -} - -void -sassign(e1) - int e1; -{ - int e2,e3,e4,sz; - char *xrn; - - e2 = cadr(e1); - e3 = cadr(e2); - e4 = caddr(e1); - sz = size(cadr(e2)); /* cld rep movsb */ - g_expr(e4); - emit_push(); - g_expr(e2); - xrn = emit_pop(0); - return; -} - -void -assign(e1) - int e1; -{ - char *op; - int e2,e3,e4,byte; - char *xrn; - - op = ((byte=(car(e1) == CASS))? "movb" : "movl"); - /* e2=e4 */ - e2 = cadr(e1); - e3 = cadr(e2); - e4 = caddr(e1); - switch(car(e2)) { - case GVAR: /* i=3 */ - g_expr(e4); - if (byte) use_data_reg(creg,1); - printf("\t%s %s,%s\n",op,crn,caddr(e2)); - return; - case LVAR: - g_expr(e4); - if (byte) use_data_reg(creg,1); - printf("\t%s %s,%d(%%ebp)\n",op,crn,lvar(cadr(e2))); - return; - case REGISTER: - g_expr(e4); - if (creg!=cadr(e2)) - printf("\t%s %s,%s\n",op,crn,register_name(cadr(e2))); - return; - } - g_expr(e4); - emit_push(); - g_expr(e2); - xrn = emit_pop(0); - if (byte) use_data_reg(creg,1); - printf("\t%s %s,(%s)\n",op,xrn,crn); - printf("\tmovl %s,%s\n",xrn,crn); - return; -} - -void -assop(e1) - int e1; -{ - int e2,e3,byte,op,new_reg; - char *xrn; - - /* e2 op= e3 */ - byte = (car(e1) == CASSOP); - e2 = cadr(e1); - if (car(e2)==INDIRECT) e2=cadr(e2); - e3 = caddr(e1); - op = cadddr(e1); - - g_expr(e3); - emit_push(); - if (car(e2)==REGISTER) { - new_reg=creg; - set_crn(cadr(e2)); - tosop(op); - set_crn(new_reg); - printf("\tmovl %s,%s\n",register_name(cadr(e2)),crn); - return; - } - g_expr(e2); - xrn = emit_pop(0); /* pop e3 value */ - printf("\tpushl %s # assop \n",crn); /* push e2 address */ - ld_indexx(byte,0,crn); - new_reg = get_register(); - /* push e3 value */ - if(new_reg<0) { /* もうレジスタがない */ - reg_stack[reg_sp++] = -1; - printf("\tpushl %s\n",xrn); - } else { - reg_stack[reg_sp++] = xreg; /* push するかわりにレジスタを使う */ - } - tosop(op); - if(new_reg>=0) free_register(new_reg); - printf("\tpopl %s # assop \n",drn); - printf("\t%s %s,(%s)\n",byte ? "movb" : "movl",crn,drn); - return; - -} - - -void -tosop(op) - int op; -{ - int oreg; - char *orn; - - oreg = pop_register(); - switch(op) { - case LSHIFT: - case ULSHIFT: - shift("sall",oreg); - return; - case RSHIFT: - shift("sarl",oreg); - return; - case URSHIFT: - shift("shrl",oreg); - return; - } - if(oreg==-1) { - printf("\tpopl %s\n",drn); - oreg = dreg; - } - orn = reg_name[rname[oreg]]; - switch(op) { - case ADD: - printf("\taddl %s,%s\n",orn,crn); - return; - case SUB: - printf("\tsubl %s,%s\n",orn,crn); - return; - case BAND: - printf("\tandl %s,%s\n",orn,crn); - return; - case EOR: - printf("\txorl %s,%s\n",orn,crn); - return; - case BOR: - printf("\torl %s,%s\n",orn,crn); - return; - case MUL: - case UMUL: - /* use_register(dreg,REG_EDX,0); */ - printf("\t%s %s,%s\n","imull",orn,crn); - return; - case DIV: - case UDIV: - orn = div_setup(oreg); - if (op==DIV) - printf("\tcltd\n\tdivl %s\n",orn); - else - printf("\txor %%edx,%%edx\n\tidivl %s\n",orn); - div_cleanup(orn); - return; - case MOD: - case UMOD: - orn = div_setup(oreg); - if (op==DIV) - printf("\tcltd\n\tdivl %s\n",orn); - else - printf("\txor %%edx,%%edx\n\tidivl %s\n",orn); - rname[creg]=REG_EDX; - crn=reg_name[REG_EDX]; - rname[dreg]=REG_EAX; - drn=reg_name[REG_EAX]; - div_cleanup(orn); - return; - } -} - -static char *dvi_push = "(%esp)"; - -char * -div_setup(oreg) - int oreg; -{ - if (oreg<0) { - use_register(creg,REG_EAX,1); - use_register(dreg,REG_EDX,0); - return 0; - } - if (register_full()) { - printf("\tpushl %s\n",reg_name[rname[oreg]]); - use_register(creg,REG_EAX,1); - use_register(oreg,REG_EDX,0); - return dvi_push; - } - regs[oreg]=1; - use_register(creg,REG_EAX,1); - use_register(dreg,REG_EDX,0); - regs[oreg]=0; - return reg_name[rname[oreg]]; -} - -div_cleanup(orn) - char *orn; -{ - if (orn==dvi_push) - printf("\taddl $4,%%esp\n"); -} - -void -shift(op, reg) - char *op; - int reg; -{ - if (reg>=0) { - use_register(lreg,REG_ECX,1); - } else { - use_register(dreg,REG_ECX,0); - printf("\tpopl %%ecx\n"); - } - printf("\t%s %%cl,%s\n",op,crn); -} - -void -ld_indexx(byte, n, xrn) - int byte; - int n; - char *xrn; -{ - char *op; - - op = byte ? "movsbl" : "movl"; - if (n) - printf("\t%s %d(%s),%s\n",op,n,xrn,crn); - else - printf("\t%s (%s),%s\n",op,xrn,crn); -} - -void -st_indexx(byte, n, xrn) - int byte; - int n; - char *xrn; -{ - char *op; - - op = byte ? "movb" : "movl"; - if (n) - printf("\t%s %s,%d(%s)\n",op,crn,n,xrn); - else - printf("\t%s %s,(%s)\n",op,crn,xrn); -} - -void -indexy(op, gvar) - char *op; - char *gvar; -{ - printf("\t%s %s,%s\n",op,crn,gvar); -} - -void -cmpdimm(e, csreg) - int e; - int csreg; -{ - /* used in dosiwtch() */ - use_register(creg,csreg,0); - printf("\tcmpl $%d,%s\n",e,crn); -} - -void -opening(filename) - char *filename; -{ - printf("\t.file \"%s\"\n",filename); - printf("\t.version\t\"01.01\"\n"); - printf("gcc2_compiled.:\n"); - printf(".text\n"); - emit_init(); -} - -void -closing() -{ - global_table(); - printf("\t.ident \"Micro-C compiled\"\n"); -} - -void -jmp_label(l) - int l; -{ - printf("\tjmp\t_%d\n",l); -} - -void -jmp_eq_label(l) - int l; -{ - printf("\tje\t_%d\n",l); -} - -void -rexpr(e1, l1, s) - int e1; - int l1; - char *s; -{ - g_expr(list3(SUB,cadr(e1),caddr(e1))); - printf("\tj%s\t_%d\n",s,l1); -} - -void -jcond(l, cond) - int l; - char cond; -{ - printf("\tj%s\t_%d\n",cond?"ne":"e",l); -} - -void -jmp(l) - int l; -{ - control=0; - printf("\tjmp\t_%d\n",l); - /* align? */ -} - -int -fwdlabel() -{ - return labelno++; -} - -void -fwddef(l) - int l; -{ - control=1; - printf("_%d:\n",l); -} - -int -backdef() -{ - control=1; - printf("_%d:\n",labelno); - return labelno++; -} - -void -def_label(cslabel, dlabel) - int cslabel; - int dlabel; -{ - int fl; - - fl = 0; - if (control) { - jmp(fl=fwdlabel()); - } - fwddef(cslabel); - if (dlabel) - jmp(dlabel); - if (fl) { - fwddef(fl); - } -} - -void -gen_comment(s) - char *s; -{ - printf("# %s",s); -} - -void -gen_source(s) - char *s; -{ - printf("%s",s); -} - -void -code_enter(name) - char *name; -{ - disp_offset = code_disp_offset; - emit_init(); - printf("\t.align 4\n"); - if (stmode!=STATIC) - printf(".globl %s\n",name); - printf("\t.type\t%s,@function\n",name); - printf("%s:\n",name); -} - -void -code_enter1(disp) - int disp; -{ - if(disp) { - printf("\tsubl $%d,%%esp\n",-disp); - } -} - -void -code_leave(name) - char *name; -{ - local_table(); - printf("_%d:\n",labelno); - printf("\t.size\t%s,_%d-%s\n",name,labelno,name); - labelno++; -} - -void -enter(name) - char *name; -{ - disp_offset = func_disp_offset; - emit_init(); - printf("\t.align 2\n"); - if (stmode!=STATIC) - printf(".globl %s\n",name); - printf("%s:\n",name); - printf("\t.type\t%s,@function\n",name); - printf("\tpushl %%ebp\n"); - printf("\tmovl %%esp,%%ebp\n"); - printf("\tpushl %%ebx\n"); - printf("\tpushl %%ecx\n"); - printf("\tpushl %%edx\n"); - if (REGISTERS6) { - printf("\tpushl %%edi\n"); - printf("\tpushl %%esi\n"); - } -} - -void -enter1(disp) - int disp; -{ - if(disp) printf("\tsubl $%d,%%esp\n",-disp); -} - -void -leave(control, name) - int control; - char *name; -{ - if (control) - use_register(creg,REG_EAX,1); - if (retcont) { - if (control) - jmp(retlabel); - fwddef(retcont); - use_register(creg,REG_EAX,0); - printf("\tmovl %s,%s\n",reg_name[REG_ESI],crn); - /* printf("\tleave\n"); */ - } - fwddef(retlabel); - use_register(creg,REG_EAX,0); - if (REGISTERS6) { - printf("\tpopl %%esi\n"); - printf("\tpopl %%edi\n"); - } - /* if(disp) printf("\taddl $%d,%%esp\n",-disp); */ - printf("\tlea %d(%%ebp),%%esp\n",disp_offset); - printf("\tpopl %%edx\n"); - printf("\tpopl %%ecx\n"); - printf("\tpopl %%ebx\n"); - printf("\tleave\n"); - printf("\tret\n"); - local_table(); - printf("_%d:\n",labelno); - printf("\t.size\t%s,_%d-%s\n",name,labelno,name); - labelno++; -} - - -void -ret() -{ - use_register(creg,REG_EAX,1); - jmp(retlabel); -} - -void -gen_gdecl(n, gpc) - char *n; - int gpc; -{ - /* - if (stmode!=STATIC) - printf(".globl %s\n",n); - */ -} - -void -align(t) - int t; -{ - if (t!=CHAR) { - if (data_alignment & 1) - printf("\t.align 2\n"); - data_alignment = 0; - } -} - -void -emit_data(e, t, n) - int e; - int t; - NMTBL *n; -{ - int l; - char *name; - name = n->nm; - if(mode==GDECL) { /* global */ - if (n->dsp != -1) { - n->dsp = -1; /* initiallized flag */ - printf(".globl\t%s\n",name); - data_mode(name); - align(t); - printf("%s:\n",name); - } else { - data_mode(0); - } - if(car(e)==CONST) { - if (t==CHAR) { - printf("\t.byte %d\n",cadr(e)); - if (data_alignment>0) - data_alignment++; - gpc += 1; - } else { - printf("\t.long %d\n",cadr(e)); - gpc += int_size; - } - } else if(t!=CHAR) { - gpc += int_size; - if(car(e)==ADDRESS&&car(cadr(e))==GVAR) { - printf("\t.long %s\n",caddr(cadr(e))); - } else if(car(e)==FNAME) { - printf("\t.long %s\n",((NMTBL *)cadr(e))->nm); - } else if(car(e)==STRING) { - if (car(n->ty)!=ARRAY || cadr(n->ty)!=CHAR) { - l = fwdlabel(); - printf("\t.long _%d\n",l); - printf(".section\t.rodata\n"); - printf("_%d:\n",l); - output_mode = RODATA_EMIT_MODE; - } - ascii((char *)cadr(e)); - } else error(TYERR); - } - } else { - /* if (n->sc!=LVAR) { error(TYERR); return; } */ - if(car(e)==CONST) { - printf("\tmovl $%d,%s\n",cadr(e),crn); - printf("\t%s %s,%d(%%ebp)\n",t==CHAR?"movsbl":"movl",crn,n->dsp); - } else if(t!=CHAR) { - if(car(e)==ADDRESS&&car(cadr(e))==GVAR) - printf("\tlea %s,%s\n",caddr(e),crn); - else if(car(e)==FNAME) - printf("\tlea %s,%s\n",((NMTBL *)cadr(e))->nm,crn); - else if(car(e)==STRING) { - string(e); - } else error(TYERR); - printf("\tmovl %s,%d(%%ebp)\n",crn,n->dsp); - } - } -} - -void -emit_data_closing(n) - NMTBL *n; -{ - int lb; - if (mode=GDECL) { - data_mode(0); - lb=fwdlabel(); - printf("_%d:\n",lb); - printf("\t.size\t%s,_%d-%s\n",n->nm,lb,n->nm); - } -} - -void -global_table() -{ - NMTBL *n; - for(n=ntable;n < &ntable[GSYMS];n++) { - if (n->sc == GVAR && n->dsp != -1) { - /* n->dsp = -1 means initialized global */ - printf(".comm %s,%d\n",n->nm,size(n->ty)); - } - } -} - -void -local_table() -{ - NMTBL *n; - /* static local variables */ - for(n=ntable+GSYMS;n < &ntable[GSYMS+LSYMS];n++) { - if (n->sc == GVAR) { - printf(".lcomm %s,%d\n",n->nm,size(n->ty)); - } - } -} - -void -text_mode() -{ - if (output_mode!=TEXT_EMIT_MODE) { - printf(".text\n"); - printf("\t.align 2\n"); - output_mode = TEXT_EMIT_MODE; - } -} - -void -data_mode(name) - char *name; -{ - if (output_mode!=DATA_EMIT_MODE) { - printf(".data\n"); - output_mode = DATA_EMIT_MODE; - } - if (name) - printf("\t.type\t%s,@object\n",name); -} - -int -lvar(l) - int l; -{ - if (l<0) { - if (fnptr->sc==CODE) - return l+code_disp_offset; - else - return l+disp_offset; - } else { - return l+arg_offset; - } -} - -/* end */
--- a/ansi/mc-nop-386.c.save Fri Jan 14 12:10:42 2000 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1508 +0,0 @@ -/* Micro-C Code Generatation Part for intel386 */ - -#define EXTERN extern -#include "mc.h" - -#define REGISTERS6 0 - -void code_init(void); -void free_register(int i); -void emit_init(void); -void emit_push(void); -void gexpr(int e1); -void g_expr(int e1); -void bexpr(int e1, char cond, int l1); -void b_expr(int e1, char cond, int l1); -void string(int e1); -void function(int e1); -void machinop(int e1); -void rindirect(int e1); -void assign(int e1); -void sassign(int e1); -void assop(int e1); -void tosop(int op); -char *div_setup(int oreg) ; -void shift(char *op, int reg) ; -void ld_indexx(int byte, int n, char *xrn); -void st_indexx(int byte, int n, char *xrn); -void indexy(char *op, char *gvar); -void cmpdimm(int e, int csreg); -void global_table(void) ; -void local_table(void) ; -void opening(char *filename); -void closing(void); -void gen_gdecl(char *n, int gpc) ; -void jmp_label(int l); -void jmp_eq_label(int l); -void rexpr(int e1, int l1, char *s); -void jcond(int l, char cond); -void jmp(int l); -void def_label(int cslabel, int dlabel) ; -void gen_comment(char *s); -void gen_source(char *s); -void code_enter(char *name) ; -void code_leave(char *name) ; -void enter(char *name) ; -void enter1(int disp) ; -void ret(void); -void emit_data(int e, int t, NMTBL *n); -void text_mode(void); -void data_mode(char *name); -int get_register_var(void); -void jump(int e1, int env); -int lvar(int l); - -int cadr(int e); -int car(int e); -int caddr(int e); -int fwdlabel(void); -void fwddef(int l); -int cadddr(int e); -int backdef(void); -int error(int n); -int size(int t); -int list3(int e1, int e2, int e3); - -#define TEXT_EMIT_MODE 0 -#define DATA_EMIT_MODE 1 -#define RODATA_EMIT_MODE 2 - -static output_mode = TEXT_EMIT_MODE; -static data_alignment = 0; - -/* - local1 <----24 local variable - %esi -20 <- disp_offset - %edi -16 - %edx -12 - %ecx -8 - %ebx -4 - %ebp = %esp 0 - %eip 4 <- arg_offset - arg1 8 - see enter/enter1/leave - */ -int arg_offset = 8; -int disp_offset = -20; -int func_disp_offset = -20; -int code_disp_offset = 0; -int int_size = 4; -int endian = 0; -int MAX_REGISTER=6; /* intel386のレジスタを4つまで使う*/ -int REAL_MAX_REGISTER=8; /* intel386のレジスタが8つということ*/ -int MAX_DATA_REG=4; -int MAX_POINTER=3; -int MAX_REGISTGER_VAR=2; - -static int creg; /* current register */ -static char *crn; /* current register name */ -static int lreg; /* operand register */ -static char *lrn; /* operand register name */ -static int dreg; /* temporary register */ -static char *drn; /* temporary register name */ -static int xreg; /* pointer register */ -static int reg_sp; /* REGister Stack-Pointer */ - - -#define REG_EAX 0 -#define REG_EBX 1 -#define REG_ECX 2 -#define REG_EDX 3 -#define REG_ESI 4 -#define REG_EDI 5 -#define REG_EBP 6 -#define REG_ESP 7 - - -#define DATA_REG 0 -#define POINTER_REG 3 -static char *reg_name[8]; -static char *reg_name_l[4]; - -/* - creg currrent virtual register - lreg operand virtual register - dreg spare virtual register - - rname[creg] currrent real register - rname[lreg] operand real register - rname[dreg] spare real register - - regs[] virtual register usage - - reg_name[rname[creg]] - */ - -#define MAX_MAX 10 -static int rname[MAX_MAX]; -static int regs[MAX_MAX]; /* 使われているレジスタを示すフラグ */ -static int reg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ - -void -code_init(void) -{ - if (REGISTERS6) { - arg_offset = 8; - func_disp_offset = -20; - int_size = 4; - endian = 0; - MAX_REGISTER=6; - MAX_DATA_REG=4; - MAX_POINTER=3; - } else { - arg_offset = 8; - func_disp_offset = -12; - int_size = 4; - endian = 0; - MAX_REGISTER=4; - MAX_DATA_REG=4; - MAX_POINTER=1; - } - MAX_REGISTER_VAR=2; - - reg_name[REG_EAX] = "%eax"; - reg_name[REG_EBX] = "%ebx"; - reg_name[REG_ECX] = "%ecx"; - reg_name[REG_EDX] = "%edx"; - reg_name[REG_ESI] = "%esi"; - reg_name[REG_EDI] = "%edi"; - reg_name[REG_EBP] = "%ebp"; - reg_name[REG_ESP] = "%esp"; - reg_name_l[REG_EAX] = "%al"; - reg_name_l[REG_EBX] = "%bl"; - reg_name_l[REG_ECX] = "%cl"; - reg_name_l[REG_EDX] = "%dl"; - -} - -char * -register_name(int i) -{ - return reg_name[rname[i]]; -} - -int -get_register(void) -{ /* 使われていないレジスタを調べる */ - int i; - for(i=0;i<MAX_REGISTER;i++) { - if (! regs[i]) { /* 使われていないなら */ - regs[i]=1; /* そのレジスタを使うことを宣言し */ - return i; /* その場所を表す番号を返す */ - } - } - return -1; /* 空いている場所がないなら、それを表す -1 を返す */ -} - -void -free_register(int i) { /* いらなくなったレジスタを開放 */ - regs[i]=0; -} - -int -register_full(void) -{ - int i; - for(i=0;i<MAX_REGISTER;i++) { - if (! regs[i]) { - return 0; - } - } - return 1; -} - -void -gexpr_init(void) -{ - int i; - while(reg_sp > 0) { - free_register(reg_stack[--reg_sp]); - } - text_mode(); -} - -void -emit_init(void) -{ - int i; - for(i=0;i<REAL_MAX_REGISTER;i++) regs[i]=0; - for(i=0;i<REAL_MAX_REGISTER;i++) rname[i]=i; - creg = get_register(); - crn = reg_name[rname[creg]]; - dreg = get_register(); - drn = reg_name[rname[dreg]]; - reg_sp = 0; - text_mode(); -} - -void -set_crn(int i) -{ - creg = i; - crn = reg_name[rname[creg]]; -} - -void -set_drn(int i) -{ - dreg = i; - drn = reg_name[rname[dreg]]; -} - -int -virtual(int real) -{ - int real_v,i; - real_v = -1; - for(i=0;i<MAX_REGISTER;i++) { - if (rname[i]==real) { - real_v=i; - break; - } - } - if (real_v == -1) - error(-1); - return real_v; -} - -void -use_register(int virt, int real, int move) -{ - int real_v; - char *move_op; - if (rname[virt]==real) - return; - real_v = virtual(real); - move_op = regs[real_v]?"\txchg %s,%s\n":"\tmovl %s,%s\n"; - if (move || regs[real_v]) { - printf(move_op,reg_name[rname[virt]],reg_name[real]); - } - rname[real_v] = rname[virt]; - rname[virt] = real; - crn = reg_name[rname[creg]]; - drn = reg_name[rname[dreg]]; - lrn = reg_name[rname[lreg]]; -} - -void -use_pointer(int virt, int move) -{ - int i; - if (rname[virt]>=POINTER_REG) - return; - for(i=POINTER_REG;i<MAX_REGISTER;i++) { - if (!regs[virtual(i)]) { - use_register(virt,i,move); - return; - } - } - /* we prefer EBX */ - use_register(virt,REG_EBX,move); -} - -void -use_data_reg(int virt, int move) -{ - int i; - if (rname[virt]<MAX_DATA_REG) - return; - for(i=0;i<MAX_DATA_REG;i++) { - if (!regs[virtual(i)]) { - use_register(virt,i,move); - return; - } - } - /* we prefer EBX */ - use_register(virt,REG_EBX,move); -} - -int -pop_register(void) -{ /* レジスタから値を取り出す */ - int i,j; - - j = creg; - i = reg_stack[--reg_sp]; - - if(i<0) { - return i; - } else { - free_register(i); - lreg = i; - lrn = reg_name[rname[lreg]]; - regs[i]=0; - return lreg; - } -} - -int -stack_used(void) { - return reg_stack[--reg_sp]<0; -} - -void -emit_push(void) -{ - int new_reg; - new_reg = get_register(); - if(new_reg<0) { /* もうレジスタがない */ - reg_stack[reg_sp++] = -1; - printf("\tpushl %s\n",crn); - } else { - reg_stack[reg_sp++] = creg; /* push するかわりにレジスタを使う */ - set_crn(new_reg); - } -} - -char * -emit_pop(int type) -{ - char *xrn; - if (pop_register()==-1) { - if (type==POINTER_REG) - use_pointer(dreg,0); - else if (type==DATA_REG) - use_data_reg(dreg,0); - printf("\tpopl %s\n",drn); - xrn = drn; - xreg = dreg; - } else { - xrn = lrn; - xreg = lreg; - } - return xrn; -} - -int -get_register_var(void) -{ - int i; - for(i=REG_ESI;i<REG_ESP;i++) { - if (! regs[i]) { /* 使われていないなら */ - regs[i]=1; /* そのレジスタを使うことを宣言し */ - return i; /* その場所を表す番号を返す */ - } - } - return -1; -} - -void -gexpr(int e1) -{ - gexpr_init(); - g_expr(e1); - csvalue = rname[creg]; /* for siwtch value */ -} - -void -g_expr(int e1) -{ - int e2,e3,e4; - char *xrn; - NMTBL *n; - - if (chk) return; - e2 = cadr(e1); - switch (car(e1)){ - case GVAR: - /* use_pointer(creg,0); */ - printf("\tmovl $%s,%s\n",caddr(e1),crn); - return; - case RGVAR: - /* use_pointer(creg,0); */ - printf("\tmovl %s,%s\n",caddr(e1),crn); - return; - case CRGVAR: - printf("\tmovsbl %s,%s\n",caddr(e1),crn); - return; - case LVAR: - /* use_pointer(creg,0); */ - printf("\tlea %d(%%ebp),%s\n",lvar(e2),crn); - return; - case REGISTER: - /* this is of course redundant... */ - printf("\tmovl %s,%s\n",register_name(e2),crn); - return; - case RLVAR: - printf("\tmovl %d(%%ebp),%s\n",lvar(e2),crn); - return; - case CRLVAR: - printf("\tmovsbl %d(%%ebp),%s\n",lvar(e2),crn); - return; - case FNAME: - printf("\tmovl $%s,%s\n",((NMTBL *)e2)->nm,crn); - return; - case CONST: /* 代入する値が0でも特別な処理はしない */ - printf("\tmovl $%d,%s\n",e2,crn); - return; - case STRING: - string(e1); - return; - case FUNCTION: - function(e1); - return; - case CODE: - jump(e2,caddr(e1)); - return; - case INDIRECT: - g_expr(e2); - return; - case RINDIRECT: case CRINDIRECT: - rindirect(e1); - return; - case ADDRESS: - g_expr(e2); - return; - case MINUS: /* レジスタに対し、neglを実行すれば実現可能 */ - g_expr(e2); - /* use_data_reg(creg,1); */ - printf("\tnegl %s\n", crn); - return; - case BNOT: /* ~ */ - g_expr(e2); - /* use_data_reg(creg,1); */ - printf("\tnotl %s\n", crn); - return; - case LNOT: /* ! */ - g_expr(e2); - use_data_reg(creg,1); - printf("\tcmpl $0,%s\n", crn); - printf("\tsete %s\n", reg_name_l[rname[creg]]); - printf("\tmovzbl %s,%s\n", reg_name_l[rname[creg]],crn); - return; - case PREINC: - if (car(e2)==REGISTER) { - printf("\taddl $%d,%s\n",caddr(e1),register_name(cadr(e2))); - printf("\tmovl %s,%s\n",register_name(cadr(e2)),crn); - return; - } - g_expr(e2); - printf("\taddl $%d,(%s)\n",caddr(e1),crn); - printf("\tmovl (%s),%s\n",crn,crn); - return; - case POSTINC: - if (car(e2)==REGISTER) { - printf("\tmovl %s,%s\n",register_name(cadr(e2)),crn); - printf("\taddl $%d,%s\n",caddr(e1),register_name(cadr(e2))); - return; - } - g_expr(e2); - emit_push(); -/* in case of register full we should copy crn to drn */ - xrn = emit_pop(0); - printf("\tmovl (%s),%s\n",xrn,crn); - printf("\taddl $%d,(%s)\n",caddr(e1),xrn); - return; - case CPOSTINC: - /* char *p; *p++ */ - if (car(e2)==REGISTER) { - printf("\tmovl %s,%s\n",register_name(cadr(e2)),crn); - printf("\taddl $%d,%s\n",caddr(e1),register_name(cadr(e2))); - return; - } - g_expr(e2); - emit_push(); /* in case of register full we should copy crn to drn */ - xrn = emit_pop(0); - printf("\tmovsbl (%s),%s\n",xrn,crn); - printf("\tincl (%s)\n",xrn); - return; - case CPREINC: - if (car(e2)==REGISTER) { - printf("\taddl $%d,%s\n",caddr(e1),register_name(cadr(e2))); - printf("\tmovl %s,%s\n",register_name(cadr(e2)),crn); - return; - } - g_expr(e2); - printf("\tincl (%s)\n",crn); - printf("\tmovsbl (%s),%s\n",crn,crn); - return; - case CPOSTDEC: - if (car(e2)==REGISTER) { - printf("\tmovl %s,%s\n",register_name(cadr(e2)),crn); - printf("\tdecl %s\n",register_name(cadr(e2))); - return; - } - g_expr(e2); - printf("\tmovsbl (%s),%s\n",crn,crn); - printf("\tdecl (%s)\n",crn); - return; - case CPREDEC: - if (car(e2)==REGISTER) { - printf("\tdecl %s\n",register_name(cadr(e2))); - printf("\tmovl %s,%s\n",register_name(cadr(e2)),crn); - return; - } - g_expr(e2); - emit_push(); - xrn = emit_pop(0); - printf("\tdecl (%s)\n",xrn); - printf("\tmovsbl (%s),%s\n",xrn,crn); - return; - case MUL: case UMUL: - case DIV: case UDIV: - case MOD: case UMOD: - case LSHIFT: case ULSHIFT: case RSHIFT: case URSHIFT: - case ADD: case SUB: case BAND: case EOR: case BOR: - machinop(e1); - return; - case COND: - e2=fwdlabel(); - b_expr(cadr(e1),0,e2); - g_expr(caddr(e1)); - e4 = rname[creg]; - jmp(e3=fwdlabel()); - fwddef(e2); - g_expr(cadddr(e1)); - use_register(creg,e4,1); - fwddef(e3); - return; - case SASS: - sassign(e1); - return; - case ASS: case CASS: - assign(e1); - return; - case ASSOP: case CASSOP: - assop(e1); - return; - case COMMA: - g_expr(e2); - g_expr(caddr(e1)); - return; - case RETURN: - n = (NMTBL *)e2; - if (retcont==0) - retcont=fwdlabel(); - printf("\tleal _%d,%s\n",retcont,crn); - return; - case ENVIRONMENT: - printf("\tmovl %%ebp,%s\n",crn); - return; - default: - b_expr(e1,1,e2=fwdlabel()); /* including > < ... */ - printf("\txorl %s,%s\n",crn,crn); - jmp(e3=fwdlabel()); - fwddef(e2); - printf("\tmovl $1,%s\n",crn); - fwddef(e3); - } -} - -void -bexpr(int e1, char cond, int l1) -{ - gexpr_init(); - b_expr(e1,cond,l1); -} - -void -b_expr(int e1, char cond, int l1) -{ - int e2,l2; - if (chk) return; - e2=cadr(e1); - switch(car(e1)) { - case LNOT: - b_expr(e2,!cond,l1); - return; - case GT: - rexpr(e1,l1,cond?"g":"le"); - return; - case UGT: - rexpr(e1,l1,cond?"a":"be"); - return; - case GE: - rexpr(e1,l1,cond?"ge":"l"); - return; - case UGE: - rexpr(e1,l1,cond?"ae":"b"); - return; - case LT: - rexpr(e1,l1,cond?"l":"ge"); - return; - case ULT: - rexpr(e1,l1,cond?"b":"ae"); - return; - case LE: - rexpr(e1,l1,cond?"le":"g"); - return; - case ULE: - rexpr(e1,l1,cond?"be":"a"); - return; - case EQ: - rexpr(e1,l1,cond?"e":"ne"); - return; - case NEQ: - rexpr(e1,l1,cond?"ne":"e"); - return; - case LAND: - b_expr(e2,0,cond?(l2=fwdlabel()):l1); - b_expr(caddr(e1),cond,l1); - if(cond) fwddef(l2); - return; - case LOR: - b_expr(e2,1,cond?l1:(l2=fwdlabel())); - b_expr(caddr(e1),cond,l1); - if(!cond) fwddef(l2); - return; - case CRGVAR: - printf("\tcmpb $0,%s\n",caddr(e1)); - jcond(l1,cond); - return; - case CRLVAR: - printf("\tcmpb $0,%d(%%ebp)\n",lvar(e2)); - jcond(l1,cond); - return; - case RGVAR: - printf("\tcmpl $0,%s\n",caddr(e1)); - jcond(l1,cond); - return; - case RLVAR: - printf("\tcmpl $0,%d(%%ebp)\n",lvar(e2)); - jcond(l1,cond); - return; - case REGISTER: - printf("\tcmpl $0,%s\n",register_name(e2)); - jcond(l1,cond); - return; - case CONST: - if((cond&&e2)||(!cond&&!e2)) jmp(l1); - return; - default: - g_expr(e1); - printf("\tcmpl $0,%s\n",crn); - jcond(l1,cond); - return; - } -} - -void -ascii(char *s) -{ - printf("\t.string \""); - while(*s) { - if (*s=='\n') - printf("%cn",92); - else if (*s<' ') - printf("%c%03o",92,*s); - else if (*s==34) - printf("%c%c",92,34); - else - printf("%c",*s); - s++; - } - printf("%c\n",34); -} - -void -string(int e1) -{ - char *s; - int i,lb; - - if (0) { - s=(char *)cadr(e1); - lb=fwdlabel(); - printf("\tjmp _%d\n",lb); - i=backdef(); - ascii(s); - printf("\t.align 2\n"); - fwddef(lb); - printf("\tlea _%d,%s\n",i,crn); - } else { - s=(char *)cadr(e1); - printf(".section\t.rodata\n"); - lb=fwdlabel(); - printf("_%d:\n",lb); - ascii(s); - if (output_mode==TEXT_EMIT_MODE) { - printf(".text\n"); - } else { - text_mode(); - } - printf("\tlea _%d,%s\n",lb,crn); - } -} - -void -function(int e1) -{ - int e2,e3,e4,e5,nargs; - NMTBL *n; - - e2 = cadr(e1); - nargs = 0; - for (e3 = caddr(e1); e3; e3 = cadr(e3)) { - n=(NMTBL *)(e5=(cadr(e4 = car(e3)))); - switch(car(e4)) { - case FNAME: - printf("\tlea %s,%s\n",n->nm,crn); - printf("\tpushl %s\n",crn); - break; - case ADDRESS: - g_expr(e5); - printf("\tpushl %s\n",crn); - break; - default:g_expr(e4); - printf("\tpushl %s\n",crn); - } - ++nargs; - } - if (car(e2) == FNAME) { - n=(NMTBL *)cadr(e2); - use_register(creg,REG_EAX,0); - printf("\tcall\t%s\n",n->nm); - } else { - g_expr(e2); - use_register(creg,REG_EAX,0); - printf("\tcall\t*%s\n",crn); - } - if (nargs) printf("\taddl $%d,%%esp\n",4*nargs); -} - -void -jump(int e1, int env) -{ - int i,e2,e3,e4,e5,nargs,regs; - NMTBL *n,*code0; - int new_disp; - char *xrn; - - /* count number of args */ - nargs = 0; - for (e3 = caddr(e1); e3;e3 =cadr(e3)) nargs++; - new_disp = -(nargs-MAX_REGISTER_VAR)*int_size; - if (new_disp > 0) - new_disp=0; -/* printf("# new_disp %d,disp %d\n",new_disp,disp); */ - if (new_disp < disp) { - printf("\tlea %d(%%ebp),%%esp\n",new_disp+disp_offset); - } - /* compute jump address */ - e2 = cadr(e1); - if (car(e2) == FNAME) { - code0=(NMTBL *)cadr(e2); - if (code0->sc!=CODE) { - error(STERR); return; - } - } else { /* indirect */ - g_expr(e2); - emit_push(); - } - /* compute arguments */ - regs = nargs-1; - i=0; - for (e3 = caddr(e1); e3;e3 =cadr(e3),i++) { - n=(NMTBL *)(e5=(cadr(e4 = car(e3)))); - switch(car(e4)) { - case FNAME: - printf("\tlea %s,%s\n",n->nm,crn); - emit_push(); - break; - case ADDRESS: - g_expr(e5); - emit_push(); - break; -/* -printf("# cadr(e4) %d ==disp_offset+(-1-i)*int_size %d\n", cadr(e4), disp_offset+(-2-i)*int_size); - */ - case RLVAR: - case CRLVAR: - if (env==0 && cadr(e4)==disp_offset+(-1-i)*int_size) { - /* Same positioned local variable. No need to copy */ - reg_stack[reg_sp++] = -2; - --regs; - continue; - } - case REGISTER: - if (rname[cadr(e4)]==REG_ESI+regs) { - /* Same register variable. No need to copy */ - reg_stack[reg_sp++] = cadr(e4); - --regs; - continue; - } - default: - g_expr(e4); - emit_push(); - } - --regs; - } - /* save frame pointer before jump in fuction */ - if (fnptr->sc==FUNCTION) { - printf("\tmovl %%ebp,%d(%%ebp)\n",disp_offset); - } - if (env) { - /* change frame pointer */ - g_expr(env); - printf("\tmovl %s,%%ebp\n",crn); - } - /* copy arguments to destination environment if necessary */ - for(i=0;i<nargs;i++) { - if (i>=MAX_REGISTGER_VAR) { - if (reg_stack[reg_sp-1]== -2) { - /* same positioned variable */ - reg_sp--; - } else { - xrn=emit_pop(0); - printf("\tmovl %s,%d(%%ebp)\n",xrn, - disp_offset+(-(nargs-i))*int_size); - } - } else if (reg_stack[--reg_sp]>=REG_ESI) { - /* the same registger */ - ; - } else { - if(reg_stack[reg_sp]<0) { - printf("\tpopl %s\n",reg_name[rname[REG_ESI+i]]); - } else { - printf("\tmovl %s,%s\n", - reg_name[rname[reg_stack[reg_sp]]], - reg_name[rname[REG_ESI+i]]); - free_register(reg_stack[reg_sp]); - } - } - } - if (car(e2) != FNAME) { - xrn=emit_pop(0); - } -/* printf("# new_disp %d,disp %d\n",new_disp,disp); */ - if (new_disp>disp) { - /* shrink stack if necessary */ - printf("\tlea %d(%%ebp),%%esp\n",new_disp+disp_offset); - } - if (fnptr->sc==FUNCTION) { - /* link operation for leave, %ebp must point saved old %ebp */ - printf("\tlea %d(%%ebp),%%ebp\n",disp_offset); - } - if (car(e2) == FNAME) { - printf("\tjmp %s\n",code0->nm); - } else { - printf("\tjmp *%s\n",xrn); - } -} - - -void -machinop(int e1) -{ - int e2,e3,op; - - e2 = cadr(e1); - op = car(e1); - e3 = caddr(e1); - g_expr(e3); - emit_push(); - g_expr(e2); - tosop(car(e1)); - return; -} - - -void -rindirect(int e1) /* *(p +5 ) */ - -{ - char *op; - int e2,e3,byte; - - op = ((byte = (car(e1) == CRINDIRECT)) ? "movsbl" : "movl"); - e3 = cadr(e2 = cadr(e1)); - g_expr(e2); - printf("\t%s (%s),%s\n",op,crn,crn); -} - -void -sassign(int e1) -{ - int e2,e3,e4,sz; - char *xrn; - - e2 = cadr(e1); - e3 = cadr(e2); - e4 = caddr(e1); - sz = size(cadr(e2)); /* cld rep movsb */ - g_expr(e4); - emit_push(); - g_expr(e2); - xrn = emit_pop(0); - return; -} - -void -assign(int e1) -{ - char *op; - int e2,e3,e4,byte; - char *xrn; - - op = ((byte=(car(e1) == CASS))? "movb" : "movl"); - /* e2=e4 */ - e2 = cadr(e1); - e3 = cadr(e2); - e4 = caddr(e1); - switch(car(e2)) { - case GVAR: /* i=3 */ - g_expr(e4); - if (byte) use_data_reg(creg,1); - printf("\t%s %s,%s\n",op,crn,caddr(e2)); - return; - case LVAR: - g_expr(e4); - if (byte) use_data_reg(creg,1); - printf("\t%s %s,%d(%%ebp)\n",op,crn,lvar(cadr(e2))); - return; - case REGISTER: - g_expr(e4); - if (creg!=cadr(e2)) - printf("\t%s %s,%s\n",op,crn,register_name(cadr(e2))); - return; - } - g_expr(e4); - emit_push(); - g_expr(e2); - xrn = emit_pop(0); - if (byte) use_data_reg(creg,1); - printf("\t%s %s,(%s)\n",op,xrn,crn); - printf("\tmovl %s,%s\n",xrn,crn); - return; -} - -void -assop(int e1) -{ - int e2,e3,byte,op,new_reg; - char *xrn; - - /* e2 op= e3 */ - byte = (car(e1) == CASSOP); - e2 = cadr(e1); - if (car(e2)==INDIRECT) e2=cadr(e2); - e3 = caddr(e1); - op = cadddr(e1); - - g_expr(e3); - emit_push(); - if (car(e2)==REGISTER) { - new_reg=creg; - set_crn(cadr(e2)); - tosop(op); - set_crn(new_reg); - printf("\tmovl %s,%s\n",register_name(cadr(e2)),crn); - return; - } - g_expr(e2); - xrn = emit_pop(0); /* pop e3 value */ - printf("\tpushl %s # assop \n",crn); /* push e2 address */ - ld_indexx(byte,0,crn); - new_reg = get_register(); - /* push e3 value */ - if(new_reg<0) { /* もうレジスタがない */ - reg_stack[reg_sp++] = -1; - printf("\tpushl %s\n",xrn); - } else { - reg_stack[reg_sp++] = xreg; /* push するかわりにレジスタを使う */ - } - tosop(op); - if(new_reg>=0) free_register(new_reg); - printf("\tpopl %s # assop \n",drn); - printf("\t%s %s,(%s)\n",byte ? "movb" : "movl",crn,drn); - return; - -} - - -void -tosop(int op) -{ - int oreg; - char *orn; - - oreg = pop_register(); - switch(op) { - case LSHIFT: - case ULSHIFT: - shift("sall",oreg); - return; - case RSHIFT: - shift("sarl",oreg); - return; - case URSHIFT: - shift("shrl",oreg); - return; - } - if(oreg==-1) { - printf("\tpopl %s\n",drn); - oreg = dreg; - } - orn = reg_name[rname[oreg]]; - switch(op) { - case ADD: - printf("\taddl %s,%s\n",orn,crn); - return; - case SUB: - printf("\tsubl %s,%s\n",orn,crn); - return; - case BAND: - printf("\tandl %s,%s\n",orn,crn); - return; - case EOR: - printf("\txorl %s,%s\n",orn,crn); - return; - case BOR: - printf("\torl %s,%s\n",orn,crn); - return; - case MUL: - case UMUL: - /* use_register(dreg,REG_EDX,0); */ - printf("\t%s %s,%s\n","imull",orn,crn); - return; - case DIV: - case UDIV: - orn = div_setup(oreg); - if (op==DIV) - printf("\tcltd\n\tdivl %s\n",orn); - else - printf("\txor %%edx,%%edx\n\tidivl %s\n",orn); - div_cleanup(orn); - return; - case MOD: - case UMOD: - orn = div_setup(oreg); - if (op==DIV) - printf("\tcltd\n\tdivl %s\n",orn); - else - printf("\txor %%edx,%%edx\n\tidivl %s\n",orn); - rname[creg]=REG_EDX; - crn=reg_name[REG_EDX]; - rname[dreg]=REG_EAX; - drn=reg_name[REG_EAX]; - div_cleanup(orn); - return; - } -} - -static char *dvi_push = "(%esp)"; - -char * -div_setup(int oreg) -{ - if (oreg<0) { - use_register(creg,REG_EAX,1); - use_register(dreg,REG_EDX,0); - return 0; - } - if (register_full()) { - printf("\tpushl %s\n",reg_name[rname[oreg]]); - use_register(creg,REG_EAX,1); - use_register(oreg,REG_EDX,0); - return dvi_push; - } - regs[oreg]=1; - use_register(creg,REG_EAX,1); - use_register(dreg,REG_EDX,0); - regs[oreg]=0; - return reg_name[rname[oreg]]; -} - -div_cleanup(char *orn) -{ - if (orn==dvi_push) - printf("\taddl $4,%%esp\n"); -} - -void -shift(char *op, int reg) -{ - if (reg>=0) { - use_register(lreg,REG_ECX,1); - } else { - use_register(dreg,REG_ECX,0); - printf("\tpopl %%ecx\n"); - } - printf("\t%s %%cl,%s\n",op,crn); -} - -void -ld_indexx(int byte, int n, char *xrn) -{ - char *op; - - op = byte ? "movsbl" : "movl"; - if (n) - printf("\t%s %d(%s),%s\n",op,n,xrn,crn); - else - printf("\t%s (%s),%s\n",op,xrn,crn); -} - -void -st_indexx(int byte, int n, char *xrn) -{ - char *op; - - op = byte ? "movb" : "movl"; - if (n) - printf("\t%s %s,%d(%s)\n",op,crn,n,xrn); - else - printf("\t%s %s,(%s)\n",op,crn,xrn); -} - -void -indexy(char *op, char *gvar) -{ - printf("\t%s %s,%s\n",op,crn,gvar); -} - -void -cmpdimm(int e, int csreg) -{ - /* used in dosiwtch() */ - use_register(creg,csreg,0); - printf("\tcmpl $%d,%s\n",e,crn); -} - -void -opening(char *filename) -{ - printf("\t.file \"%s\"\n",filename); - printf("\t.version\t\"01.01\"\n"); - printf("gcc2_compiled.:\n"); - printf(".text\n"); - emit_init(); -} - -void -closing(void) -{ - global_table(); - printf("\t.ident \"Micro-C compiled\"\n"); -} - -void -jmp_label(int l) -{ - printf("\tjmp\t_%d\n",l); -} - -void -jmp_eq_label(int l) -{ - printf("\tje\t_%d\n",l); -} - -void -rexpr(int e1, int l1, char *s) -{ - g_expr(list3(SUB,cadr(e1),caddr(e1))); - printf("\tj%s\t_%d\n",s,l1); -} - -void -jcond(int l, char cond) -{ - printf("\tj%s\t_%d\n",cond?"ne":"e",l); -} - -void -jmp(int l) -{ - control=0; - printf("\tjmp\t_%d\n",l); - /* align? */ -} - -int -fwdlabel(void) -{ - return labelno++; -} - -void -fwddef(int l) -{ - control=1; - printf("_%d:\n",l); -} - -int -backdef(void) -{ - control=1; - printf("_%d:\n",labelno); - return labelno++; -} - -void -def_label(int cslabel, int dlabel) -{ - int fl; - - fl = 0; - if (control) { - jmp(fl=fwdlabel()); - } - fwddef(cslabel); - if (dlabel) - jmp(dlabel); - if (fl) { - fwddef(fl); - } -} - -void -gen_comment(char *s) -{ - printf("# %s",s); -} - -void -gen_source(char *s) -{ - printf("%s",s); -} - -void -code_enter(char *name) -{ - disp_offset = code_disp_offset; - emit_init(); - printf("\t.align 4\n"); - if (stmode!=STATIC) - printf(".globl %s\n",name); - printf("\t.type\t%s,@function\n",name); - printf("%s:\n",name); -} - -void -code_enter1(int disp) -{ - if(disp) { - printf("\tsubl $%d,%%esp\n",-disp); - } -} - -void -code_leave(char *name) -{ - local_table(); - printf("_%d:\n",labelno); - printf("\t.size\t%s,_%d-%s\n",name,labelno,name); - labelno++; -} - -void -enter(char *name) -{ - disp_offset = func_disp_offset; - emit_init(); - printf("\t.align 2\n"); - if (stmode!=STATIC) - printf(".globl %s\n",name); - printf("%s:\n",name); - printf("\t.type\t%s,@function\n",name); - printf("\tpushl %%ebp\n"); - printf("\tmovl %%esp,%%ebp\n"); - printf("\tpushl %%ebx\n"); - printf("\tpushl %%ecx\n"); - printf("\tpushl %%edx\n"); - if (REGISTERS6) { - printf("\tpushl %%edi\n"); - printf("\tpushl %%esi\n"); - } -} - -void -enter1(int disp) -{ - if(disp) printf("\tsubl $%d,%%esp\n",-disp); -} - -void -leave(int control, char *name) -{ - if (control) - use_register(creg,REG_EAX,1); - if (retcont) { - if (control) - jmp(retlabel); - fwddef(retcont); - use_register(creg,REG_EAX,0); - printf("\tmovl %s,%s\n",reg_name[REG_ESI],crn); - /* printf("\tleave\n"); */ - } - fwddef(retlabel); - use_register(creg,REG_EAX,0); - if (REGISTERS6) { - printf("\tpopl %%esi\n"); - printf("\tpopl %%edi\n"); - } - /* if(disp) printf("\taddl $%d,%%esp\n",-disp); */ - printf("\tlea %d(%%ebp),%%esp\n",disp_offset); - printf("\tpopl %%edx\n"); - printf("\tpopl %%ecx\n"); - printf("\tpopl %%ebx\n"); - printf("\tleave\n"); - printf("\tret\n"); - local_table(); - printf("_%d:\n",labelno); - printf("\t.size\t%s,_%d-%s\n",name,labelno,name); - labelno++; -} - - -void -ret(void) -{ - use_register(creg,REG_EAX,1); - jmp(retlabel); -} - -void -gen_gdecl(char *n, int gpc) -{ - /* - if (stmode!=STATIC) - printf(".globl %s\n",n); - */ -} - -void -align(int t) -{ - if (t!=CHAR) { - if (data_alignment & 1) - printf("\t.align 2\n"); - data_alignment = 0; - } -} - -void -emit_data(int e, int t, NMTBL *n) -{ - int l; - char *name; - name = n->nm; - if(mode==GDECL) { /* global */ - if (n->dsp != -1) { - n->dsp = -1; /* initiallized flag */ - printf(".globl\t%s\n",name); - data_mode(name); - align(t); - printf("%s:\n",name); - } else { - data_mode(0); - } - if(car(e)==CONST) { - if (t==CHAR) { - printf("\t.byte %d\n",cadr(e)); - if (data_alignment>0) - data_alignment++; - gpc += 1; - } else { - printf("\t.long %d\n",cadr(e)); - gpc += int_size; - } - } else if(t!=CHAR) { - gpc += int_size; - if(car(e)==ADDRESS&&car(cadr(e))==GVAR) { - printf("\t.long %s\n",caddr(cadr(e))); - } else if(car(e)==FNAME) { - printf("\t.long %s\n",((NMTBL *)cadr(e))->nm); - } else if(car(e)==STRING) { - if (car(n->ty)!=ARRAY || cadr(n->ty)!=CHAR) { - l = fwdlabel(); - printf("\t.long _%d\n",l); - printf(".section\t.rodata\n"); - printf("_%d:\n",l); - output_mode = RODATA_EMIT_MODE; - } - ascii((char *)cadr(e)); - } else error(TYERR); - } - } else { - /* if (n->sc!=LVAR) { error(TYERR); return; } */ - if(car(e)==CONST) { - printf("\tmovl $%d,%s\n",cadr(e),crn); - printf("\t%s %s,%d(%%ebp)\n",t==CHAR?"movsbl":"movl",crn,n->dsp); - } else if(t!=CHAR) { - if(car(e)==ADDRESS&&car(cadr(e))==GVAR) - printf("\tlea %s,%s\n",caddr(e),crn); - else if(car(e)==FNAME) - printf("\tlea %s,%s\n",((NMTBL *)cadr(e))->nm,crn); - else if(car(e)==STRING) { - string(e); - } else error(TYERR); - printf("\tmovl %s,%d(%%ebp)\n",crn,n->dsp); - } - } -} - -void -emit_data_closing(NMTBL *n) -{ - int lb; - if (mode=GDECL) { - data_mode(0); - lb=fwdlabel(); - printf("_%d:\n",lb); - printf("\t.size\t%s,_%d-%s\n",n->nm,lb,n->nm); - } -} - -void -global_table(void) -{ - NMTBL *n; - for(n=ntable;n < &ntable[GSYMS];n++) { - if (n->sc == GVAR && n->dsp != -1) { - /* n->dsp = -1 means initialized global */ - printf(".comm %s,%d\n",n->nm,size(n->ty)); - } - } -} - -void -local_table(void) -{ - NMTBL *n; - /* static local variables */ - for(n=ntable+GSYMS;n < &ntable[GSYMS+LSYMS];n++) { - if (n->sc == GVAR) { - printf(".lcomm %s,%d\n",n->nm,size(n->ty)); - } - } -} - -void -text_mode(void) -{ - if (output_mode!=TEXT_EMIT_MODE) { - printf(".text\n"); - printf("\t.align 2\n"); - output_mode = TEXT_EMIT_MODE; - } -} - -void -data_mode(char *name) -{ - if (output_mode!=DATA_EMIT_MODE) { - printf(".data\n"); - output_mode = DATA_EMIT_MODE; - } - if (name) - printf("\t.type\t%s,@object\n",name); -} - -int -lvar(int l) -{ - if (l<0) { - if (fnptr->sc==CODE) - return l+code_disp_offset; - else - return l+disp_offset; - } else { - return l+arg_offset; - } -} - -/* end */
--- a/ansi/mc-parse.c Fri Jan 14 12:10:42 2000 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2662 +0,0 @@ -#define EXTERN /**/ -#include "mc.h" - -void ntable_consistency(); -static void adecl(); -static void decl_data(); -static int alpha(); -static int binop(); -int caddr(); -int cadr(); -int car(); -static void compatible(); -static void decl(); -static void def(); -static int digit(); -static void docase(); -static void docomp(); -static void dodefault(); -static void dodo(); -static void dofor(); -static void dogoto(); -static void doif(); -static void dolabel(); -static void doswitch(); -static void doreturn(); -static void dowhile(); -static void errmsg(); -static void copy(); -void error(); -static int expr(); -static int expr0(); -static int expr1(); -static int expr2(); -static int expr3(); -static int expr4(); -static int expr5(); -static int expr6(); -static int expr7(); -static int expr8(); -static int expr9(); -static int expr10(); -static int expr11(); -static int expr12(); -static int expr13(); -static int expr14(); -static int expr15(); -static int expr16(); -static void fcheck(); -static void fdecl(); -static int getch(); -static int getfree(); -static void getline(); -static void getstring(); -static int getsym(); -static int indop(); -static void init(); -static int integral(); -static void lcheck(); -int list2(); -int list3(); -int list4(); -static void reserve(); -static int macroeq(); -static int ndecl0(); -static int ndecl1(); -static int neqname(); -static void newfile(); -static int postequ(); -static void reverse(); -static int reverse0(); -static int rplacad(); -static int rvalue(); -static int scalar(); -static int sdecl(); -static int skipspc(); -static void statement(); -static int strop(); -static int typeid(); -static int typename(); -static int typespec(); -static int cexpr(); -static void code_decl(); - -extern void exit(); -extern void closing(); -extern void opening(); -extern void gen_gdecl(); -extern void enter(); -extern void enter1(); -extern void leave(); -extern void ret(); -extern void jmp(); -extern void gexpr(); -extern int get_register_var(); -extern void bexpr(); -extern int fwdlabel(); -extern void fwddef(); -extern int backdef(); -extern int def_label(); -extern void jmp_label(); -extern void cmpdimm(); -extern void jcond(); -extern void jmp_eq_label(); -extern void gen_comment(); -extern void gen_source(); -extern void code_init(); -extern void emit_data_closing(); -extern void emit_data(); - -int -main(argc, argv) - int argc; - char **argv; -{ - NMTBL *nptr; - int i; - char *ccout; - - if(argc==1) exit(1); - lsrc = chk = asmf = 0; - ccout = OUTPUT_FILE_NAME; - ac=argc; - av=argv; - for (ac2=1; (ac2 < ac) && (*av[ac2] == '-'); ++ac2) { - switch (*(av[ac2]+1)) { - case 'S': case 's': - lsrc = 1; - break; - case 'O': case 'o': - ccout = av[ac2]+2; - break; - case 'C': case 'c': - chk = 1; - break; - case 'D': case 'd': - debug = 1; - break; - default: - error(OPTION); - exit(1); - } - } - fclose(stdout); - if (!chk) - if ( (obuf = fopen(ccout,"w")) == NULL ) error(FILERR); - init(); - while(1) { - for (nptr = &ntable[GSYMS],i=LSYMS; i--;) - (nptr++)->sc = 0; - mode=TOP; - lfree= HEAPSIZE; - while(getsym()==SM); - mode=GDECL; - stmode=0; - args=0; - decl(); - } - /*NOTREACHED*/ -} - -void -error(n) - int n; -{ - if(n == EOFERR) { - if(filep!=filestack) { - fclose(filep->fcb); - lineno=filep->ln; - --filep; - return; - } else if(ac2!=ac) { - fclose(filep->fcb); - newfile(); - return; - } else if(mode == TOP) { - /* - if (!chk) fprintf(stderr, - "Total internal labels : %u.\n",labelno-1); - fprintf(stderr, - "Total global variables : %u bytes.\n\n",gpc); - */ - closing(); - exit(0); - } - } - fprintf(stderr,"%5d:%s.\n",lineno, - (n==FILERR) ? "Can't open specified file" : - (n==DCERR) ? "Declaration syntax" : - (n==STERR) ? "Statement syntax" : - (n==EXERR) ? "Expression syntax" : - (n==CNERR) ? "Constant required" : - (n==CHERR) ? "Illegal character" : - (n==GSERR) ? "Too many global symbols" : - (n==LSERR) ? "Too many local symbols" : - (n==STRERR) ? "Too many strings or macros" : - (n==LNERR) ? "Line too long" : - (n==EOFERR) ? "Unexpected end of file" : - (n==MCERR) ? "Macro syntax" : - (n==INCERR) ? "Include syntax" : - (n==HPERR) ? "Too long expression" : - (n==TYERR) ? "Type mismatch" : - (n==LVERR) ? "Lvalue required" : - (n==UDERR) ? "Undeclared identifier" : - (n==OPTION) ? "Illegal option" : - (n==REG_ERR) ? "illegal register var" : - (n==CODE_ERR) ? "goto code is necessary" : - "Bug of compiler"); - errmsg(); - exit(1); -} - -void -errmsg() -{ - char *p,*lim; - - if(lineno==0) return; - fprintf(stderr,"%s",linebuf); - lim=(mflag?chptrsave:chptr); - for (p=linebuf; p < lim;) - fprintf(stderr,(*p++ == '\t') ? "\t" : " "); - fprintf (stderr,"^\n"); -} - -void -checksym(s) - int s; -{ - char *p; - - if (sym != s) { - p=(s==RPAR) ? "')'": (s==RBRA) ? "']'": (s==SM) ? "';'": - (s==LPAR) ? "'('": (s==WHILE) ? "'while'": - (s==COLON) ? "':'": "Identifier"; - fprintf(stderr,"%d:%s expected.\n",lineno,p); - errmsg(); - } else - getsym(); -} - -void -init() -{ - NMTBL *nptr; - int i; - - cheapp=cheap; - for(nptr = ntable,i = GSYMS; i--;) (nptr++)->sc = 0; - reserve("int",INT); - reserve("void",VOID); - reserve("char",CHAR); - reserve("struct",STRUCT); - reserve("union",UNION); - reserve("unsigned",UNSIGNED); - reserve("static",STATIC); - reserve("goto",GOTO); - reserve("return",RETURN); - reserve("break",BREAK); - reserve("continue",CONTINUE); - reserve("if",IF); - reserve("else",ELSE); - reserve("for",FOR); - reserve("do",DO); - reserve("while",WHILE); - reserve("switch",SWITCH); - reserve("case",CASE); - reserve("default",DEFAULT); - reserve("typedef",TYPEDEF); - reserve("sizeof",SIZEOF); - reserve("long",LONG); - reserve("short",SHORT); - reserve("extern",EXTRN); - reserve("register",REGISTER); - reserve("code",CODE); - reserve("environment",ENVIRONMENT); - gpc=glineno=mflag=0; - gfree=ilabel=1; - labelno=2; - lfree=HEAPSIZE; - filep=filestack; - code_init(); - newfile(); - getline(); - getch(); -} - -void -newfile() -{ - lineno=0; - /* fprintf(stderr,"%s:\n",av[ac2]); */ - opening(av[ac2]); - if ( (filep->fcb = fopen(av[ac2++],"r")) == NULL ) error(FILERR); -} - -void -reserve(s, d) - char *s; - int d; -{ - NMTBL *nptr; - int i; - - hash=0; name=namebuf; i=0; - while((name[i++] = *s)) { - hash=((7*hash) ^ *s++); - } - if (cheapp+i >= cheap+CHEAPSIZE) error(STRERR); - name[i++] = 0; - (nptr = gsearch())->sc = RESERVE; - nptr->dsp = d; -} - -static -NMTBL null_nptr; - -void -decl() -{ - NMTBL *n; - int t; - - if(sym==STATIC) { - if(mode==LDECL) { - getsym(); - mode=STADECL; - stmode=LDECL; - } else if(mode==GDECL) { - getsym(); - stmode=STATIC; - } else - error(DCERR); - } else if(sym==REGISTER) { - if(mode!=LDECL) - error(DCERR); - stmode=REGISTER; - getsym(); - } else if(sym==EXTRN) { - getsym(); - stmode=EXTRN; - } else if(sym==TYPEDEF) { - if(mode==GDECL) { - getsym(); - mode=GTDECL; - } else if(mode==LDECL) { - getsym(); - mode=LTDECL; - } else - error(DCERR); - } - if((t=typespec())==0) return; - if(sym==SM) return; - type=t; - n=decl0(); - reverse(t); - if (n == &null_nptr) { - error(DCERR); - return; - } - if(sym==LC || ( sym!=SM && sym!=COMMA && sym!=ASS )) { - if (car(type)==CODE) { - code_decl(n); return; - } else if (car(type)==FUNCTION) { - fdecl(n); return; - } - } - def(n); - while(sym==COMMA) { - getsym(); - type=t; - n=decl0(); - reverse(t); - if(n == &null_nptr) error(DCERR); - /* if(args) error(DCERR); */ - def(n); - } - if(sym!=SM) error(DCERR); - if(mode==GTDECL) - mode=GDECL; - if(mode==STADECL||mode==LTDECL) - mode=LDECL; -} - -int -typespec() -{ - int t; - - switch(sym) { - case VOID: - case INT: - case CHAR: - case CODE: - t= sym; - getsym(); - break; - case STRUCT: - case UNION: - t=sdecl(sym); - break; - case UNSIGNED: - t = UNSIGNED; - if(getsym()==INT) getsym(); - break; - case SHORT: - t=CHAR; - if(getsym()==INT) getsym(); - break; - case LONG: - t=INT; - if(getsym()==INT) getsym(); - break; - default: - if(sym==IDENT) { - if(nptr->sc==TYPE) { - t=nptr->ty; - getsym(); - break; - } else if(nptr->sc==EMPTY && gnptr->sc==TYPE) { - t=gnptr->ty; - getsym(); - break; - } - } - if(mode==LDECL) return 0; - t= INT; - } - return t; -} - -struct nametable * -decl0() -{ - NMTBL *n; - if(sym==MUL) { - getsym(); - n=decl0(); - type=list2(POINTER,type); - return n; - } - return decl1(); -} - - -NMTBL * -decl1() -{ - NMTBL *n; - int i,t; - - if(sym==LPAR) { - getsym(); - n=decl0(); - checksym(RPAR); - } else if (sym == IDENT) { - n=nptr; - getsym(); - } else { - /* error(DCERR); */ - n= &null_nptr; - } - while(1) { - if(sym==LBRA) { - if(getsym()==RBRA) { - getsym(); - if(mode==ADECL) { - t=type; - type=list2(POINTER,type); - } else if (mode==GDECL) { - t=type; - type=list3(ARRAY,t,0); - } else { - error(DCERR); - } - } else { - t=type; - i=cexpr(expr()); - checksym(RBRA); - type=list3(ARRAY,t,i); - } - } else if(sym==LPAR) { - if(mode==GDECL) { - mode=ADECL;getsym();mode=GDECL; /* ??? */ - } else - getsym(); - if(sym==RPAR) - getsym(); - else { - if (type==CODE) { - n->sc=CODE; - n->dsp=0; - stmode=REGISTER; - adecl(n); - stmode=0; - n->sc=EMPTY; - type=list3(CODE,type,cadr(n->ty)); - return n; - } else { - n->sc=FUNCTION; - n->dsp=0; - adecl(n); - n->sc=EMPTY; - } - } - type=list3(FUNCTION,type,cadr(n->ty)); - } else - return n; - } -} - - -void -adecl(n) - NMTBL *n; -{ - NMTBL *arg,*sfnptr; - int sreg_var,t; - int stype; - - stype=type; - sfnptr=fnptr; - fnptr=n; - sreg_var=reg_var; - reg_var=0; - n->dsp=0; - if(mode!=GDECL && mode!=ADECL) error(DCERR); - mode=ADECL; - args= 0; - for(;;) { - if(sym==IDENT && nptr->sc!=TYPE) { - heap[n->ty+2] = list2(INT,caddr(n->ty)); - if (stmode==REGISTER && reg_var < MAX_REGISTER_VAR) { - nptr->ty = INT; - nptr->sc = REGISTER; - if ((nptr->dsp = get_register_var())<0) - error(-1); - reg_var++; - } else { - nptr->ty = INT; - nptr->sc = LVAR; - nptr->dsp = args ; - args += int_size; - } - getsym(); - if(sym==RPAR) break; - } else { - if(sym==DOTS) { - heap[n->ty+2] = list2(INT,caddr(n->ty)); - getsym(); - break; - } - if((t=typespec())==0) { - error(DCERR); - break; - } - if(sym!=COMMA && sym!=RPAR) { - if(sym==RPAR) break; - type=t; - arg=decl0(); - reverse(t); - if (arg != &null_nptr) { /* no varname typespec only */ - def(arg); - } - } - heap[n->ty+2] = list2(INT,caddr(n->ty)); - if(sym==RPAR) break; - } - if (sym!=COMMA) error(DCERR); - getsym(); - } - checksym(RPAR); - mode=GDECL; - reg_var=sreg_var; - fnptr=sfnptr; - type=stype; - return; -} - -void -reverse(t1) - int t1; -{ - int t2,t3; - t2=t1; - - while(type!=t1) { - t3=cadr(type); - rplacad(type,t2); - t2=type; - type=t3; - } - type = t2; -} - -int -reverse0(t1) - int t1; -{ - int t2,t3; - - t2=0; - while(t1) { - t3=cadr(t1); - rplacad(t1,t2); - t2=t1; - t1=t3; - } - return t2; -} - -int -size(t) - int t; -{ - if(t==CHAR) return 1; - if(t==VOID) return 0; - if(scalar(t)) return int_size; - if(car(t)==STRUCT||car(t)==UNION) { - if(cadr(t)==-1) error(DCERR); - return(cadr(t)); - } - if(car(t)==ARRAY) - return(size(cadr(t))*caddr(t)); - else - error(DCERR); - return 0; -} - -void -def(n) - NMTBL *n; -{ - int sz,nsc,ndsp,slfree,t,e; - char *p; - - if(car(type)==FUNCTION) { - fcheck(n); - return; - } - if (n->sc!=EMPTY && - !(n->sc==GVAR&&n->dsp==EXTRN) && - !(n->sc==FUNCTION&&n->dsp==EXTRN) && - (mode!=ADECL || n->sc!=LVAR || n->ty!=INT) && - (mode!=ADECL || n->sc!=REGISTER || n->ty!=INT) && - ((mode!=GSDECL&&mode!=LSDECL) || n->sc!=FIELD || n->dsp!=disp) && - ((mode!=GUDECL&&mode!=LUDECL) || n->sc!=FIELD || n->dsp!=0) ) - error(DCERR); - sz = size(n->ty = type); - switch(mode) { - case GDECL: - gen_gdecl(n->nm,gpc); - case STADECL: - nsc = GVAR; - ndsp = gpc; - if (stmode==EXTRN) - n->dsp = EXTRN; - else - n->dsp = ndsp; /* emit_data will override this */ - n->sc = nsc; - if (stmode==LDECL) { - copy(n,n->nm); - cheapp[-1] = '.'; - ndsp = ++stat_no; - while(ndsp>0) { - *cheapp++ = ndsp%10+'0'; - ndsp /= 10; - } - *cheapp++ = 0; - } - if(sym==ASS) { - decl_data(type,n); - emit_data_closing(n); - /* gpc is incremented by emit_data */ - } else - gpc +=sz; - return; - case GSDECL: - nsc = FIELD; - ndsp = disp; - disp += sz; - break; - case GUDECL: - nsc = FIELD; - ndsp = 0; - if (disp < sz) disp = sz; - break; - case GTDECL: - nsc = TYPE; - break; - case ADECL: - if (stmode==REGISTER && reg_var <MAX_REGISTER_VAR) { - if (type!=CHAR && !scalar(type)) - error(TYERR); - nsc = REGISTER; - reg_var++; - ndsp = get_register_var(); - break; - } - nptr->sc = LVAR; - if(type==CHAR) { - /* nptr->ty=INT; */ - if (nptr->dsp==0) { - nptr->dsp = args; - if (endian) - n->dsp += int_size-1; - } - args += int_size; - } else { - if (nptr->dsp==0) - nptr->dsp = args; - args += sz; - } - if(type==VOID) { - } else if (!scalar(type)) { - if((t=car(type))==STRUCT || t==UNION) { - nptr->ty = type; - } else - error(TYERR); - } - return; - case LDECL: - if (stmode==REGISTER && reg_var <=MAX_REGISTER_VAR) { - if(!scalar(type)) /* non integer register type ... */ - error(DCERR); - nsc = REGISTER; - reg_var++; - ndsp = get_register_var(); - } else { - nsc = LVAR; - ndsp = (disp -= sz); - } - if(sym==ASS) { - decl_data(type,n); - } - break; - case LSDECL: - nsc = FIELD; - ndsp = disp; - disp += sz; - break; - case LUDECL: - nsc = FIELD; - ndsp = 0; - if (disp < sz) disp = sz; - break; - case LTDECL: - nsc = TYPE; - break; - default: - error(DCERR); - } - n->sc = nsc; - if (stmode==EXTRN) - n->dsp = EXTRN; - else - n->dsp = ndsp; -} - -void -emit_init_vars() -{ - while(init_vars) { - g_expr(car(init_vars)); - init_vars = cadr(init_vars); - } -} - -void -assign_data(e, t, n) - int e; - int t; - int n; -{ - int ass; - - if(mode==GDECL) { - emit_data(e,t,(NMTBL *)n); - } else if(mode==LDECL) { - if (t==STRUCT || t==UNION) { - ass = list3(SASS,list2(LVAR,nptr->dsp),e); - } else { - if(t==CHAR) { - ass =list3(CASS,list2(LVAR,nptr->dsp),e); - } else { - ass = list3(ASS,list2(LVAR,nptr->dsp),e); - } - } - init_vars = list2(ass,init_vars); - } else { - error(DCERR); - } -} - -void -decl_data(t, n) - int t; - NMTBL *n; - /* type */ - -{ - int t1,slfree,e,i; - - getsym(); - if (scalar(t)) { - slfree=lfree; - e=expr1(); - if(car(e)!=CONST && t==CHAR) - error(TYERR); - emit_data(e,t,n); - lfree=slfree; - type=t; - return; - } - t1 = car(t); - if (t1==ARRAY) { - if (sym==LC) { - t1 = cadr(t); - for(i=0;;i++) { - if (sym!=RC) - decl_data(t1,n); - if (sym==COMMA) { continue; - } else if (sym==RC) { - if (caddr(t)==0) { - heap[t+2]=i; - } else if (caddr(t)!=i+1) { - error(TYERR); - } - getsym(); - return; - } else { - error(TYERR); - } - } - } else if (cadr(t)==CHAR) { - slfree=lfree; - e=expr1(); - if(car(e)!=STRING) - error(TYERR); - emit_data(e,STRING,n); - heap[t+2]= size(type); - lfree=slfree; - } else - error(DCERR); - } else if (t1==STRUCT) { - if(cadr(t)==-1) error(DCERR); - t1 = caddr(t); /* list of fields */ - while(t1) { - decl_data(car(t1),n); /* alignment? */ - t1 = cadr(t1); - if ( t1 && sym==COMMA) continue; - if (!t1 && sym!=RC) error(DCERR); - } - getsym(); - return; - } else { - error(TYERR); /* should be initialization error */ - } -} - -int -sdecl(s) - int s; -{ - int smode,sdisp,type0,type1; - NMTBL *nptr0,*gnptr0; - int tags; - - smode=mode; - if (mode==GDECL || mode==GSDECL || mode==GUDECL || mode==GTDECL) - mode=(s==STRUCT?GSDECL:GUDECL); - else - mode=(s==STRUCT?LSDECL:LUDECL); - sdisp=disp; - disp=0; - if (getsym() == IDENT) { - nptr0 = nptr; - gnptr0 = gnptr; - if (getsym() == LC) { - if (nptr0->sc != EMPTY) error(DCERR); - nptr0->sc = TAG; - tags = 0; - nptr0->ty = list3(s,-1,tags); - while (getsym() != RC) { - decl(); - tags = list2(type,tags); - } - getsym(); - tags=reverse0(tags); - heap[nptr0->ty+2]=tags; - rplacad(type0 = nptr0->ty,disp); - } else { - if(nptr0->sc == EMPTY) nptr0=gnptr0; - if(nptr0->sc == EMPTY) error(UDERR); - if(nptr0->sc != TAG) error(TYERR); - type0 = nptr0->ty; - } - } else if(sym==LC) { - tags = 0; - while(getsym() != RC) { - decl(); - tags = list2(type,tags); - } - getsym(); - tags=reverse0(tags); - type0 = list3(s,disp,tags); - } - else error(DCERR); - disp=sdisp; - mode=smode; - return type0; -} - -void -code_decl(n) - NMTBL *n; -{ - if (n->sc==EMPTY) n->sc = CODE; - code_enter(n->nm); - fnptr=n; - args= 0; - reg_var=0; - mode=ADECL; - stmode=REGISTER; - while (sym!=LC) { /* argument declaration !ANSI */ - decl(); getsym(); - } - disp=0; - init_vars=0; - /* local variable declaration */ - stmode=0; - mode=STAT; - init_vars=0; - while (typeid(getsym()) || sym==STATIC || sym==EXTRN || sym==TYPEDEF) { - mode=LDECL; - decl(); - mode=STAT; - } - control=1; - code_enter1(disp); - emit_init_vars(); - while(sym!=RC) statement(); - if(control) - error(STERR); - control=0; - code_leave(n->nm); -} - -void -fdecl(n) - NMTBL *n; -{ - enter(n->nm); - fnptr=n; - retlabel=fwdlabel(); - retcont = 0; - - args=0; - reg_var=0; - fcheck(n); - mode=ADECL; - while (sym!=LC) { /* argument declaration !ANSI */ - stmode=0; - decl(); getsym(); - } - disp=0; - init_vars=0; - /* local variable declaration */ - mode=STAT; - while (typeid(getsym()) || sym==STATIC || sym==EXTRN - || sym==REGISTER || sym==TYPEDEF) { - mode=LDECL; - stmode=0; - decl(); - mode=STAT; - } - control=1; - enter1(disp); - emit_init_vars(); - while(sym!=RC) statement(); - - leave(control,n->nm); - retpending = 0; - control=0; -} - -void -fcheck(n) - NMTBL *n; -{ - if(mode!=GDECL||car(type)!=FUNCTION) error(DCERR); - if(n->sc==FUNCTION) compatible(car(n->ty),cadr(type)); - else { - if(n->sc!=EMPTY) - error(DCERR); - else { - n->sc=FUNCTION; - n->ty=list2(cadr(type),0); - } - } -} - -void -compatible(t1, t2) - int t1; - int t2; -{ - if(integral(t1)) { - if(t1!=t2) error(TYERR); - } - else if(car(t1)!=car(t2)) - error(TYERR); - else if((car(t1)==STRUCT || car(t1)==UNION) && cadr(t1)!=cadr(t2)) - error(TYERR); - else if(car(t1)==POINTER || car(t1)==ARRAY ||car(t1)==FUNCTION) - compatible(cadr(t1),cadr(t2)); -} - -int -scalar(t) - int t; -{ - return(integral(t)||car(t)==POINTER); -} - -int -integral(t) - int t; -{ - return(t==INT||t==CHAR||t==UNSIGNED); -} - -void -checkret() -{ - if (retpending) { - ret(); - control=0; - retpending=0; - } -} - -void -statement() -{ - int slfree; - - if(sym==SM) { - getsym(); return; - } - checkret(); - switch(sym) { - case IF: - doif(); - return; - case WHILE: - dowhile(); - return; - case DO: - dodo(); - return; - case FOR: - dofor(); - return; - case SWITCH: - doswitch(); - return; - case LC: - docomp(); - return; - case BREAK: - jmp(blabel); - getsym(); - checksym(SM); - return; - case CONTINUE: - jmp(clabel); - getsym(); - checksym(SM); - return; - case CASE: - docase(); - statement(); - return; - case DEFAULT: - dodefault(); - statement(); - return; - case RETURN: - doreturn(); - return; - case GOTO: - dogoto(); - return; - default: - if(sym==IDENT&&skipspc()==':') { - dolabel(); - statement(); - } else { - slfree=lfree; - gexpr(expr()); - lfree=slfree; - checksym(SM); - } - } -} - -void -doif() -{ - int l1,l2,slfree; - getsym(); - checksym(LPAR); - slfree=lfree; - bexpr(expr(),0,l1=fwdlabel()); - lfree=slfree; - checksym(RPAR); - statement(); - checkret(); - if(sym==ELSE) { - if ((l2 = control)) - jmp(l2=fwdlabel()); - fwddef(l1); - getsym(); - statement(); - checkret(); - if (l2) fwddef(l2); - } - else fwddef(l1); -} - -void -dowhile() -{ - int sbreak,scontinue,slfree,e; - - sbreak=blabel; - scontinue=clabel; - blabel=fwdlabel(); - clabel=backdef(); - getsym(); - checksym(LPAR); - slfree=lfree; - e=expr(); - checksym(RPAR); - if(sym==SM) { - bexpr(e,1,clabel); - lfree=slfree; - getsym(); - } else { - bexpr(e,0,blabel); - lfree=slfree; - statement(); - checkret(); - if(control) - jmp(clabel); - } - fwddef(blabel); - clabel=scontinue; - blabel=sbreak; -} - -void -dodo() -{ - int sbreak,scontinue,l,slfree; - - sbreak=blabel; - scontinue=clabel; - blabel=fwdlabel(); - clabel=fwdlabel(); - l=backdef(); - getsym(); - statement(); - checkret(); - fwddef(clabel); - checksym(WHILE); - checksym(LPAR); - slfree=lfree; - bexpr(expr(),1,l); - lfree=slfree; - checksym(RPAR); - checksym(SM); - fwddef(blabel); - clabel=scontinue; - blabel=sbreak; -} - -void -dofor() -{ - int sbreak,scontinue,l,e,slfree; - - sbreak=blabel; - scontinue=clabel; - blabel=fwdlabel(); - getsym(); - checksym(LPAR); - slfree=lfree; - if(sym!=SM) { - gexpr(expr()); - checksym(SM); - } - else getsym(); - lfree=slfree; - l=backdef(); - if(sym!=SM) { - bexpr(expr(),0,blabel); - checksym(SM); - } - else getsym(); - lfree=slfree; - if(sym==RPAR) { - clabel=l; - getsym(); - statement(); - checkret(); - } else { - clabel=fwdlabel(); - e=expr(); - checksym(RPAR); - statement(); - checkret(); - fwddef(clabel); - gexpr(e); - lfree=slfree; - } - jmp(l); - fwddef(blabel); - clabel=scontinue; - blabel=sbreak; -} - -void -doswitch() -{ - int sbreak,scase,sdefault,slfree,svalue; - - sbreak=blabel; /* save parents break label */ - blabel=fwdlabel(); - sdefault=dlabel; /* save parents default label */ - dlabel=0; - scase=cslabel; /* save parents next case label */ - getsym(); - checksym(LPAR); - slfree=lfree; - svalue=csvalue1; /* save parents switch value */ - gexpr(expr()); - csvalue1=csvalue ; - lfree=slfree; - checksym(RPAR); - cslabel = control = 0; - /* should be case statement but... */ - statement(); - checkret(); - if(dlabel) def_label(cslabel,dlabel); - else fwddef(cslabel); - csvalue1=svalue; - cslabel=scase; - dlabel=sdefault; - fwddef(blabel); - blabel=sbreak; -} - -void -docomp() -{ - getsym(); - while(sym!=RC) { statement(); checkret();} - getsym(); -} - -void -docase() -{ - int c,l,slfree; - - c=0; - slfree=lfree; - while(sym==CASE) { - getsym(); - c=list2(cexpr(expr()),c); - checksym(COLON); - } - l=fwdlabel(); - if (control) { - control=0; - jmp(l); - } - if (cslabel) fwddef(cslabel); - while(cadr(c)) { - cmpdimm(car(c),csvalue1); - jcond(l,0); - c=cadr(c); - } - lfree=slfree; - cmpdimm(car(c),csvalue1); - jcond(cslabel=fwdlabel(),1); - fwddef(l); -} - -void -dodefault() -{ - getsym(); - checksym(COLON); - if (dlabel) error(STERR); - if (!cslabel) jmp(cslabel = fwdlabel()); - dlabel = backdef(); -} - -void -doreturn() -{ - int slfree; - - if(getsym()==SM) { - getsym(); - retpending = 1; - return; - } - slfree=lfree; - gexpr(expr()); - lfree=slfree; - checksym(SM); - retpending = 1; -} - - -void -dogoto() -{ - NMTBL *nptr0; - int t,e1,e2,env; - - getsym(); - e1 = expr(); - t=car(e1); - if (t==FNAME) { - nptr0 = (NMTBL *)cadr(e1); - t = nptr0->sc; - if (t==EMPTY) { - nptr0->sc = FLABEL; - jmp(nptr0->dsp = fwdlabel()); - } else if (t==FLABEL||t==BLABEL) { - jmp(nptr0->dsp); - } - control=0; - checksym(SM); - return; - } - if (t==COMMA) { - env = caddr(e1); - e1 = cadr(e1); - t = car(e1); - } else { - env = 0; - } - if (t==FUNCTION) { - e2 = cadr(e1); - if (car(e2) == FNAME) { - nptr0=(NMTBL *)cadr(e2); - nptr0->sc = CODE; - } - gexpr(list3(CODE,e1,env)); - control=0; - checksym(SM); - return; - } - error(STERR); - return; -} - -void -dolabel() -{ - if(nptr->sc == FLABEL) - fwddef(nptr->dsp); - else if(nptr->sc != EMPTY) - error(TYERR); - nptr->sc = BLABEL; - nptr->dsp = backdef(); - getsym(); - checksym(COLON); -} - -int -expr() -{ - return(rvalue(expr0())); -} - -int -expr0() -{ - int e; - - e=expr1(); - while(sym==COMMA) { - getsym();e=list3(COMMA,e,rvalue(expr1())); - } - return e; -} - -int -expr1() -{ - int e1,e2,t,op; - e1=expr2(); - switch (sym) { - case ASS: - lcheck(e1); - t=type; - getsym(); - e2=rvalue(expr1()); - if(t==VOID) - error(TYERR); - if(t==CHAR) { - type= INT;return(list3(CASS,e1,e2)); - } else if(t==STRUCT||t==UNION) { - type= t;return(list3(SASS,e1,e2)); - } - type=t; - return(list3(ASS,e1,e2)); - case ADD+AS: case SUB+AS: case MUL+AS: case DIV+AS: case MOD+AS: - case RSHIFT+AS: case LSHIFT+AS: case BAND+AS: case EOR+AS: case BOR+AS: - op = sym-AS; - lcheck(e1); - t=type; - getsym(); - e2=rvalue(expr1()); - if(!integral(type)) error(TYERR); - if((t==UNSIGNED||type==UNSIGNED)&& - (op==MUL||op==DIV||op==MOD||op==RSHIFT||op==LSHIFT)) - op=op+US; - if(t==CHAR) { - type= INT; - return(list4(CASSOP,e1,e2,op)); - } - type=t; - if(integral(t)) return(list4(ASSOP,e1,e2,op)); - if((op!=ADD&&op!=SUB)||car(t)!=POINTER) error(TYERR); - e2=binop(MUL,e2,list2(CONST,size(cadr(t))),INT,UNSIGNED); - type=t; - return list4(ASSOP,e1,e2,op); - default: - return(e1); - } -} - -int -expr2() -{ - int e1,e2,e3,t; - - e1=expr3(); - if(sym==COND) { - e1=rvalue(e1); - getsym(); - e2=rvalue(expr2()); - t=type; - checksym(COLON); - e3=rvalue(expr2()); - if(car(e1)==CONST) { - if(cadr(e1)) { - type=t;return e2; - } else - return e3; - } - if(type==INT||(t!=INT&&type==UNSIGNED)) - type=t; - return(list4(COND,e1,e2,e3)); - } - return(e1); -} - -int -expr3() -{ - int e; - - e=expr4(); - while(sym==LOR) { - e=rvalue(e); - getsym(); - e=list3(LOR,e,rvalue(expr4())); - type= INT; - } - return(e); -} - -int -expr4() -{ - int e; - - e=expr5(); - while(sym==LAND) { - e=rvalue(e); - getsym(); - e=list3(LAND,e,rvalue(expr5())); - type= INT; - } - return(e); -} - -int -expr5() -{ - int e1,e2,t; - - e1=expr6(); - while(sym==BOR) { - e1=rvalue(e1); - t=type; - getsym(); - e2=rvalue(expr6()); - e1=binop(BOR,e1,e2,t,type); - } - return(e1); -} - -int -expr6() -{ - int e1,e2,t; - - e1=expr7(); - while(sym==EOR) { - e1=rvalue(e1); - t=type; - getsym(); - e2=rvalue(expr7()); - e1=binop(EOR,e1,e2,t,type); - } - return(e1); -} - -int -expr7() -{ - int e1,e2,t; - - e1=expr8(); - while(sym==BAND) { - e1=rvalue(e1); - t=type; - getsym(); - e2=rvalue(expr8()); - e1=binop(BAND,e1,e2,t,type); - } - return(e1); -} - -int -expr8() -{ - int e,op; - - e=expr9(); - while((op=sym)==EQ||op==NEQ) { - e=rvalue(e); - getsym(); - e=list3(op,e,rvalue(expr9())); - type= INT; - } - return e; -} - -int -expr9() -{ - int e1,e2,t,op; - - e1=expr10(); - while((op=sym)==GT||op==GE||op==LT||op==LE) { - e1=rvalue(e1); - t=type; - getsym(); - e2=rvalue(expr10()); - if(t==INT&&type==INT) - e1=list3(op,e1,e2); - else - e1=list3(op+US,e1,e2); - type= INT; - } - return e1; -} - -int -expr10() -{ - int e1,e2,t,op; - - e1=expr11(); - while((op=sym)==RSHIFT||op==LSHIFT) { - e1=rvalue(e1); - t=type; - getsym(); - e2=rvalue(expr11()); - e1=binop(op,e1,e2,t,type); - } - return e1; -} - -int -expr11() -{ - int e1,e2,t,op; - - e1=expr12(); - while((op=sym)==ADD||op==SUB) { - e1=rvalue(e1); - t=type; - getsym(); - e2=rvalue(expr12()); - e1=binop(op,e1,e2,t,type); - } - return e1; -} - -int -expr12() -{ - int e1,e2,t,op; - - e1=expr13(); - while((op=sym)==MUL||op==DIV||op==MOD) { - e1=rvalue(e1); - t=type; - getsym(); - e2=rvalue(expr13()); - e1=binop(op,e1,e2,t,type); - } - return e1; -} - -int -expr13() -{ - int e,op; - - switch (op = sym) { - case INC: case DEC: - getsym(); - lcheck(e=expr13()); - if(type==CHAR) { - type= INT; - return(list2(op==INC?CPREINC:CPREDEC,e)); - } - if(integral(type)) - return(list3(PREINC,e,op==INC?1:-1)); - if(car(type)!=POINTER) - error(TYERR); - return(list3(PREINC,e, - op==INC?size(cadr(type)):-size(cadr(type)) )); - case MUL: - getsym(); - e=rvalue(expr13()); - return(indop(e)); - case BAND: - getsym(); - switch(car(e=expr13())) { - case INDIRECT: - e=cadr(e); - break; - case GVAR: - case LVAR: - e=list2(ADDRESS,e); - break; - case FNAME: - return e; - default:error(LVERR); - } - type=list2(POINTER,type); - return e; - case SUB: - getsym(); - e=rvalue(expr13()); - if(!integral(type)) - error(TYERR); - return(car(e)==CONST?list2(CONST,-cadr(e)):list2(MINUS,e)); - case BNOT: - getsym(); - e=rvalue(expr13()); - if(!integral(type)) - error(TYERR); - return(car(e)==CONST?list2(CONST,~cadr(e)):list2(BNOT,e)); - case LNOT: - getsym(); - return(list2(LNOT,rvalue(expr13()))); - case SIZEOF: - if(getsym()==LPAR) { - if(typeid(getsym())) { - e=list2(CONST,size(typename())); - type=INT; - checksym(RPAR); - return e; - } else { - e=expr0(); - checksym(RPAR); - expr16(e); - if(sym==INC||sym==DEC) { - getsym(); - if(type==CHAR) type=INT; - else if(!scalar(type)) - error(TYERR); - } - } - } else - expr13(); - e=list2(CONST,size(type)); - type=INT; - return e; - } - e=expr14(); - if((op=sym)==INC||op==DEC) { - lcheck(e); - getsym(); - if(type==CHAR) { - type= INT; - return(list2(op==INC?CPOSTINC:CPOSTDEC,e)); - } - if(integral(type)) - return(list3(POSTINC,e,op==INC?1:-1)); - if(car(type)!=POINTER) - error(TYERR); - return (list3(POSTINC,e, - op == INC ? size(cadr(type)): -size(cadr(type)) )); - } - return e; -} - -int -expr14() -{ - int e1,t; - - switch(sym) { - case IDENT: - switch(nptr->sc) { - case GVAR: - e1=list3(GVAR,nptr->dsp,(int)nptr->nm); - type=nptr->ty; - getsym(); - break; - case LVAR: - e1=list2(LVAR,nptr->dsp); - type=nptr->ty; - getsym(); - break; - case REGISTER: - e1=list2(REGISTER,nptr->dsp); - type=nptr->ty; - getsym(); - break; - case FLABEL: case BLABEL: - case FUNCTION: case CODE: - e1=list2(FNAME,(int)nptr); - type=list3(nptr->sc,car(nptr->ty),cadr(nptr->ty)); - getsym(); - break; - case EMPTY: - if(getsym()==LPAR) { - nptr->sc = FUNCTION; - nptr->ty= list2(INT,0); - type= list3(FUNCTION,INT,0); - e1=expr15(list2(FNAME,(int)nptr)); - break; - } else { - e1=list2(FNAME,(int)nptr); - type=list3(nptr->sc,nptr->ty,0); - break; - } - default:error(UDERR); - } - break; - case STRING: - e1=list3(STRING,(int)sptr,symval); - type=list3(ARRAY,CHAR,symval); - getsym(); - break; - case CONST: - type= INT; - e1=list2(CONST,symval); - getsym(); - break; - case RETURN: - if (fnptr->sc != FUNCTION) { - error(STERR); - } - type=list2(POINTER,CODE); - e1=list2(RETURN,(int)fnptr); - getsym(); - break; - case ENVIRONMENT: - type=list2(POINTER,INT); - e1=list2(ENVIRONMENT,0); - getsym(); - break; - case LPAR: - if(typeid(getsym())) { - t=typename(); - checksym(RPAR); - e1=expr13(); - type=t; - return e1; - } - e1=expr0(); - checksym(RPAR); - break; - default:error(EXERR); - } - return expr16(e1); -} - -int -expr16(e1) - int e1; -{ - int e2,t; - - while(1) { - if(sym==LBRA) { - e1=rvalue(e1); - t=type; - getsym(); - e2=rvalue(expr0()); - checksym(RBRA); - e1=binop(ADD,e1,e2,t,type); - e1=indop(e1); - } else if(sym==LPAR) e1=expr15(e1); - else if(sym==PERIOD) e1=strop(e1); - else if(sym==ARROW) e1=strop(indop(rvalue(e1))); - else break; - } - if(car(e1)==FNAME) type=list2(POINTER,type); - return e1; -} - -int -rvalue(e) - int e; -{ - int t; - if(type==CHAR) { - type= INT; - switch(car(e)) { - case GVAR: - return(list3(CRGVAR,cadr(e),caddr(e))); - case LVAR: - return(list2(CRLVAR,cadr(e))); - case INDIRECT: - return(list2(CRINDIRECT,cadr(e))); - default:return(e); - } - } - if(!integral(type)&&type!=VOID) { - if(type==CODE) { return(e); - } else if((t=car(type))==ARRAY) { - type=list2(POINTER,cadr(type)); - if(car(e)==INDIRECT) return cadr(e); - return list2(ADDRESS,e); - } else if(t==STRUCT || t==UNION) { return e; - } else if(t!=POINTER) error(TYERR); - } - switch(car(e)) { - case GVAR: - return(list3(RGVAR,cadr(e),caddr(e))); - case LVAR: - return(list2(RLVAR,cadr(e))); - case INDIRECT: - return(list2(RINDIRECT,cadr(e))); - default:return(e); - } -} - -void -lcheck(e) - int e; -{ - int t; - if(!scalar(type)|| - (car(e)!=GVAR&&car(e)!=LVAR&&car(e)!=INDIRECT&&car(e)!=REGISTER)) - if ((t=car(type))<0 && t!=STRUCT && t!=UNION) - error(LVERR); -} - -int -indop(e) - int e; -{ - if(type!=INT&&type!=UNSIGNED) { - if(car(type)==POINTER) - type=cadr(type); - else error(TYERR); - } else - type= CHAR; - if(car(e)==ADDRESS) - return(cadr(e)); - return(list2(INDIRECT,e)); -} - -int -strop(e) - int e; -{ - getsym(); - if (sym!=IDENT||nptr->sc!=FIELD) error(TYERR); - if (integral(type)||(car(type)!=STRUCT && car(type)!=UNION)) - e=rvalue(e); - type = nptr->ty; - switch(car(e)) { - case GVAR: - e=list2(INDIRECT,list3(ADD,e,list2(CONST,nptr->dsp))); - break; - case LVAR: - e=list2(car(e),cadr(e) + nptr->dsp); - break; - case INDIRECT: - if(!nptr->dsp) break; - e=list2(INDIRECT,list3(ADD,cadr(e),list2(CONST,nptr->dsp))); - break; - default: - e=list2(INDIRECT,list3(ADD,e,list2(CONST,nptr->dsp))); - } - getsym(); - return e; -} - -int -binop(op, e1, e2, t1, t2) - int op; - int e1; - int e2; - int t1; - int t2; -{ - int e; - - if(car(e1)==CONST&&car(e2)==CONST) { - e1=cadr(e1); - e2=cadr(e2); - type= INT; - switch(op) { - case BOR: - e=e1|e2;break; - case EOR: - e=e1^e2;break; - case BAND: - e=e1&e2;break; - case ADD: - if(integral(t1)) { - if(integral(t2)) { - e=e1+e2; - } else { - if(car(t2)!=POINTER) error(TYERR); - e=size(cadr(t2))*e1+e2; - type=t2; - } - } else { - if(car(t1)!=POINTER) error(TYERR); - e=e1+size(cadr(t1))*e2; - type=t1; - } - break; - case SUB: - if(integral(t1)) { - e=e1-e2; - } else { - if(car(t1)!=POINTER) error(TYERR); - e=e1-size(cadr(t1))*e2; - type=t1; - } - break; - case MUL: - e=e1*e2;break; - case DIV: - if(!e2) error(EXERR);e=e1/e2;break; - case MOD: - if(!e2) error(EXERR);e=e1%e2;break; - case RSHIFT: - e=e1>>e2;break; - case LSHIFT: - e=e1<<e2; - } - return list2(CONST,e); - } - if((op==ADD||op==MUL||op==BOR||op==EOR||op==BAND)&& - (car(e1)==CONST||(car(e2)!=CONST&& - (car(e1)==RGVAR||car(e1)==RLVAR)))) { - e=e1;e1=e2;e2=e;e=t1;t1=t2;t2=e; - } - if(op==ADD) { - if(integral(t1)) { - if(integral(t2)) { - if(t1==INT) type=t2;else type=t1; - return(list3(ADD,e1,e2)); - } - if(car(t2)!=POINTER) error(TYERR); - e=binop(MUL,e1,list2(CONST,size(cadr(t2))),t1,INT); - type=t2; - return(list3(ADD,e,e2)); - } - if(car(t1)!=POINTER||!integral(t2)) error(TYERR); - e=binop(MUL,e2,list2(CONST,size(cadr(t1))),t2,INT); - type=t1; - if(car(e1)==ADDRESS&&car(e)==CONST&&car(cadr(e1))!=GVAR) - return(list2(ADDRESS,list2(car(cadr(e1)), - cadr(cadr(e1))+cadr(e)))); - return(list3(ADD,e1,e)); - } - if(op==SUB) { - if(integral(t1)) { - if(!integral(t2)) error(TYERR); - if(t1==INT) type=t2;else type=t1; - return(list3(SUB,e1,e2)); - } - if(car(t1)!=POINTER) error(TYERR); - if(integral(t2)) { - e=binop(MUL,e2,list2(CONST,size(cadr(t1))),t2,INT); - type=t1; - return(list3(SUB,e1,e)); - } - if(car(t2)!=POINTER) - error(TYERR); - compatible(t1,t2); - e=list3(SUB,e1,e2); - e=binop(DIV,e,list2(CONST,size(cadr(t1))),UNSIGNED,INT); - type= INT; - return e; - } - if(!integral(t1)||!integral(t2)) error(TYERR); - if(t1==INT) type=t2;else type=t1; - if((op==MUL||op==DIV)&&car(e2)==CONST&&cadr(e2)==1) return e1; - if(op==BOR||op==EOR||op==BAND) return(list3(op,e1,e2)); - return(list3(type==UNSIGNED?op+US:op,e1,e2)); -} - -int -expr15(e1) - int e1; -{ - int t,arglist; - - t=type; - if(integral(t)|| (car(t)!=FUNCTION && car(t)!=CODE)) - error(TYERR); - getsym(); - arglist=0; - while(sym!=RPAR) { - arglist=list2(rvalue(expr1()),arglist); - if(sym!=COMMA) break; - getsym(); - } - checksym(RPAR); - if(car(t)!=CODE) { - t=cadr(t); - if(t==CHAR) type= INT;else type=t; - } - return list3(FUNCTION,e1,arglist); -} - -int -typeid(s) - int s; -{ - return (integral(s) || s==CODE || s==SHORT || s==LONG || s==STRUCT || s==UNION || - (s==IDENT && nptr->sc==TYPE)); -} - -int -typename() -{ - int t; - - type=t=typespec(); - ndecl0(); - reverse(t); - return type; -} - -int -ndecl0() -{ - if(sym==MUL) { - getsym(); - return type=list2(POINTER,ndecl0()); - } - return ndecl1(); -} - -int -ndecl1() -{ - int i,t,arglist; - - if(sym==LPAR) { - if(getsym()==RPAR) { - type=list3(FUNCTION,type,0); getsym(); - } else { - ndecl0(); - checksym(RPAR); - } - } - while(1) { - if(sym==LBRA) { - getsym(); - t=type; - i=cexpr(expr()); - checksym(RBRA); - type=list3(ARRAY,t,i); - } else if(sym==LPAR) { - t = type; - getsym(); - arglist=0; - while(sym!=RPAR) { - ndecl0(); - arglist=list2(type,arglist); - if(sym!=COMMA) break; - getsym(); - } - checksym(RPAR); - type=list3(FUNCTION,t,arglist); - } - else return type; - } -} - -int -cexpr(e) - int e; -{ - if (car(e) != CONST) error(CNERR); - return (cadr(e)); -} - -int -getsym() -{ - NMTBL *nptr0,*nptr1; - int i; - char c; - - if (alpha(skipspc())) { - i = hash = 0; - name = namebuf; - while (alpha(ch) || digit(ch)) { - if (i < LBUFSIZE-1) - hash=(7*hash ^ (name[i++]=ch)); - getch(); - } - name[i++] = '\0'; - nptr0 = gsearch(); - if (nptr0->sc == RESERVE) return sym = nptr0->dsp; - if (nptr0->sc == MACRO && !mflag) { - mflag++; - chsave = ch; - chptrsave = chptr; - chptr = (char *)nptr0->dsp; - getch(); - return getsym(); - } - sym = IDENT; - gnptr=nptr=nptr0; - if (mode==ADECL && nptr0->sc ==TYPE) return sym; - if (mode==GDECL || mode==GSDECL || mode==GUDECL || - mode==GTDECL || mode==TOP) { - return sym; - } - nptr1=lsearch(nptr0->nm); - if (mode==STAT) - if (nptr1->sc == EMPTY) return sym; - else { nptr=nptr1; return sym;} - nptr=nptr1; - return sym; - } else if (digit(ch)) { - symval=0; - if (ch == '0') { - if (getch() == 'x' || ch == 'X') { - while(1) { - if(digit(getch())) - symval=symval*16+ch-'0'; - else if('a'<=ch&&ch<='f') - symval=symval*16+ch-'a'+10; - else if('A'<=ch&&ch<='F') - symval=symval*16+ch-'A'+10; - else break; - } - } else { - while (digit(ch)) { - symval=symval*8+ch-'0';getch(); - } - } - } else { - while(digit(ch)) { - symval=symval*10+ch-'0';getch(); - } - } - return sym=CONST; - } else if(ch=='\'') { - getch(); - symval=escape(); - if(ch!='\'') error(CHERR); - getch(); - return sym=CONST; - } else if(ch=='"') { - getstring(); - return sym= STRING; - } - c=ch; - getch(); - switch(c) { - case '*': - return postequ(MUL,MUL+AS); - case '&': - if(ch=='&') {getch();return sym=LAND;} - return postequ(BAND,BAND+AS); - case '-': - if(ch=='>') {getch();return sym=ARROW;} - if(ch=='-') {getch();return sym=DEC;} - return postequ(SUB,SUB+AS); - case '!': - return postequ(LNOT,NEQ); - case '~': - return sym=BNOT; - case '+': - if(ch=='+') {getch();return sym=INC;} - return postequ(ADD,ADD+AS); - case '%': - return postequ(MOD,MOD+AS); - case '^': - return postequ(EOR,EOR+AS); - case '|': - if(ch=='|') {getch();return sym=LOR;} - return postequ(BOR,BOR+AS); - case '=': - return postequ(ASS,EQ); - case '>': - if(ch=='>') {getch();return postequ(RSHIFT,RSHIFT+AS);} - return postequ(GT,GE); - case '<': - if(ch=='<') {getch();return postequ(LSHIFT,LSHIFT+AS);} - return postequ(LT,LE); - case '(': - return sym=LPAR; - case ')': - return sym=RPAR; - case '[': - return sym=LBRA; - case ']': - return sym=RBRA; - case '{': - return sym=LC; - case '}': - return sym=RC; - case ',': - return sym=COMMA; - case ';': - return sym=SM; - case ':': - return sym=COLON; - case '?': - return sym=COND; - case '.': - if(ch=='.') { - getch(); - if (ch=='.') { - getch(); - return sym=DOTS; - } - error(CHERR); - return getsym(); - } else - return sym=PERIOD; - case '/': - if(ch!='*') return postequ(DIV,DIV+AS); - getch(); - while(ch=='*'?getch()!='/':getch()); - getch(); - return getsym(); - default: - error(CHERR); - return getsym(); - } -} - -int -postequ(s1, s2) - int s1; - int s2; -{ - if(ch=='=') {getch();return sym=s2;} - return sym=s1; -} - -int -alpha(c) - char c; -{ - return(('a'<=c&&c<='z')||('A'<=c&&c<='Z')||c=='_'); -} - -int -digit(c) - char c; -{ - return('0'<=c&&c<='9'); -} - - -NMTBL * -gsearch() -{ - NMTBL *nptr,*iptr; - - iptr=nptr= &ntable[hash % GSYMS]; - while(nptr->sc!=0 && neqname(nptr->nm)) { - if (++nptr== &ntable[GSYMS]) - nptr=ntable; - if (nptr==iptr) error(GSERR); - } - if (nptr->sc == 0) { - copy(nptr,name); - nptr->sc=EMPTY; - } - return nptr; -} - -NMTBL * -lsearch(name) - char *name; -{ - NMTBL *nptr,*iptr; - - iptr=nptr= &ntable[hash%LSYMS+GSYMS]; - while(nptr->sc!=0 && neqname(nptr->nm)) { - if (++nptr== &ntable[LSYMS+GSYMS]) - nptr= &ntable[GSYMS]; - if (nptr==iptr) error(LSERR); - } - if (nptr->sc == 0) { - nptr->nm=name; /* already saved in gsearch */ - nptr->sc=EMPTY; - nptr->dsp=0; - } - return nptr; -} - -void -copy(nptr, s) - NMTBL *nptr; - char *s; -{ - nptr->nm = cheapp; - while(*cheapp++ = *s++); -} - -int -neqname(p) - char *p; -{ - char *q; - - if (!p) - return 0; - q=name; - while(*p && *p!='.') - if(*p++ != *q++) return 1; - return (*q!=0); -} - -void -getstring() -{ - getch(); - symval = 0; - sptr = cheapp; - while (ch != '"') { - *cheapp++ = escape(); - symval++; - if (cheapp >= cheap+CHEAPSIZE) error(STRERR); - } - getch(); - *cheapp++ = '\0'; - symval++; -} - -int -skipspc() -{ - while(ch=='\t'||ch=='\n'||ch==' '||ch=='\r') - getch(); - return ch; -} - -int -getch() -{ - if(*chptr) return ch= *chptr++; - if(mflag) { - mflag=0;chptr=chptrsave;return ch=chsave; - } - getline(); - return getch(); -} - -char -escape() -{ - char c; - if ((c=ch) == '\\') { - if (digit(c=getch())) { - c = ch-'0'; - if (digit(getch())) { - c = c*8+ch-'0'; - if (digit(getch())) { - c=c*8+ch-'0';getch(); - } - } - return c; - } - getch(); - switch(c) { - case 'n': - return '\n'; - case 't': - return '\t'; - case 'b': - return '\b'; - case 'r': - return '\r'; - case 'f': - return '\f'; - case '\n': - return escape(); - default: - return c; - } - } - if (c == '\n') error(EXERR); - getch(); - return c; -} - -FILE * -getfname() -{ - int i; - char name[LBUFSIZE]; - FILE *fp; - - getch(); - if(skipspc()!='"') error(INCERR); - for(i=0;(getch()!='"' && ch!='\n');) { - if(i<LBUFSIZE-1) name[i++]=ch; - } - if(ch=='\n') error(INCERR); - name[i]=0; - fp = fopen(name,"r") ; - return ( (filep+1)->fcb = fp ); -} - -void -getline() -{ - int i; - int c; - - lineno++; - glineno++; - chptr=linebuf; - i=0; - /* while ((*chptr++ = c = getc(filep->fcb)) != '\n') { - we cannot handle unsaved register in library call - so make it easy for the compiler - */ - while ((c=getc(filep->fcb)),(*chptr++=c)!='\n') { - if (++i > LBUFSIZE-2) error(LNERR); - if (c==EOF) { - error(EOFERR); - --chptr; - } - } - *chptr = '\0'; - if (lsrc && !asmf) gen_comment(linebuf); - if (*(chptr = linebuf) == '#') { - ++chptr; - if (macroeq("define")) { - i=mode; - mode=GDECL; - ch= *chptr; - if (getsym() == IDENT) { - if (nptr->sc == EMPTY) { - nptr->sc = MACRO; - nptr->dsp = (int)cheapp; - while ((*cheapp++ = c = *chptr++) - && c != '\n'); - *cheapp++ = '\0'; - if (cheapp >= cheap+CHEAPSIZE) - error(STRERR); - if (!c) error(EOFERR); - } else error(MCERR); - } else error(MCERR); - mode=i; - *(chptr = linebuf) = '\0'; - } else if (macroeq("include")) { - if(filep+1 >= filestack + FILES) error(FILERR); - if ( ((filep+1)->fcb=getfname()) == NULL) error(FILERR); - (filep+1)->ln=lineno; - lineno=0; - ++filep; - *(chptr = linebuf) = '\0'; - } else if (macroeq("asm")) { - if (asmf) error(MCERR); - asmf = 1; - getline(); - while (asmf) { - gen_source(linebuf); - getline(); - } - } else if (macroeq("endasm")) { - if (!asmf) error(MCERR); - asmf = 0; - } else if (macroeq(" ")) - getline(); - else error(MCERR); - } -} - -int -macroeq(s) - char *s; -{ - char *p; - - for (p = chptr; *s;) if (*s++ != *p++) return 0; - chptr = p; - return 1; -} - -int -car(e) - int e; -{ - return heap[e]; -} - -int -cadr(e) - int e; -{ - return heap[e+1]; -} - -int -caddr(e) - int e; -{ - return heap[e+2]; -} - -int -cadddr(e) - int e; -{ - return heap[e+3]; -} - -int -list2(e1, e2) - int e1; - int e2; -{ - int e; - - e=getfree(2); - heap[e]=e1; - heap[e+1]=e2; - return e; -} - -int -list3(e1, e2, e3) - int e1; - int e2; - int e3; -{ - int e; - - e=getfree(3); - heap[e]=e1; - heap[e+1]=e2; - heap[e+2]=e3; - return e; -} - -int -list4(e1, e2, e3, e4) - int e1; - int e2; - int e3; - int e4; -{ - int e; - - e=getfree(4); - heap[e]=e1; - heap[e+1]=e2; - heap[e+2]=e3; - heap[e+3]=e4; - return e; -} - -int -getfree(n) - int n; -{ - int e; - - switch (mode) { - case GDECL: case GSDECL: case GUDECL: case GTDECL: - e=gfree; - gfree+=n; - break; - default: - lfree-=n; - e=lfree; - } - if(lfree<gfree) error(HPERR); - return e; -} - -int -rplacad(e, n) - int e; - int n; -{ - heap[e+1]=n; - return e; -} - -int -rplacadd(e, n) - int e; - int n; -{ - heap[e+2]=n; - return e; -} - -display_ntable(n, s) - NMTBL *n; - char *s; -{ - fprintf(stderr,"\n%s %0x %0x ",s,n,ntable); - fprintf(stderr,"nptr->sc %d ",n->sc); - fprintf(stderr,"nptr->dsp %d ",n->dsp); - fprintf(stderr,"nptr->ty %d ",n->ty); - fprintf(stderr,"nptr->nm %s\n",n->nm); -} - -/* end */
--- a/ansi/mc-parse.c.save Fri Jan 14 12:10:42 2000 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2596 +0,0 @@ -#define EXTERN /**/ -#include "mc.h" - -void ntable_consistency(); -static void adecl(NMTBL *n); -static void decl_data(int t, NMTBL *n); -static int alpha(char c); -static int binop(int op, int e1, int e2, int t1, int t2); -int caddr(int e); -int cadr(int e); -int car(int e); -static void compatible(int t1, int t2); -static void decl(void); -static void def(NMTBL *n); -static int digit(char c); -static void docase(void); -static void docomp(void); -static void dodefault(void); -static void dodo(void); -static void dofor(void); -static void dogoto(void); -static void doif(void); -static void dolabel(void); -static void doswitch(void); -static void doreturn(void); -static void dowhile(void); -static void errmsg(void); -static void copy(NMTBL *nptr, char *s); -void error(int n); -static int expr(void); -static int expr0(void); -static int expr1(void); -static int expr2(void); -static int expr3(void); -static int expr4(void); -static int expr5(void); -static int expr6(void); -static int expr7(void); -static int expr8(void); -static int expr9(void); -static int expr10(void); -static int expr11(void); -static int expr12(void); -static int expr13(void); -static int expr14(void); -static int expr15(int e1); -static int expr16(int e1); -static void fcheck(NMTBL *n); -static void fdecl(NMTBL *n); -static int getch(void); -static int getfree(int n); -static void getline(void); -static void getstring(void); -static int getsym(void); -static int indop(int e); -static void init(void); -static int integral(int t); -static void lcheck(int e); -int list2(int e1, int e2); -int list3(int e1, int e2, int e3); -int list4(int e1, int e2, int e3, int e4); -static void reserve(char *s, int d); -static int macroeq(char *s); -static int ndecl0(void); -static int ndecl1(void); -static int neqname(char *p); -static void newfile(void); -static int postequ(int s1, int s2); -static void reverse(int t1); -static int reverse0(int t1); -static int rplacad(int e, int n); -static int rvalue(int e); -static int scalar(int t); -static int sdecl(int s); -static int skipspc(void); -static void statement(void); -static int strop(int e); -static int typeid(int s); -static int typename(void); -static int typespec(void); -static int cexpr(int e); -static void code_decl(NMTBL *n); - -extern void exit(int); -extern void closing(void); -extern void opening(char *filename); -extern void gen_gdecl(char *n, int gpc); -extern void enter(char *name); -extern void enter1(int disp); -extern void leave(int control, char *name); -extern void ret(void); -extern void jmp(int l); -extern void gexpr(int e1); -extern int get_register_var(void); -extern void bexpr(int e1, char cond, int l1); -extern int fwdlabel(void); -extern void fwddef(int l); -extern int backdef(void); -extern int def_label(int cslabel, int dlabel); -extern void jmp_label(int l); -extern void cmpdimm(int e, int csreg); -extern void jcond(int l, char cond); -extern void jmp_eq_label(int l); -extern void gen_comment(char *s); -extern void gen_source(char *s); -extern void code_init(void); -extern void emit_data_closing(NMTBL *n); -extern void emit_data(int e, int t, NMTBL *n); - -int -main(int argc, char **argv) -{ - NMTBL *nptr; - int i; - char *ccout; - - if(argc==1) exit(1); - lsrc = chk = asmf = 0; - ccout = OUTPUT_FILE_NAME; - ac=argc; - av=argv; - for (ac2=1; (ac2 < ac) && (*av[ac2] == '-'); ++ac2) { - switch (*(av[ac2]+1)) { - case 'S': case 's': - lsrc = 1; - break; - case 'O': case 'o': - ccout = av[ac2]+2; - break; - case 'C': case 'c': - chk = 1; - break; - case 'D': case 'd': - debug = 1; - break; - default: - error(OPTION); - exit(1); - } - } - fclose(stdout); - if (!chk) - if ( (obuf = fopen(ccout,"w")) == NULL ) error(FILERR); - init(); - while(1) { - for (nptr = &ntable[GSYMS],i=LSYMS; i--;) - (nptr++)->sc = 0; - mode=TOP; - lfree= HEAPSIZE; - while(getsym()==SM); - mode=GDECL; - stmode=0; - args=0; - decl(); - } - /*NOTREACHED*/ -} - -void -error(int n) -{ - if(n == EOFERR) { - if(filep!=filestack) { - fclose(filep->fcb); - lineno=filep->ln; - --filep; - return; - } else if(ac2!=ac) { - fclose(filep->fcb); - newfile(); - return; - } else if(mode == TOP) { - /* - if (!chk) fprintf(stderr, - "Total internal labels : %u.\n",labelno-1); - fprintf(stderr, - "Total global variables : %u bytes.\n\n",gpc); - */ - closing(); - exit(0); - } - } - fprintf(stderr,"%5d:%s.\n",lineno, - (n==FILERR) ? "Can't open specified file" : - (n==DCERR) ? "Declaration syntax" : - (n==STERR) ? "Statement syntax" : - (n==EXERR) ? "Expression syntax" : - (n==CNERR) ? "Constant required" : - (n==CHERR) ? "Illegal character" : - (n==GSERR) ? "Too many global symbols" : - (n==LSERR) ? "Too many local symbols" : - (n==STRERR) ? "Too many strings or macros" : - (n==LNERR) ? "Line too long" : - (n==EOFERR) ? "Unexpected end of file" : - (n==MCERR) ? "Macro syntax" : - (n==INCERR) ? "Include syntax" : - (n==HPERR) ? "Too long expression" : - (n==TYERR) ? "Type mismatch" : - (n==LVERR) ? "Lvalue required" : - (n==UDERR) ? "Undeclared identifier" : - (n==OPTION) ? "Illegal option" : - (n==REG_ERR) ? "illegal register var" : - (n==CODE_ERR) ? "goto code is necessary" : - "Bug of compiler"); - errmsg(); - exit(1); -} - -void -errmsg(void) -{ - char *p,*lim; - - if(lineno==0) return; - fprintf(stderr,"%s",linebuf); - lim=(mflag?chptrsave:chptr); - for (p=linebuf; p < lim;) - fprintf(stderr,(*p++ == '\t') ? "\t" : " "); - fprintf (stderr,"^\n"); -} - -void -checksym(int s) -{ - char *p; - - if (sym != s) { - p=(s==RPAR) ? "')'": (s==RBRA) ? "']'": (s==SM) ? "';'": - (s==LPAR) ? "'('": (s==WHILE) ? "'while'": - (s==COLON) ? "':'": "Identifier"; - fprintf(stderr,"%d:%s expected.\n",lineno,p); - errmsg(); - } else - getsym(); -} - -void -init(void) -{ - NMTBL *nptr; - int i; - - cheapp=cheap; - for(nptr = ntable,i = GSYMS; i--;) (nptr++)->sc = 0; - reserve("int",INT); - reserve("void",VOID); - reserve("char",CHAR); - reserve("struct",STRUCT); - reserve("union",UNION); - reserve("unsigned",UNSIGNED); - reserve("static",STATIC); - reserve("goto",GOTO); - reserve("return",RETURN); - reserve("break",BREAK); - reserve("continue",CONTINUE); - reserve("if",IF); - reserve("else",ELSE); - reserve("for",FOR); - reserve("do",DO); - reserve("while",WHILE); - reserve("switch",SWITCH); - reserve("case",CASE); - reserve("default",DEFAULT); - reserve("typedef",TYPEDEF); - reserve("sizeof",SIZEOF); - reserve("long",LONG); - reserve("short",SHORT); - reserve("extern",EXTRN); - reserve("register",REGISTER); - reserve("code",CODE); - reserve("environment",ENVIRONMENT); - gpc=glineno=mflag=0; - gfree=ilabel=1; - labelno=2; - lfree=HEAPSIZE; - filep=filestack; - code_init(); - newfile(); - getline(); - getch(); -} - -void -newfile(void) -{ - lineno=0; - /* fprintf(stderr,"%s:\n",av[ac2]); */ - opening(av[ac2]); - if ( (filep->fcb = fopen(av[ac2++],"r")) == NULL ) error(FILERR); -} - -void -reserve(char *s, int d) -{ - NMTBL *nptr; - int i; - - hash=0; name=namebuf; i=0; - while((name[i++] = *s)) { - hash=((7*hash) ^ *s++); - } - if (cheapp+i >= cheap+CHEAPSIZE) error(STRERR); - name[i++] = 0; - (nptr = gsearch())->sc = RESERVE; - nptr->dsp = d; -} - -static -NMTBL null_nptr; - -void -decl(void) -{ - NMTBL *n; - int t; - - if(sym==STATIC) { - if(mode==LDECL) { - getsym(); - mode=STADECL; - stmode=LDECL; - } else if(mode==GDECL) { - getsym(); - stmode=STATIC; - } else - error(DCERR); - } else if(sym==REGISTER) { - if(mode!=LDECL) - error(DCERR); - stmode=REGISTER; - getsym(); - } else if(sym==EXTRN) { - getsym(); - stmode=EXTRN; - } else if(sym==TYPEDEF) { - if(mode==GDECL) { - getsym(); - mode=GTDECL; - } else if(mode==LDECL) { - getsym(); - mode=LTDECL; - } else - error(DCERR); - } - if((t=typespec())==0) return; - if(sym==SM) return; - type=t; - n=decl0(); - reverse(t); - if (n == &null_nptr) { - error(DCERR); - return; - } - if(sym==LC || ( sym!=SM && sym!=COMMA && sym!=ASS )) { - if (car(type)==CODE) { - code_decl(n); return; - } else if (car(type)==FUNCTION) { - fdecl(n); return; - } - } - def(n); - while(sym==COMMA) { - getsym(); - type=t; - n=decl0(); - reverse(t); - if(n == &null_nptr) error(DCERR); - /* if(args) error(DCERR); */ - def(n); - } - if(sym!=SM) error(DCERR); - if(mode==GTDECL) - mode=GDECL; - if(mode==STADECL||mode==LTDECL) - mode=LDECL; -} - -int -typespec(void) -{ - int t; - - switch(sym) { - case VOID: - case INT: - case CHAR: - case CODE: - t= sym; - getsym(); - break; - case STRUCT: - case UNION: - t=sdecl(sym); - break; - case UNSIGNED: - t = UNSIGNED; - if(getsym()==INT) getsym(); - break; - case SHORT: - t=CHAR; - if(getsym()==INT) getsym(); - break; - case LONG: - t=INT; - if(getsym()==INT) getsym(); - break; - default: - if(sym==IDENT) { - if(nptr->sc==TYPE) { - t=nptr->ty; - getsym(); - break; - } else if(nptr->sc==EMPTY && gnptr->sc==TYPE) { - t=gnptr->ty; - getsym(); - break; - } - } - if(mode==LDECL) return 0; - t= INT; - } - return t; -} - -struct nametable * -decl0(void) -{ - NMTBL *n; - if(sym==MUL) { - getsym(); - n=decl0(); - type=list2(POINTER,type); - return n; - } - return decl1(); -} - - -NMTBL * -decl1(void) -{ - NMTBL *n; - int i,t; - - if(sym==LPAR) { - getsym(); - n=decl0(); - checksym(RPAR); - } else if (sym == IDENT) { - n=nptr; - getsym(); - } else { - /* error(DCERR); */ - n= &null_nptr; - } - while(1) { - if(sym==LBRA) { - if(getsym()==RBRA) { - getsym(); - if(mode==ADECL) { - t=type; - type=list2(POINTER,type); - } else if (mode==GDECL) { - t=type; - type=list3(ARRAY,t,0); - } else { - error(DCERR); - } - } else { - t=type; - i=cexpr(expr()); - checksym(RBRA); - type=list3(ARRAY,t,i); - } - } else if(sym==LPAR) { - if(mode==GDECL) { - mode=ADECL;getsym();mode=GDECL; /* ??? */ - } else - getsym(); - if(sym==RPAR) - getsym(); - else { - if (type==CODE) { - n->sc=CODE; - n->dsp=0; - stmode=REGISTER; - adecl(n); - stmode=0; - n->sc=EMPTY; - type=list3(CODE,type,cadr(n->ty)); - return n; - } else { - n->sc=FUNCTION; - n->dsp=0; - adecl(n); - n->sc=EMPTY; - } - } - type=list3(FUNCTION,type,cadr(n->ty)); - } else - return n; - } -} - - -void -adecl(NMTBL *n) -{ - NMTBL *arg,*sfnptr; - int sreg_var,t; - int stype; - - stype=type; - sfnptr=fnptr; - fnptr=n; - sreg_var=reg_var; - reg_var=0; - n->dsp=0; - if(mode!=GDECL && mode!=ADECL) error(DCERR); - mode=ADECL; - args= 0; - for(;;) { - if(sym==IDENT && nptr->sc!=TYPE) { - heap[n->ty+2] = list2(INT,caddr(n->ty)); - if (stmode==REGISTER && reg_var < MAX_REGISTER_VAR) { - nptr->ty = INT; - nptr->sc = REGISTER; - if ((nptr->dsp = get_register_var())<0) - error(-1); - reg_var++; - } else { - nptr->ty = INT; - nptr->sc = LVAR; - nptr->dsp = args ; - args += int_size; - } - getsym(); - if(sym==RPAR) break; - } else { - if(sym==DOTS) { - heap[n->ty+2] = list2(INT,caddr(n->ty)); - getsym(); - break; - } - if((t=typespec())==0) { - error(DCERR); - break; - } - if(sym!=COMMA && sym!=RPAR) { - if(sym==RPAR) break; - type=t; - arg=decl0(); - reverse(t); - if (arg != &null_nptr) { /* no varname typespec only */ - def(arg); - } - } - heap[n->ty+2] = list2(INT,caddr(n->ty)); - if(sym==RPAR) break; - } - if (sym!=COMMA) error(DCERR); - getsym(); - } - checksym(RPAR); - mode=GDECL; - reg_var=sreg_var; - fnptr=sfnptr; - type=stype; - return; -} - -void -reverse(int t1) -{ - int t2,t3; - t2=t1; - - while(type!=t1) { - t3=cadr(type); - rplacad(type,t2); - t2=type; - type=t3; - } - type = t2; -} - -int -reverse0(int t1) -{ - int t2,t3; - - t2=0; - while(t1) { - t3=cadr(t1); - rplacad(t1,t2); - t2=t1; - t1=t3; - } - return t2; -} - -int -size(int t) -{ - if(t==CHAR) return 1; - if(t==VOID) return 0; - if(scalar(t)) return int_size; - if(car(t)==STRUCT||car(t)==UNION) { - if(cadr(t)==-1) error(DCERR); - return(cadr(t)); - } - if(car(t)==ARRAY) - return(size(cadr(t))*caddr(t)); - else - error(DCERR); - return 0; -} - -void -def(NMTBL *n) -{ - int sz,nsc,ndsp,slfree,t,e; - char *p; - - if(car(type)==FUNCTION) { - fcheck(n); - return; - } - if (n->sc!=EMPTY && - !(n->sc==GVAR&&n->dsp==EXTRN) && - !(n->sc==FUNCTION&&n->dsp==EXTRN) && - (mode!=ADECL || n->sc!=LVAR || n->ty!=INT) && - (mode!=ADECL || n->sc!=REGISTER || n->ty!=INT) && - ((mode!=GSDECL&&mode!=LSDECL) || n->sc!=FIELD || n->dsp!=disp) && - ((mode!=GUDECL&&mode!=LUDECL) || n->sc!=FIELD || n->dsp!=0) ) - error(DCERR); - sz = size(n->ty = type); - switch(mode) { - case GDECL: - gen_gdecl(n->nm,gpc); - case STADECL: - nsc = GVAR; - ndsp = gpc; - if (stmode==EXTRN) - n->dsp = EXTRN; - else - n->dsp = ndsp; /* emit_data will override this */ - n->sc = nsc; - if (stmode==LDECL) { - copy(n,n->nm); - cheapp[-1] = '.'; - ndsp = ++stat_no; - while(ndsp>0) { - *cheapp++ = ndsp%10+'0'; - ndsp /= 10; - } - *cheapp++ = 0; - } - if(sym==ASS) { - decl_data(type,n); - emit_data_closing(n); - /* gpc is incremented by emit_data */ - } else - gpc +=sz; - return; - case GSDECL: - nsc = FIELD; - ndsp = disp; - disp += sz; - break; - case GUDECL: - nsc = FIELD; - ndsp = 0; - if (disp < sz) disp = sz; - break; - case GTDECL: - nsc = TYPE; - break; - case ADECL: - if (stmode==REGISTER && reg_var <MAX_REGISTER_VAR) { - if (type!=CHAR && !scalar(type)) - error(TYERR); - nsc = REGISTER; - reg_var++; - ndsp = get_register_var(); - break; - } - nptr->sc = LVAR; - if(type==CHAR) { - /* nptr->ty=INT; */ - if (nptr->dsp==0) { - nptr->dsp = args; - if (endian) - n->dsp += int_size-1; - } - args += int_size; - } else { - if (nptr->dsp==0) - nptr->dsp = args; - args += sz; - } - if(type==VOID) { - } else if (!scalar(type)) { - if((t=car(type))==STRUCT || t==UNION) { - nptr->ty = type; - } else - error(TYERR); - } - return; - case LDECL: - if (stmode==REGISTER && reg_var <=MAX_REGISTER_VAR) { - if(!scalar(type)) /* non integer register type ... */ - error(DCERR); - nsc = REGISTER; - reg_var++; - ndsp = get_register_var(); - } else { - nsc = LVAR; - ndsp = (disp -= sz); - } - if(sym==ASS) { - decl_data(type,n); - } - break; - case LSDECL: - nsc = FIELD; - ndsp = disp; - disp += sz; - break; - case LUDECL: - nsc = FIELD; - ndsp = 0; - if (disp < sz) disp = sz; - break; - case LTDECL: - nsc = TYPE; - break; - default: - error(DCERR); - } - n->sc = nsc; - if (stmode==EXTRN) - n->dsp = EXTRN; - else - n->dsp = ndsp; -} - -void -emit_init_vars(void) -{ - while(init_vars) { - g_expr(car(init_vars)); - init_vars = cadr(init_vars); - } -} - -void -assign_data(int e, int t, int n) -{ - int ass; - - if(mode==GDECL) { - emit_data(e,t,(NMTBL *)n); - } else if(mode==LDECL) { - if (t==STRUCT || t==UNION) { - ass = list3(SASS,list2(LVAR,nptr->dsp),e); - } else { - if(t==CHAR) { - ass =list3(CASS,list2(LVAR,nptr->dsp),e); - } else { - ass = list3(ASS,list2(LVAR,nptr->dsp),e); - } - } - init_vars = list2(ass,init_vars); - } else { - error(DCERR); - } -} - -void -decl_data(int t, NMTBL *n) - /* type */ - -{ - int t1,slfree,e,i; - - getsym(); - if (scalar(t)) { - slfree=lfree; - e=expr1(); - if(car(e)!=CONST && t==CHAR) - error(TYERR); - emit_data(e,t,n); - lfree=slfree; - type=t; - return; - } - t1 = car(t); - if (t1==ARRAY) { - if (sym==LC) { - t1 = cadr(t); - for(i=0;;i++) { - if (sym!=RC) - decl_data(t1,n); - if (sym==COMMA) { continue; - } else if (sym==RC) { - if (caddr(t)==0) { - heap[t+2]=i; - } else if (caddr(t)!=i+1) { - error(TYERR); - } - getsym(); - return; - } else { - error(TYERR); - } - } - } else if (cadr(t)==CHAR) { - slfree=lfree; - e=expr1(); - if(car(e)!=STRING) - error(TYERR); - emit_data(e,STRING,n); - heap[t+2]= size(type); - lfree=slfree; - } else - error(DCERR); - } else if (t1==STRUCT) { - if(cadr(t)==-1) error(DCERR); - t1 = caddr(t); /* list of fields */ - while(t1) { - decl_data(car(t1),n); /* alignment? */ - t1 = cadr(t1); - if ( t1 && sym==COMMA) continue; - if (!t1 && sym!=RC) error(DCERR); - } - getsym(); - return; - } else { - error(TYERR); /* should be initialization error */ - } -} - -int -sdecl(int s) -{ - int smode,sdisp,type0,type1; - NMTBL *nptr0,*gnptr0; - int tags; - - smode=mode; - if (mode==GDECL || mode==GSDECL || mode==GUDECL || mode==GTDECL) - mode=(s==STRUCT?GSDECL:GUDECL); - else - mode=(s==STRUCT?LSDECL:LUDECL); - sdisp=disp; - disp=0; - if (getsym() == IDENT) { - nptr0 = nptr; - gnptr0 = gnptr; - if (getsym() == LC) { - if (nptr0->sc != EMPTY) error(DCERR); - nptr0->sc = TAG; - tags = 0; - nptr0->ty = list3(s,-1,tags); - while (getsym() != RC) { - decl(); - tags = list2(type,tags); - } - getsym(); - tags=reverse0(tags); - heap[nptr0->ty+2]=tags; - rplacad(type0 = nptr0->ty,disp); - } else { - if(nptr0->sc == EMPTY) nptr0=gnptr0; - if(nptr0->sc == EMPTY) error(UDERR); - if(nptr0->sc != TAG) error(TYERR); - type0 = nptr0->ty; - } - } else if(sym==LC) { - tags = 0; - while(getsym() != RC) { - decl(); - tags = list2(type,tags); - } - getsym(); - tags=reverse0(tags); - type0 = list3(s,disp,tags); - } - else error(DCERR); - disp=sdisp; - mode=smode; - return type0; -} - -void -code_decl(NMTBL *n) -{ - if (n->sc==EMPTY) n->sc = CODE; - code_enter(n->nm); - fnptr=n; - args= 0; - reg_var=0; - mode=ADECL; - stmode=REGISTER; - while (sym!=LC) { /* argument declaration !ANSI */ - decl(); getsym(); - } - disp=0; - init_vars=0; - /* local variable declaration */ - stmode=0; - mode=STAT; - init_vars=0; - while (typeid(getsym()) || sym==STATIC || sym==EXTRN || sym==TYPEDEF) { - mode=LDECL; - decl(); - mode=STAT; - } - control=1; - code_enter1(disp); - emit_init_vars(); - while(sym!=RC) statement(); - if(control) - error(STERR); - control=0; - code_leave(n->nm); -} - -void -fdecl(NMTBL *n) -{ - enter(n->nm); - fnptr=n; - retlabel=fwdlabel(); - retcont = 0; - - args=0; - reg_var=0; - fcheck(n); - mode=ADECL; - while (sym!=LC) { /* argument declaration !ANSI */ - stmode=0; - decl(); getsym(); - } - disp=0; - init_vars=0; - /* local variable declaration */ - mode=STAT; - while (typeid(getsym()) || sym==STATIC || sym==EXTRN - || sym==REGISTER || sym==TYPEDEF) { - mode=LDECL; - stmode=0; - decl(); - mode=STAT; - } - control=1; - enter1(disp); - emit_init_vars(); - while(sym!=RC) statement(); - - leave(control,n->nm); - retpending = 0; - control=0; -} - -void -fcheck(NMTBL *n) -{ - if(mode!=GDECL||car(type)!=FUNCTION) error(DCERR); - if(n->sc==FUNCTION) compatible(car(n->ty),cadr(type)); - else { - if(n->sc!=EMPTY) - error(DCERR); - else { - n->sc=FUNCTION; - n->ty=list2(cadr(type),0); - } - } -} - -void -compatible(int t1, int t2) -{ - if(integral(t1)) { - if(t1!=t2) error(TYERR); - } - else if(car(t1)!=car(t2)) - error(TYERR); - else if((car(t1)==STRUCT || car(t1)==UNION) && cadr(t1)!=cadr(t2)) - error(TYERR); - else if(car(t1)==POINTER || car(t1)==ARRAY ||car(t1)==FUNCTION) - compatible(cadr(t1),cadr(t2)); -} - -int -scalar(int t) -{ - return(integral(t)||car(t)==POINTER); -} - -int -integral(int t) -{ - return(t==INT||t==CHAR||t==UNSIGNED); -} - -void -checkret(void) -{ - if (retpending) { - ret(); - control=0; - retpending=0; - } -} - -void -statement(void) -{ - int slfree; - - if(sym==SM) { - getsym(); return; - } - checkret(); - switch(sym) { - case IF: - doif(); - return; - case WHILE: - dowhile(); - return; - case DO: - dodo(); - return; - case FOR: - dofor(); - return; - case SWITCH: - doswitch(); - return; - case LC: - docomp(); - return; - case BREAK: - jmp(blabel); - getsym(); - checksym(SM); - return; - case CONTINUE: - jmp(clabel); - getsym(); - checksym(SM); - return; - case CASE: - docase(); - statement(); - return; - case DEFAULT: - dodefault(); - statement(); - return; - case RETURN: - doreturn(); - return; - case GOTO: - dogoto(); - return; - default: - if(sym==IDENT&&skipspc()==':') { - dolabel(); - statement(); - } else { - slfree=lfree; - gexpr(expr()); - lfree=slfree; - checksym(SM); - } - } -} - -void -doif(void) -{ - int l1,l2,slfree; - getsym(); - checksym(LPAR); - slfree=lfree; - bexpr(expr(),0,l1=fwdlabel()); - lfree=slfree; - checksym(RPAR); - statement(); - checkret(); - if(sym==ELSE) { - if ((l2 = control)) - jmp(l2=fwdlabel()); - fwddef(l1); - getsym(); - statement(); - checkret(); - if (l2) fwddef(l2); - } - else fwddef(l1); -} - -void -dowhile(void) -{ - int sbreak,scontinue,slfree,e; - - sbreak=blabel; - scontinue=clabel; - blabel=fwdlabel(); - clabel=backdef(); - getsym(); - checksym(LPAR); - slfree=lfree; - e=expr(); - checksym(RPAR); - if(sym==SM) { - bexpr(e,1,clabel); - lfree=slfree; - getsym(); - } else { - bexpr(e,0,blabel); - lfree=slfree; - statement(); - checkret(); - if(control) - jmp(clabel); - } - fwddef(blabel); - clabel=scontinue; - blabel=sbreak; -} - -void -dodo(void) -{ - int sbreak,scontinue,l,slfree; - - sbreak=blabel; - scontinue=clabel; - blabel=fwdlabel(); - clabel=fwdlabel(); - l=backdef(); - getsym(); - statement(); - checkret(); - fwddef(clabel); - checksym(WHILE); - checksym(LPAR); - slfree=lfree; - bexpr(expr(),1,l); - lfree=slfree; - checksym(RPAR); - checksym(SM); - fwddef(blabel); - clabel=scontinue; - blabel=sbreak; -} - -void -dofor(void) -{ - int sbreak,scontinue,l,e,slfree; - - sbreak=blabel; - scontinue=clabel; - blabel=fwdlabel(); - getsym(); - checksym(LPAR); - slfree=lfree; - if(sym!=SM) { - gexpr(expr()); - checksym(SM); - } - else getsym(); - lfree=slfree; - l=backdef(); - if(sym!=SM) { - bexpr(expr(),0,blabel); - checksym(SM); - } - else getsym(); - lfree=slfree; - if(sym==RPAR) { - clabel=l; - getsym(); - statement(); - checkret(); - } else { - clabel=fwdlabel(); - e=expr(); - checksym(RPAR); - statement(); - checkret(); - fwddef(clabel); - gexpr(e); - lfree=slfree; - } - jmp(l); - fwddef(blabel); - clabel=scontinue; - blabel=sbreak; -} - -void -doswitch(void) -{ - int sbreak,scase,sdefault,slfree,svalue; - - sbreak=blabel; /* save parents break label */ - blabel=fwdlabel(); - sdefault=dlabel; /* save parents default label */ - dlabel=0; - scase=cslabel; /* save parents next case label */ - getsym(); - checksym(LPAR); - slfree=lfree; - svalue=csvalue1; /* save parents switch value */ - gexpr(expr()); - csvalue1=csvalue ; - lfree=slfree; - checksym(RPAR); - cslabel = control = 0; - /* should be case statement but... */ - statement(); - checkret(); - if(dlabel) def_label(cslabel,dlabel); - else fwddef(cslabel); - csvalue1=svalue; - cslabel=scase; - dlabel=sdefault; - fwddef(blabel); - blabel=sbreak; -} - -void -docomp(void) -{ - getsym(); - while(sym!=RC) { statement(); checkret();} - getsym(); -} - -void -docase(void) -{ - int c,l,slfree; - - c=0; - slfree=lfree; - while(sym==CASE) { - getsym(); - c=list2(cexpr(expr()),c); - checksym(COLON); - } - l=fwdlabel(); - if (control) { - control=0; - jmp(l); - } - if (cslabel) fwddef(cslabel); - while(cadr(c)) { - cmpdimm(car(c),csvalue1); - jcond(l,0); - c=cadr(c); - } - lfree=slfree; - cmpdimm(car(c),csvalue1); - jcond(cslabel=fwdlabel(),1); - fwddef(l); -} - -void -dodefault(void) -{ - getsym(); - checksym(COLON); - if (dlabel) error(STERR); - if (!cslabel) jmp(cslabel = fwdlabel()); - dlabel = backdef(); -} - -void -doreturn(void) -{ - int slfree; - - if(getsym()==SM) { - getsym(); - retpending = 1; - return; - } - slfree=lfree; - gexpr(expr()); - lfree=slfree; - checksym(SM); - retpending = 1; -} - - -void -dogoto(void) -{ - NMTBL *nptr0; - int t,e1,e2,env; - - getsym(); - e1 = expr(); - t=car(e1); - if (t==FNAME) { - nptr0 = (NMTBL *)cadr(e1); - t = nptr0->sc; - if (t==EMPTY) { - nptr0->sc = FLABEL; - jmp(nptr0->dsp = fwdlabel()); - } else if (t==FLABEL||t==BLABEL) { - jmp(nptr0->dsp); - } - control=0; - checksym(SM); - return; - } - if (t==COMMA) { - env = caddr(e1); - e1 = cadr(e1); - t = car(e1); - } else { - env = 0; - } - if (t==FUNCTION) { - e2 = cadr(e1); - if (car(e2) == FNAME) { - nptr0=(NMTBL *)cadr(e2); - nptr0->sc = CODE; - } - gexpr(list3(CODE,e1,env)); - control=0; - checksym(SM); - return; - } - error(STERR); - return; -} - -void -dolabel(void) -{ - if(nptr->sc == FLABEL) - fwddef(nptr->dsp); - else if(nptr->sc != EMPTY) - error(TYERR); - nptr->sc = BLABEL; - nptr->dsp = backdef(); - getsym(); - checksym(COLON); -} - -int -expr(void) -{ - return(rvalue(expr0())); -} - -int -expr0(void) -{ - int e; - - e=expr1(); - while(sym==COMMA) { - getsym();e=list3(COMMA,e,rvalue(expr1())); - } - return e; -} - -int -expr1(void) -{ - int e1,e2,t,op; - e1=expr2(); - switch (sym) { - case ASS: - lcheck(e1); - t=type; - getsym(); - e2=rvalue(expr1()); - if(t==VOID) - error(TYERR); - if(t==CHAR) { - type= INT;return(list3(CASS,e1,e2)); - } else if(t==STRUCT||t==UNION) { - type= t;return(list3(SASS,e1,e2)); - } - type=t; - return(list3(ASS,e1,e2)); - case ADD+AS: case SUB+AS: case MUL+AS: case DIV+AS: case MOD+AS: - case RSHIFT+AS: case LSHIFT+AS: case BAND+AS: case EOR+AS: case BOR+AS: - op = sym-AS; - lcheck(e1); - t=type; - getsym(); - e2=rvalue(expr1()); - if(!integral(type)) error(TYERR); - if((t==UNSIGNED||type==UNSIGNED)&& - (op==MUL||op==DIV||op==MOD||op==RSHIFT||op==LSHIFT)) - op=op+US; - if(t==CHAR) { - type= INT; - return(list4(CASSOP,e1,e2,op)); - } - type=t; - if(integral(t)) return(list4(ASSOP,e1,e2,op)); - if((op!=ADD&&op!=SUB)||car(t)!=POINTER) error(TYERR); - e2=binop(MUL,e2,list2(CONST,size(cadr(t))),INT,UNSIGNED); - type=t; - return list4(ASSOP,e1,e2,op); - default: - return(e1); - } -} - -int -expr2(void) -{ - int e1,e2,e3,t; - - e1=expr3(); - if(sym==COND) { - e1=rvalue(e1); - getsym(); - e2=rvalue(expr2()); - t=type; - checksym(COLON); - e3=rvalue(expr2()); - if(car(e1)==CONST) { - if(cadr(e1)) { - type=t;return e2; - } else - return e3; - } - if(type==INT||(t!=INT&&type==UNSIGNED)) - type=t; - return(list4(COND,e1,e2,e3)); - } - return(e1); -} - -int -expr3(void) -{ - int e; - - e=expr4(); - while(sym==LOR) { - e=rvalue(e); - getsym(); - e=list3(LOR,e,rvalue(expr4())); - type= INT; - } - return(e); -} - -int -expr4(void) -{ - int e; - - e=expr5(); - while(sym==LAND) { - e=rvalue(e); - getsym(); - e=list3(LAND,e,rvalue(expr5())); - type= INT; - } - return(e); -} - -int -expr5(void) -{ - int e1,e2,t; - - e1=expr6(); - while(sym==BOR) { - e1=rvalue(e1); - t=type; - getsym(); - e2=rvalue(expr6()); - e1=binop(BOR,e1,e2,t,type); - } - return(e1); -} - -int -expr6(void) -{ - int e1,e2,t; - - e1=expr7(); - while(sym==EOR) { - e1=rvalue(e1); - t=type; - getsym(); - e2=rvalue(expr7()); - e1=binop(EOR,e1,e2,t,type); - } - return(e1); -} - -int -expr7(void) -{ - int e1,e2,t; - - e1=expr8(); - while(sym==BAND) { - e1=rvalue(e1); - t=type; - getsym(); - e2=rvalue(expr8()); - e1=binop(BAND,e1,e2,t,type); - } - return(e1); -} - -int -expr8(void) -{ - int e,op; - - e=expr9(); - while((op=sym)==EQ||op==NEQ) { - e=rvalue(e); - getsym(); - e=list3(op,e,rvalue(expr9())); - type= INT; - } - return e; -} - -int -expr9(void) -{ - int e1,e2,t,op; - - e1=expr10(); - while((op=sym)==GT||op==GE||op==LT||op==LE) { - e1=rvalue(e1); - t=type; - getsym(); - e2=rvalue(expr10()); - if(t==INT&&type==INT) - e1=list3(op,e1,e2); - else - e1=list3(op+US,e1,e2); - type= INT; - } - return e1; -} - -int -expr10(void) -{ - int e1,e2,t,op; - - e1=expr11(); - while((op=sym)==RSHIFT||op==LSHIFT) { - e1=rvalue(e1); - t=type; - getsym(); - e2=rvalue(expr11()); - e1=binop(op,e1,e2,t,type); - } - return e1; -} - -int -expr11(void) -{ - int e1,e2,t,op; - - e1=expr12(); - while((op=sym)==ADD||op==SUB) { - e1=rvalue(e1); - t=type; - getsym(); - e2=rvalue(expr12()); - e1=binop(op,e1,e2,t,type); - } - return e1; -} - -int -expr12(void) -{ - int e1,e2,t,op; - - e1=expr13(); - while((op=sym)==MUL||op==DIV||op==MOD) { - e1=rvalue(e1); - t=type; - getsym(); - e2=rvalue(expr13()); - e1=binop(op,e1,e2,t,type); - } - return e1; -} - -int -expr13(void) -{ - int e,op; - - switch (op = sym) { - case INC: case DEC: - getsym(); - lcheck(e=expr13()); - if(type==CHAR) { - type= INT; - return(list2(op==INC?CPREINC:CPREDEC,e)); - } - if(integral(type)) - return(list3(PREINC,e,op==INC?1:-1)); - if(car(type)!=POINTER) - error(TYERR); - return(list3(PREINC,e, - op==INC?size(cadr(type)):-size(cadr(type)) )); - case MUL: - getsym(); - e=rvalue(expr13()); - return(indop(e)); - case BAND: - getsym(); - switch(car(e=expr13())) { - case INDIRECT: - e=cadr(e); - break; - case GVAR: - case LVAR: - e=list2(ADDRESS,e); - break; - case FNAME: - return e; - default:error(LVERR); - } - type=list2(POINTER,type); - return e; - case SUB: - getsym(); - e=rvalue(expr13()); - if(!integral(type)) - error(TYERR); - return(car(e)==CONST?list2(CONST,-cadr(e)):list2(MINUS,e)); - case BNOT: - getsym(); - e=rvalue(expr13()); - if(!integral(type)) - error(TYERR); - return(car(e)==CONST?list2(CONST,~cadr(e)):list2(BNOT,e)); - case LNOT: - getsym(); - return(list2(LNOT,rvalue(expr13()))); - case SIZEOF: - if(getsym()==LPAR) { - if(typeid(getsym())) { - e=list2(CONST,size(typename())); - type=INT; - checksym(RPAR); - return e; - } else { - e=expr0(); - checksym(RPAR); - expr16(e); - if(sym==INC||sym==DEC) { - getsym(); - if(type==CHAR) type=INT; - else if(!scalar(type)) - error(TYERR); - } - } - } else - expr13(); - e=list2(CONST,size(type)); - type=INT; - return e; - } - e=expr14(); - if((op=sym)==INC||op==DEC) { - lcheck(e); - getsym(); - if(type==CHAR) { - type= INT; - return(list2(op==INC?CPOSTINC:CPOSTDEC,e)); - } - if(integral(type)) - return(list3(POSTINC,e,op==INC?1:-1)); - if(car(type)!=POINTER) - error(TYERR); - return (list3(POSTINC,e, - op == INC ? size(cadr(type)): -size(cadr(type)) )); - } - return e; -} - -int -expr14(void) -{ - int e1,t; - - switch(sym) { - case IDENT: - switch(nptr->sc) { - case GVAR: - e1=list3(GVAR,nptr->dsp,(int)nptr->nm); - type=nptr->ty; - getsym(); - break; - case LVAR: - e1=list2(LVAR,nptr->dsp); - type=nptr->ty; - getsym(); - break; - case REGISTER: - e1=list2(REGISTER,nptr->dsp); - type=nptr->ty; - getsym(); - break; - case FLABEL: case BLABEL: - case FUNCTION: case CODE: - e1=list2(FNAME,(int)nptr); - type=list3(nptr->sc,car(nptr->ty),cadr(nptr->ty)); - getsym(); - break; - case EMPTY: - if(getsym()==LPAR) { - nptr->sc = FUNCTION; - nptr->ty= list2(INT,0); - type= list3(FUNCTION,INT,0); - e1=expr15(list2(FNAME,(int)nptr)); - break; - } else { - e1=list2(FNAME,(int)nptr); - type=list3(nptr->sc,nptr->ty,0); - break; - } - default:error(UDERR); - } - break; - case STRING: - e1=list3(STRING,(int)sptr,symval); - type=list3(ARRAY,CHAR,symval); - getsym(); - break; - case CONST: - type= INT; - e1=list2(CONST,symval); - getsym(); - break; - case RETURN: - if (fnptr->sc != FUNCTION) { - error(STERR); - } - type=list2(POINTER,CODE); - e1=list2(RETURN,(int)fnptr); - getsym(); - break; - case ENVIRONMENT: - type=list2(POINTER,INT); - e1=list2(ENVIRONMENT,0); - getsym(); - break; - case LPAR: - if(typeid(getsym())) { - t=typename(); - checksym(RPAR); - e1=expr13(); - type=t; - return e1; - } - e1=expr0(); - checksym(RPAR); - break; - default:error(EXERR); - } - return expr16(e1); -} - -int -expr16(int e1) -{ - int e2,t; - - while(1) { - if(sym==LBRA) { - e1=rvalue(e1); - t=type; - getsym(); - e2=rvalue(expr0()); - checksym(RBRA); - e1=binop(ADD,e1,e2,t,type); - e1=indop(e1); - } else if(sym==LPAR) e1=expr15(e1); - else if(sym==PERIOD) e1=strop(e1); - else if(sym==ARROW) e1=strop(indop(rvalue(e1))); - else break; - } - if(car(e1)==FNAME) type=list2(POINTER,type); - return e1; -} - -int -rvalue(int e) -{ - int t; - if(type==CHAR) { - type= INT; - switch(car(e)) { - case GVAR: - return(list3(CRGVAR,cadr(e),caddr(e))); - case LVAR: - return(list2(CRLVAR,cadr(e))); - case INDIRECT: - return(list2(CRINDIRECT,cadr(e))); - default:return(e); - } - } - if(!integral(type)&&type!=VOID) { - if(type==CODE) { return(e); - } else if((t=car(type))==ARRAY) { - type=list2(POINTER,cadr(type)); - if(car(e)==INDIRECT) return cadr(e); - return list2(ADDRESS,e); - } else if(t==STRUCT || t==UNION) { return e; - } else if(t!=POINTER) error(TYERR); - } - switch(car(e)) { - case GVAR: - return(list3(RGVAR,cadr(e),caddr(e))); - case LVAR: - return(list2(RLVAR,cadr(e))); - case INDIRECT: - return(list2(RINDIRECT,cadr(e))); - default:return(e); - } -} - -void -lcheck(int e) -{ - int t; - if(!scalar(type)|| - (car(e)!=GVAR&&car(e)!=LVAR&&car(e)!=INDIRECT&&car(e)!=REGISTER)) - if ((t=car(type))<0 && t!=STRUCT && t!=UNION) - error(LVERR); -} - -int -indop(int e) -{ - if(type!=INT&&type!=UNSIGNED) { - if(car(type)==POINTER) - type=cadr(type); - else error(TYERR); - } else - type= CHAR; - if(car(e)==ADDRESS) - return(cadr(e)); - return(list2(INDIRECT,e)); -} - -int -strop(int e) -{ - getsym(); - if (sym!=IDENT||nptr->sc!=FIELD) error(TYERR); - if (integral(type)||(car(type)!=STRUCT && car(type)!=UNION)) - e=rvalue(e); - type = nptr->ty; - switch(car(e)) { - case GVAR: - e=list2(INDIRECT,list3(ADD,e,list2(CONST,nptr->dsp))); - break; - case LVAR: - e=list2(car(e),cadr(e) + nptr->dsp); - break; - case INDIRECT: - if(!nptr->dsp) break; - e=list2(INDIRECT,list3(ADD,cadr(e),list2(CONST,nptr->dsp))); - break; - default: - e=list2(INDIRECT,list3(ADD,e,list2(CONST,nptr->dsp))); - } - getsym(); - return e; -} - -int -binop(int op, int e1, int e2, int t1, int t2) -{ - int e; - - if(car(e1)==CONST&&car(e2)==CONST) { - e1=cadr(e1); - e2=cadr(e2); - type= INT; - switch(op) { - case BOR: - e=e1|e2;break; - case EOR: - e=e1^e2;break; - case BAND: - e=e1&e2;break; - case ADD: - if(integral(t1)) { - if(integral(t2)) { - e=e1+e2; - } else { - if(car(t2)!=POINTER) error(TYERR); - e=size(cadr(t2))*e1+e2; - type=t2; - } - } else { - if(car(t1)!=POINTER) error(TYERR); - e=e1+size(cadr(t1))*e2; - type=t1; - } - break; - case SUB: - if(integral(t1)) { - e=e1-e2; - } else { - if(car(t1)!=POINTER) error(TYERR); - e=e1-size(cadr(t1))*e2; - type=t1; - } - break; - case MUL: - e=e1*e2;break; - case DIV: - if(!e2) error(EXERR);e=e1/e2;break; - case MOD: - if(!e2) error(EXERR);e=e1%e2;break; - case RSHIFT: - e=e1>>e2;break; - case LSHIFT: - e=e1<<e2; - } - return list2(CONST,e); - } - if((op==ADD||op==MUL||op==BOR||op==EOR||op==BAND)&& - (car(e1)==CONST||(car(e2)!=CONST&& - (car(e1)==RGVAR||car(e1)==RLVAR)))) { - e=e1;e1=e2;e2=e;e=t1;t1=t2;t2=e; - } - if(op==ADD) { - if(integral(t1)) { - if(integral(t2)) { - if(t1==INT) type=t2;else type=t1; - return(list3(ADD,e1,e2)); - } - if(car(t2)!=POINTER) error(TYERR); - e=binop(MUL,e1,list2(CONST,size(cadr(t2))),t1,INT); - type=t2; - return(list3(ADD,e,e2)); - } - if(car(t1)!=POINTER||!integral(t2)) error(TYERR); - e=binop(MUL,e2,list2(CONST,size(cadr(t1))),t2,INT); - type=t1; - if(car(e1)==ADDRESS&&car(e)==CONST&&car(cadr(e1))!=GVAR) - return(list2(ADDRESS,list2(car(cadr(e1)), - cadr(cadr(e1))+cadr(e)))); - return(list3(ADD,e1,e)); - } - if(op==SUB) { - if(integral(t1)) { - if(!integral(t2)) error(TYERR); - if(t1==INT) type=t2;else type=t1; - return(list3(SUB,e1,e2)); - } - if(car(t1)!=POINTER) error(TYERR); - if(integral(t2)) { - e=binop(MUL,e2,list2(CONST,size(cadr(t1))),t2,INT); - type=t1; - return(list3(SUB,e1,e)); - } - if(car(t2)!=POINTER) - error(TYERR); - compatible(t1,t2); - e=list3(SUB,e1,e2); - e=binop(DIV,e,list2(CONST,size(cadr(t1))),UNSIGNED,INT); - type= INT; - return e; - } - if(!integral(t1)||!integral(t2)) error(TYERR); - if(t1==INT) type=t2;else type=t1; - if((op==MUL||op==DIV)&&car(e2)==CONST&&cadr(e2)==1) return e1; - if(op==BOR||op==EOR||op==BAND) return(list3(op,e1,e2)); - return(list3(type==UNSIGNED?op+US:op,e1,e2)); -} - -int -expr15(int e1) -{ - int t,arglist; - - t=type; - if(integral(t)|| (car(t)!=FUNCTION && car(t)!=CODE)) - error(TYERR); - getsym(); - arglist=0; - while(sym!=RPAR) { - arglist=list2(rvalue(expr1()),arglist); - if(sym!=COMMA) break; - getsym(); - } - checksym(RPAR); - if(car(t)!=CODE) { - t=cadr(t); - if(t==CHAR) type= INT;else type=t; - } - return list3(FUNCTION,e1,arglist); -} - -int -typeid(int s) -{ - return (integral(s) || s==CODE || s==SHORT || s==LONG || s==STRUCT || s==UNION || - (s==IDENT && nptr->sc==TYPE)); -} - -int -typename(void) -{ - int t; - - type=t=typespec(); - ndecl0(); - reverse(t); - return type; -} - -int -ndecl0(void) -{ - if(sym==MUL) { - getsym(); - return type=list2(POINTER,ndecl0()); - } - return ndecl1(); -} - -int -ndecl1(void) -{ - int i,t,arglist; - - if(sym==LPAR) { - if(getsym()==RPAR) { - type=list3(FUNCTION,type,0); getsym(); - } else { - ndecl0(); - checksym(RPAR); - } - } - while(1) { - if(sym==LBRA) { - getsym(); - t=type; - i=cexpr(expr()); - checksym(RBRA); - type=list3(ARRAY,t,i); - } else if(sym==LPAR) { - t = type; - getsym(); - arglist=0; - while(sym!=RPAR) { - ndecl0(); - arglist=list2(type,arglist); - if(sym!=COMMA) break; - getsym(); - } - checksym(RPAR); - type=list3(FUNCTION,t,arglist); - } - else return type; - } -} - -int -cexpr(int e) -{ - if (car(e) != CONST) error(CNERR); - return (cadr(e)); -} - -int -getsym(void) -{ - NMTBL *nptr0,*nptr1; - int i; - char c; - - if (alpha(skipspc())) { - i = hash = 0; - name = namebuf; - while (alpha(ch) || digit(ch)) { - if (i < LBUFSIZE-1) - hash=(7*hash ^ (name[i++]=ch)); - getch(); - } - name[i++] = '\0'; - nptr0 = gsearch(); - if (nptr0->sc == RESERVE) return sym = nptr0->dsp; - if (nptr0->sc == MACRO && !mflag) { - mflag++; - chsave = ch; - chptrsave = chptr; - chptr = (char *)nptr0->dsp; - getch(); - return getsym(); - } - sym = IDENT; - gnptr=nptr=nptr0; - if (mode==ADECL && nptr0->sc ==TYPE) return sym; - if (mode==GDECL || mode==GSDECL || mode==GUDECL || - mode==GTDECL || mode==TOP) { - return sym; - } - nptr1=lsearch(nptr0->nm); - if (mode==STAT) - if (nptr1->sc == EMPTY) return sym; - else { nptr=nptr1; return sym;} - nptr=nptr1; - return sym; - } else if (digit(ch)) { - symval=0; - if (ch == '0') { - if (getch() == 'x' || ch == 'X') { - while(1) { - if(digit(getch())) - symval=symval*16+ch-'0'; - else if('a'<=ch&&ch<='f') - symval=symval*16+ch-'a'+10; - else if('A'<=ch&&ch<='F') - symval=symval*16+ch-'A'+10; - else break; - } - } else { - while (digit(ch)) { - symval=symval*8+ch-'0';getch(); - } - } - } else { - while(digit(ch)) { - symval=symval*10+ch-'0';getch(); - } - } - return sym=CONST; - } else if(ch=='\'') { - getch(); - symval=escape(); - if(ch!='\'') error(CHERR); - getch(); - return sym=CONST; - } else if(ch=='"') { - getstring(); - return sym= STRING; - } - c=ch; - getch(); - switch(c) { - case '*': - return postequ(MUL,MUL+AS); - case '&': - if(ch=='&') {getch();return sym=LAND;} - return postequ(BAND,BAND+AS); - case '-': - if(ch=='>') {getch();return sym=ARROW;} - if(ch=='-') {getch();return sym=DEC;} - return postequ(SUB,SUB+AS); - case '!': - return postequ(LNOT,NEQ); - case '~': - return sym=BNOT; - case '+': - if(ch=='+') {getch();return sym=INC;} - return postequ(ADD,ADD+AS); - case '%': - return postequ(MOD,MOD+AS); - case '^': - return postequ(EOR,EOR+AS); - case '|': - if(ch=='|') {getch();return sym=LOR;} - return postequ(BOR,BOR+AS); - case '=': - return postequ(ASS,EQ); - case '>': - if(ch=='>') {getch();return postequ(RSHIFT,RSHIFT+AS);} - return postequ(GT,GE); - case '<': - if(ch=='<') {getch();return postequ(LSHIFT,LSHIFT+AS);} - return postequ(LT,LE); - case '(': - return sym=LPAR; - case ')': - return sym=RPAR; - case '[': - return sym=LBRA; - case ']': - return sym=RBRA; - case '{': - return sym=LC; - case '}': - return sym=RC; - case ',': - return sym=COMMA; - case ';': - return sym=SM; - case ':': - return sym=COLON; - case '?': - return sym=COND; - case '.': - if(ch=='.') { - getch(); - if (ch=='.') { - getch(); - return sym=DOTS; - } - error(CHERR); - return getsym(); - } else - return sym=PERIOD; - case '/': - if(ch!='*') return postequ(DIV,DIV+AS); - getch(); - while(ch=='*'?getch()!='/':getch()); - getch(); - return getsym(); - default: - error(CHERR); - return getsym(); - } -} - -int -postequ(int s1, int s2) -{ - if(ch=='=') {getch();return sym=s2;} - return sym=s1; -} - -int -alpha(char c) -{ - return(('a'<=c&&c<='z')||('A'<=c&&c<='Z')||c=='_'); -} - -int -digit(char c) -{ - return('0'<=c&&c<='9'); -} - - -NMTBL * -gsearch(void) -{ - NMTBL *nptr,*iptr; - - iptr=nptr= &ntable[hash % GSYMS]; - while(nptr->sc!=0 && neqname(nptr->nm)) { - if (++nptr== &ntable[GSYMS]) - nptr=ntable; - if (nptr==iptr) error(GSERR); - } - if (nptr->sc == 0) { - copy(nptr,name); - nptr->sc=EMPTY; - } - return nptr; -} - -NMTBL * -lsearch(char *name) -{ - NMTBL *nptr,*iptr; - - iptr=nptr= &ntable[hash%LSYMS+GSYMS]; - while(nptr->sc!=0 && neqname(nptr->nm)) { - if (++nptr== &ntable[LSYMS+GSYMS]) - nptr= &ntable[GSYMS]; - if (nptr==iptr) error(LSERR); - } - if (nptr->sc == 0) { - nptr->nm=name; /* already saved in gsearch */ - nptr->sc=EMPTY; - nptr->dsp=0; - } - return nptr; -} - -void -copy(NMTBL *nptr, char *s) -{ - nptr->nm = cheapp; - while(*cheapp++ = *s++); -} - -int -neqname(char *p) -{ - char *q; - - if (!p) - return 0; - q=name; - while(*p && *p!='.') - if(*p++ != *q++) return 1; - return (*q!=0); -} - -void -getstring(void) -{ - getch(); - symval = 0; - sptr = cheapp; - while (ch != '"') { - *cheapp++ = escape(); - symval++; - if (cheapp >= cheap+CHEAPSIZE) error(STRERR); - } - getch(); - *cheapp++ = '\0'; - symval++; -} - -int -skipspc(void) -{ - while(ch=='\t'||ch=='\n'||ch==' '||ch=='\r') - getch(); - return ch; -} - -int -getch(void) -{ - if(*chptr) return ch= *chptr++; - if(mflag) { - mflag=0;chptr=chptrsave;return ch=chsave; - } - getline(); - return getch(); -} - -char -escape(void) -{ - char c; - if ((c=ch) == '\\') { - if (digit(c=getch())) { - c = ch-'0'; - if (digit(getch())) { - c = c*8+ch-'0'; - if (digit(getch())) { - c=c*8+ch-'0';getch(); - } - } - return c; - } - getch(); - switch(c) { - case 'n': - return '\n'; - case 't': - return '\t'; - case 'b': - return '\b'; - case 'r': - return '\r'; - case 'f': - return '\f'; - case '\n': - return escape(); - default: - return c; - } - } - if (c == '\n') error(EXERR); - getch(); - return c; -} - -FILE * -getfname(void) -{ - int i; - char name[LBUFSIZE]; - FILE *fp; - - getch(); - if(skipspc()!='"') error(INCERR); - for(i=0;(getch()!='"' && ch!='\n');) { - if(i<LBUFSIZE-1) name[i++]=ch; - } - if(ch=='\n') error(INCERR); - name[i]=0; - fp = fopen(name,"r") ; - return ( (filep+1)->fcb = fp ); -} - -void -getline(void) -{ - int i; - int c; - - lineno++; - glineno++; - chptr=linebuf; - i=0; - /* while ((*chptr++ = c = getc(filep->fcb)) != '\n') { - we cannot handle unsaved register in library call - so make it easy for the compiler - */ - while ((c=getc(filep->fcb)),(*chptr++=c)!='\n') { - if (++i > LBUFSIZE-2) error(LNERR); - if (c==EOF) { - error(EOFERR); - --chptr; - } - } - *chptr = '\0'; - if (lsrc && !asmf) gen_comment(linebuf); - if (*(chptr = linebuf) == '#') { - ++chptr; - if (macroeq("define")) { - i=mode; - mode=GDECL; - ch= *chptr; - if (getsym() == IDENT) { - if (nptr->sc == EMPTY) { - nptr->sc = MACRO; - nptr->dsp = (int)cheapp; - while ((*cheapp++ = c = *chptr++) - && c != '\n'); - *cheapp++ = '\0'; - if (cheapp >= cheap+CHEAPSIZE) - error(STRERR); - if (!c) error(EOFERR); - } else error(MCERR); - } else error(MCERR); - mode=i; - *(chptr = linebuf) = '\0'; - } else if (macroeq("include")) { - if(filep+1 >= filestack + FILES) error(FILERR); - if ( ((filep+1)->fcb=getfname()) == NULL) error(FILERR); - (filep+1)->ln=lineno; - lineno=0; - ++filep; - *(chptr = linebuf) = '\0'; - } else if (macroeq("asm")) { - if (asmf) error(MCERR); - asmf = 1; - getline(); - while (asmf) { - gen_source(linebuf); - getline(); - } - } else if (macroeq("endasm")) { - if (!asmf) error(MCERR); - asmf = 0; - } else if (macroeq(" ")) - getline(); - else error(MCERR); - } -} - -int -macroeq(char *s) -{ - char *p; - - for (p = chptr; *s;) if (*s++ != *p++) return 0; - chptr = p; - return 1; -} - -int -car(int e) -{ - return heap[e]; -} - -int -cadr(int e) -{ - return heap[e+1]; -} - -int -caddr(int e) -{ - return heap[e+2]; -} - -int -cadddr(int e) -{ - return heap[e+3]; -} - -int -list2(int e1, int e2) -{ - int e; - - e=getfree(2); - heap[e]=e1; - heap[e+1]=e2; - return e; -} - -int -list3(int e1, int e2, int e3) -{ - int e; - - e=getfree(3); - heap[e]=e1; - heap[e+1]=e2; - heap[e+2]=e3; - return e; -} - -int -list4(int e1, int e2, int e3, int e4) -{ - int e; - - e=getfree(4); - heap[e]=e1; - heap[e+1]=e2; - heap[e+2]=e3; - heap[e+3]=e4; - return e; -} - -int -getfree(int n) -{ - int e; - - switch (mode) { - case GDECL: case GSDECL: case GUDECL: case GTDECL: - e=gfree; - gfree+=n; - break; - default: - lfree-=n; - e=lfree; - } - if(lfree<gfree) error(HPERR); - return e; -} - -int -rplacad(int e, int n) -{ - heap[e+1]=n; - return e; -} - -int -rplacadd(int e, int n) -{ - heap[e+2]=n; - return e; -} - -display_ntable(NMTBL *n, char *s) -{ - fprintf(stderr,"\n%s %0x %0x ",s,n,ntable); - fprintf(stderr,"nptr->sc %d ",n->sc); - fprintf(stderr,"nptr->dsp %d ",n->dsp); - fprintf(stderr,"nptr->ty %d ",n->ty); - fprintf(stderr,"nptr->nm %s\n",n->nm); -} - -/* end */
--- a/ansi/mc-tree.c Fri Jan 14 12:10:42 2000 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,178 +0,0 @@ -#define EXTERN /**/ -#include "mc.h" - -typedef -struct tree_node { - int tree_type; - char *tree_name; - char *tree_args; -} tree_node_type; - -tree_node_type tree_nodes[] = { - {(-1),"INT",""}, - {(-2),"CHAR",""}, - {(-3),"UNSIGNED",""}, - {(-4),"POINTER","t"}, - {(-5),"ARRAY","tv"}, - {(-6),"STRUCT","vt"}, - {(-7),"UNION",""}, - {(-8),"FUNCTION","t"}, - {(-9),"EMPTY",""}, - {(-10),"STATIC",""}, - {(-11),"GOTO",""}, - {(-12),"RETURN",""}, - {(-13),"BREAK",""}, - {(-14),"CONTINUE",""}, - {(-15),"IF",""}, - {(-16),"ELSE",""}, - {(-17),"FOR",""}, - {(-18),"DO",""}, - {(-19),"WHILE",""}, - {(-20),"SWITCH",""}, - {(-21),"CASE",""}, - {(-22),"DEFAULT",""}, - {(-23),"RESERVE",""}, - {(-24),"TAG",""}, - {(-25),"FIELD",""}, - {(-26),"IDENT",""}, - {(-27),"STRING",""}, - {(-28),"MACRO",""}, - {(-29),"BLABEL",""}, - {(-30),"FLABEL",""}, - {(-31),"TYPEDEF",""}, - {(-32),"SIZEOF",""}, - {(-33),"TYPE",""}, - {(-34),"LONG",""}, - {(-35),"SHORT",""}, - {(-36),"EXTERN",""}, - {(-37),"REGISTER",""}, - {(-38),"CODE",""}, - {1,"GVAR","vs"}, - {2,"RGVAR","vs"}, - {3,"CRGVAR","vs"}, - {4,"LVAR","v"}, - {5,"RLVAR","v"}, - {6,"CRLVAR","v"}, - {7,"CONST","v"}, - {8,"FNAME","n"}, - {9,"INDIRECT","e"}, - {10,"RINDIRECT","e"}, - {11,"CRINDIRECT","e"}, - {12,"ADDRESS","e"}, - {13,"MINUS","e"}, - {14,"LNOT","e"}, - {15,"BNOT","e"}, - {16,"INC",""}, - {17,"POSTINC","e"}, - {18,"PREINC","e"}, - {19,"CPOSTINC","e"}, - {20,"CPREINC","e"}, - {21,"DEC",""}, - {22,"CPOSTDEC","e"}, - {23,"CPREDEC","e"}, - {24,"MUL","ee"}, - {25,"UMUL","ee"}, - {26,"DIV","ee"}, - {27,"UDIV","ee"}, - {28,"MOD","ee"}, - {29,"UMOD","ee"}, - {30,"ADD","ee"}, - {31,"SUB","ee"}, - {32,"RSHIFT","ee"}, - {33,"URSHIFT","ee"}, - {34,"LSHIFT","ee"}, - {35,"ULSHIFT","ee"}, - {36,"GT","ee"}, - {37,"UGT","ee"}, - {38,"GE","ee"}, - {39,"UGE","ee"}, - {40,"LT","ee"}, - {41,"ULT","ee"}, - {42,"LE","ee"}, - {43,"ULE","ee"}, - {44,"EQ","ee"}, - {45,"NEQ","ee"}, - {46,"BAND","ee"}, - {47,"EOR","ee"}, - {48,"BOR","ee"}, - {49,"LAND","ee"}, - {50,"LOR","ee"}, - {51,"COND","eee"}, - {52,"ASS","ee"}, - {53,"CASS","ee"}, - {54,"ASSOP","eev"}, - {55,"CASSOP","eev"}, - {56,"COMMA","ee"}, - {57,"LPAR",""}, - {58,"RPAR",""}, - {59,"LBRA",""}, - {60,"RBRA",""}, - {61,"LC",""}, - {62,"RC",""}, - {63,"COLON","ee"}, - {64,"SM",""}, - {65,"PERIOD",""}, - {66,"ARROW",""}, - {66,"CNAME",""}, - {100,"AS",""} -}; - -tree_print(e) - int e; -{ - printf("* generate code on type:\n* "); - tree_parse(type); - printf("\n* expr:\n* "); - tree_parse(e); - printf("\n"); -} - -int tree_level; - -tree_parse(e) - int e; -{ - tree_node_type *t; - int i,j; - char *s; - - if(e<0) { - for(t=tree_nodes;t->tree_type!=100;t++) { - if(t->tree_type==e) { - for(j=0;j<tree_level;j++) putchar(' '); - printf("list(%s)",t->tree_name); - break; - } - } - } else { - i = car(e); - for(t=tree_nodes;t->tree_type!=100;t++) { - if(t->tree_type==i) { - tree_level++; - for(j=0;j<tree_level;j++) putchar(' '); - printf("list(%s",t->tree_name); - for(i=1,s=t->tree_args;*s;s++,i++) { - switch(*s) { - case 'e': - case 't': - printf(",\n*"); - tree_parse(heap[e+i]); break; - case 'v': - printf(",%d",heap[e+i]); break; - case 'n': - printf(",%s",((NMTBL *)heap[e+i])->nm); break; - case 's': - printf(",%s",heap[e+i]); break; - case 'i': - printf(",%d",heap[e+i]); break; - } - } - tree_level--; - printf(")"); - break; - } - } - } -} - -
--- a/ansi/mc-tree.c.save Fri Jan 14 12:10:42 2000 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,176 +0,0 @@ -#define EXTERN /**/ -#include "mc.h" - -typedef -struct tree_node { - int tree_type; - char *tree_name; - char *tree_args; -} tree_node_type; - -tree_node_type tree_nodes[] = { - {(-1),"INT",""}, - {(-2),"CHAR",""}, - {(-3),"UNSIGNED",""}, - {(-4),"POINTER","t"}, - {(-5),"ARRAY","tv"}, - {(-6),"STRUCT","vt"}, - {(-7),"UNION",""}, - {(-8),"FUNCTION","t"}, - {(-9),"EMPTY",""}, - {(-10),"STATIC",""}, - {(-11),"GOTO",""}, - {(-12),"RETURN",""}, - {(-13),"BREAK",""}, - {(-14),"CONTINUE",""}, - {(-15),"IF",""}, - {(-16),"ELSE",""}, - {(-17),"FOR",""}, - {(-18),"DO",""}, - {(-19),"WHILE",""}, - {(-20),"SWITCH",""}, - {(-21),"CASE",""}, - {(-22),"DEFAULT",""}, - {(-23),"RESERVE",""}, - {(-24),"TAG",""}, - {(-25),"FIELD",""}, - {(-26),"IDENT",""}, - {(-27),"STRING",""}, - {(-28),"MACRO",""}, - {(-29),"BLABEL",""}, - {(-30),"FLABEL",""}, - {(-31),"TYPEDEF",""}, - {(-32),"SIZEOF",""}, - {(-33),"TYPE",""}, - {(-34),"LONG",""}, - {(-35),"SHORT",""}, - {(-36),"EXTERN",""}, - {(-37),"REGISTER",""}, - {(-38),"CODE",""}, - {1,"GVAR","vs"}, - {2,"RGVAR","vs"}, - {3,"CRGVAR","vs"}, - {4,"LVAR","v"}, - {5,"RLVAR","v"}, - {6,"CRLVAR","v"}, - {7,"CONST","v"}, - {8,"FNAME","n"}, - {9,"INDIRECT","e"}, - {10,"RINDIRECT","e"}, - {11,"CRINDIRECT","e"}, - {12,"ADDRESS","e"}, - {13,"MINUS","e"}, - {14,"LNOT","e"}, - {15,"BNOT","e"}, - {16,"INC",""}, - {17,"POSTINC","e"}, - {18,"PREINC","e"}, - {19,"CPOSTINC","e"}, - {20,"CPREINC","e"}, - {21,"DEC",""}, - {22,"CPOSTDEC","e"}, - {23,"CPREDEC","e"}, - {24,"MUL","ee"}, - {25,"UMUL","ee"}, - {26,"DIV","ee"}, - {27,"UDIV","ee"}, - {28,"MOD","ee"}, - {29,"UMOD","ee"}, - {30,"ADD","ee"}, - {31,"SUB","ee"}, - {32,"RSHIFT","ee"}, - {33,"URSHIFT","ee"}, - {34,"LSHIFT","ee"}, - {35,"ULSHIFT","ee"}, - {36,"GT","ee"}, - {37,"UGT","ee"}, - {38,"GE","ee"}, - {39,"UGE","ee"}, - {40,"LT","ee"}, - {41,"ULT","ee"}, - {42,"LE","ee"}, - {43,"ULE","ee"}, - {44,"EQ","ee"}, - {45,"NEQ","ee"}, - {46,"BAND","ee"}, - {47,"EOR","ee"}, - {48,"BOR","ee"}, - {49,"LAND","ee"}, - {50,"LOR","ee"}, - {51,"COND","eee"}, - {52,"ASS","ee"}, - {53,"CASS","ee"}, - {54,"ASSOP","eev"}, - {55,"CASSOP","eev"}, - {56,"COMMA","ee"}, - {57,"LPAR",""}, - {58,"RPAR",""}, - {59,"LBRA",""}, - {60,"RBRA",""}, - {61,"LC",""}, - {62,"RC",""}, - {63,"COLON","ee"}, - {64,"SM",""}, - {65,"PERIOD",""}, - {66,"ARROW",""}, - {66,"CNAME",""}, - {100,"AS",""} -}; - -tree_print(int e) -{ - printf("* generate code on type:\n* "); - tree_parse(type); - printf("\n* expr:\n* "); - tree_parse(e); - printf("\n"); -} - -int tree_level; - -tree_parse(int e) -{ - tree_node_type *t; - int i,j; - char *s; - - if(e<0) { - for(t=tree_nodes;t->tree_type!=100;t++) { - if(t->tree_type==e) { - for(j=0;j<tree_level;j++) putchar(' '); - printf("list(%s)",t->tree_name); - break; - } - } - } else { - i = car(e); - for(t=tree_nodes;t->tree_type!=100;t++) { - if(t->tree_type==i) { - tree_level++; - for(j=0;j<tree_level;j++) putchar(' '); - printf("list(%s",t->tree_name); - for(i=1,s=t->tree_args;*s;s++,i++) { - switch(*s) { - case 'e': - case 't': - printf(",\n*"); - tree_parse(heap[e+i]); break; - case 'v': - printf(",%d",heap[e+i]); break; - case 'n': - printf(",%s",((NMTBL *)heap[e+i])->nm); break; - case 's': - printf(",%s",heap[e+i]); break; - case 'i': - printf(",%d",heap[e+i]); break; - } - } - tree_level--; - printf(")"); - break; - } - } - } -} - -
--- a/ansi/mc.h Fri Jan 14 12:10:42 2000 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,195 +0,0 @@ -/* Micro-C header file */ - -#define DEBUG error(-1) - -/*#include "CCLIB.TXT" */ -#include "stdio.h" - -#define SIZE_INT 4 - -#define INT (-1) -#define CHAR (-2) -#define UNSIGNED (-3) -#define POINTER (-4) -#define ARRAY (-5) -#define STRUCT (-6) -#define UNION (-7) -#define FUNCTION (-8) -#define EMPTY (-9) - -#define STATIC (-10) -#define GOTO (-11) -#define RETURN (-12) -#define BREAK (-13) -#define CONTINUE (-14) -#define IF (-15) -#define ELSE (-16) -#define FOR (-17) -#define DO (-18) -#define WHILE (-19) -#define SWITCH (-20) -#define CASE (-21) -#define DEFAULT (-22) -#define RESERVE (-23) -#define TAG (-24) -#define FIELD (-25) -#define IDENT (-26) -#define STRING (-27) -#define MACRO (-28) -#define BLABEL (-29) -#define FLABEL (-30) -#define TYPEDEF (-31) -#define SIZEOF (-32) -#define TYPE (-33) -#define LONG (-34) -#define SHORT (-35) -#define EXTRN (-36) -#define VOID (-37) -#define REGISTER (-38) -#define CODE (-39) -#define ENVIRONMENT (-40) - -#define TOP 0 -#define GDECL 1 -#define GSDECL 2 -#define GUDECL 3 -#define ADECL 4 -#define LDECL 5 -#define LSDECL 6 -#define LUDECL 7 -#define STADECL 8 -#define STAT 9 -#define GTDECL 10 -#define LTDECL 11 - -#define GVAR 1 -#define RGVAR 2 -#define CRGVAR 3 -#define LVAR 4 -#define RLVAR 5 -#define CRLVAR 6 -#define CONST 7 -#define FNAME 8 -#define INDIRECT 9 -#define RINDIRECT 10 -#define CRINDIRECT 11 -#define ADDRESS 12 -#define MINUS 13 -#define LNOT 14 -#define BNOT 15 -#define INC 16 -#define POSTINC 17 -#define PREINC 18 -#define CPOSTINC 19 -#define CPREINC 20 -#define DEC 21 -#define CPOSTDEC 22 -#define CPREDEC 23 -#define MUL 24 -#define UMUL 25 -#define DIV 26 -#define UDIV 27 -#define MOD 28 -#define UMOD 29 -#define ADD 30 -#define SUB 31 -#define RSHIFT 32 -#define URSHIFT 33 -#define LSHIFT 34 -#define ULSHIFT 35 -#define GT 36 -#define UGT 37 -#define GE 38 -#define UGE 39 -#define LT 40 -#define ULT 41 -#define LE 42 -#define ULE 43 -#define EQ 44 -#define NEQ 45 -#define BAND 46 -#define EOR 47 -#define BOR 48 -#define LAND 49 -#define LOR 50 -#define COND 51 -#define ASS 52 -#define CASS 53 -#define ASSOP 54 -#define CASSOP 55 -#define COMMA 56 -#define LPAR 57 -#define RPAR 58 -#define LBRA 59 -#define RBRA 60 -#define LC 61 -#define RC 62 -#define COLON 63 -#define SM 64 -#define PERIOD 65 -#define ARROW 66 -#define CNAME 67 -#define SASS 68 -#define DOTS 69 - -#define US 1 -#define AS 100 - -#define FILERR 1 -#define DCERR 2 -#define STERR 3 -#define EXERR 4 -#define CNERR 5 -#define CHERR 6 -#define GSERR 7 -#define LSERR 8 -#define STRERR 9 -#define LNERR 10 -#define EOFERR 11 -#define MCERR 12 -#define INCERR 13 -#define HPERR 14 -#define TYERR 15 -#define LVERR 16 -#define UDERR 17 -#define OPTION 18 -#define REG_ERR 19 -#define CODE_ERR 20 - -#define GSYMS 9000 -#define LSYMS 500 - -#define HEAPSIZE 10000 -/* #define CHEAPSIZE 3000 */ -#define CHEAPSIZE 256000 -#define LBUFSIZE 4096 - -#define FILES 3 -#define OUTPUT_FILE_NAME "mcout.s" - -EXTERN int sym,ch,chsave,type,mode,stmode,gfree,lfree,mflag,lineno,glineno; -EXTERN int labelno,gpc,disp,reg_var,debug; -EXTERN int symval,args,init_vars,heap[HEAPSIZE]; -EXTERN int blabel,clabel,dlabel,cslabel,ilabel,control,ac,ac2,lsrc,chk,asmf; -EXTERN int MAX_REGISTER_VAR; - -EXTERN unsigned hash; - -EXTERN char linebuf[LBUFSIZE],namebuf[LBUFSIZE],*chptr,*chptrsave; -EXTERN char *name,*cheapp,**av,/*obuf[320],*/*sptr,escape(); -EXTERN int arg_offset,stat_no,int_size,disp_offset,endian,csvalue,csvalue1; -EXTERN int code_arg_offset; -EXTERN int retlabel,retpending,retcont; - -EXTERN FILE *obuf; - -typedef struct nametable { - char *nm; - int sc,ty,dsp; } NMTBL; - -EXTERN NMTBL ntable[GSYMS+LSYMS],*nptr,*gnptr,*decl0(),*decl1(),*lsearch(),*gsearch(); -EXTERN NMTBL *fnptr; - -EXTERN struct {int fd,ln;/*char fcb[320]*/FILE *fcb;} *filep,filestack[FILES]; -EXTERN char cheap[CHEAPSIZE]; -
--- a/ansi/mc.h.save Fri Jan 14 12:10:42 2000 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,195 +0,0 @@ -/* Micro-C header file */ - -#define DEBUG error(-1) - -/*#include "CCLIB.TXT" */ -#include "stdio.h" - -#define SIZE_INT 4 - -#define INT (-1) -#define CHAR (-2) -#define UNSIGNED (-3) -#define POINTER (-4) -#define ARRAY (-5) -#define STRUCT (-6) -#define UNION (-7) -#define FUNCTION (-8) -#define EMPTY (-9) - -#define STATIC (-10) -#define GOTO (-11) -#define RETURN (-12) -#define BREAK (-13) -#define CONTINUE (-14) -#define IF (-15) -#define ELSE (-16) -#define FOR (-17) -#define DO (-18) -#define WHILE (-19) -#define SWITCH (-20) -#define CASE (-21) -#define DEFAULT (-22) -#define RESERVE (-23) -#define TAG (-24) -#define FIELD (-25) -#define IDENT (-26) -#define STRING (-27) -#define MACRO (-28) -#define BLABEL (-29) -#define FLABEL (-30) -#define TYPEDEF (-31) -#define SIZEOF (-32) -#define TYPE (-33) -#define LONG (-34) -#define SHORT (-35) -#define EXTRN (-36) -#define VOID (-37) -#define REGISTER (-38) -#define CODE (-39) -#define ENVIRONMENT (-40) - -#define TOP 0 -#define GDECL 1 -#define GSDECL 2 -#define GUDECL 3 -#define ADECL 4 -#define LDECL 5 -#define LSDECL 6 -#define LUDECL 7 -#define STADECL 8 -#define STAT 9 -#define GTDECL 10 -#define LTDECL 11 - -#define GVAR 1 -#define RGVAR 2 -#define CRGVAR 3 -#define LVAR 4 -#define RLVAR 5 -#define CRLVAR 6 -#define CONST 7 -#define FNAME 8 -#define INDIRECT 9 -#define RINDIRECT 10 -#define CRINDIRECT 11 -#define ADDRESS 12 -#define MINUS 13 -#define LNOT 14 -#define BNOT 15 -#define INC 16 -#define POSTINC 17 -#define PREINC 18 -#define CPOSTINC 19 -#define CPREINC 20 -#define DEC 21 -#define CPOSTDEC 22 -#define CPREDEC 23 -#define MUL 24 -#define UMUL 25 -#define DIV 26 -#define UDIV 27 -#define MOD 28 -#define UMOD 29 -#define ADD 30 -#define SUB 31 -#define RSHIFT 32 -#define URSHIFT 33 -#define LSHIFT 34 -#define ULSHIFT 35 -#define GT 36 -#define UGT 37 -#define GE 38 -#define UGE 39 -#define LT 40 -#define ULT 41 -#define LE 42 -#define ULE 43 -#define EQ 44 -#define NEQ 45 -#define BAND 46 -#define EOR 47 -#define BOR 48 -#define LAND 49 -#define LOR 50 -#define COND 51 -#define ASS 52 -#define CASS 53 -#define ASSOP 54 -#define CASSOP 55 -#define COMMA 56 -#define LPAR 57 -#define RPAR 58 -#define LBRA 59 -#define RBRA 60 -#define LC 61 -#define RC 62 -#define COLON 63 -#define SM 64 -#define PERIOD 65 -#define ARROW 66 -#define CNAME 67 -#define SASS 68 -#define DOTS 69 - -#define US 1 -#define AS 100 - -#define FILERR 1 -#define DCERR 2 -#define STERR 3 -#define EXERR 4 -#define CNERR 5 -#define CHERR 6 -#define GSERR 7 -#define LSERR 8 -#define STRERR 9 -#define LNERR 10 -#define EOFERR 11 -#define MCERR 12 -#define INCERR 13 -#define HPERR 14 -#define TYERR 15 -#define LVERR 16 -#define UDERR 17 -#define OPTION 18 -#define REG_ERR 19 -#define CODE_ERR 20 - -#define GSYMS 9000 -#define LSYMS 500 - -#define HEAPSIZE 10000 -/* #define CHEAPSIZE 3000 */ -#define CHEAPSIZE 256000 -#define LBUFSIZE 4096 - -#define FILES 3 -#define OUTPUT_FILE_NAME "mcout.s" - -EXTERN int sym,ch,chsave,type,mode,stmode,gfree,lfree,mflag,lineno,glineno; -EXTERN int labelno,gpc,disp,reg_var,debug; -EXTERN int symval,args,init_vars,heap[HEAPSIZE]; -EXTERN int blabel,clabel,dlabel,cslabel,ilabel,control,ac,ac2,lsrc,chk,asmf; -EXTERN int MAX_REGISTER_VAR; - -EXTERN unsigned hash; - -EXTERN char linebuf[LBUFSIZE],namebuf[LBUFSIZE],*chptr,*chptrsave; -EXTERN char *name,*cheapp,**av,/*obuf[320],*/*sptr,escape(void); -EXTERN int arg_offset,stat_no,int_size,disp_offset,endian,csvalue,csvalue1; -EXTERN int code_arg_offset; -EXTERN int retlabel,retpending,retcont; - -EXTERN FILE *obuf; - -typedef struct nametable { - char *nm; - int sc,ty,dsp; } NMTBL; - -EXTERN NMTBL ntable[GSYMS+LSYMS],*nptr,*gnptr,*decl0(void),*decl1(void),*lsearch(char *name),*gsearch(void); -EXTERN NMTBL *fnptr; - -EXTERN struct {int fd,ln;/*char fcb[320]*/FILE *fcb;} *filep,filestack[FILES]; -EXTERN char cheap[CHEAPSIZE]; -
--- a/ansi/stdio.h Fri Jan 14 12:10:42 2000 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,89 +0,0 @@ -#define const - -typedef struct { - /* this is all wrong, but so what? */ - char pad[96]; -} FILE; - - -extern FILE __sstdin; -extern FILE __sstdout; -extern FILE __sstderr; - -#define stdin (&__sstdin) -#define stdout (&__sstdout) -#define stderr (&__sstderr) -#define BUFSIZ 1024 /* size of buffer used by setbuf */ -#define EOF (-1) -#define NULL 0 - -typedef int size_t; -typedef /*long*/ int fpos_t; -typedef void *__gnuc_va_list; - -void clearerr(); -int fclose(); -int feof(); -int ferror(); -int fflush(); -int fgetc(); -int fgetpos(); -int fileno(); -void flockfile(); -int fprintf(); -int fpurge(); -int fputc(); -int fputs(); -size_t fread(); -int fscanf(); -/* int fseek(FILE *, long int, int); */ -int fsetpos(); -long ftell(); -int ftrylockfile(); -void funlockfile(); -size_t fwrite(); -int getc(); -int getc_unlocked(); -int getchar(); -int getchar_unlocked(); -int getw(); -int pclose(); -void perror(); -int printf(); -int putc(); -int putc_unlocked(); -int putchar(); -int putchar_unlocked(); -int puts(); -int putw(); -int remove(); -int rename (); -void rewind(); -int scanf(); -void setbuf(); -void setbuffer(); -int setlinebuf(); -int setvbuf(); -int snprintf(); -int sprintf(); -int sscanf(); -int ungetc(); -int vfprintf(); -int vfscanf(); -int vprintf(); -int vscanf(); -int vsnprintf(); -int vsprintf(); -int vsscanf(); -char *ctermid(); -FILE *fdopen(); -char *fgetln(); -char *fgets(); -FILE *fopen(); -FILE *freopen(); -FILE *funopen(); -char *gets(); -FILE *popen(); -char *tempnam(); -FILE *tmpfile(); -char *tmpnam();
--- a/ansi/stdio.h.save Fri Jan 14 12:10:42 2000 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,89 +0,0 @@ -#define const - -typedef struct { - /* this is all wrong, but so what? */ - char pad[96]; -} FILE; - - -extern FILE __sstdin; -extern FILE __sstdout; -extern FILE __sstderr; - -#define stdin (&__sstdin) -#define stdout (&__sstdout) -#define stderr (&__sstderr) -#define BUFSIZ 1024 /* size of buffer used by setbuf */ -#define EOF (-1) -#define NULL 0 - -typedef int size_t; -typedef /*long*/ int fpos_t; -typedef void *__gnuc_va_list; - -void clearerr(FILE *); -int fclose(FILE *); -int feof(FILE *); -int ferror(FILE *); -int fflush(FILE *); -int fgetc(FILE *); -int fgetpos(FILE *, fpos_t *); -int fileno(FILE *); -void flockfile(); -int fprintf(FILE *, const char *, ...); -int fpurge(); -int fputc(int, FILE *); -int fputs(const char *, FILE *); -size_t fread(void *, size_t, size_t, FILE *); -int fscanf(FILE *, const char *, ...); -/* int fseek(FILE *, long int, int); */ -int fsetpos(FILE *, const fpos_t *); -long ftell(FILE *); -int ftrylockfile(); -void funlockfile(); -size_t fwrite(const void *, size_t, size_t, FILE *); -int getc(FILE *); -int getc_unlocked(); -int getchar(void); -int getchar_unlocked(); -int getw(FILE *); -int pclose(FILE *); -void perror(const char *); -int printf(const char *, ...); -int putc(int, FILE *); -int putc_unlocked(); -int putchar(int); -int putchar_unlocked(); -int puts(const char *); -int putw(int, FILE *); -int remove(const char *); -int rename (const char *, const char *); -void rewind(FILE *); -int scanf(const char *, ...); -void setbuf(FILE *, char *); -void setbuffer(); -int setlinebuf(); -int setvbuf(FILE *, char *, int, size_t); -int snprintf(); -int sprintf(char *, const char *, ...); -int sscanf(const char *, const char *, ...); -int ungetc(int, FILE *); -int vfprintf(FILE *, const char *, __gnuc_va_list); -int vfscanf(); -int vprintf(const char *, __gnuc_va_list); -int vscanf(); -int vsnprintf(); -int vsprintf(char *, const char *, __gnuc_va_list); -int vsscanf(); -char *ctermid(char *); -FILE *fdopen(int, const char *); -char *fgetln(); -char *fgets(char *, int, FILE *); -FILE *fopen(const char *, const char *); -FILE *freopen(const char *, const char *, FILE *); -FILE *funopen(); -char *gets(char *); -FILE *popen(const char *, const char *); -char *tempnam(const char *, const char *); -FILE *tmpfile(void); -char *tmpnam(char *);