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" | 				SubSystem="1" | ||||||
| 				OptimizeReferences="2" | 				OptimizeReferences="2" | ||||||
| 				EnableCOMDATFolding="2" | 				EnableCOMDATFolding="2" | ||||||
|  | 				LinkTimeCodeGeneration="0" | ||||||
| 				TargetMachine="1" | 				TargetMachine="1" | ||||||
| 			/> | 			/> | ||||||
| 			<Tool | 			<Tool | ||||||
|  | |||||||
| @ -285,7 +285,7 @@ typedef struct s_stringpair { | |||||||
|  */ |  */ | ||||||
| #define tFIRST   256    /* value of first multi-character operator */ | #define tFIRST   256    /* value of first multi-character operator */ | ||||||
| #define tMIDDLE  280    /* value of last 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 */ | /* multi-character operators */ | ||||||
| #define taMULT   256    /* *= */ | #define taMULT   256    /* *= */ | ||||||
| #define taDIV    257    /* /= */ | #define taDIV    257    /* /= */ | ||||||
| @ -343,38 +343,39 @@ typedef struct s_stringpair { | |||||||
| #define tSTATE   308 | #define tSTATE   308 | ||||||
| #define tSTATIC  309 | #define tSTATIC  309 | ||||||
| #define tSTOCK   310 | #define tSTOCK   310 | ||||||
| #define tSWITCH  311 | #define tSTRUCT  311 | ||||||
| #define tTAGOF   312 | #define tSWITCH  312 | ||||||
| #define tTHEN    313 | #define tTAGOF   313 | ||||||
| #define tWHILE   314 | #define tTHEN    314 | ||||||
|  | #define tWHILE   315 | ||||||
| /* compiler directives */ | /* compiler directives */ | ||||||
| #define tpASSERT 315    /* #assert */ | #define tpASSERT 316    /* #assert */ | ||||||
| #define tpDEFINE 316 | #define tpDEFINE 317 | ||||||
| #define tpELSE   317    /* #else */ | #define tpELSE   318    /* #else */ | ||||||
| #define tpELSEIF 318    /* #elseif */ | #define tpELSEIF 319    /* #elseif */ | ||||||
| #define tpEMIT   319 | #define tpEMIT   320 | ||||||
| #define tpENDIF  320 | #define tpENDIF  321 | ||||||
| #define tpENDINPUT 321 | #define tpENDINPUT 322 | ||||||
| #define tpENDSCRPT 322 | #define tpENDSCRPT 323 | ||||||
| #define tpERROR  323 | #define tpERROR  324 | ||||||
| #define tpFILE   324 | #define tpFILE   325 | ||||||
| #define tpIF     325    /* #if */ | #define tpIF     326    /* #if */ | ||||||
| #define tINCLUDE 326 | #define tINCLUDE 327 | ||||||
| #define tpLINE   327 | #define tpLINE   328 | ||||||
| #define tpPRAGMA 328 | #define tpPRAGMA 329 | ||||||
| #define tpTRYINCLUDE 329 | #define tpTRYINCLUDE 330 | ||||||
| #define tpUNDEF  330 | #define tpUNDEF  331 | ||||||
| /* semicolon is a special case, because it can be optional */ | /* semicolon is a special case, because it can be optional */ | ||||||
| #define tTERM    331    /* semicolon or newline */ | #define tTERM    332    /* semicolon or newline */ | ||||||
| #define tENDEXPR 332    /* forced end of expression */ | #define tENDEXPR 333    /* forced end of expression */ | ||||||
| /* other recognized tokens */ | /* other recognized tokens */ | ||||||
| #define tNUMBER  333    /* integer number */ | #define tNUMBER  334    /* integer number */ | ||||||
| #define tRATIONAL 334   /* rational number */ | #define tRATIONAL 335   /* rational number */ | ||||||
| #define tSYMBOL  335 | #define tSYMBOL  336 | ||||||
| #define tLABEL   336 | #define tLABEL   337 | ||||||
| #define tSTRING  337 | #define tSTRING  338 | ||||||
| #define tEXPR    338 /* for assigment to "lastst" only (see SC1.C) */ | #define tEXPR    339 /* for assigment to "lastst" only (see SC1.C) */ | ||||||
| #define tENDLESS 339 /* endless loop, for assigment to "lastst" only */ | #define tENDLESS 340 /* endless loop, for assigment to "lastst" only */ | ||||||
| 
 | 
 | ||||||
| /* (reversed) evaluation of staging buffer */ | /* (reversed) evaluation of staging buffer */ | ||||||
| #define sSTARTREORDER 0x01 | #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 declfuncvar(int fpublic,int fstatic,int fstock,int fconst); | ||||||
| static void declglb(char *firstname,int firsttag,int fpublic,int fstatic, | static void declglb(char *firstname,int firsttag,int fpublic,int fstatic, | ||||||
|                     int stock,int fconst); |                     int stock,int fconst); | ||||||
|  | static void declstructvar(char *firstname,int fpublic, pstruct_t *pstruct); | ||||||
| static int declloc(int fstatic); | static int declloc(int fstatic); | ||||||
| static void decl_const(int table); | static void decl_const(int table); | ||||||
|  | static void declstruct(); | ||||||
| static void decl_enum(int table); | static void decl_enum(int table); | ||||||
| static cell needsub(int *tag,constvalue **enumroot); | static cell needsub(int *tag,constvalue **enumroot); | ||||||
| static void initials(int ident,int tag,cell *size,int dim[],int numdim, | 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(); |       inst_datetime_defines(); | ||||||
|     #endif |     #endif | ||||||
|     resetglobals(); |     resetglobals(); | ||||||
|  |     pstructs_free(); | ||||||
| 	funcenums_free(); | 	funcenums_free(); | ||||||
|     sc_ctrlchar=sc_ctrlchar_org; |     sc_ctrlchar=sc_ctrlchar_org; | ||||||
|     sc_packstr=lcl_packstr; |     sc_packstr=lcl_packstr; | ||||||
| @ -388,6 +391,7 @@ int pc_compile(int argc, char *argv[]) | |||||||
|   reduce_referrers(&glbtab); |   reduce_referrers(&glbtab); | ||||||
|   delete_symbols(&glbtab,0,TRUE,FALSE); |   delete_symbols(&glbtab,0,TRUE,FALSE); | ||||||
|   funcenums_free(); |   funcenums_free(); | ||||||
|  |   pstructs_free(); | ||||||
|   #if !defined NO_DEFINE |   #if !defined NO_DEFINE | ||||||
|     delete_substtable(); |     delete_substtable(); | ||||||
|     inst_datetime_defines(); |     inst_datetime_defines(); | ||||||
| @ -1414,6 +1418,9 @@ static void parse(void) | |||||||
|     case tFUNCENUM: |     case tFUNCENUM: | ||||||
|       dofuncenum(); |       dofuncenum(); | ||||||
|       break; |       break; | ||||||
|  |     case tSTRUCT: | ||||||
|  |       declstruct(); | ||||||
|  |       break; | ||||||
|     case tPUBLIC: |     case tPUBLIC: | ||||||
|       /* This can be a public function or a public variable; see the comment
 |       /* This can be a public function or a public variable; see the comment
 | ||||||
|        * above (for static functions/variables) for details. |        * 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) | static void declfuncvar(int fpublic,int fstatic,int fstock,int fconst) | ||||||
| { | { | ||||||
|   char name[sNAMEMAX+11]; |   char name[sNAMEMAX+11]; | ||||||
|   int tok,tag; |   int tok,tag=0; | ||||||
|   char *str; |   char *str; | ||||||
|   cell val; |   cell val; | ||||||
|   int invalidfunc; |   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); |   tok=lex(&val,&str); | ||||||
|   /* if we arrived here, this may not be a declaration of a native function
 |   /* if we arrived here, this may not be a declaration of a native function
 | ||||||
|    * or variable |    * or variable | ||||||
| @ -1664,11 +1678,209 @@ static void declfuncvar(int fpublic,int fstatic,int fstock,int fconst) | |||||||
|     invalidfunc= fconst || (fpublic && fstock); |     invalidfunc= fconst || (fpublic && fstock); | ||||||
|     if (invalidfunc || !newfunc(name,tag,fpublic,fstatic,fstock)) { |     if (invalidfunc || !newfunc(name,tag,fpublic,fstatic,fstock)) { | ||||||
|       /* if not a function, try a global variable */ |       /* if not a function, try a global variable */ | ||||||
|  |       if (pstruct) { | ||||||
|  |         declstructvar(name,fpublic,pstruct); | ||||||
|  |       } else { | ||||||
|         declglb(name,tag,fpublic,fstatic,fstock,fconst); |         declglb(name,tag,fpublic,fstatic,fstock,fconst); | ||||||
|  |       } | ||||||
|     } /* if */ |     } /* if */ | ||||||
|   } /* 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
 | /*  declglb     - declare global symbols
 | ||||||
|  * |  * | ||||||
|  *  Declare a static (global) variable. Global variables are stored in |  *  Declare a static (global) variable. Global variables are stored in | ||||||
| @ -2612,8 +2824,110 @@ static void decl_const(int vclass) | |||||||
|   needtoken(tTERM); |   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) | static void dofuncenum(void) | ||||||
| { | { | ||||||
| @ -2750,7 +3064,8 @@ static void dofuncenum(void) | |||||||
| 						arg->dimcount += 1; | 						arg->dimcount += 1; | ||||||
| 					} while (matchtoken('[')); | 					} while (matchtoken('[')); | ||||||
| 					/* Handle strings */ | 					/* 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); | 						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", |          "assert", "*begin", "break", "case", "chars", "const", "continue", "default", | ||||||
|          "defined", "do", "else", "*end", "enum", "exit", "for", "forward", "funcenum", "goto", |          "defined", "do", "else", "*end", "enum", "exit", "for", "forward", "funcenum", "goto", | ||||||
|          "if", "native", "new", "decl", "operator", "public", "return", "sizeof", |          "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", |          "#assert", "#define", "#else", "#elseif", "#emit", "#endif", "#endinput", | ||||||
|          "#endscript", "#error", "#file", "#if", "#include", "#line", "#pragma", |          "#endscript", "#error", "#file", "#if", "#include", "#line", "#pragma", | ||||||
|          "#tryinclude", "#undef", |          "#tryinclude", "#undef", | ||||||
|  | |||||||
| @ -86,7 +86,7 @@ static char *errmsg[] = { | |||||||
| /*045*/  "too many function arguments\n", | /*045*/  "too many function arguments\n", | ||||||
| /*046*/  "unknown array size (variable \"%s\")\n", | /*046*/  "unknown array size (variable \"%s\")\n", | ||||||
| /*047*/  "array sizes do not match, or destination array is too small\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", | /*049*/  "invalid line continuation\n", | ||||||
| /*050*/  "invalid range\n", | /*050*/  "invalid range\n", | ||||||
| /*051*/  "invalid subscript, use \"[ ]\" operators on major dimensions\n", | /*051*/  "invalid subscript, use \"[ ]\" operators on major dimensions\n", | ||||||
|  | |||||||
| @ -8,6 +8,112 @@ memuse_list_t *heapusage = NULL; | |||||||
| memuse_list_t *stackusage = NULL; | memuse_list_t *stackusage = NULL; | ||||||
| funcenum_t *firstenum = NULL; | funcenum_t *firstenum = NULL; | ||||||
| funcenum_t *lastenum = 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() | void funcenums_free() | ||||||
| { | { | ||||||
|  | |||||||
| @ -46,6 +46,35 @@ typedef struct funcenum_s | |||||||
|   struct funcenum_s *next; |   struct funcenum_s *next; | ||||||
| } funcenum_t; | } 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 |  * Function enumeration tags | ||||||
|  */ |  */ | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user