コード例 #1
0
ファイル: pr_lex.cpp プロジェクト: luaman/zq
type_t *PR_ParseFunctionType (type_t *returnType)
{
	type_t	newtype;
	memset (&newtype, 0, sizeof(newtype));
	newtype.type = ev_function;
	newtype.aux_type = returnType;
	newtype.num_parms = 0;

	if (PR_Check (")")) {
		// empty args
		return PR_GetType (&newtype);
	}

	do {
		if (PR_Check ("...")) {
			// variable args
			PR_Expect (")");
			newtype.num_parms |= VA_BIT;
			return PR_GetType (&newtype);
		}

		if (newtype.num_parms >= MAX_PARMS)
			PR_ParseError ("too many parameters (max. %d allowed)", (int)MAX_PARMS);

		type_t *type = PR_ParseType ();
		char *name = PR_ParseName ();
		strlcpy (pr_parm_names[newtype.num_parms], name, sizeof(pr_parm_names[newtype.num_parms]));
		newtype.parm_types[newtype.num_parms] = type;
		newtype.num_parms++;
	} while (PR_Check (","));

	PR_Expect (")");

	return PR_GetType(&newtype);
}
コード例 #2
0
ファイル: pr_lex.cpp プロジェクト: luaman/zq
/*
============
PR_ParseType

Parses a variable type, including field and functions types
============
*/
type_t *PR_ParseType (void)
{
	if (PR_Check ("."))
	{
		type_t	newtype;
		memset (&newtype, 0, sizeof(newtype));
		newtype.type = ev_field;
		newtype.aux_type = PR_ParseType ();
		return PR_GetType (&newtype);
	}

	type_t	*type;

	bool constant = PR_Check ("const");

	if (!strcmp (pr_token, "float") )
		type = constant ? &type_const_float : &type_float;
	else if (!strcmp (pr_token, "vector") )
		type = constant ? &type_const_vector : &type_vector;
	else if (!strcmp (pr_token, "entity") )
		type = &type_entity;
	else if (!strcmp (pr_token, "string") )
		type = constant ? &type_const_string : &type_string;
	else if (!strcmp (pr_token, "void") )
		type = &type_void;
	else
	{
		PR_ParseError ("\"%s\" is not a type", pr_token);
		type = &type_void;	// shut up compiler warning
	}
	PR_Lex ();

	if (PR_Check("(")) {
		// function type

		// go back to non-const types
		// FIXME: don't bother?  Or force const types instead?
		if (type == &type_const_float)
			type = &type_float;
		else if (type == &type_const_vector)
			type = &type_vector;
		else if (type == &type_const_string)
			type = &type_string;

		return PR_ParseFunctionType(type);
	}

	return type;
}
コード例 #3
0
static type_t *ParseUnionType (void)
{
	type_t	*type;
	type_t	newType;

	type = PR_ParseType();
	if (type->type == ev_field)
	{
		PR_ParseError("union field types are implicit");
	}
	memset(&newType, 0, sizeof(newType));
	newType.type = ev_field;
	newType.aux_type = type;
	return PR_FindType(&newType);
}
コード例 #4
0
void CO_ParseDefs (void)
{
	int		i;
	const char	*name;
	def_t	*def;
	type_t	*type;
	int	elementCount;
	gofs_t	offset;

	type = PR_ParseType();

	if (type == &type_union)
	{
		if (pr_scope)
		{
			PR_ParseError("unions must be global");
		}
		ParseUnion();
		return;
	}

	if (pr_scope && (type->type == ev_field || type->type == ev_function))
	{
		PR_ParseError("fields and functions must be global");
	}

	do
	{
		name = PR_ParseName();
		if (TK_CHECK(TK_LPAREN))
		{
			ParseCStyleFunctionDef(name, type);
			return;
		}

		elementCount = 0;
		if (TK_CHECK(TK_LBRACKET))
		{
			def = GetArrayDef(name, type, &elementCount);
		}
		else
		{
			def = PR_GetDef(type, name, pr_scope, true);
		}

		// Check for initialization
		if (TK_CHECK(TK_ASSIGN))
		{
			if (def->initialized)
			{
				PR_ParseError("'%s' : redefinition", name);
			}
			if (type->type == ev_field)
			{
				PR_ParseError("fields cannot be initialized");
			}

			if (elementCount != 0)
			{
				LX_Require("{");
				i = 0;
				offset = def->ofs;
				do
				{
					if (pr_token_type != tt_immediate)
					{
						PR_ParseError("immediate type required for %s", name);
					}
					if (pr_immediate_type->type != type->type)
					{
						PR_ParseError("wrong immediate type for %s", name);
					}
					memcpy(pr_globals+offset, &pr_immediate, 4*type_size[pr_immediate_type->type]);
					offset += type_size[pr_immediate_type->type];
					i++;
					LX_Fetch();
				} while (TK_CHECK(TK_COMMA));

				LX_Require("}");
				if (i != elementCount)
				{
					PR_ParseError("element count mismatch in array"
							" initialization");
				}
				def->initialized = 1;
				continue;
			}
			else if (type->type == ev_function)
			{
				ParseFunctionDef(def, type);
				continue;
			}
			else if (pr_immediate_type != type)
			{
				PR_ParseError("wrong immediate type for %s", name);
			}
			def->initialized = 1;
			memcpy(pr_globals+def->ofs, &pr_immediate, 4*type_size[pr_immediate_type->type]);
			LX_Fetch();
		}
		else if (elementCount != 0 && type->type != ev_field)
		{
			memset(pr_globals+def->ofs, 0, elementCount*4*type_size[type->type]);
			def->initialized = 1;
		}
	} while (TK_CHECK(TK_COMMA));

	LX_Require(";");
}
コード例 #5
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(";");
	}
}
コード例 #6
0
ファイル: PR_COMP.C プロジェクト: ChunHungLiu/Quake-Tools
/*
================
PR_ParseDefs

Called at the outer layer and when a local statement is hit
================
*/
void PR_ParseDefs (void)
{
	char		*name;
	type_t		*type;
	def_t		*def;
	function_t	*f;
	dfunction_t	*df;
	int			i;
	int			locals_start;

	type = PR_ParseType ();
	
	if (pr_scope && (type->type == ev_field || type->type == ev_function) )
		PR_ParseError ("Fields and functions must be global");
		
	do
	{
		name = PR_ParseName ();

		def = PR_GetDef (type, name, pr_scope, true);
		
// check for an initialization
		if ( PR_Check ("=") )
		{
			if (def->initialized)
				PR_ParseError ("%s redeclared", name);
	
			if (type->type == ev_function)
			{
				locals_start = locals_end = numpr_globals;
				pr_scope = def;
				f = PR_ParseImmediateStatements (type);
				pr_scope = NULL;
				def->initialized = 1;
				G_FUNCTION(def->ofs) = numfunctions;
				f->def = def;
//				if (pr_dumpasm)
//					PR_PrintFunction (def);

		// fill in the dfunction
				df = &functions[numfunctions];
				numfunctions++;
				if (f->builtin)
					df->first_statement = -f->builtin;
				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];
				
				continue;
			}
			else if (pr_immediate_type != type)
				PR_ParseError ("wrong immediate type for %s", name);
	
			def->initialized = 1;
			memcpy (pr_globals + def->ofs, &pr_immediate, 4*type_size[pr_immediate_type->type]);
			PR_Lex ();
		}
		
	} while (PR_Check (","));

	PR_Expect (";");
}
コード例 #7
0
ファイル: pr_comp.cpp プロジェクト: luaman/zq
/*
================
PR_ParseDefs

Called at the outer layer and when a local statement is hit
================
*/
void PR_ParseDefs (void)
{
	type_t *type = PR_ParseType ();

	if (pr_scope && type->type == ev_field)
		PR_ParseError ("'%s': local field definitions are illegal", pr_token);

	int	c_defs = 0;
	bool qc_style_function_def = false;

	// functions are always global
	def_t *defscope = (type->type == ev_function) ? NULL : pr_scope;

	do
	{
		char *name = PR_ParseName ();

		if (type->type != ev_function && PR_Check("(")) {
			// C-style function declaration

			char functionName[MAX_NAME];

			if (strlen(name) >= (size_t)MAX_NAME)
				PR_ParseError ("name of function \"%s\" is too long (max. %d chars)", name, (int)(MAX_NAME - 1));

			strcpy (functionName, name);

			type_t *functionType = PR_ParseFunctionType (type);

			def_t *def = PR_GetDef (functionType, functionName, NULL, pr_scope);

			if ((!c_defs && !strcmp(pr_token, "{")) || PR_Check("=")) {
				// C-style function definition (including builtin function definition #1, #2, etc.)
				PR_ParseFunctionBody (functionType, functionName, def);
				while (PR_Check(";"))
					;	// skip redundant semicolons
				return;
			}

			continue;
		}

		def_t *def = PR_GetDef (type, name, defscope, pr_scope);

		if (type->type == ev_void) {
			// end_sys_globals and end_sys_fields are special flags for structure dumping
			if (strcmp(name, "end_sys_globals") && strcmp(name, "end_sys_fields"))
				PR_ParseError ("'%s' : illegal use of type 'void'", name);
		}

		// check for an initialization
		if (PR_Check("=")) {
			if (type->type == ev_function) {
				// QuakeC-style function definition
				qc_style_function_def = true;
				PR_ParseFunctionBody (type, name, def);
			}
			else
				// variable initialization
				PR_ParseInitialization (type, name, def);
		}

	} while (c_defs++, PR_Check (","));

	if (qc_style_function_def && c_defs == 1)
		;	// allow void() func = {} without semicolon
	else
		PR_Expect (";");

	while (PR_Check(";"))
		;	// skip redundant semicolons
}
コード例 #8
0
type_t *PR_ParseType (void)
{
	const char	*name;
	type_t	newtype;
	type_t	*type;

	if (TK_CHECK(TK_PERIOD))
	{
		if (LX_CheckFetch("union"))
		{
			return &type_union;
		}
		memset(&newtype, 0, sizeof(newtype));
		newtype.type = ev_field;
		newtype.aux_type = PR_ParseType();
		return PR_FindType(&newtype);
	}

	if (!strcmp (pr_token, "float") )
		type = &type_float;
	else if (!strcmp (pr_token, "vector") )
		type = &type_vector;
//	else if (!strcmp (pr_token, "float") )
//		type = &type_float;
	else if (!strcmp (pr_token, "entity") )
		type = &type_entity;
	else if (!strcmp (pr_token, "string") )
		type = &type_string;
	else if (!strcmp (pr_token, "void") )
		type = &type_void;
	else
	{
		PR_ParseError ("\"%s\" is not a type", pr_token);
		type = &type_float;	// shut up compiler warning
	}
	LX_Fetch();

	if (!TK_CHECK(TK_LPAREN))
	{
		return type;
	}

	// Function type
	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))
		{
			newtype.num_parms = -1;	// variable args
		}
		else
		{
			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(")");
	}
	return PR_FindType(&newtype);
}