Mercurial > hg > CbC > old > device
changeset 561:de0b0380c461
comments
author | kono |
---|---|
date | Sat, 07 Jan 2006 19:46:27 +0900 |
parents | d6ff45d719a5 |
children | 0a156c491f81 |
files | Changes Makefile mc-inline.c mc-macro.c mc-parse.c |
diffstat | 5 files changed, 168 insertions(+), 36 deletions(-) [+] |
line wrap: on
line diff
--- a/Changes Sat Jan 07 18:11:53 2006 +0900 +++ b/Changes Sat Jan 07 19:46:27 2006 +0900 @@ -7995,4 +7995,5 @@ UTF-8 使えるようにする? ascii を拡張すれば良いだけだよね。 - +なんか、macro の history のcheckをしてないな。 +
--- a/Makefile Sat Jan 07 18:11:53 2006 +0900 +++ b/Makefile Sat Jan 07 19:46:27 2006 +0900 @@ -11,7 +11,7 @@ MFLAGS=$(MFALGS) BASE=$(BASE) STAGE=$(STAGE) ARCH=powerpc MC=mc-$(ARCH) -# MLIB = -lm +MLIB = -lm PRINTF= # printf.c CONVERTER=conv/c.o conv/null.o # conv/c2cbc.o conv/cbc2c.o
--- a/mc-inline.c Sat Jan 07 18:11:53 2006 +0900 +++ b/mc-inline.c Sat Jan 07 19:46:27 2006 +0900 @@ -625,6 +625,9 @@ return list4(car(e),pexpr(cadr(e)),e1,cadddr(e)); } +// handle local variable declaration +// initialization is accumrated in parse tree +// should consider int k=some_compile_time_constant; static int p_decl(int e) {
--- a/mc-macro.c Sat Jan 07 18:11:53 2006 +0900 +++ b/mc-macro.c Sat Jan 07 19:46:27 2006 +0900 @@ -22,15 +22,20 @@ static char * mappend0(int lists,char **result); static int macro_processing(); -static void -gen_source(char *s) -{ - printf("%s",s); -} +/* + +macro_expansion(NMTBL *nptrm) + innput macro term (and chptr for arguments) + result put into cheap, and chptr is set. + current ch and chptr are pushed into chptr stack. -/* - replace macro term into cheap. - ## concatenation requires repeated replace. + ## concatenation requires repeated replace. + + In macro_function and macro_eavl, + expand result is put into macrop local variable. + list2("replaced string",next) + to generate result, mappend/reverse0 is necessary. + */ extern void @@ -53,9 +58,9 @@ } cheap = reset_cheap(&scheap); macropp = cheap->ptr; - // we can reset cheap, no page wrap in this case + // append result override, working cheap, but it's OK. mappend0(reverse0(macrop),¯opp); - cheap->ptr[-1] ='\n'; + cheap->ptr[-1] ='\n'; // makes some tokenize happy cheap->ptr[0] =0; cheap = increment_cheap(cheap,¯opp); while (mconcat) { @@ -64,6 +69,8 @@ mconcat = 0; macrop = 0; // remove \s**##\s* + // it is difficult to remove previous space on the fly, + // so multi path loop is required for(s=t=macropp;*s;) { if ((c=*s++)=='#'&&*s=='#') { if (t>s-3) t=s-2; else t--; @@ -74,6 +81,7 @@ *t++=c; } *t++=0; + // evaluate generated result again if (lsrc) printf("### %s",macropp); macrop=macro_eval(macrop,macropp,0); cheap = reset_cheap(&scheap); @@ -85,9 +93,11 @@ cheap = increment_cheap(cheap,¯opp); } cheap = reset_cheap(&scheap); + // genrated macro will be overwrited by cheap, but it's OK, again mconcat = 0; set_lfree(slfree); if (lsrc && !asmf && nptrm->sc==FMACRO) gen_comment(macropp); + // push previous chptr, and change it to the generate macro chptrsave = glist2((int)chptr,chptrsave); chsave = glist2(ch,chsave); chptr = macropp; @@ -99,6 +109,7 @@ /* file name concatenation + on cheap */ static char * @@ -124,6 +135,8 @@ "name" => name current_file_name_dir / name include_path / name + (no difference?) + next flag ignores the first occurence. */ static int @@ -191,9 +204,12 @@ } } if(!fp) { error(FILERR); return filep->fcb; } + // we have so search current directory of the included file + // keep track the name copy_current_file_dir(s=p); // File name determined. Dispose extra copies. cheap = reset_cheap(&scheap); + // Generated name needs copy. if (p!=name) { name = cheap->ptr; while((*cheap->ptr = *s++)) cheap = increment_cheap(cheap,&name); @@ -249,6 +265,10 @@ /* getline from chptr or chinput (for internal source) with macro processing + generate comment + generate ST_COMMENT parse tree, in inline mode + In getch, if chptr is empty, pop chptr stack, if stack is empy + read from fp. */ static int next_eof; @@ -296,6 +316,7 @@ if (lsrc && !asmf && !macro_if_skip && linebuf[0]) { gen_comment(linebuf); if (inmode) { + // inline mode int i=0; int c; char *p; @@ -398,6 +419,7 @@ c = (chptr[-4]=='n'); macro_if_current++; if (!macro_if_skip) { + // try getsym in IFDEF mode to avoid symbol define mode_save = mode; mode = IFDEF; ch= *chptr; i = getsym(0); @@ -472,6 +494,7 @@ mode=IFDEF; ch= *chptr; if (getsym(0)) { + // make it EMPTY if (nptr->sc == MACRO) { nptr->sc = EMPTY; } else if (nptr->sc == FMACRO) { @@ -496,13 +519,14 @@ } break; #if ASM_CODE + // deprecated, use asm function case 'a': if (c=='a'&¯oeq("asm")) { if (asmf) error(MCERR); asmf = 1; getline(); while (asmf) { - gen_source(linebuf); + printf("%s",linebuf); getline(); } return 0; @@ -536,6 +560,8 @@ /* macro interpreter */ +/* generate macro define */ + extern void macro_define(char *macro) { @@ -580,6 +606,8 @@ while((c=*chptr)==' '||c=='\t') chptr++; nptr->dsp = list2((int)cheap->ptr,args); /* macro body */ body = (char **)&car(nptr->dsp); + + // now copy it to the body while ((*cheap->ptr = c = *chptr++) && c != '\n') { cheap = increment_cheap(cheap,body); @@ -714,16 +742,21 @@ int args,sargs,values,evalues; char *macro; + // make argument list sargs = args = cadr(nptr->dsp); values = macro_args(pchptr); if (pchptr==&chptr) { ch = *chptr++; } + // eval all argument list evalues = 0; while(values) { evalues = list2(macro_eval(0,(char *)car(values),history),evalues); values = cadr(values); } + // define all arguments locally + // #define arg0 arg0_value + // #define arg1 arg2_value .... evalues = reverse0(evalues); enter_scope(); while(args) { @@ -732,9 +765,11 @@ args = cadr(args); evalues = cadr(evalues); } + // process body replacement macro = (char *)car(nptr->dsp); macrop = macro_eval(macrop,macro,list2((int)macro,history)); args = sargs; + // unbind arguments leave_scope(); return macrop; } @@ -752,6 +787,7 @@ /* Evaluate macro string. reuslt: list2("replaced string",next) + history is necessary to avoid recursion */ static int @@ -787,9 +823,10 @@ in_quote = 1; } else if (c=='#' && *body=='#') { mconcat = 1; - // name concatenation. mark only. remove and re-evaluate + // name concatenation. flag only. remove and re-evaluate // in the top level. (and skip space) } else if (alpha(c)) { + // find a name body--; // ungetc nptrm = get_name(body,&len,NONDEF); if (!nptrm) { @@ -802,6 +839,7 @@ c = *body; nptrm = name_space_search(nptrm,MACRO); macro = (char *)car(nptrm->dsp); +// if (check_recurse(macro,history)) goto skip; switch(nptrm->sc) { case FMACRO: if (c==' '||c=='\t') { @@ -829,6 +867,7 @@ } default: macro = nptrm->nm; +// skip: case LMACRO: while((*cheap->ptr = *macro++)/* && len-- */) cheap = increment_cheap(cheap,expand);
--- a/mc-parse.c Sat Jan 07 18:11:53 2006 +0900 +++ b/mc-parse.c Sat Jan 07 19:46:27 2006 +0900 @@ -24,7 +24,9 @@ #endif static int HEAP_REPORT = 0; -static int lfree_type_limit; +static int lfree_type_limit; // debugging purpose + // list of local declared type have to be + // keep NMTBL null_nptr; NMTBL *fnptr; // current compiling function @@ -1890,6 +1892,9 @@ } /* generate function from parse tree */ +/* some inline functions are external or indirectly called */ +/* even if it is a static. Generate these in closing(); */ +/* should be in mc-inline.c? */ extern void pfdecl(NMTBL *n) @@ -2045,23 +2050,20 @@ fprintf(stderr," error: label at end of compound statement\n"); return; } - statement(use); + goto loop; } else { + // ({... ; value}) requires delayed handling of lastexp. + // lastexp will be flushed in checkret(), or used by + // statement expression. + if (use) + lastexp = expr(0); if (inmode) { - if (use) { - lastexp = expr(0); - } else { - e = expr(0); - parse = list3(ST_COMP,parse,e); - } + e = expr(0); + parse = list3(ST_COMP,parse,e); } else { - if (use) { - lastexp = expr(0); - } else { - slfree=lfree; - gexpr(expr(0),use); - set_lfree(slfree); - } + slfree=lfree; + gexpr(expr(0),use); + set_lfree(slfree); } conv->sm_(); checksym(SM); @@ -2237,7 +2239,12 @@ getsym(0); checksym(LPAR); slfree=lfree; + // + // for(int hge;hge<0;hge--) {... } + // if (typeid(sym) || sym==REGISTER ) { + // initializer with declaration + // for has strange scope rule enter_scope(); dflag = 1; mode=LDECL; stmode=0; @@ -2251,6 +2258,7 @@ } getsym(0); } else if(sym!=SM) { + // initial expression (without declartion) checkret(); if (inmode) { p0 = expr(0); @@ -2271,6 +2279,7 @@ l=backdef(); } if(sym!=SM) { + // loop condition expression if (inmode) { p1 = expr(0); } else { @@ -2285,6 +2294,7 @@ } set_lfree(slfree); if(sym==RPAR) { + // no continue expression clabel=l; conv->for_body_(); getsym(0); @@ -2294,6 +2304,7 @@ e = 0; } } else { + // continue expression clabel=fwdlabel(); e=expr(0); conv->for_body_(); @@ -2323,17 +2334,14 @@ /* compound statement {} + may contain declaration */ static void docomp(int use) { int slimit = lfree_type_limit ; int sinit_vars = init_vars; -// int pparse = parse; conv->lc_(); -// if (inmode) { -// parse = 0; -// } local_decl(); emit_init_vars(); lfree_type_limit = lfree; @@ -2342,14 +2350,34 @@ lfree_type_limit = slimit; init_vars = sinit_vars; leave_scope(); -// if (inmode) { -// parse = list3(ST_COMP,pparse,reverse0(parse)); -// } getsym(0); } /* CASE_CODE generates table jump + + CASCADE + switch(c) { compute c + jmp cslabel0 + case 5; cslabel0: cmp c,5 + jne cslabel1 + ..... + break; jmp blabel + default: dlabel: + } clsabel1: if (defalut) jmp dlabel + blabel: + CASE_CODE + switch(c) { compute c + case 5; cslabel0: cmp c,5 + jne jtable_JMP <-- at least one case required + ..... + break; jmp blabel + default: dlabel: + } clsabel1: if (defalut) jmp dlabel + table_JMP: table_jmp + blabel: + + cslist keeps list of case/label pair */ static void @@ -2607,6 +2635,15 @@ conv->case_(0,1); } +// return statement +// return values in a fixed register (architecture dependent) +// struct value is copied to the place passed by the caller, +// by called function, and return it's pointer to the caller. +// +// current register is moved to corret one in checkret(); +// other complex stack work will be done at the last of +// generated function. (retpending flag) + static void doreturn(void) { @@ -2630,6 +2667,7 @@ if ((car(type)==STRUCT || car(type)==UNION)&& size(type)==cadr(struct_return)) { if(car(e)==RSTRUCT && car(cadr(e))==FUNCTION) { + /* CASCADING struct return */ /* return struct_return_f(); case */ /* pass the return pointer to the called function */ replace_return_struct(cadr(e), @@ -2652,6 +2690,7 @@ error(TYERR); /* should check compatible */ } } else { + // normal value if (inmode) { e = correct_type(expr(0),cadr(fnptr->ty)); parse = list3(ST_RETURN,parse,e); @@ -2679,6 +2718,7 @@ e1 = expr(0); t=car(e1); if (type==VOID) { + /* indirect goto */ if (car(e1)==RINDIRECT) { if (inmode) { parse = list3(ST_GOTO,parse,e1); @@ -2690,6 +2730,7 @@ return; } if (t==FNAME) { + /* classical goto */ nptr0 = (NMTBL *)cadr(e1); t = nptr0->sc; if (t==EMPTY||t==EXTRN1||t==EXTRN) { @@ -2711,6 +2752,7 @@ return; } if (t==COMMA) { + /* CbC environment option */ env = caddr(e1); e1 = cadr(e1); t = car(e1); @@ -3519,24 +3561,28 @@ checksym(RPAR); break; case ENVIRONMENT: + // return current frame pointer (or equivalent) conv-> environment_(); type=list2(POINTER,VOID); e1=list2(ENVIRONMENT,0); getsym(0); break; case C_FILE: + // return current file name nptr=get_name(filep->name0,0,0); type=list3(ARRAY,CHAR,nptr->dsp); e1=list3(STRING,(int)nptr,nptr->dsp); getsym(0); break; case C_FUNCTION: + // return current function name nptr=get_name(fnptr->nm,0,0); type=list3(ARRAY,CHAR,nptr->dsp); e1=list3(STRING,(int)nptr,nptr->dsp); getsym(0); break; case C_LINE: + // return current lineno in int type=UNSIGNED; e1=list2(CONST,lineno); getsym(0); @@ -3555,6 +3601,7 @@ conv->rpar_(); checksym(RPAR); if (sym==LC && (t>0 && (car(t)==STRUCT||car(t)==UNION))) { + // initializer // q->lock = (spinlock_t) { }; smode = mode; type = t; @@ -3576,6 +3623,9 @@ // if COMMA expr is not gexpred by !control, // l2 is not defined and generates undefined error. // cntl prevents this. + // + // In docomp, last expression is kept in lastexp. + // int l,b,l2,cntl=control; if (inmode) { int sparse = parse; parse=0; @@ -3657,6 +3707,7 @@ /* checks type */ /* make temporary struct for return value */ /* but it is better to see we can reuse old one */ + /* a = f().a case */ if (tmp_struct && !inmode) { sz = size(tmp_struct->ty); if (sz>=size(type)) { @@ -3682,6 +3733,10 @@ return tmp_struct; } +/* + function call + + */ static int expr15(int e1) { @@ -3802,6 +3857,7 @@ /* type prefix in cast + (type definition)expre */ static int @@ -3878,6 +3934,7 @@ reset_cheap(struct cheap *scheap) abandone cheap to save_cheap point. + To avoid interference, allocate new cheap pool and struct. */ extern struct cheap * @@ -3953,6 +4010,9 @@ /* Symbol table handling + hash table + lexical scope structure + for macro and local variable, goto label, string */ static int @@ -4033,6 +4093,9 @@ return hash_search(name,&scheap,i,hash0,DEF); } +/* + All strings are kept in hash table, and shared. + */ static void getstring(void) { @@ -4395,6 +4458,10 @@ free_nptr_list = n; } +/* + nptr pool (for resue) + */ + extern NMTBL * get_nptr() { @@ -4459,6 +4526,12 @@ return nptr; } +/* + lexical name scope handler + enter_scope + leave_scope + */ + extern NMTBL * name_space_search(NMTBL *hash,int sc) { @@ -4570,6 +4643,10 @@ if (use) extrn_use(nptr0); } +/* + Character handling + */ + extern int neqname(char *p,char *q) { @@ -4622,6 +4699,8 @@ escape(void) { char c; + // Unicode? + if ((c=ch) == '\\') { if (digit(c=getch())) { c = ch-'0'; @@ -4950,6 +5029,10 @@ return p1; } +/* + attribute list for nptr->attr + */ + extern int has_attr(NMTBL *n,int attr) { @@ -5007,6 +5090,12 @@ fprintf(stderr,"nptr->nm %s\n",n->nm); } +/* + type attribute + type = list3(ATTRIBUTE,type,attr); + use type_value to remove this + */ + extern int set_type_attr(int type,int attr) {