示例#1
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;
}
示例#2
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 ();
}
示例#3
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;
}
示例#4
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 (";");
}
示例#5
0
def_t *PR_Expression (int priority)
{
	opcode_t	*op, *oldop;
	def_t		*e, *e2;
	etype_t		type_a, type_b, type_c;
	
	if (priority == 0)
		return PR_Term ();
		
	e = PR_Expression (priority-1);
		
	while (1)
	{
		if (priority == 1 && PR_Check ("(") )
			return PR_ParseFunctionCall (e);

		for (op=pr_opcodes ; op->name ; op++)
		{
			if (op->priority != priority)
				continue;
			if (!PR_Check (op->name))
				continue;
			if ( op->right_associative )
			{
			// if last statement is an indirect, change it to an address of
				if ( (unsigned)(statements[numstatements-1].op - OP_LOAD_F) < 6 )
				{
					statements[numstatements-1].op = OP_ADDRESS;
					def_pointer.type->aux_type = e->type;
					e->type = def_pointer.type;
				}
				e2 = PR_Expression (priority);
			}
			else
				e2 = PR_Expression (priority-1);
				
		// type check
			type_a = e->type->type;
			type_b = e2->type->type;

			if (op->name[0] == '.')// field access gets type from field
			{
				if (e2->type->aux_type)
					type_c = e2->type->aux_type->type;
				else
					type_c = -1;	// not a field
			}
			else
				type_c = ev_void;
				
			oldop = op;
			while (type_a != op->type_a->type->type
			|| type_b != op->type_b->type->type
			|| (type_c != ev_void && type_c != op->type_c->type->type) )
			{
				op++;
				if (!op->name || strcmp (op->name , oldop->name))
					PR_ParseError ("type mismatch for %s", oldop->name);
			}
			
			if (type_a == ev_pointer && type_b != e->type->aux_type->type)
				PR_ParseError ("type mismatch for %s", op->name);
			
			
			if (op->right_associative)
				e = PR_Statement (op, e2, e);
			else
				e = PR_Statement (op, e, e2);
			
			if (type_c != ev_void)	// field access gets type from field
				e->type = e2->type->aux_type;
			
			break;
		}
		if (!op->name)
			break;	// next token isn't at this priority level
	}
	
	return e;
}
示例#6
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 (";");
}
示例#7
0
文件: pr_comp.cpp 项目: luaman/zq
/*
==============
PR_Expression
==============
*/
def_t *PR_Expression (int priority)
{
	opcode_t	*op, *oldop;
	def_t		*e, *e2;
	etype_t		type_a, type_b, type_c;

	if (priority == 0)
		return PR_Term ();

	e = PR_Expression (priority-1);

	while (1)
	{
		if (priority == 1 && PR_Check ("(") )
			return PR_ParseFunctionCall (e);

		for (op=pr_opcodes ; op->name ; op++)
		{
			if (op->priority != priority)
				continue;
			if (!PR_Check (op->name))
				continue;

			if (op->name[0] == '.')
			{
				char *name = PR_ParseName ();

				if (e->type != &type_entity)
					PR_ParseError ("left of '.%s' must have entity type", name);

				e2 = PR_FindDef (name, pr_scope);
				if (!e2 || e2->type->type != ev_field)
					PR_ParseError ("'%s' is not a field", name);

				type_c = e2->type->aux_type->type;

				// we still allow ".void foo" so need to check
				if (type_c == ev_void)
					PR_ParseError ("tried to access a 'void' field");

				assert (type_c != ev_pointer && type_c != ev_void);
				while (type_c != op->type_c) {
					op++;
					assert (op->name);
				}

				e = PR_Statement (op, e, e2);

				// field access gets type from field
				e->type = e2->type->aux_type;
				break;
			}

			if (op->right_associative)
			{
				if (e->type->constant)
					PR_ParseError ("assignment to constant");

			// if last statement is an indirect, change it to an address of
				if ( (unsigned)(statements[numstatements-1].op - OP_LOAD_F) < 6 )
				{
					statements[numstatements-1].op = (unsigned short)OP_ADDRESS;
					def_pointer.type->aux_type = e->type;
					e->type = def_pointer.type;
				}
				e2 = PR_Expression (priority);
			}
			else
				e2 = PR_Expression (priority-1);

		// type check
			type_a = e->type->type;
			type_b = e2->type->type;

			oldop = op;
			while (type_a != op->type_a || type_b != op->type_b )
			{
				op++;
				if (!op->name || strcmp (op->name , oldop->name))
					PR_ParseError ("type mismatch for %s", oldop->name);
			}

			if (type_a == ev_pointer && type_b != e->type->aux_type->type)
				PR_ParseError ("type mismatch for %s", op->name);

#if 0
			if (e->type->constant && e2->type->constant) {
				// try to calculate the expression at compile time
				eval_t result;
				if (PR_Calc(op - pr_opcodes, (eval_t *)(pr_globals + e->ofs),
						(eval_t *)(pr_globals + e2->ofs), &result))
				{
//					printf ("line %i: folding %s %s %s into %s\n", pr_source_line, e->name, op->name, e2->name,
//						PR_ValueString(op->type_c, &val));

					type_t *resulttype;
					switch (op->type_c) {
						case ev_float: resulttype = &type_const_float; break;
						//case ev_string: resulttype = &type_const_string; break;
						case ev_vector: resulttype = &type_const_vector; break;
						default: assert (false);
					}

					e = PR_GetImmediate (resulttype, result);
					break;
				}
			}
#endif

			if (op->right_associative)
				e = PR_Statement (op, e2, e);
			else
				e = PR_Statement (op, e, e2);

			break;
		}
		if (!op->name)
			break;	// next token isn't at this priority level
	}

	return e;
}
示例#8
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
}