예제 #1
0
static void ParseFunctionDef (def_t *def, type_t *type)
{
	int		i;
	function_t	*f;
	dfunction_t	*df;
	int	locals_start;

	locals_start = locals_end = numpr_globals;
	pr_scope = def;
	f = ParseImmediateStatements(type);
	pr_scope = NULL;
	def->initialized = 1;
	G_FUNCTION(def->ofs) = numfunctions;
	f->def = def;

	// Fill in the dfunction
	df = &functions[numfunctions];
	numfunctions++;
	if (f->builtin)
	{
		df->first_statement = -f->builtin;
		def->referenceCount++;	
	}
	else
	{
		df->first_statement = f->code;
	}
	df->s_name = CopyString(f->def->name);
	df->s_file = s_file;
	df->numparms =  f->def->type->num_parms;
	df->locals = locals_end-locals_start;
	df->parm_start = locals_start;
	for (i = 0; i < df->numparms; i++)
	{
		df->parm_size[i] = type_size[f->def->type->parm_types[i]->type];
	}
}
예제 #2
0
static void ParseCStyleFunctionDef (const char *funcName, type_t *type)
{
	int		i;
	const char	*name = NULL;	// FIXME: init to NULL, avoid compiler warning
	type_t	newType;
	type_t	*funcType;
	def_t	*def;
	function_t	*f;
	dfunction_t	*df;
	int	locals_start;
	char	funcIdent[MAX_NAME];
	int	initClass;

	strcpy(funcIdent, funcName);
	memset(&newType, 0, sizeof(newType));
	newType.type = ev_function;
	newType.aux_type = type; // Return type
	newType.num_parms = 0;
	if (!TK_CHECK(TK_RPAREN))
	{
		if (TK_CHECK(TK_ELLIPSIS))
		{ // Variable args
			newType.num_parms = -1;
		}
		else if (!LX_CheckFetch("void"))
		{
			do
			{
				type = PR_ParseType();
				name = PR_ParseName();
				strcpy(pr_parm_names[newType.num_parms], name);
				newType.parm_types[newType.num_parms] = type;
				newType.num_parms++;
			} while (TK_CHECK(TK_COMMA));
		}
		LX_Require(")");
	}

	funcType = PR_FindType(&newType);
	def = PR_GetDef(funcType, funcIdent, pr_scope, true);

	if (def->initialized)
	{
		PR_ParseError("%s redeclared", funcName);
	}

	if (TK_TEST(TK_LBRACE)
		|| TK_TEST(TK_LBRACKET)
		|| TK_TEST(TK_COLON))
	{
		initClass = pr_tokenclass;
		if (def->initialized)
		{
			PR_ParseError("%s redeclared", name);
		}
		locals_start = locals_end = numpr_globals;
		pr_scope = def;
		f = ParseImmediateStatements(funcType);
		pr_scope = NULL;
		def->initialized = 1;
		G_FUNCTION(def->ofs) = numfunctions;
		f->def = def;
		df = &functions[numfunctions];
		numfunctions++;
		if (f->builtin)
		{
			df->first_statement = -f->builtin;
			def->referenceCount++;
		}
		else
		{
			df->first_statement = f->code;
		}
		df->s_name = CopyString(f->def->name);
		df->s_file = s_file;
		df->numparms =  f->def->type->num_parms;
		df->locals = locals_end - locals_start;
		df->parm_start = locals_start;
		for (i = 0; i < df->numparms; i++)
		{
			df->parm_size[i] =
				type_size[f->def->type->parm_types[i]->type];
		}
		if (initClass == TK_COLON)
		{
			LX_Require(";");
		}
	}
	else
	{
		LX_Require(";");
	}
}
예제 #3
0
void Compiler::ParseFunctionDef( type_t *type, const char *name )
{
	def_t		   *def;
	function_t	f;
	dfunction_t	*df;
	int			i;
	char        parm_names[ MAX_PARMS ][ MAX_NAME ];
	int         numparms;
	
	if ( pr_scope )
	{
		lex.ParseError( "Functions must be global" );
	}
	
	type = ParseFunction( type, parm_names, &numparms );
	def = program.GetDef( type, name, NULL, true, &lex );
	
	// check if this is a prototype or declaration
	if ( !lex.Check( "{" ) )
	{
		// it's just a prototype, so get the ; and move on
		lex.Expect( ";" );
		return;
	}
	
	if ( def->initialized )
	{
		lex.ParseError( "%s redeclared", name );
	}
	
	program.locals_start = program.numpr_globals;
	program.locals_end = program.numpr_globals;
	
	pr_scope = def;
	f = ParseImmediateStatements( type, parm_names, numparms );
	pr_scope = NULL;
	
	program.locals_end = program.numpr_globals;
	
	def->initialized = 1;
	
	if ( program.numfunctions >= MAX_FUNCTIONS )
	{
		lex.ParseError( "Exceeded max functions." );
		gi.Error( ERR_DROP, "Compile failed." );
	}
	
	program.setFunction( def->ofs, program.numfunctions );
	
	// fill in the dfunction
	df = &program.functions[ program.numfunctions ];
	program.numfunctions++;
	
	df->eventnum = 0;
	df->first_statement = f.code;
	df->s_name = def->name;
	df->s_file = program.s_file;
	df->numparms = def->type->num_parms;
	df->minparms = def->type->min_parms;
	df->locals = program.locals_end - program.locals_start;
	df->parm_start = program.locals_start;
	df->parm_total = 0;
	
	for( i = 0; i < df->numparms; i++ )
	{
		df->parm_size[ i ] = type_size[ def->type->parm_types[ i ]->type ];
		df->parm_total += df->parm_size[ i ];
	}
	
	program.locals_start = program.locals_end;
}