示例#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_ParseState

States are special functions made for convenience.  They automatically
set frame, nextthink (implicitly), and think (allowing forward definitions).

// void() name = [framenum, nextthink] {code}
// expands to:
// function void name ()
// {
//		self.frame=framenum;
//		self.nextthink = time + 0.1;
//		self.think = nextthink
//		<code>
// };
==============
*/
void PR_ParseState (void)
{
	char	*name;
	def_t	*s1, *def;
	
	if (pr_token_type != tt_immediate || pr_immediate_type != &type_float)
		PR_ParseError ("state frame must be a number");
	s1 = PR_ParseImmediate ();
	
	PR_Expect (",");

	name = PR_ParseName ();
	def = PR_GetDef (&type_function, name,0, true);
		
	PR_Expect ("]");
	
	PR_Statement (&pr_opcodes[OP_STATE], s1, def);
}
示例#3
0
/*
============
PR_ParseImmediateStatements

Parse a function body
============
*/
function_t *PR_ParseImmediateStatements (type_t *type)
{
	int			i;
	function_t	*f;
	def_t		*defs[MAX_PARMS];
	
	f = malloc (sizeof(function_t));

//
// check for builtin function definition #1, #2, etc
//
	if (PR_Check ("#"))
	{
		if (pr_token_type != tt_immediate
		|| pr_immediate_type != &type_float
		|| pr_immediate._float != (int)pr_immediate._float)
			PR_ParseError ("Bad builtin immediate");
		f->builtin = (int)pr_immediate._float;
		PR_Lex ();
		return f;
	}
	
	f->builtin = 0;
//
// define the parms
//
	for (i=0 ; i<type->num_parms ; i++)
	{
		defs[i] = PR_GetDef (type->parm_types[i], pr_parm_names[i], pr_scope, true);
		f->parm_ofs[i] = defs[i]->ofs;
		if (i > 0 && f->parm_ofs[i] < f->parm_ofs[i-1])
			Error ("bad parm order");
	}
	
	f->code = numstatements;

//
// check for a state opcode
//
	if (PR_Check ("["))
		PR_ParseState ();
		
//
// parse regular statements
//
	PR_Expect ("{");

	while (!PR_Check("}"))
		PR_ParseStatement ();
	
// emit an end of statements opcode
	PR_Statement (pr_opcodes, 0,0);


	return f;
}
示例#4
0
/*
============
PR_ParseFunctionCall
============
*/
def_t *PR_ParseFunctionCall (def_t *func)
{
	def_t		*e;
	int			arg;
	type_t		*t;
	
	t = func->type;

	if (t->type != ev_function)
		PR_ParseError ("not a function");
	
// copy the arguments to the global parameter variables
	arg = 0;
	if (!PR_Check(")"))
	{
		do
		{
			if (t->num_parms != -1 && arg >= t->num_parms)
				PR_ParseError ("too many parameters");
			e = PR_Expression (TOP_PRIORITY);

			if (arg == 0 && func->name)
			{
			// save information for model and sound caching
				if (!strncmp(func->name,"precache_sound", 14))
					PrecacheSound (e, func->name[14]);
				else if (!strncmp(func->name,"precache_model", 14))
					PrecacheModel (e, func->name[14]);
				else if (!strncmp(func->name,"precache_file", 13))
					PrecacheFile (e, func->name[13]);
			}
						
			if (t->num_parms != -1 && ( e->type != t->parm_types[arg] ) )
				PR_ParseError ("type mismatch on parm %i", arg);
		// a vector copy will copy everything
			def_parms[arg].type = t->parm_types[arg];
			PR_Statement (&pr_opcodes[OP_STORE_V], e, &def_parms[arg]);
			arg++;
		} while (PR_Check (","));
	
		if (t->num_parms != -1 && arg != t->num_parms)
			PR_ParseError ("too few parameters");
		PR_Expect (")");
	}
	if (arg >8)
		PR_ParseError ("More than eight parameters");
		

	PR_Statement (&pr_opcodes[OP_CALL0+arg], func, 0);
	
	def_ret.type = t->aux_type;
	return &def_ret;
}
示例#5
0
文件: pr_comp.cpp 项目: luaman/zq
/*
============
PR_ParseFunctionCall
============
*/
def_t *PR_ParseFunctionCall (def_t *func)
{
	def_t		*e;
	int			 arg;
	type_t		*t;

	t = func->type;

	if (t->type != ev_function)
		PR_ParseError ("not a function");

	// copy the arguments to the global parameter variables
	arg = 0;
	if (!PR_Check(")"))
	{
		do
		{
			if (arg >= t->num_parms || arg >= MAX_PARMS /* works properly with varargs */)
				PR_ParseError ("too many parameters");
			e = PR_Expression (TOP_PRIORITY);

			if (arg < (t->num_parms & VA_MASK) && !CompareType(e->type, t->parm_types[arg]))
				PR_ParseError ("type mismatch on parm %i", arg);
			// a vector copy will copy everything
			def_parms[arg].type = t->parm_types[arg];
			PR_Statement (&pr_opcodes[OP_STORE_V], e, &def_parms[arg]);
			arg++;
		} while (PR_Check (","));

		if (arg < (t->num_parms & VA_MASK))
			PR_ParseError ("too few parameters");
		PR_Expect (")");
	}
	if (arg > MAX_PARMS)
		PR_ParseError ("more than %d parameters", (int)MAX_PARMS);

	PR_Statement (&pr_opcodes[OP_CALL0+arg], func, 0);

	def_ret.type = t->aux_type;
	return &def_ret;
}
示例#6
0
/*
============
PR_Term
============
*/
def_t *PR_Term (void)
{
	def_t	*e, *e2;
	etype_t	t;
	
	if (PR_Check ("!"))
	{
		e = PR_Expression (NOT_PRIORITY);
		t = e->type->type;
		if (t == ev_float)
			e2 = PR_Statement (&pr_opcodes[OP_NOT_F], e, 0);
		else if (t == ev_string)
			e2 = PR_Statement (&pr_opcodes[OP_NOT_S], e, 0);
		else if (t == ev_entity)
			e2 = PR_Statement (&pr_opcodes[OP_NOT_ENT], e, 0);
		else if (t == ev_vector)
			e2 = PR_Statement (&pr_opcodes[OP_NOT_V], e, 0);
		else if (t == ev_function)
			e2 = PR_Statement (&pr_opcodes[OP_NOT_FNC], e, 0);
		else
		{
			e2 = NULL;		// shut up compiler warning;
			PR_ParseError ("type mismatch for !");
		}
		return e2;
	}
	
	if (PR_Check ("("))
	{
		e = PR_Expression (TOP_PRIORITY);
		PR_Expect (")");
		return e;
	}
	
	return PR_ParseValue ();
}
示例#7
0
/*
================
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 (";");
}
示例#8
0
/*
============
PR_ParseStatement

============
*/
void PR_ParseStatement (void)
{
	def_t				*e;
	dstatement_t		*patch1, *patch2;
	
	if (PR_Check ("{"))
	{
		do
		{
			PR_ParseStatement ();
		} while (!PR_Check ("}"));
		return;
	}
	
	if (PR_Check("return"))
	{
		if (PR_Check (";"))
		{
			PR_Statement (&pr_opcodes[OP_RETURN], 0, 0);
			return;
		}
		e = PR_Expression (TOP_PRIORITY);
		PR_Expect (";");
		PR_Statement (&pr_opcodes[OP_RETURN], e, 0);
		return;		
	}
	
	if (PR_Check("while"))
	{
		PR_Expect ("(");
		patch2 = &statements[numstatements];
		e = PR_Expression (TOP_PRIORITY);
		PR_Expect (")");
		patch1 = &statements[numstatements];
		PR_Statement (&pr_opcodes[OP_IFNOT], e, 0);
		PR_ParseStatement ();
		junkdef.ofs = patch2 - &statements[numstatements];
		PR_Statement (&pr_opcodes[OP_GOTO], &junkdef, 0);
		patch1->b = &statements[numstatements] - patch1;
		return;
	}
	
	if (PR_Check("do"))
	{
		patch1 = &statements[numstatements];
		PR_ParseStatement ();
		PR_Expect ("while");
		PR_Expect ("(");
		e = PR_Expression (TOP_PRIORITY);
		PR_Expect (")");
		PR_Expect (";");
		junkdef.ofs = patch1 - &statements[numstatements];
		PR_Statement (&pr_opcodes[OP_IF], e, &junkdef);
		return;
	}
	
	if (PR_Check("local"))
	{
		PR_ParseDefs ();
		locals_end = numpr_globals;
		return;
	}
	
	if (PR_Check("if"))
	{
		PR_Expect ("(");
		e = PR_Expression (TOP_PRIORITY);
		PR_Expect (")");
		
		patch1 = &statements[numstatements];
		PR_Statement (&pr_opcodes[OP_IFNOT], e, 0);
		
		PR_ParseStatement ();
		
		if (PR_Check ("else"))
		{
			patch2 = &statements[numstatements];
			PR_Statement (&pr_opcodes[OP_GOTO], 0, 0);
			patch1->b = &statements[numstatements] - patch1;
			PR_ParseStatement ();
			patch2->a = &statements[numstatements] - patch2;
		}
		else
			patch1->b = &statements[numstatements] - patch1;
		
		return;
	}
	
	PR_Expression (TOP_PRIORITY);
	PR_Expect (";");
}
示例#9
0
文件: pr_comp.cpp 项目: luaman/zq
/*
============
PR_ParseStatement

============
*/
void PR_ParseStatement (void)
{
	def_t			*e		= NULL;
	dstatement_t	*patch1	= NULL;
	dstatement_t	*patch2	= NULL;

	if (PR_Check(";"))
		return;

	if (PR_Check ("{"))
	{
		while (!PR_Check ("}"))
			PR_ParseStatement ();
		return;
	}

	if (PR_Check("return"))
	{
		if (PR_Check (";"))
		{
			PR_Statement (&pr_opcodes[OP_RETURN], 0, 0);
			return;
		}
		e = PR_Expression (TOP_PRIORITY);
		PR_Expect (";");
		PR_Statement (&pr_opcodes[OP_RETURN], e, 0);
		return;
	}

	if (PR_Check("while"))
	{
		PR_Expect ("(");
		patch2 = &statements[numstatements];
		e = PR_Expression (TOP_PRIORITY);
		PR_Expect (")");
		patch1 = &statements[numstatements];
		PR_Statement (&pr_opcodes[OP_IFNOT], e, 0);
		PR_ParseStatement ();
		junkdef.ofs = patch2 - &statements[numstatements];
		PR_Statement (&pr_opcodes[OP_GOTO], &junkdef, 0);
		patch1->b = (unsigned short)(&statements[numstatements] - patch1);
		return;
	}

	if (PR_Check("do"))
	{
		patch1 = &statements[numstatements];
		PR_ParseStatement ();
		PR_Expect ("while");
		PR_Expect ("(");
		e = PR_Expression (TOP_PRIORITY);
		PR_Expect (")");
		PR_Expect (";");
		junkdef.ofs = patch1 - &statements[numstatements];
		PR_Statement (&pr_opcodes[OP_IF], e, &junkdef);
		return;
	}

	if ( PR_Check("local") || !strcmp(pr_token, "const") || !strcmp(pr_token, "float") || !strcmp(pr_token, "vector")
		|| !strcmp(pr_token, "entity") || !strcmp(pr_token, "string") || !strcmp(pr_token, "void"))
	{
		PR_ParseDefs ();
		locals_end = numpr_globals;
		return;
	}

	if (PR_Check("if"))
	{
		PR_Expect ("(");
		e = PR_Expression (TOP_PRIORITY);
		PR_Expect (")");

		patch1 = &statements[numstatements];
		PR_Statement (&pr_opcodes[OP_IFNOT], e, 0);

		PR_ParseStatement ();

		if (PR_Check ("else"))
		{
			patch2 = &statements[numstatements];
			PR_Statement (&pr_opcodes[OP_GOTO], 0, 0);
			patch1->b = (unsigned short)(&statements[numstatements] - patch1);
			PR_ParseStatement ();
			patch2->a = (unsigned short)(&statements[numstatements] - patch2);
		}
		else
			patch1->b = (unsigned short)(&statements[numstatements] - patch1);

		return;
	}

	if (PR_Check("else"))
		PR_ParseError ("illegal else without matching if");

	PR_Expression (TOP_PRIORITY);
	PR_Expect (";");
}
示例#10
0
文件: pr_comp.cpp 项目: luaman/zq
/*
============
PR_Term
============
*/
def_t *PR_Term (void)
{
	if (pr_token_type != tt_punct)
		return PR_ParseValue ();

	def_t	*e, *e2;
	etype_t	t;

	if (PR_Check ("!"))
	{
		e = PR_Expression (NOT_PRIORITY);
		t = e->type->type;
		if (t == ev_float)
			e2 = PR_Statement (&pr_opcodes[OP_NOT_F], e, 0);
		else if (t == ev_string)
			e2 = PR_Statement (&pr_opcodes[OP_NOT_S], e, 0);
		else if (t == ev_entity)
			e2 = PR_Statement (&pr_opcodes[OP_NOT_ENT], e, 0);
		else if (t == ev_vector)
			e2 = PR_Statement (&pr_opcodes[OP_NOT_V], e, 0);
		else if (t == ev_function)
			e2 = PR_Statement (&pr_opcodes[OP_NOT_FNC], e, 0);
		else {
			PR_ParseError ("type mismatch for !");
			return NULL;	// shut up compiler
		}
		return e2;
	}

	if (PR_Check ("("))
	{
		e = PR_Expression (TOP_PRIORITY);
		PR_Expect (")");
		return e;
	}

	if (PR_Check("-")) {
		e = PR_Expression (1 /* FIXME, correct? */);
		t = e->type->type;
		if (t == ev_float) {
			eval_t v;
			v._float = 0;
			def_t *imm = PR_GetImmediate (&type_const_float, v);
			e2 = PR_Statement (&pr_opcodes[OP_SUB_F], imm, e);
		} else if (t == ev_vector) {
			eval_t v;
			v.vector[0] = v.vector[1] = v.vector[2] = 0;
			def_t *imm = PR_GetImmediate (&type_const_vector, v);
			e2 = PR_Statement (&pr_opcodes[OP_SUB_V], imm, e);
		} else {
			PR_ParseError ("type mismatch for -");
			return NULL;	// shut up compiler
		}
		return e2;
	}

	if (PR_Check("+")) {
		e = PR_Expression (1 /* FIXME, correct? */);
		t = e->type->type;
		if (t != ev_float && t != ev_vector) {
			PR_ParseError ("type mismatch for +");
			return NULL;	// shut up compiler
		}
		return e;
	}

	PR_ParseError ("syntax error : '%s'", pr_token);
	return NULL;	// shut up compiler
}
示例#11
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
}