コード例 #1
0
ファイル: PR_LEX.C プロジェクト: ChunHungLiu/Quake-Tools
/*
==============
PR_LexGrab

Deals with counting sequence numbers and replacing frame macros
==============
*/
void PR_LexGrab (void)
{	
	pr_file_p++;	// skip the $
	if (!PR_SimpleGetToken ())
		PR_ParseError ("hanging $");
	
// check for $frame
	if (!strcmp (pr_token, "frame"))
	{
		PR_ParseFrame ();
		PR_Lex ();
	}
// ignore other known $commands
	else if (!strcmp (pr_token, "cd")
	|| !strcmp (pr_token, "origin")
	|| !strcmp (pr_token, "base")
	|| !strcmp (pr_token, "flags")
	|| !strcmp (pr_token, "scale")
	|| !strcmp (pr_token, "skin") )
	{	// skip to end of line
		while (PR_SimpleGetToken ())
		;
		PR_Lex ();
	}
// look for a frame name macro
	else
		PR_FindMacro ();
}
コード例 #2
0
ファイル: PR_COMP.C プロジェクト: ChunHungLiu/Quake-Tools
/*
============
PR_CompileFile

compiles the 0 terminated text, adding defintions to the pr structure
============
*/
qboolean	PR_CompileFile (char *string, char *filename)
{	
	if (!pr.memory)
		Error ("PR_CompileFile: Didn't clear");

	PR_ClearGrabMacros ();	// clear the frame macros
		
	pr_file_p = string;
	s_file = CopyString (filename);

	pr_source_line = 0;
	
	PR_NewLine ();

	PR_Lex ();	// read first token

	while (pr_token_type != tt_eof)
	{
		if (setjmp(pr_parse_abort))
		{
			if (++pr_error_count > MAX_ERRORS)
				return false;
			PR_SkipToSemicolon ();
			if (pr_token_type == tt_eof)
				return false;		
		}

		pr_scope = NULL;	// outside all functions
		
		PR_ParseDefs ();
	}
	
	return (pr_error_count == 0);
}
コード例 #3
0
ファイル: pr_lex.c プロジェクト: base698/ProQCC
void 
PR_Expect(char *string)
{
    if (DefCmp(string, pr_token))
	PR_ParseError("expected %s, found %s", string, pr_token);
    PR_Lex();
}
コード例 #4
0
ファイル: PR_LEX.C プロジェクト: ChunHungLiu/Quake-Tools
/*
=============
PR_Check

Returns true and gets the next token if the current token equals string
Returns false and does nothing otherwise
=============
*/
qboolean PR_Check (char *string)
{
	if (strcmp (string, pr_token))
		return false;
		
	PR_Lex ();
	return true;
}
コード例 #5
0
ファイル: PR_LEX.C プロジェクト: ChunHungLiu/Quake-Tools
/*
============
PR_SkipToSemicolon

For error recovery, also pops out of nested braces
============
*/
void PR_SkipToSemicolon (void)
{
	do
	{
		if (!pr_bracelevel && PR_Check (";"))
			return;
		PR_Lex ();
	} while (pr_token[0]);	// eof will return a null token
}
コード例 #6
0
ファイル: qcc.c プロジェクト: fmutant/scriptorium
void PR_Expect (char *string, token_type_t type)
{
	if (STRCMP(string, pr_token))
		PR_ParseError (550, "Expected %s, found %s",string, pr_token);
	if (type)
		if (pr_token_type != type)
			PR_ParseError (550, "Expected %s, found %s",string, pr_token);
	PR_Lex ();
} 
コード例 #7
0
ファイル: PR_COMP.C プロジェクト: ChunHungLiu/Quake-Tools
/*
============
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;
}
コード例 #8
0
ファイル: qcc.c プロジェクト: fmutant/scriptorium
boolean PR_Check (char *string, token_type_t type)
{
	if (STRCMP(string, pr_token))
		return false;
	if (type)
		if (pr_token_type != type)
			return false;

	PR_Lex ();
	return true;
}
コード例 #9
0
ファイル: pr_comp.cpp プロジェクト: luaman/zq
/*
============
PR_ParseImmediate

Allocates the immediate if needed and gets next token
============
*/
def_t *PR_ParseImmediate (void)
{
	assert (pr_immediate_type == &type_const_float ||
			pr_immediate_type == &type_const_string ||
			pr_immediate_type == &type_const_vector);

	def_t *def = PR_GetImmediate (pr_immediate_type, pr_immediate, pr_immediate_string);
	PR_Lex ();

	return def;
}
コード例 #10
0
ファイル: PR_LEX.C プロジェクト: ChunHungLiu/Quake-Tools
/*
============
PR_ParseName

Checks to see if the current token is a valid name
============
*/
char *PR_ParseName (void)
{
	static char	ident[MAX_NAME];
	
	if (pr_token_type != tt_name)
		PR_ParseError ("not a name");
	if (strlen(pr_token) >= MAX_NAME-1)
		PR_ParseError ("name too long");
	strcpy (ident, pr_token);
	PR_Lex ();
	
	return ident;
}
コード例 #11
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;
}
コード例 #12
0
ファイル: pr_comp.cpp プロジェクト: luaman/zq
/*
================
PR_ParseInitialization

"<type> <name> = " was parsed, parse the rest
================
*/
void PR_ParseInitialization (type_t *type, char *name, def_t *def)
{
	if (def->initialized)
		PR_ParseError ("%s redeclared", name);

	if (pr_token_type != tt_immediate && pr_token_type != tt_name)
		PR_ParseError ("syntax error : '%s'", pr_token);

	if (pr_token_type == tt_name) {
		PR_ParseError ("initializer is not a constant");
	}

	if (!CompareType(pr_immediate_type, type))
		PR_ParseError ("wrong immediate type for %s", name);

	def->initialized = 1;
	if (type == &type_const_string || type == &type_string)
		pr_immediate.string = CopyString (pr_immediate_string);
	memcpy (pr_globals + def->ofs, &pr_immediate, 4*type_size[pr_immediate_type->type]);
	PR_Lex ();
}
コード例 #13
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 (";");
}
コード例 #14
0
ファイル: PR_COMP.C プロジェクト: ChunHungLiu/Quake-Tools
/*
============
PR_ParseImmediate

Looks for a preexisting constant
============
*/
def_t	*PR_ParseImmediate (void)
{
	def_t	*cn;
	
// check for a constant with the same value
	for (cn=pr.def_head.next ; cn ; cn=cn->next)
	{
		if (!cn->initialized)
			continue;
		if (cn->type != pr_immediate_type)
			continue;
		if (pr_immediate_type == &type_string)
		{
			if (!strcmp(G_STRING(cn->ofs), pr_immediate_string) )
			{
				PR_Lex ();
				return cn;
			}
		}
		else if (pr_immediate_type == &type_float)
		{
			if ( G_FLOAT(cn->ofs) == pr_immediate._float )
			{
				PR_Lex ();
				return cn;
			}
		}
		else if	(pr_immediate_type == &type_vector)
		{
			if ( ( G_FLOAT(cn->ofs) == pr_immediate.vector[0] )
			&& ( G_FLOAT(cn->ofs+1) == pr_immediate.vector[1] )
			&& ( G_FLOAT(cn->ofs+2) == pr_immediate.vector[2] ) )
			{
				PR_Lex ();
				return cn;
			}
		}
		else			
			PR_ParseError ("weird immediate type");		
	}
	
// allocate a new one
	cn = malloc (sizeof(def_t));
	cn->next = NULL;

	pr.def_tail->next = cn;
	pr.def_tail = cn;

	cn->search_next = pr.search;
	pr.search = cn;

	cn->type = pr_immediate_type;
	cn->name = "IMMEDIATE";
	cn->initialized = 1;
	cn->scope = NULL;		// always share immediates

// copy the immediate to the global area
	cn->ofs = numpr_globals;
	pr_global_defs[cn->ofs] = cn;
	numpr_globals += type_size[pr_immediate_type->type];
	if (pr_immediate_type == &type_string)
		pr_immediate.string = CopyString (pr_immediate_string);
	
	memcpy (pr_globals + cn->ofs, &pr_immediate, 4*type_size[pr_immediate_type->type]);
	
	PR_Lex ();

	return cn;
}
コード例 #15
0
ファイル: pr_lex.cpp プロジェクト: luaman/zq
/*
========================
PR_LexPrecomp

parses and executes directives
  with a leading '#':
  #define
  #undef
  #ifdef
  #ifndef
  #else
  #endif
  #error
  #message
  #pragma message
========================
*/
void          PR_LexPrecomp (void)
{
	// yeah it isn't quite Precompiler is it?
	pr_file_p++;  // skip the hash
	if (!PR_SimpleGetToken ())
		PR_ParseError ("Q534: Invalid preprocessor command"); // that's not possible

	if (!strcmp(pr_token, "ifdef"))
	{
		if (ifdefdepth > ignoredepth)
		{
			// inside another ignored "ifdef"/"ifndef"
			// -> ignore statements
			ifdefdepth++;
			return;
		}
		ifdefdepth++;
		ignoredepth = ifdefdepth;
		PR_Lex();
		if (!PR_FindDefine(pr_token, true))
		{
			// not defined
			// -> ignore statements until endif or else
			ignoredepth--;
			while(ifdefdepth > ignoredepth)
				PR_Lex();
			return;
		}
		// defined
		// -> parse statements
		PR_Lex();
		return;
	}
	else
	if (!strcmp(pr_token, "ifndef"))
	{
		if (ifdefdepth > ignoredepth)
		{
			// inside another ignored ifdef
			// -> ignore statements
			ifdefdepth++;
			return;
		}
		ifdefdepth++;
		ignoredepth = ifdefdepth;
		PR_Lex();
		if (PR_FindDefine(pr_token, true))
		{
			// defined
			// -> ignore statements
			ignoredepth--;
			while(ifdefdepth > ignoredepth)
				PR_Lex();
			return;
		}
		PR_Lex();
		return;
	}
	else
	if (!strcmp(pr_token, "endif"))
	{
		ifdefdepth--;
		if (ifdefdepth < 0)
		  PR_ParseError ("Q119: Too many #endifs");
		PR_Lex();
		return;
	}
	else
	if (!strcmp(pr_token, "else"))
	{
		if (ifdefdepth == (ignoredepth + 1))
		{
			// the "ifdef" or "ifndef" part has not been entered
			// -> parse the statements inside "else"
			//print("parsing statment %s in else on %s(%ld)", pr_token, s_file + strings, pr_source_line);
			ignoredepth = ifdefdepth;
			pr_token_type = tt_name;
			PR_Lex();
			return;
		}

		// "ifdef" or "ifndef" part has already been entered
		// -> ignore statements in "else" part
		ignoredepth--;
		while (ifdefdepth > ignoredepth)
			PR_Lex();
		return;
	}
	else
	if (ifdefdepth > ignoredepth)
	{
		//print("ignored %s on %s(%ld)", pr_token, s_file + strings, pr_source_line);
		return;
	}
	else
	if (PR_Check("error"))
	{
		if (pr_immediate_type != &type_string && pr_immediate_type != &type_const_string)
		  PR_ParseError ("Q541: Error must be a string");
		PR_ParseError ("User Error on %s(%ld): %s", s_file + strings, pr_source_line, pr_immediate_string);
		PR_Lex();
		return;
	}
	else
	if (PR_Check("message"))
	{
		if (pr_immediate_type != &type_string && pr_immediate_type != &type_const_string)
		  PR_ParseError ("Q541: Message must be a string");
		printf ("Message on %s(%ld): %s\n", s_file + strings, (long)pr_source_line, pr_immediate_string);
		PR_Lex();
		return;
	}
	else
	if (PR_Check("pragma"))
	{
		if (PR_Check("message"))
		{
			if (pr_immediate_type != &type_string && pr_immediate_type != &type_const_string)
				PR_ParseError ("Q541: Message must be a string");
			printf ("Message on %s(%ld): %s\n", s_file + strings, (long)pr_source_line, pr_immediate_string);
			PR_Lex();
			return;
		}

		// unknown pragma directive
		printf ("Warning on %s(%ld): unknown #pragma \"%s\" (will be ignored)", s_file + strings, (long)pr_source_line, pr_token);

		// skip to the end of the line
		while (PR_SimpleGetToken ())
			;

		PR_Lex();
		return;
	}
	else
	if (PR_Check("define"))
	{
		char	define_name[2048];

		if (pr_token_type != tt_name)
			PR_ParseError ("Q543: #define: Invalid name");

		// predefine it:
		strlcpy (define_name, pr_token, sizeof(define_name));

		if (PR_AddDefine (define_name, &type_const_float, NULL, false) <= 0)
			PR_ParseError ("Q544: #define \"%s\": creation failed", define_name);

		// get the value of the define
		PR_Lex();
		if (pr_token_type == tt_immediate)
		{
			if (pr_immediate_type != &type_float && pr_immediate_type != &type_const_float)
				PR_ParseError ("Q545: #define \"%s\": Invalid type of value", define_name);

         // finally fix the define (with given value)
			if (PR_AddDefine (define_name, pr_immediate_type, &pr_immediate, false) <= 0)
				PR_ParseError ("Q544: #define \"%s\": creation failed", define_name);

			PR_Lex();
		}
		else
		{
			eval_t   value;

			value._float = 1;

			// finally fix the define (with default-value)
			if (PR_AddDefine (define_name, &type_const_float, &value, false) <= 0)
				PR_ParseError ("Q544: #define \"%s\": creation failed", define_name);
		}

		return;
	}
	else
	if (PR_Check("undef"))
	{
		if (pr_token_type != tt_name)
			PR_ParseError ("Q544: #undef: Invalid name");

		PR_DelDefine (pr_token, false);

		PR_Lex();
		return;
	}
} // END_FUNC PR_LexPrecomp