SYMBOL* findgoto(char* sname) { char sname2[NAMESIZE * 3]; strcpy(sname2, "00goto_"); strcat(sname2, currfn->name); strcat(sname2, "_"); strcat(sname2, sname); return (findglb(sname2)); }
/* * Call specified function */ SC_FUNC void ffcall(symbol *sym,const char *label,int numargs) { char symname[2*sNAMEMAX+16]; char aliasname[sNAMEMAX+1]; int wasAlias = 0; assert(sym!=NULL); assert(sym->ident==iFUNCTN); if (sc_asmfile) funcdisplayname(symname,sym->name); if ((sym->usage & uNATIVE)!=0) { /* reserve a SYSREQ id if called for the first time */ assert(label==NULL); stgwrite("\tsysreq.c "); if (sc_status==statWRITE && (sym->usage & uREAD)==0 && sym->addr>=0) sym->addr=ntv_funcid++; /* Look for an alias */ if (lookup_alias(aliasname, sym->name)) { symbol *asym = findglb(aliasname, sGLOBAL); if (asym && asym->ident==iFUNCTN && ((sym->usage & uNATIVE) != 0)) { sym = asym; if (sc_status==statWRITE && (sym->usage & uREAD)==0 && sym->addr>=0) { sym->addr=ntv_funcid++; markusage(sym, uREAD); } } } outval(sym->addr,FALSE); if (sc_asmfile) { stgwrite("\t; "); stgwrite(symname); } /* if */ stgwrite("\n"); /* write on a separate line, to mark a sequence point for the peephole optimizer */ stgwrite("\tstack "); outval((numargs+1)*sizeof(cell), TRUE); code_idx+=opcodes(2)+opargs(2); } else { /* normal function */ stgwrite("\tcall "); if (label!=NULL) { stgwrite("l."); stgwrite(label); } else { stgwrite(sym->name); } /* if */ if (sc_asmfile && (label!=NULL || (!isalpha(sym->name[0]) && sym->name[0]!='_' && sym->name[0]!=sc_ctrlchar))) { stgwrite("\t; "); stgwrite(symname); } /* if */ stgwrite("\n"); code_idx+=opcodes(1)+opargs(1); } /* if */ }
LayoutSpec deduce_layout_spec_by_name(const char *name) { symbol *sym; methodmap_t *map; int tag = pc_findtag(name); if (tag != -1 && (tag & FUNCTAG)) return Layout_FuncTag; if (pstructs_find(name)) return Layout_PawnStruct; if ((map = methodmap_find_by_name(name)) != NULL) return map->spec; if ((sym = findglb(name, sGLOBAL)) != NULL) return Layout_Enum; return Layout_None; }
LayoutSpec deduce_layout_spec_by_tag(int tag) { symbol *sym; const char *name; methodmap_t *map; if ((map = methodmap_find_by_tag(tag)) != NULL) return map->spec; if (tag & FUNCTAG) return Layout_FuncTag; name = pc_tagname(tag); if (pstructs_find(name)) return Layout_PawnStruct; if ((sym = findglb(name, sGLOBAL)) != NULL) return Layout_Enum; return Layout_None; }
LayoutSpec deduce_layout_spec_by_tag(int tag) { if (methodmap_t* map = methodmap_find_by_tag(tag)) return map->spec; Type* type = gTypes.find(tag); if (type && type->isFunction()) return Layout_FuncTag; if (type && type->isStruct()) return Layout_PawnStruct; const char* name = pc_tagname(tag); if (findglb(name)) return Layout_Enum; return Layout_None; }
static cell do_call(FILE *fbin,const char *params,cell opcode,cell cip) { char name[sNAMEMAX+1]; int i; symbol *sym; ucell p; for (i=0; !isspace(*params); i++,params++) { assert(*params!='\0'); assert(i<sNAMEMAX); name[i]=*params; } /* for */ name[i]='\0'; if (name[0]=='l' && name[1]=='.') { /* this is a label, not a function symbol */ i=(int)hex2ucell(name+2,NULL); assert(i>=0 && i<sc_labnum); if (fbin!=NULL) { assert(lbltab!=NULL); p=lbltab[i]-cip; /* make relative address */ } /* if */ } else { /* look up the function address; note that the correct file number must * already have been set (in order for static globals to be found). */ sym=findglb(name,sGLOBAL); assert(sym!=NULL); assert(sym->ident==iFUNCTN || sym->ident==iREFFUNC); assert(sym->vclass==sGLOBAL); p=sym->addr-cip; /* make relative address */ } /* if */ if (fbin!=NULL) { write_cell(fbin,opcode); write_cell(fbin,p); } /* if */ return opcodes(1)+opargs(1); }
/* * add a string to the constant pool * handle underscore * */ int add_buffer (char *p, char c, int is_address) { SYMBOL *s = 0; /* underscore */ if (alpha(*p)) { if (!is_address) { s = findglb(p); if (!s) { error("undefined global"); return (0); } /* Unless preceded by an address operator, we need to get the value, and it better be constant... */ p = get_const(s); if (!p) { error("non-constant initializer"); return (0); } } else if (c != '(') { /* If we want the address, we need an underscore prefix. */ if (const_data_idx < MAX_CONST_DATA) const_data[const_data_idx++] = '_'; } } /* string */ while (*p) { if (const_data_idx < MAX_CONST_DATA) const_data[const_data_idx++] = *p; p++; } /* tell the caller if there were any addresses involved */ return ((s && s->ident == POINTER) || is_address); }
void #endif dumpfns() { int ident,type,storage; SYMBOL *ptr; FILE *fp; #ifdef HEADERFILE outstr(";\tHeader file for file:\t"); outstr(Filename); outstr("\n;\n;\tEven if empty do not delete!!!\n"); outstr(";\n;\t***START OF HEADER DEFNS***\n\n"); #else outstr("\n\n; --- Start of Scope Defns ---\n\n"); #endif if (!glbcnt) return; /* Start at the start! */ glbptr=STARTGLB; ptr=STARTGLB; while (ptr < ENDGLB) { if (ptr->name[0] != 0 && ptr->name[0] != '0' ) { ident=ptr->ident; if (ident==FUNCTIONP) ident=FUNCTION; type =ptr->type; storage=ptr->storage; if ( ident == FUNCTION && ptr->size != 0 ) { outstr("\tdefc\t"); outname(ptr->name,1); ot("=\t"); outdec(ptr->size); nl(); } else { if (ident == FUNCTION && storage!=LSTATIC ) { if (storage==EXTERNAL) { if (ptr->flags&LIBRARY) { GlobalPrefix(LIB); if ( (ptr->flags&SHARED) && useshare ){ outstr(ptr->name); outstr("_sl\n"); GlobalPrefix(LIB); } } else { GlobalPrefix(XREF); } } else { if (ptr->offset.i == FUNCTION || ptr->storage==DECLEXTN ) GlobalPrefix(XDEF); else GlobalPrefix(XREF); } outname(ptr->name,dopref(ptr)); nl(); } else { if (storage == EXTERNP) { GlobalPrefix(XDEF); outname(ptr->name,1); nl(); outstr("\tdefc\t"); outname(ptr->name,1); ot("=\t"); outdec(ptr->size); nl(); } else if (ident != ENUM && type !=ENUM && ident != MACRO && storage != LSTATIC && storage != LSTKEXT && storage!=TYPDEF ) { if (storage == EXTERNAL) GlobalPrefix(XREF); else GlobalPrefix(XDEF); outname(ptr->name,1); nl(); } } } } ++ptr; } /* * If a module requires floating point then previously we wrote * it out to the header file. However, if the module didn't * contain main() then important routines wouldn't be included. * So, if main didn't need float, but ours did we couldn't * compile correctly. * * The solution was to separate startup code, and then define * a new file to which all the math type headers would be * appended. * * This file is zcc_opt.def in the source code directory. * */ if ( (fp=fopen("zcc_opt.def","a")) == NULL ) { error(E_ZCCOPT); } /* Now output the org */ if (zorg) { fprintf(fp,"\nIF !DEFINED_myzorg\n"); fprintf(fp,"\tDEFINE DEFINED_myzorg\n"); fprintf(fp,"\tdefc myzorg = %u\n",zorg); fprintf(fp,"ENDIF"); } if (appz88) { int k,value=0; fprintf(fp,"\nIF !NEED_appstartup\n"); fprintf(fp,"\tDEFINE\tNEED_appstartup\n"); if (safedata != -1 ) fprintf(fp,"\tdefc safedata = %d\n",safedata); if (intuition) fprintf(fp,"\tdefc intuition = 1\n"); if (farheapsz != -1) { fprintf(fp,"\tDEFINE DEFINED_farheapsz\n"); fprintf(fp,"\tdefc farheapsz = %d\n",farheapsz); } if (reqpag != -1 ) { fprintf(fp,"\tdefc reqpag = %d\n",reqpag); value=reqpag; } else { /* * Consider the malloc pool as well, if defined we need 32 (standard) + * size of malloc - this is a little kludgy, hence the tuning command * line option */ if ( (k=findmac("HEAPSIZE"))) { sscanf(&macq[k],"%d",&value); if (value != 0 ) value/=256; } value+=32; fprintf(fp,"\tdefc reqpag = %d\n",value); } if (value > 32) expanded=YES; fprintf(fp,"\tdefc NEED_expanded = %d\n",expanded); fprintf(fp,"ENDIF\n\n"); } if (incfloat) { fprintf(fp,"\nIF !NEED_floatpack\n"); fprintf(fp,"\tDEFINE\tNEED_floatpack\n"); fprintf(fp,"ENDIF\n\n"); } if (mathz88) { fprintf(fp,"\nIF !NEED_mathz88\n"); fprintf(fp,"\tDEFINE\tNEED_mathz88\n"); fprintf(fp,"ENDIF\n\n"); } if (lpointer) { fprintf(fp,"\nIF !NEED_farpointer\n"); fprintf(fp,"\tDEFINE NEED_farpointer\n"); fprintf(fp,"ENDIF\n\n"); } if (startup) { fprintf(fp,"\nIF !DEFINED_startup\n"); fprintf(fp,"\tDEFINE DEFINED_startup\n"); fprintf(fp,"\tdefc startup=%d\n",startup); fprintf(fp,"ENDIF\n\n"); } /* * Now, we're gonna use #pragma define _FAR_PTR to indicate whether we need * far stuff - this has to go with a -D_FAR_PTR from the compile line * as well for everything to work just right, so if we find this then * we can indicate to the startup code via zcc_opt.def what the scam * is - this could be used for eg. to allocate space for file structures * etc */ if ( (ptr=findglb("_FAR_PTR")) && ptr->ident==MACRO ) { fprintf(fp,"\nIF !NEED_farstartup\n"); fprintf(fp,"\tDEFINE NEED_farstartup\n"); fprintf(fp,"ENDIF\n\n"); } fclose(fp); if ( defvars != 0 ) WriteDefined("defvarsaddr",defvars); switch(printflevel) { case 1: WriteDefined("ministdio",0); break; case 2: WriteDefined("complexstdio",0); break; case 3: WriteDefined("floatstdio",0); break; } /* * DO_inline is obsolete, but it may have a use sometime.. */ if (doinline) outstr("\tDEFINE\tDO_inline\n"); outstr("\n\n; --- End of Scope Defns ---\n\n"); }
newfunc () { char n[NAMESIZE], *ptr; fexitlab = getlabel(); if (!symname (n) ) { error ("illegal function or declaration"); kill (); return; } if (ptr = findglb (n)) { if (ptr[IDENT] != FUNCTION) multidef (n); else if (ptr[OFFSET] == FUNCTION) multidef (n); else ptr[OFFSET] = FUNCTION; } else addglb (n, FUNCTION, CINT, FUNCTION, PUBLIC); prologue (); if (!match ("(")) error ("missing open paren"); prefix (); outstr (n); col (); nl (); locptr = STARTLOC; argstk = 0; while (!match (")")) { if (symname (n)) { if (findloc (n)) multidef (n); else { addloc (n, 0, 0, argstk, AUTO); argstk = argstk + intsize(); } } else { error ("illegal argument name"); junk (); } blanks (); if (!streq (line + lptr, ")")) { if (!match (",")) error ("expected comma"); } if (endst ()) break; } stkp = 0; argtop = argstk; while (argstk) { if (amatch ("register", 8)) { if (amatch("char", 4)) getarg(CCHAR); else if (amatch ("int", 3)) getarg(CINT); else getarg(CINT); ns(); } else if (amatch ("char", 4)) { getarg (CCHAR); ns (); } else if (amatch ("int", 3)) { getarg (CINT); ns (); } else { error ("wrong number args"); break; } } statement(YES); printlabel(fexitlab); col(); nl(); modstk (0); gret (); stkp = 0; locptr = STARTLOC; }
SYMBOL * #endif AddFuncCode(char *n, char type, char ident, char sign,char zfar, int storage, int more, char check,char simple,TAG_SYMBOL *otag, long *addr) { unsigned char tvalue; /* Used to hold protot value */ char typ; /* Temporary type */ int itag; itag=0; if (otag) itag=otag-tagtab; /* tag number */ lastst = 0; /* no last statement */ locptr = STARTLOC ; /* deallocate all locals */ fnstart = lineno ; /* remember where fn began */ /* * Do some elementary checking before hand.. */ if (zfar && ident!=FUNCTIONP) { zfar=NO; warning(W_FAR); } if ( ( currfn=findglb(n) ) ) { /* already in symbol table ? */ if ( currfn->ident != FUNCTION && currfn->ident != FUNCTIONP ) { /* already variable by that name */ multidef(); } else if ( currfn->offset.i == FUNCTION && !currfn->prototyped) { /* already function by that name */ multidef(); } else { /* we have what was earlier assumed to be a function */ if (currfn->storage == EXTERNAL && currfn->flags&LIBRARY ) { /* Overwriting a lib function, is that what you wanted?!? Handy for * compiling the library though!! Change type to local static to prevent * being dumped in the scope list.. */ if (makelib || storage == LSTATIC ) { currfn->storage=LSTATIC; } else { currfn->storage=LIBOVER; } currfn->offset.i=FUNCTION; } else { /* * I'm not sure what *exactly* I was trying to achieve here djm 25/2/00 */ if (currfn->storage != EXTERNAL && ( (currfn->flags&LIBRARY) != LIBRARY) ) { currfn->flags&=(~LIBRARY); currfn->size = 0; } currfn->offset.i = FUNCTION ; currfn->storage = storage; } } } /* if not in table, define as a function now */ else { typ=type; if (ident == FUNCTIONP) typ=(zfar ? CPTR : CINT ); currfn = addglb(n, FUNCTION, typ, FUNCTION, storage, more, 0); currfn->size=0; currfn->prototyped=0; currfn->flags= (sign&UNSIGNED) | (zfar&FARPTR); if (type == STRUCT) currfn->tagarg[0]=itag; /* * Set our function prototype - what we are! * args[0] is free for use */ currfn->args[0]=CalcArgValue(type, ident, currfn->flags); } tvalue=CalcArgValue(type,ident,((sign&UNSIGNED) | (zfar&FARPTR)) ); if ( currfn->args[0] != tvalue || (type==STRUCT && currfn->tagarg[0] != itag ) ){ char buffer[120]; warning(W_DIFFTYPE); warning(W_DIFFTYPE2,ExpandArgValue(currfn->args[0],buffer,currfn->tagarg[0])); warning(W_DIFFTYPE3,ExpandArgValue(tvalue,buffer,itag) ); } /* we had better see open paren for args... */ if ( check && (cmatch('(') == 0) ) error(E_PAREN); locptr = STARTLOC ; /* "clear" local symbol table */ undeclared = 0 ; /* init arg count */ /* Check to see if we are doing ANSI fn defs - must be a better way of * doing this! (Have an array and check by that?) */ if (CheckANSI()) { return( dofnansi(currfn, addr) ); /* So we can pass back result */ } DoFnKR(currfn,simple); return(0); }
/** * begin a function * called from "parse", this routine tries to make a function out * of what follows * modified version. p.l. woods */ newfunc() { char n[NAMESIZE]; int idx, type; fexitlab = getlabel(); if (!symname(n)) { error("illegal function or declaration"); kill(); return; } if (idx = findglb(n)) { if (symbol_table[idx].identity != FUNCTION) multidef(n); else if (symbol_table[idx].offset == FUNCTION) multidef(n); else symbol_table[idx].offset = FUNCTION; } else add_global(n, FUNCTION, CINT, FUNCTION, PUBLIC); if (!match("(")) error("missing open paren"); output_string(n); output_label_terminator(); newline(); local_table_index = NUMBER_OF_GLOBALS; //locptr = STARTLOC; argstk = 0; // ANSI style argument declaration if (doAnsiArguments() == 0) { // K&R style argument declaration while (!match(")")) { if (symname(n)) { if (findloc(n)) multidef(n); else { add_local(n, 0, 0, argstk, AUTO); argstk = argstk + INTSIZE; } } else { error("illegal argument name"); junk(); } blanks(); if (!streq(line + lptr, ")")) { if (!match(",")) error("expected comma"); } if (endst()) break; } stkp = 0; argtop = argstk; while (argstk) { if (type = get_type()) { getarg(type); need_semicolon(); } else { error("wrong number args"); break; } } } statement(YES); print_label(fexitlab); output_label_terminator(); newline(); gen_modify_stack(0); gen_ret(); stkp = 0; local_table_index = NUMBER_OF_GLOBALS; //locptr = STARTLOC; }
primary (lvalue_t *lval) { char sname[NAMESIZE]; int num[1], k, symbol_table_idx, offset, reg; symbol_t *symbol; lval->ptr_type = 0; /* clear pointer/array type */ if (match ("(")) { k = hier1 (lval); needbrack (")"); return (k); } if (amatch("sizeof", 6)) { needbrack("("); gen_immediate_c(); if (amatch("int", 3)) output_number(INTSIZE); else if (amatch("char", 4)) output_number(1); else if (symname(sname)) { if ((symbol_table_idx = findloc(sname)) || (symbol_table_idx = findglb(sname))) { symbol = &symbol_table[symbol_table_idx]; if (symbol->storage == LSTATIC) error("sizeof local static"); offset = symbol->count; if ((symbol->type & CINT) || (symbol->identity == POINTER)) offset *= INTSIZE; output_number(offset); } else { error("sizeof undeclared variable"); output_number(0); } } else { error("sizeof only on simple type or variable"); } needbrack(")"); newline(); lval->symbol = 0; lval->indirect = 0; return(0); } if (symname (sname)) { if (symbol_table_idx = findloc (sname)) { symbol = &symbol_table[symbol_table_idx]; reg = gen_get_location (symbol); lval->symbol = symbol; lval->indirect = symbol->type; if (symbol->identity == ARRAY) { //lval->ptr_type = symbol->type; lval->ptr_type = 0; return 0; } if (symbol->identity == POINTER) { lval->indirect = UINT; lval->ptr_type = symbol->type; } return reg; } if (symbol_table_idx = findglb (sname)) { symbol = &symbol_table[symbol_table_idx]; lval->symbol = symbol; switch (symbol->identity) { case ARRAY: gen_immediate_a (); output_string (symbol->name); newline (); /* Fall through */ case FUNCTION: lval->indirect = lval->ptr_type = symbol_table[symbol_table_idx].type; lval->ptr_type = 0; return 0; default: lval->indirect = 0; if (symbol->identity == POINTER) { lval->ptr_type = symbol->type; } return 1; } } blanks (); if (ch() != '(') error("undeclared variable"); symbol_table_idx = add_global (sname, FUNCTION, CINT, 0, PUBLIC, 1); symbol = &symbol_table[symbol_table_idx]; lval->symbol = symbol; lval->indirect = 0; return 0; } if (constant (num)) { lval->symbol = 0; lval->indirect = 0; return 0; } error ("invalid expression"); gen_immediate_c (); output_number(0); newline (); junk (); return 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; } } }