added very, very primitive, mostly unusable structs. the most these can do so far is expose themselves publically
--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40172
This commit is contained in:
		
							parent
							
								
									767f6fa9ab
								
							
						
					
					
						commit
						f8e7a10e06
					
				| @ -144,6 +144,7 @@ | ||||
| 				SubSystem="1" | ||||
| 				OptimizeReferences="2" | ||||
| 				EnableCOMDATFolding="2" | ||||
| 				LinkTimeCodeGeneration="0" | ||||
| 				TargetMachine="1" | ||||
| 			/> | ||||
| 			<Tool | ||||
|  | ||||
| @ -285,7 +285,7 @@ typedef struct s_stringpair { | ||||
|  */ | ||||
| #define tFIRST   256    /* value of first multi-character operator */ | ||||
| #define tMIDDLE  280    /* value of last multi-character operator */ | ||||
| #define tLAST    330    /* value of last multi-character match-able token */ | ||||
| #define tLAST    331    /* value of last multi-character match-able token */ | ||||
| /* multi-character operators */ | ||||
| #define taMULT   256    /* *= */ | ||||
| #define taDIV    257    /* /= */ | ||||
| @ -343,38 +343,39 @@ typedef struct s_stringpair { | ||||
| #define tSTATE   308 | ||||
| #define tSTATIC  309 | ||||
| #define tSTOCK   310 | ||||
| #define tSWITCH  311 | ||||
| #define tTAGOF   312 | ||||
| #define tTHEN    313 | ||||
| #define tWHILE   314 | ||||
| #define tSTRUCT  311 | ||||
| #define tSWITCH  312 | ||||
| #define tTAGOF   313 | ||||
| #define tTHEN    314 | ||||
| #define tWHILE   315 | ||||
| /* compiler directives */ | ||||
| #define tpASSERT 315    /* #assert */ | ||||
| #define tpDEFINE 316 | ||||
| #define tpELSE   317    /* #else */ | ||||
| #define tpELSEIF 318    /* #elseif */ | ||||
| #define tpEMIT   319 | ||||
| #define tpENDIF  320 | ||||
| #define tpENDINPUT 321 | ||||
| #define tpENDSCRPT 322 | ||||
| #define tpERROR  323 | ||||
| #define tpFILE   324 | ||||
| #define tpIF     325    /* #if */ | ||||
| #define tINCLUDE 326 | ||||
| #define tpLINE   327 | ||||
| #define tpPRAGMA 328 | ||||
| #define tpTRYINCLUDE 329 | ||||
| #define tpUNDEF  330 | ||||
| #define tpASSERT 316    /* #assert */ | ||||
| #define tpDEFINE 317 | ||||
| #define tpELSE   318    /* #else */ | ||||
| #define tpELSEIF 319    /* #elseif */ | ||||
| #define tpEMIT   320 | ||||
| #define tpENDIF  321 | ||||
| #define tpENDINPUT 322 | ||||
| #define tpENDSCRPT 323 | ||||
| #define tpERROR  324 | ||||
| #define tpFILE   325 | ||||
| #define tpIF     326    /* #if */ | ||||
| #define tINCLUDE 327 | ||||
| #define tpLINE   328 | ||||
| #define tpPRAGMA 329 | ||||
| #define tpTRYINCLUDE 330 | ||||
| #define tpUNDEF  331 | ||||
| /* semicolon is a special case, because it can be optional */ | ||||
| #define tTERM    331    /* semicolon or newline */ | ||||
| #define tENDEXPR 332    /* forced end of expression */ | ||||
| #define tTERM    332    /* semicolon or newline */ | ||||
| #define tENDEXPR 333    /* forced end of expression */ | ||||
| /* other recognized tokens */ | ||||
| #define tNUMBER  333    /* integer number */ | ||||
| #define tRATIONAL 334   /* rational number */ | ||||
| #define tSYMBOL  335 | ||||
| #define tLABEL   336 | ||||
| #define tSTRING  337 | ||||
| #define tEXPR    338 /* for assigment to "lastst" only (see SC1.C) */ | ||||
| #define tENDLESS 339 /* endless loop, for assigment to "lastst" only */ | ||||
| #define tNUMBER  334    /* integer number */ | ||||
| #define tRATIONAL 335   /* rational number */ | ||||
| #define tSYMBOL  336 | ||||
| #define tLABEL   337 | ||||
| #define tSTRING  338 | ||||
| #define tEXPR    339 /* for assigment to "lastst" only (see SC1.C) */ | ||||
| #define tENDLESS 340 /* endless loop, for assigment to "lastst" only */ | ||||
| 
 | ||||
| /* (reversed) evaluation of staging buffer */ | ||||
| #define sSTARTREORDER 0x01 | ||||
|  | ||||
| @ -88,8 +88,10 @@ static void dumpzero(int count); | ||||
| static void declfuncvar(int fpublic,int fstatic,int fstock,int fconst); | ||||
| static void declglb(char *firstname,int firsttag,int fpublic,int fstatic, | ||||
|                     int stock,int fconst); | ||||
| static void declstructvar(char *firstname,int fpublic, pstruct_t *pstruct); | ||||
| static int declloc(int fstatic); | ||||
| static void decl_const(int table); | ||||
| static void declstruct(); | ||||
| static void decl_enum(int table); | ||||
| static cell needsub(int *tag,constvalue **enumroot); | ||||
| static void initials(int ident,int tag,cell *size,int dim[],int numdim, | ||||
| @ -326,6 +328,7 @@ int pc_compile(int argc, char *argv[]) | ||||
|       inst_datetime_defines(); | ||||
|     #endif | ||||
|     resetglobals(); | ||||
|     pstructs_free(); | ||||
| 	funcenums_free(); | ||||
|     sc_ctrlchar=sc_ctrlchar_org; | ||||
|     sc_packstr=lcl_packstr; | ||||
| @ -388,6 +391,7 @@ int pc_compile(int argc, char *argv[]) | ||||
|   reduce_referrers(&glbtab); | ||||
|   delete_symbols(&glbtab,0,TRUE,FALSE); | ||||
|   funcenums_free(); | ||||
|   pstructs_free(); | ||||
|   #if !defined NO_DEFINE | ||||
|     delete_substtable(); | ||||
|     inst_datetime_defines(); | ||||
| @ -1414,6 +1418,9 @@ static void parse(void) | ||||
|     case tFUNCENUM: | ||||
|       dofuncenum(); | ||||
|       break; | ||||
|     case tSTRUCT: | ||||
|       declstruct(); | ||||
|       break; | ||||
|     case tPUBLIC: | ||||
|       /* This can be a public function or a public variable; see the comment
 | ||||
|        * above (for static functions/variables) for details. | ||||
| @ -1627,12 +1634,19 @@ static void insert_docstring_separator(void) | ||||
| static void declfuncvar(int fpublic,int fstatic,int fstock,int fconst) | ||||
| { | ||||
|   char name[sNAMEMAX+11]; | ||||
|   int tok,tag; | ||||
|   int tok,tag=0; | ||||
|   char *str; | ||||
|   cell val; | ||||
|   int invalidfunc; | ||||
|   pstruct_t *pstruct = NULL; | ||||
| 
 | ||||
|   tag=pc_addtag(NULL); | ||||
|   tok=lex(&val,&str); | ||||
|   if (tok == tLABEL) { | ||||
|     pstruct=pstructs_find(str); | ||||
|     tag=pc_addtag(str); | ||||
|   } else { | ||||
|     lexpush(); | ||||
|   } | ||||
|   tok=lex(&val,&str); | ||||
|   /* if we arrived here, this may not be a declaration of a native function
 | ||||
|    * or variable | ||||
| @ -1664,11 +1678,209 @@ static void declfuncvar(int fpublic,int fstatic,int fstock,int fconst) | ||||
|     invalidfunc= fconst || (fpublic && fstock); | ||||
|     if (invalidfunc || !newfunc(name,tag,fpublic,fstatic,fstock)) { | ||||
|       /* if not a function, try a global variable */ | ||||
|       declglb(name,tag,fpublic,fstatic,fstock,fconst); | ||||
|       if (pstruct) { | ||||
|         declstructvar(name,fpublic,pstruct); | ||||
|       } else { | ||||
|         declglb(name,tag,fpublic,fstatic,fstock,fconst); | ||||
|       } | ||||
|     } /* if */ | ||||
|   } /* if */ | ||||
| } | ||||
| 
 | ||||
| /* declstruct	- declare global struct symbols
 | ||||
|  *  | ||||
|  * global references: glb_declared		(altered) | ||||
|  */ | ||||
| static void declstructvar(char *firstname,int fpublic, pstruct_t *pstruct) | ||||
| { | ||||
| 	char name[sNAMEMAX+1]; | ||||
| 	int tok,i; | ||||
| 	cell val; | ||||
| 	char *str; | ||||
| 	int cur_litidx = 0; | ||||
| 	cell *values, *found; | ||||
| 	int usage; | ||||
| 	symbol *mysym; | ||||
| 
 | ||||
| 	strcpy(name, firstname); | ||||
| 
 | ||||
| 	values = (cell *)malloc(pstruct->argcount * sizeof(cell)); | ||||
| 	found = (cell *)malloc(pstruct->argcount * sizeof(cell)); | ||||
| 	 | ||||
| 	memset(found, 0, sizeof(cell) * pstruct->argcount); | ||||
| 
 | ||||
| 
 | ||||
| 	/**
 | ||||
| 	 * Lastly, very lastly, we will insert a copy of this variable. | ||||
| 	 * This is soley to expose the pubvar. | ||||
| 	 */ | ||||
| 	usage = uDEFINE|uREAD|uCONST; | ||||
| 	if (fpublic) | ||||
| 	{ | ||||
| 		usage |= uPUBLIC; | ||||
| 	} | ||||
| 	mysym=addsym(name, 0, iVARIABLE, sGLOBAL, pc_addtag(pstruct->name), usage); | ||||
| 
 | ||||
| 	/* Maybe error with "public struct requires initialization?" */ | ||||
| 	if (!needtoken('=')) | ||||
| 	{ | ||||
| 		matchtoken(';'); | ||||
| 		return; | ||||
| 	} | ||||
| 	needtoken('{'); | ||||
| 	do | ||||
| 	{ | ||||
| 		structarg_t *arg; | ||||
| 		/* Detect early exit */ | ||||
| 		if (matchtoken('}')) | ||||
| 		{ | ||||
| 			lexpush(); | ||||
| 			break; | ||||
| 		} | ||||
| 		tok=lex(&val,&str); | ||||
| 		if (tok != tSYMBOL) | ||||
| 		{ | ||||
| 			error(1, "-identifier-", str); | ||||
| 			continue; | ||||
| 		} | ||||
| 		arg=pstructs_getarg(pstruct,str); | ||||
| 		if (arg == NULL) | ||||
| 		{ | ||||
| 			/* :TODO: change to "Could not find member %s in struct %s" */ | ||||
| 			error(31); | ||||
| 		} | ||||
| 		needtoken('='); | ||||
| 		cur_litidx = litidx; | ||||
| 		tok=lex(&val,&str); | ||||
| 		if (!arg) | ||||
| 		{ | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (tok == tSTRING) | ||||
| 		{ | ||||
| 			assert(litidx != 0); | ||||
| 			if (arg->dimcount != 1) | ||||
| 			{ | ||||
| 				error(48); | ||||
| 			} else if (arg->tag != pc_tag_string) { | ||||
| 				error(213); | ||||
| 			} | ||||
| 			values[arg->index] = glb_declared * sizeof(cell); | ||||
| 			glb_declared += (litidx-cur_litidx); | ||||
| 			found[arg->index] = 1; | ||||
| 		} else if (tok == tNUMBER || tok == tRATIONAL) { | ||||
| 			/* eat optional 'f' */ | ||||
| 			matchtoken('f'); | ||||
| 			if (arg->ident != iVARIABLE && arg->ident != iREFERENCE) | ||||
| 			{ | ||||
| 				error(23); | ||||
| 			} else { | ||||
| 				if (arg->tag == pc_addtag("Float") && tok == tNUMBER || | ||||
| 					arg->tag == 0 && tok == tRATIONAL) | ||||
| 				{ | ||||
| 					error(213); | ||||
| 				} | ||||
| 				if (arg->ident == iVARIABLE) | ||||
| 				{ | ||||
| 					values[arg->index] = val; | ||||
| 				} else if (arg->ident == iREFERENCE) { | ||||
| 					values[arg->index] = glb_declared * sizeof(cell); | ||||
| 					glb_declared += 1; | ||||
| 					litadd(val); | ||||
| 					cur_litidx = litidx; | ||||
| 				} | ||||
| 				found[arg->index] = 1; | ||||
| 			} | ||||
| 		} else if (tok == tSYMBOL) { | ||||
| 			symbol *sym = NULL; | ||||
| 			for (sym=glbtab.next; sym!=NULL; sym=sym->next) | ||||
| 			{ | ||||
| 				if (sym->vclass != sGLOBAL) | ||||
| 				{ | ||||
| 					continue; | ||||
| 				} | ||||
| 				if (strcmp(sym->name, str) == 0) | ||||
| 				{ | ||||
| 					if (arg->ident == iREFERENCE && sym->ident != iVARIABLE) | ||||
| 					{ | ||||
| 						/* :TODO: Change to "symbol \"%s\" does not have a matching type */ | ||||
| 						error(20, str); | ||||
| 					} else if (arg->ident == iARRAY) { | ||||
| 						if (sym->ident != iARRAY) | ||||
| 						{ | ||||
| 							/* :TODO: Change to "symbol \"%s\" does not have a matching type */ | ||||
| 							error(20, str); | ||||
| 						} else { | ||||
| 							/* :TODO: We should check dimension sizes here... */ | ||||
| 						} | ||||
| 					} else if (arg->ident == iREFARRAY) { | ||||
| 						if (sym->ident != iARRAY) | ||||
| 						{ | ||||
| 							/* :TODO: Change to "symbol \"%s\" does not have a matching type */ | ||||
| 							error(20, str); | ||||
| 						} | ||||
| 						/* :TODO: Check dimension sizes! */ | ||||
| 					} else { | ||||
| 						/* :TODO: Change to "symbol \"%s\" does not have a matching type */ | ||||
| 						error(20, str); | ||||
| 					} | ||||
| 					if (sym->tag != arg->tag) | ||||
| 					{ | ||||
| 						error(213); | ||||
| 					} | ||||
| 					sym->usage |= uREAD; | ||||
| 					values[arg->index] = sym->addr; | ||||
| 					found[arg->index] = 1; | ||||
| 					refer_symbol(sym, mysym); | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 			if (!sym) | ||||
| 			{ | ||||
| 				error(17, str); | ||||
| 			} | ||||
| 		} else { | ||||
| 			error(1, "-identifier-", str); | ||||
| 		} | ||||
| 	} while (matchtoken(',')); | ||||
| 	needtoken('}'); | ||||
| 	matchtoken(';');	/* eat up optional semicolon */ | ||||
| 
 | ||||
| 	for (i=0; i<pstruct->argcount; i++) | ||||
| 	{ | ||||
| 		if (!found[i]) | ||||
| 		{ | ||||
| 			structarg_t *arg = pstruct->args[i]; | ||||
| 			if (arg->ident == iREFARRAY) | ||||
| 			{ | ||||
| 				values[arg->index] = glb_declared * sizeof(cell); | ||||
| 				glb_declared += 1; | ||||
| 				litadd(0); | ||||
| 				cur_litidx = litidx; | ||||
| 			} else if (arg->ident == iVARIABLE) { | ||||
| 				values[arg->index] = 0; | ||||
| 			} else { | ||||
| 				/* :TODO: broken for iARRAY! (unused tho) */ | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	mysym->addr = glb_declared * sizeof(cell); | ||||
| 	glb_declared += pstruct->argcount; | ||||
| 
 | ||||
| 	for (i=0; i<pstruct->argcount; i++) | ||||
| 	{ | ||||
| 		litadd(values[i]); | ||||
| 	} | ||||
| 
 | ||||
| 	begdseg(); | ||||
| 	dumplits(); | ||||
| 	litidx=0; | ||||
| 
 | ||||
| 	free(found); | ||||
| 	free(values); | ||||
| } | ||||
| 
 | ||||
| /*  declglb     - declare global symbols
 | ||||
|  * | ||||
|  *  Declare a static (global) variable. Global variables are stored in | ||||
| @ -2612,8 +2824,110 @@ static void decl_const(int vclass) | ||||
|   needtoken(tTERM); | ||||
| } | ||||
| 
 | ||||
| /* dofuncenum - declare function enumerations
 | ||||
|  *  | ||||
| /*
 | ||||
|  * declstruct - declare a struct type | ||||
|  */ | ||||
| static void declstruct(void) | ||||
| { | ||||
| 	cell val; | ||||
| 	char *str; | ||||
| 	int tok; | ||||
| 	pstruct_t *pstruct; | ||||
| 	int size; | ||||
| 
 | ||||
| 	/* get the explicit tag (required!) */ | ||||
| 	tok = lex(&val,&str); | ||||
| 	if (tok != tSYMBOL) | ||||
| 	{ | ||||
| 		error(93); | ||||
| 	} | ||||
| 
 | ||||
| 	if (pstructs_find(str) != NULL) | ||||
| 	{ | ||||
| 		/* :TODO: change to "struct requires unique struct name" */ | ||||
| 		error(58); | ||||
| 	} | ||||
| 
 | ||||
| 	pstruct = pstructs_add(str); | ||||
| 
 | ||||
| 	needtoken('{'); | ||||
| 	do | ||||
| 	{ | ||||
| 		structarg_t arg; | ||||
| 		if (matchtoken('}')) | ||||
| 		{ | ||||
| 			/* Quick exit */ | ||||
| 			lexpush(); | ||||
| 			break; | ||||
| 		} | ||||
| 		memset(&arg, 0, sizeof(structarg_t)); | ||||
| 		tok = lex(&val,&str); | ||||
| 		if (tok == tCONST) | ||||
| 		{ | ||||
| 			arg.fconst = 1; | ||||
| 			tok = lex(&val,&str); | ||||
| 		} | ||||
| 		arg.ident = 0; | ||||
| 		if (tok == '&') | ||||
| 		{ | ||||
| 			arg.ident = iREFERENCE; | ||||
| 			tok = lex(&val,&str); | ||||
| 		} | ||||
| 		if (tok == tLABEL) | ||||
| 		{ | ||||
| 			arg.tag = pc_addtag(str); | ||||
| 			tok = lex(&val,&str); | ||||
| 		} | ||||
| 		if (tok != tSYMBOL) | ||||
| 		{ | ||||
| 			error(1, "-identifier-", str); | ||||
| 			continue; | ||||
| 		} | ||||
| 		strcpy(arg.name, str); | ||||
| 		if (matchtoken('[')) | ||||
| 		{ | ||||
| 			if (arg.ident == iREFERENCE) | ||||
| 			{ | ||||
| 				error(67, arg.name); | ||||
| 			} | ||||
| 			arg.ident = iARRAY; | ||||
| 			do  | ||||
| 			{ | ||||
| 				constvalue *enumroot; | ||||
| 				int ignore_tag; | ||||
| 				if (arg.dimcount == sDIMEN_MAX) | ||||
| 				{ | ||||
| 					error(53); | ||||
| 					break; | ||||
| 				} | ||||
| 				size = needsub(&ignore_tag, &enumroot); | ||||
| 				arg.dims[arg.dimcount++] = size; | ||||
| 			} while (matchtoken('[')); | ||||
| 			/* Handle strings */ | ||||
| 			if (arg.tag == pc_tag_string && arg.dims[arg.dimcount-1]) | ||||
| 			{ | ||||
| 				arg.dims[arg.dimcount-1] = (size + sizeof(cell)-1) / sizeof(cell); | ||||
| 			} | ||||
| 			if (arg.dimcount == 1 && !arg.dims[arg.dimcount-1]) | ||||
| 			{ | ||||
| 				arg.ident = iREFARRAY; | ||||
| 			} | ||||
| 		} else if (!arg.ident) { | ||||
| 			arg.ident = iVARIABLE; | ||||
| 		} | ||||
| 		if (pstructs_addarg(pstruct, &arg) == NULL) | ||||
| 		{ | ||||
| 			/* :TODO: change to "struct member name appears more than once" */ | ||||
| 			error(58); | ||||
| 		} | ||||
| 	} while (matchtoken(',')); | ||||
| 	needtoken('}'); | ||||
| 	matchtoken(';');	/* eat up optional semicolon */ | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  * dofuncenum - declare function enumerations | ||||
|  */ | ||||
| static void dofuncenum(void) | ||||
| { | ||||
| @ -2750,7 +3064,8 @@ static void dofuncenum(void) | ||||
| 						arg->dimcount += 1; | ||||
| 					} while (matchtoken('[')); | ||||
| 					/* Handle strings */ | ||||
| 					if (arg->tagcount == 1 && arg->tags[0] == pc_tag_string) | ||||
| 					if ((arg->tagcount == 1 && arg->tags[0] == pc_tag_string) | ||||
| 						&& arg->dims[arg->dimcount-1]) | ||||
| 					{ | ||||
| 						arg->dims[arg->dimcount-1] = (size + sizeof(cell)-1) / sizeof(cell); | ||||
| 					} | ||||
|  | ||||
| @ -1880,7 +1880,7 @@ char *sc_tokens[] = { | ||||
|          "assert", "*begin", "break", "case", "chars", "const", "continue", "default", | ||||
|          "defined", "do", "else", "*end", "enum", "exit", "for", "forward", "funcenum", "goto", | ||||
|          "if", "native", "new", "decl", "operator", "public", "return", "sizeof", | ||||
|          "sleep", "state", "static", "stock", "switch", "tagof", "*then", "while", | ||||
|          "sleep", "state", "static", "stock", "struct", "switch", "tagof", "*then", "while", | ||||
|          "#assert", "#define", "#else", "#elseif", "#emit", "#endif", "#endinput", | ||||
|          "#endscript", "#error", "#file", "#if", "#include", "#line", "#pragma", | ||||
|          "#tryinclude", "#undef", | ||||
|  | ||||
| @ -86,7 +86,7 @@ static char *errmsg[] = { | ||||
| /*045*/  "too many function arguments\n", | ||||
| /*046*/  "unknown array size (variable \"%s\")\n", | ||||
| /*047*/  "array sizes do not match, or destination array is too small\n", | ||||
| /*048*/  "array dimensions do not match\n", | ||||
| /*048*/  "array (s do not match\n", | ||||
| /*049*/  "invalid line continuation\n", | ||||
| /*050*/  "invalid range\n", | ||||
| /*051*/  "invalid subscript, use \"[ ]\" operators on major dimensions\n", | ||||
|  | ||||
| @ -8,6 +8,112 @@ memuse_list_t *heapusage = NULL; | ||||
| memuse_list_t *stackusage = NULL; | ||||
| funcenum_t *firstenum = NULL; | ||||
| funcenum_t *lastenum = NULL; | ||||
| pstruct_t *firststruct = NULL; | ||||
| pstruct_t *laststruct = NULL; | ||||
| 
 | ||||
| structarg_t *pstructs_getarg(pstruct_t *pstruct, const char *member) | ||||
| { | ||||
| 	int i; | ||||
| 
 | ||||
| 	for (i=0; i<pstruct->argcount; i++) | ||||
| 	{ | ||||
| 		if (strcmp(pstruct->args[i]->name, member) == 0) | ||||
| 		{ | ||||
| 			return pstruct->args[i]; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return NULL; | ||||
| } | ||||
| 
 | ||||
| pstruct_t *pstructs_add(const char *name) | ||||
| { | ||||
| 	pstruct_t *p = (pstruct_t *)malloc(sizeof(pstruct_t)); | ||||
| 	 | ||||
| 	memset(p, 0, sizeof(pstruct_t)); | ||||
| 	strcpy(p->name, name); | ||||
| 	 | ||||
| 	if (!firststruct) | ||||
| 	{ | ||||
| 		firststruct = p; | ||||
| 		laststruct = p; | ||||
| 	} else { | ||||
| 		laststruct->next = p; | ||||
| 		laststruct = p; | ||||
| 	} | ||||
| 
 | ||||
| 	return p; | ||||
| } | ||||
| 
 | ||||
| void pstructs_free() | ||||
| { | ||||
| 	pstruct_t *p, *next; | ||||
| 
 | ||||
| 	p = firststruct; | ||||
| 	while (p) | ||||
| 	{ | ||||
| 		while (p->argcount--) | ||||
| 		{ | ||||
| 			free(p->args[p->argcount]); | ||||
| 		} | ||||
| 		free(p->args); | ||||
| 		next = p->next; | ||||
| 		free(p); | ||||
| 		p = next; | ||||
| 	} | ||||
| 	firststruct = NULL; | ||||
| 	laststruct = NULL; | ||||
| } | ||||
| 
 | ||||
| pstruct_t *pstructs_find(const char *name) | ||||
| { | ||||
| 	pstruct_t *p = firststruct; | ||||
| 
 | ||||
| 	while (p) | ||||
| 	{ | ||||
| 		if (strcmp(p->name, name) == 0) | ||||
| 		{ | ||||
| 			return p; | ||||
| 		} | ||||
| 		p = p->next; | ||||
| 	} | ||||
| 
 | ||||
| 	return NULL; | ||||
| } | ||||
| 
 | ||||
| structarg_t *pstructs_addarg(pstruct_t *pstruct, const structarg_t *arg) | ||||
| { | ||||
| 	structarg_t *newarg; | ||||
| 	int i; | ||||
| 
 | ||||
| 	for (i=0; i<pstruct->argcount; i++) | ||||
| 	{ | ||||
| 		if (strcmp(pstruct->args[i]->name, arg->name) == 0) | ||||
| 		{ | ||||
| 			/* Don't allow dup names */ | ||||
| 			return NULL; | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	newarg = (structarg_t *)malloc(sizeof(structarg_t)); | ||||
| 
 | ||||
| 	memcpy(newarg, arg, sizeof(structarg_t)); | ||||
| 
 | ||||
| 	if (pstruct->argcount == 0) | ||||
| 	{ | ||||
| 		pstruct->args = (structarg_t **)malloc(sizeof(structarg_t *) * 1); | ||||
| 	} else { | ||||
| 		pstruct->args = (structarg_t **)realloc( | ||||
| 							pstruct->args, | ||||
| 							sizeof(structarg_t *) * (pstruct->argcount + 1)); | ||||
| 	} | ||||
| 
 | ||||
| 	newarg->offs = pstruct->argcount * sizeof(cell); | ||||
| 	newarg->index = pstruct->argcount; | ||||
| 	pstruct->args[pstruct->argcount++] = newarg; | ||||
| 
 | ||||
| 	return newarg; | ||||
| } | ||||
| 
 | ||||
| void funcenums_free() | ||||
| { | ||||
|  | ||||
| @ -46,6 +46,35 @@ typedef struct funcenum_s | ||||
|   struct funcenum_s *next; | ||||
| } funcenum_t; | ||||
| 
 | ||||
| typedef struct structarg_s | ||||
| { | ||||
|   int tag; | ||||
|   int dimcount; | ||||
|   cell dims[sDIMEN_MAX]; | ||||
|   char name[sNAMEMAX+1]; | ||||
|   int fconst; | ||||
|   int ident; | ||||
|   unsigned int offs; | ||||
|   int index; | ||||
| } structarg_t; | ||||
| 
 | ||||
| typedef struct pstruct_s | ||||
| { | ||||
|   int argcount; | ||||
|   char name[sNAMEMAX+1]; | ||||
|   structarg_t **args; | ||||
|   struct pstruct_s *next; | ||||
| } pstruct_t; | ||||
| 
 | ||||
| /**
 | ||||
|  * Pawn Structs | ||||
|  */ | ||||
| pstruct_t *pstructs_add(const char *name); | ||||
| void pstructs_free(); | ||||
| pstruct_t *pstructs_find(const char *name); | ||||
| structarg_t *pstructs_addarg(pstruct_t *pstruct, const structarg_t *arg); | ||||
| structarg_t *pstructs_getarg(pstruct_t *pstruct, const char *member); | ||||
| 
 | ||||
| /**
 | ||||
|  * Function enumeration tags | ||||
|  */ | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user