main() { glbptr=startglb; /* clear global symbols */ locptr=startloc; /* clear local symbols */ wqptr=wq; /* clear while queue */ macptr= /* clear the macro pool */ litptr= /* clear literal pool */ sp = /* stack ptr (relative) */ errcnt= /* no errors */ eof= /* not eof yet */ input= /* no input file */ input2= /* or include file */ output= /* no open units */ ncmp= /* no open compound states */ lastst= /* no last statement yet */ quote[1]= 0; /* ...all set to zero.... */ quote[0]='"'; /* fake a quote literal */ cmode=1; /* enable preprocessing */ /* */ /* compiler body */ /* */ ask(); /* get user options */ openout(); /* get an output file */ openin(); /* and initial input file */ header(); /* intro code */ parse(); /* process ALL input */ dumplits(); /* then dump literal pool */ dumpglbs(); /* and all static memory */ errorsummary(); /* summarize errors */ trailer(); /* follow-up code */ closeout(); /* close the output (if any) */ return; /* then exit to system */ }
/** * compile one file if filename is NULL redirect do to stdin/stdout * @param file filename * @return */ void compile(char *file) { if (file == NULL || filename_typeof(file) == 'c') { global_table_index = 0; local_table_index = NUMBER_OF_GLOBALS; while_table_index = 0; tag_table_index = 0; inclsp = iflevel = skiplevel = swstp = litptr = stkp = errcnt = ncmp = lastst = //quote[1] = 0; input2 = -1; //quote[0] = '"'; cmode = 1; glbflag = 1; nxtlab = 0; litlab = getlabel(); defmac("end\tmemory"); //add_global("memory", ARRAY, CCHAR, 0, EXTERN); //add_global("stack", ARRAY, CCHAR, 0, EXTERN); rglobal_table_index = global_table_index; //rglbptr = glbptr; //add_global("etext", ARRAY, CCHAR, 0, EXTERN); //add_global("edata", ARRAY, CCHAR, 0, EXTERN); defmac("short\tint"); initmac(); // compiler body if (file == NULL) { input = 0; } else if (!openin(file)) return; if (file == NULL) { output = 1; } else if (!openout()) return; header(); code_segment_gtext(); parse(); close(input); data_segment_gdata(); dumplits(); dumpglbs(); errorsummary(); trailer(); oflush(); close(output); pl(""); errs = errs || errfile; } else { writee("Don't understand file "); writee(file); errs = 1; } }
/* * main compiler routine. this routine parses all of the * ParseSpecifierarations using declare which will call funcbody as * functions are encountered. */ void compile() { while(lastst != eof) { ParseGlobalDeclarations(); if( lastst != eof) NextToken(); } dumplits(); }
// Builds the debugging log as an XML document // void Compiler::compile() { GlobalDeclaration *gd; dfs.printf("<compile>\n"); typenum = 1; symnum = 257; classname = nullptr; ZeroMemory(&gsyms[0],sizeof(gsyms)); ZeroMemory(&defsyms,sizeof(defsyms)); ZeroMemory(&tagtable,sizeof(tagtable)); ZeroMemory(&symbolTable,sizeof(symbolTable)); ZeroMemory(&typeTable,sizeof(typeTable)); AddStandardTypes(); RTFClasses::Random::srand(time(NULL)); decls = GlobalDeclaration::Make(); gd = decls; lastst = tk_nop; getch(); lstackptr = 0; lastst = 0; NextToken(); try { while(lastst != my_eof) { if (gd==nullptr) break; dfs.printf("<Parsing GlobalDecl>\n"); gd->Parse(); dfs.printf("</Parsing GlobalDecl>\n"); if( lastst != my_eof) { NextToken(); gd->next = (Declaration *)GlobalDeclaration::Make(); gd = (GlobalDeclaration*)gd->next; } } dfs.printf("</compile>\n"); } catch (C64PException * ex) { dfs.printf(errtext(ex->errnum)); dfs.printf("</compile>\n"); } dumplits(); }
int main (int argc, char *argv[]) { char *p, *pp, *bp; char **oldargv = argv; char **link_lib; long smacptr; int first = 1; char *asmdefs_global_end; macptr = 0; ctext = 0; argc--; argv++; errs = 0; sflag = 0; cdflag = 0; verboseflag = 0; startup_incl = 0; optimize = 2; /* -O2 by default */ overlayflag = 0; asmdefs[0] = '\0'; while ((p = *argv++)) { if (*p == '-') { while (*++p) switch (*p) { case 't': case 'T': ctext = 1; break; case 'c': if ((*(p + 1) == 'd')) { cdflag = 1; /* pass '-cd' to assembler */ p++; break; } else { usage(oldargv[0]); break; } case 's': if (strncmp(p, "scd", 3) == 0) { cdflag = 2; /* pass '-scd' to assembler */ p += 2; break; } else if (strncmp(p, "sgx", 3) == 0) { strcat(asmdefs, "_SGX = 1\n"); defmac("_SGX"); p += 2; break; } /* fallthrough */ case 'S': sflag = 1; break; /* defines to pass to assembler */ case 'a': if (strncmp(p, "acd", 3) == 0) { cdflag = 2; /* pass '-scd' to assembler */ strcat(asmdefs, "_AC = 1\n"); defmac("_AC"); p += 2; break; } /* fallthrough */ case 'A': bp = ++p; if (!*p) usage(oldargv[0]); while (*p && *p != '=') p++; strncat(asmdefs, bp, (p - bp)); /* if (*p == '=') *p = '\t'; */ bp = ++p; strcat(asmdefs, "\t= "); if (*bp == '\0') strcat(asmdefs, "1\n"); else { strcat(asmdefs, bp); strcat(asmdefs, "\n"); } break; case 'v': verboseflag++; if (verboseflag > 1) ctext = 1; /* "C" code in asm output */ break; case 'd': case 'D': bp = ++p; if (!*p) usage(oldargv[0]); while (*p && *p != '=') p++; if (*p == '=') *p = '\t'; while (*p) p++; p--; defmac(bp); break; case 'o': if (strncmp(p, "over", 4) == 0) { overlayflag = 1; if (strncmp(p, "overlay", 7) == 0) p += 6; else p += 3; } else { bp = ++p; while (*p && *p != ' ' && *p != '\t') p++; memcpy(user_outfile, bp, p - bp); user_outfile[p - bp] = 0; p--; } break; case 'O': /* David, made -O equal to -O2 * I'm too lazy to tape -O2 each time :) */ if (!p[1]) optimize = 2; else optimize = atoi(++p); break; case 'f': p++; if (!strcmp(p, "no-recursive")) { user_norecurse = 1; p += 11; } else if (!strcmp(p, "recursive")) { user_norecurse = 0; p += 8; } else if (!strcmp(p, "no-short-enums")) { user_short_enums = 0; p += 13; } else if (!strcmp(p, "short-enums")) { user_short_enums = 1; p += 10; } else goto unknown_option; break; case 'l': bp = ++p; while (*p && *p != ' ' && *p != '\t') p++; link_libs = realloc(link_libs, (link_lib_ptr + 2) * sizeof(*link_libs)); link_libs[link_lib_ptr] = malloc(p - bp + 1); memcpy(link_libs[link_lib_ptr], bp, p - bp); link_libs[link_lib_ptr][p - bp] = 0; strcat(asmdefs, "LINK_"); strcat(asmdefs, link_libs[link_lib_ptr]); strcat(asmdefs, "\t= 1\n"); link_libs[++link_lib_ptr] = 0; p--; break; case 'm': if (!strcmp(p + 1, "small")) { strcat(asmdefs, "SMALL\t= 1\n"); p += 5; } else { unknown_option: fprintf(stderr, "unknown option %s\n", p); exit(1); } break; default: usage(oldargv[0]); } } else { infiles = realloc(infiles, (infile_ptr + 2) * sizeof(*infiles)); infiles[infile_ptr++] = p; infiles[infile_ptr] = 0; } } smacptr = macptr; if (!infiles) usage(oldargv[0]); printf(HUC_VERSION); printf("\n"); init_path(); /* Remember the first file, it will be used as the base for the output file name unless there is a user-specified outfile. */ p = pp = infiles[0]; /* Labels count is not reset for each file because labels are global and conflicts would arise. */ nxtlab = 0; link_lib = link_libs; infile_ptr = 1; /* Remember where the global assembler defines end so we can reset to that point for each file. */ /* XXX: Even if we don't repeat the local asm defines, they are still defined because we compile everything into one assembly file. */ asmdefs_global_end = asmdefs + strlen(asmdefs); while (p) { errfile = 0; /* Truncate asm defines to the point where global defines end. */ asmdefs_global_end[0] = 0; if (extension(p) == 'c' || extension(p) == 'C') { glbptr = STARTGLB; locptr = STARTLOC; wsptr = ws; inclsp = iflevel = skiplevel = swstp = litptr = stkp = errcnt = ncmp = lastst = quote[1] = const_nb = line_number = 0; macptr = smacptr; input2 = NULL; quote[0] = '"'; cmode = 1; glbflag = 1; litlab = getlabel(); member_table_index = 0; memset(member_table, 0, sizeof(member_table)); tag_table_index = 0; norecurse = user_norecurse; typedef_ptr = 0; enum_ptr = 0; enum_type_ptr = 0; memset(fastcall_tbl, 0, sizeof(fastcall_tbl)); defpragma(); /* Macros and globals have to be reset for each file, so we have to define the defaults all over each time. */ defmac("__end\t__memory"); addglb("__memory", ARRAY, CCHAR, 0, EXTERN, 0); addglb("stack", ARRAY, CCHAR, 0, EXTERN, 0); rglbptr = glbptr; addglb("etext", ARRAY, CCHAR, 0, EXTERN, 0); addglb("edata", ARRAY, CCHAR, 0, EXTERN, 0); /* PCE specific externs */ addglb("font_base", VARIABLE, CINT, 0, EXTERN, 0); addglb_far("vdc", CINT); addglb_far("vram", CCHAR); /* end specific externs */ defmac("huc6280\t1"); defmac("huc\t1"); if (cdflag == 1) defmac("_CD\t1"); else if (cdflag == 2) defmac("_SCD\t1"); else defmac("_ROM\t1"); if (overlayflag == 1) defmac("_OVERLAY\t1"); // initmac(); /* * compiler body */ if (!openin(p)) exit(1); if (first && !openout()) exit(1); if (first) header(); asmdefines(); // gtext (); parse(); fclose(input); // gdata (); dumplits(); dumpglbs(); errorsummary(); // trailer (); pl(""); errs = errs || errfile; } else { fputs("Don't understand file ", stderr); fputs(p, stderr); fputc('\n', stderr); exit(1); } p = infiles[infile_ptr]; if (!p && link_lib && *link_lib) { /* No more command-line files, continue with libraries. */ p = lib_to_file(*link_lib); if (!p) { fprintf(stderr, "cannot find library %s\n", *link_lib); exit(1); } link_lib++; } else infile_ptr++; first = 0; } dumpfinal(); fclose(output); if (!errs && !sflag) { if (user_outfile[0]) errs = errs || assemble(user_outfile); else errs = errs || assemble(pp); } exit(errs != 0); }
/* * Compiler begins execution here */ int main(int argc, char **argv) { int n; /* Loop counter */ int i; gargc = argc ; gargv = argv ; /* * Empty our mem ptrs */ litq=dubq=tempq=glbq=0; symtab=loctab=0; wqueue=0;membptr=0;tagptr=0;swnext=0;stage=0; gotoq=0; /* allocate space for arrays */ litq = mymalloc(FNLITQ) ; /* literals, these 2 dumped end */ dubq = mymalloc(FNLITQ) ; /* Doubles */ tempq = mymalloc(LITABSZ) ; /* Temp strings... */ glbq = mymalloc(LITABSZ) ; /* Used for glb lits, dumped now */ symtab = SYM_CAST mymalloc(NUMGLBS*sizeof(SYMBOL)) ; loctab = SYM_CAST mymalloc(NUMLOC*sizeof(SYMBOL)) ; wqueue = WQ_CAST mymalloc(NUMWHILE*sizeof(WHILE_TAB)) ; gotoq= (GOTO_TAB *)calloc(NUMGOTO,sizeof(GOTO_TAB)); if (gotoq==NULL) OutOfMem(); tagptr = tagtab = TAG_CAST mymalloc(NUMTAG*sizeof(TAG_SYMBOL)) ; membptr = membtab = SYM_CAST mymalloc(NUMMEMB*sizeof(SYMBOL)) ; swnext = SW_CAST mymalloc(NUMCASE*sizeof(SW_TAB)) ; swend = swnext + (NUMCASE-1) ; stage = mymalloc(STAGESIZE) ; stagelast = stage+STAGELIMIT ; /* empty symbol table */ glbptr = STARTGLB; while ( glbptr < ENDGLB ) { glbptr->name[0] = 0 ; ++glbptr ; } glbcnt = 0 ; /* clear global symbols */ locptr = STARTLOC ; /* clear local symbols */ wqptr = wqueue ; /* clear while queue */ gltptr=dubptr=0 ; /* clear literal pools */ *litq=0; /* First entry in literal queue is zero */ litptr=1; /* So miniprintf search works */ Zsp = /* stack ptr (relative) */ errcnt = /* no errors */ errstop = /* keep going after an error */ eof = /* not eof yet */ swactive = /* not in switch */ skiplevel = /* #if not encountered */ iflevel = /* #if nesting level = 0 */ ncmp = /* no open compound states */ lastst = /* not first file to asm */ fnstart = /* current "function" started at line 0 */ lineno = /* no lines read from file */ infunc = /* not in function now */ 0 ; /* ...all set to zero.... */ stagenext = NULL_CHAR ; /* direct output mode */ input = /* no input file */ inpt2 = /* or include file */ saveout = /* no diverted output */ output = NULL_FD ; /* no open units */ currfn = NULL_SYM ; /* no function yet */ macptr = cmode = 1 ; /* clear macro pool and enable preprocessing */ ncomp=doinline=mathz88 = incfloat= compactcode =0; intuition=zorg=lpointer=cppcom=appz88=0; dosigned=NO; makelib=useshare=makeshare=sharedfile=NO; smartprintf=expanded=YES; startup=0; /* Which startup do we want? */ nxtlab = /* start numbers at lowest possible */ ctext = /* don't include the C text as comments */ errstop = /* don't stop after errors */ verbose = 0; gotocnt=0; defdenums=0; doublestrings = 0; noaltreg = NO; safedata=reqpag = -1; shareoffset=SHAREOFFSET; /* Offset for shared libs */ debuglevel=NO; farheapsz=-1; /* Size of far heap */ assemtype = ASM_Z80ASM; printflevel=0; #ifdef USEFRAME indexix=YES; useframe=NO; #endif /* * compiler body */ setup_sym() ; /* define some symbols */ /* Parse the command line options */ atexit(MemCleanup); /* To free everything */ clear(); filenum=0; for (n=1;n<argc;n++) { if (argv[n][0]=='-') ParseArgs(1+argv[n]); else {filenum=n; break;} } clear(); if (filenum == 0) { info(); exit(1); } litlab=getlabel(); /* Get labels for function lits*/ dublab=getlabel(); /* and fn doubles*/ openout(); /* get the output file */ openin(); /* and initial input file */ header(); /* intro code */ parse(); /* process ALL input */ /* dump literal queues, with label */ /* litq starts from 1, so literp has to be -1 */ dumplits(0, YES,litptr-1,litlab,litq+1) ; dumplits(1, YES,dubptr,dublab,dubq) ; dumpvars(); dumpfns(); trailer(); /* follow-up code */ closeout(); errsummary(); /* summarize errors */ if (errcnt) exit(1); exit(0); }
/* * evaluate one initialiser * * if dump is TRUE, dump literal immediately * save character string in litq to dump later * this is used for structures and arrays of pointers to char, so that the * struct or array is built immediately and the char strings are dumped later */ void init(int size, int ident, int *dim, int more, int dump, int is_struct) { int32_t value; int sz; /* number of chars in queue */ /* * djm 14/3/99 We have to rewrite this bit (ugh!) so that we store * our literal in a temporary queue, then if needed, we then dump * it out.. */ if ((sz = qstr(&value)) != -1 ) { sz++; #if 0 if (ident == VARIABLE || (size != 1 && more != CCHAR)) error(E_ASSIGN); #endif #ifdef INIT_TEST outstr("ident="); outdec(ident); outstr("size="); outdec(size); outstr("more="); outdec(more); outstr("dim="); outdec(*dim); outstr("sz="); outdec(sz); nl(); #endif if (ident == ARRAY && more == 0) { /* * Dump the literals where they are, padding out as appropriate */ if (*dim != -1 && sz > *dim) { /* * Ooops, initialised to long a string! */ warning(W_INIT2LONG); sz = *dim; gltptr = sz; *(glbq + sz - 1) = '\0'; /* Terminate string */ } dumplits(((size == 1) ? 0 : size), NO, gltptr, glblab, glbq); *dim -= sz; gltptr = 0; dumpzero(size, *dim); return; } else { /* * Store the literals in the queue! */ storeq(sz, glbq, &value); gltptr = 0; defword(); printlabel(litlab); outbyte('+'); outdec(value); nl(); --*dim; return; } } /* * djm, catch label names in structures (for (*name)() initialisation */ else { char sname[NAMEMAX + 1]; SYMBOL *ptr; if (symname(sname) && strcmp(sname,"sizeof") ) { /* We have got something.. */ if ((ptr = findglb(sname))) { /* Actually found sommat..very good! */ if (ident == POINTER || (ident == ARRAY && more)) { defword(); outname(ptr->name, dopref(ptr)); nl(); --*dim; } else if (ptr->type == ENUM) { value = ptr->size; goto constdecl; } else { error(E_DDECL); } } else error(E_UNSYMB, sname); } else if (rcmatch('}')) { #if 0 dumpzero(size,*dim); #endif } else if (constexpr(&value, 1)) { constdecl: if (ident == POINTER) { /* 24/1/03 dom - We want to be able to assign values to pointers or they're a bit useless.. */ #if 0 /* the only constant which can be assigned to a pointer is 0 */ if (value != 0) warning(W_ASSPTR); #endif size = 2; dump = YES; } if (dump) { /* struct member or array of pointer to char */ if (size == 4) { /* there appears to be a bug in z80asm regarding defl */ defbyte(); outdec((value % 65536UL) % 256); outbyte(','); outdec((value % 65536UL) / 256); outbyte(','); outdec((value / 65536UL) % 256); outbyte(','); outdec((value / 65536UL) / 256); } else { if (size == 1) defbyte(); else defword(); outdec(value); } nl(); /* Dump out a train of zeros as appropriate */ if (ident == ARRAY && more == 0) { dumpzero(size,(*dim)-1); } } else stowlit(value, size); --*dim; } } }
/* * initialise global object */ int initials(char *sname, int type, int ident, int dim, int more, TAG_SYMBOL * tag, char zfar) { int size, desize = 0; int olddim = dim; if (cmatch('=')) { /* initialiser present */ defstatic = 1; /* So no 2nd redefine djm */ gltptr = 0; glblab = getlabel(); if (dim == 0) dim = -1; switch (type) { case CCHAR: size = 1; break; case LONG: size = 4; break; case CINT: default: size = 2; } output_section("data_compiler"); // output_section("text"); prefix(); outname(sname, YES); col(); nl(); if (cmatch('{')) { /* aggregate initialiser */ if ((ident == POINTER || ident == VARIABLE) && type == STRUCT) { /* aggregate is structure or pointer to structure */ dim = 0; olddim = 1; if (ident == POINTER) point(); str_init(tag); } else { /* aggregate is not struct or struct pointer */ agg_init(size, type, ident, &dim, more, tag); } needchar('}'); } else { /* single initialiser */ init(size, ident, &dim, more, 0, 0); } /* dump literal queue and fill tail of array with zeros */ if ((ident == ARRAY && more == CCHAR) || type == STRUCT) { if (type == STRUCT) { dumpzero(tag->size, dim); desize = dim < 0 ? abs(dim+1)*tag->size : olddim * tag->size; } else { /* Handles unsized arrays of chars */ dumpzero(size, dim); dim = dim < 0 ? abs(dim+1) : olddim; cscale(type,tag,&dim); desize = dim; } dumplits(0, YES, gltptr, glblab, glbq); } else { if (!(ident == POINTER && type == CCHAR)) { dumplits(((size == 1) ? 0 : size), NO, gltptr, glblab,glbq); if ( type != CCHAR ) /* Already dumped by init? */ desize = dumpzero(size, dim); dim = dim < 0 ? abs(dim+1) : olddim; cscale(type,tag,&dim); desize = dim; } } output_section("code_compiler"); // output_section("code"); } else { char *dosign, *typ; dosign = ""; if (ident == ARRAY && (dim == 0)) { typ = ExpandType(more, &dosign, (tag - tagtab)); warning(W_NULLARRAY, dosign, typ); } /* no initialiser present, let loader insert zero */ if (ident == POINTER) type = (zfar ? CPTR : CINT); cscale(type, tag, &dim); desize = dim; } return (desize); }