/*
================
idTypeDef::PointerType

If type is a pointer, then returns the type it points to
================
*/
idTypeDef *idTypeDef::PointerType( void ) const {
	if ( type != ev_pointer ) {
		throw idCompileError( "idTypeDef::PointerType: tried to get pointer type on non-pointer" );
	}

	return auxType;
}
/*
================
idTypeDef::SetPointerType

If type is a pointer, then sets the pointer's type
================
*/
void idTypeDef::SetPointerType( idTypeDef *pointertype ) {
	if ( type != ev_pointer ) {
		throw idCompileError( "idTypeDef::SetPointerType: tried to set type on non-pointer" );
	}

	auxType = pointertype;
}
/*
================
idTypeDef::FieldType

If type is a field, then returns it's type
================
*/
idTypeDef *idTypeDef::FieldType( void ) const {
	if ( type != ev_field ) {
		throw idCompileError( "idTypeDef::FieldType: tried to get field type on non-field type" );
	}

	return auxType;
}
/*
================
idTypeDef::SetFieldType

If type is a field, then sets the function's return type
================
*/
void idTypeDef::SetFieldType( idTypeDef *fieldtype ) {
	if ( type != ev_field ) {
		throw idCompileError( "idTypeDef::SetFieldType: tried to set return type on non-function type" );
	}

	auxType = fieldtype;
}
/*
================
idTypeDef::ReturnType

If type is a function, then returns the function's return type
================
*/
idTypeDef *idTypeDef::ReturnType( void ) const {
	if ( type != ev_function ) {
		throw idCompileError( "idTypeDef::ReturnType: tried to get return type on non-function type" );
	}

	return auxType;
}
/*
================
idTypeDef::SetReturnType

If type is a function, then sets the function's return type
================
*/
void idTypeDef::SetReturnType( idTypeDef *returntype ) {
	if ( type != ev_function ) {
		throw idCompileError( "idTypeDef::SetReturnType: tried to set return type on non-function type" );
	}

	auxType = returntype;
}
/*
================
idTypeDef::SuperClass

If type is an object, then returns the object's superclass
================
*/
idTypeDef *idTypeDef::SuperClass( void ) const {
	if ( type != ev_object ) {
		throw idCompileError( "idTypeDef::SuperClass : tried to get superclass of a non-object type" );
	}

	return auxType;
}
/*
============
idProgram::GetDef

If type is NULL, it will match any type
============
*/
idVarDef *idProgram::GetDef( const idTypeDef *type, const char *name, const idVarDef *scope ) const {
	idVarDef		*def;
	idVarDef		*bestDef;
	int				bestDepth;
	int				depth;

	bestDepth = 0;
	bestDef = NULL;
	for( def = GetDefList( name ); def != NULL; def = def->Next() ) {
		if ( def->scope->Type() == ev_namespace ) {
			depth = def->DepthOfScope( scope );
			if ( !depth ) {
				// not in the same namespace
				continue;
			}
		} else if ( def->scope != scope ) {
			// in a different function
			continue;
		} else {
			depth = 1;
		}

		if ( !bestDef || ( depth < bestDepth ) ) {
			bestDepth = depth;
			bestDef = def;
		}
	}

	// see if the name is already in use for another type
	if ( bestDef && type && ( bestDef->TypeDef() != type ) ) {
		throw idCompileError( va( "Type mismatch on redeclaration of %s", name ) );
	}

	return bestDef;
}
Exemple #9
0
/*
================
idProgram::AllocStatement
================
*/
statement_t *idProgram::AllocStatement( void )
{
	if( statements.Num() >= statements.Max() )
	{
		throw idCompileError( va( "Exceeded maximum allowed number of statements (%d)", statements.Max() ) );
	}
	return statements.Alloc();
}
/*
============
idVarDef::SetValue
============
*/
void idVarDef::SetValue( const eval_t &_value, bool constant ) {
	assert( typeDef );
	if ( constant ) {
		initialized = initializedConstant;
	} else {
		initialized = initializedVariable;
	}

	switch( typeDef->Type() ) {
	case ev_pointer :
	case ev_boolean :
	case ev_field :
		*value.intPtr = _value._int;
		break;

	case ev_jumpoffset :
		value.jumpOffset = _value._int;
		break;

	case ev_argsize :
		value.argSize = _value._int;
		break;

	case ev_entity :
		*value.entityNumberPtr = _value.entity;
		break;

	case ev_string :
		idStr::Copynz( value.stringPtr, _value.stringPtr, MAX_STRING_LEN );
		break;

	case ev_float :
		*value.floatPtr = _value._float;
		break;

	case ev_vector :
		value.vectorPtr->x = _value.vector[ 0 ];
		value.vectorPtr->y = _value.vector[ 1 ];
		value.vectorPtr->z = _value.vector[ 2 ];
		break;

	case ev_function :
		value.functionPtr = _value.function;
		break;

	case ev_virtualfunction :
		value.virtualFunction = _value._int;
		break;

	case ev_object :
		*value.entityNumberPtr = _value.entity;
		break;

	default :
		throw idCompileError( va( "weird type on '%s'", Name() ) );
		break;
	}
}
/*
================
idTypeDef::AddFunctionParm

Adds a new parameter for a function type.
================
*/
void idTypeDef::AddFunctionParm( idTypeDef *parmtype, const char *name ) {
	if ( type != ev_function ) {
		throw idCompileError( "idTypeDef::AddFunctionParm : tried to add parameter on non-function type" );
	}

	parmTypes.Append( parmtype );
	idStr &parmName = parmNames.Alloc();
	parmName = name;
}
Exemple #12
0
/*
================
idProgram::CompileText
================
*/
bool idProgram::CompileText( const char *source, const char *text, bool console )
{
	idCompiler	compiler;
	int			i;
	idVarDef	*def;
	idStr		ospath;
	
	// use a full os path for GetFilenum since it calls OSPathToRelativePath to convert filenames from the parser
	ospath = fileSystem->RelativePathToOSPath( source );
	filenum = GetFilenum( ospath );
	
	try
	{
		compiler.CompileFile( text, filename, console );
		
		// check to make sure all functions prototyped have code
		for( i = 0; i < varDefs.Num(); i++ )
		{
			def = varDefs[ i ];
			if( ( def->Type() == ev_function ) && ( ( def->scope->Type() == ev_namespace ) || def->scope->TypeDef()->Inherits( &type_object ) ) )
			{
				if( !def->value.functionPtr->eventdef && !def->value.functionPtr->firstStatement )
				{
					throw idCompileError( va( "function %s was not defined\n", def->GlobalName() ) );
				}
			}
		}
	}
	
	catch( idCompileError &err )
	{
		if( console )
		{
			gameLocal.Printf( "%s\n", err.error );
			return false;
		}
		else
		{
			gameLocal.Error( "%s\n", err.error );
		}
	};
	
	if( !console )
	{
		CompileStats();
	}
	
	return true;
}
/*
================
idTypeDef::AddField

Adds a new field to an object type.
================
*/
void idTypeDef::AddField( idTypeDef *fieldtype, const char *name ) {
	if ( type != ev_object ) {
		throw idCompileError( "idTypeDef::AddField : tried to add field to non-object type" );
	}

	parmTypes.Append( fieldtype );
	idStr &parmName = parmNames.Alloc();
	parmName = name;

	if ( fieldtype->FieldType()->Inherits( &type_object ) ) {
		size += type_object.Size();
	} else {
		size += fieldtype->FieldType()->Size();
	}
}
/*
================
idProgram::AllocFunction
================
*/
function_t &idProgram::AllocFunction( idVarDef *def ) {
	if ( functions.Num() >= functions.Max() ) {
		throw idCompileError( va( "Exceeded maximum allowed number of functions (%d)", functions.Max() ) );
	}

	// fill in the dfunction
	function_t &func	= *functions.Alloc();
	func.eventdef		= NULL;
	func.def			= def;
	func.type			= def->TypeDef();
	func.firstStatement	= 0;
	func.numStatements	= 0;
	func.parmTotal		= 0;
	func.locals			= 0;
	func.filenum		= filenum;
	func.parmSize.SetGranularity( 1 );
	func.SetName( def->GlobalName() );

	def->SetFunction( &func );

	return func;
}
Exemple #15
0
/*
============
idProgram::AllocDef
============
*/
idVarDef *idProgram::AllocDef( idTypeDef *type, const char *name, idVarDef *scope, bool constant )
{
	idVarDef	*def;
	idStr		element;
	idVarDef	*def_x;
	idVarDef	*def_y;
	idVarDef	*def_z;
	
	// allocate a new def
	def = new idVarDef( type );
	def->scope		= scope;
	def->numUsers	= 1;
	def->num		= varDefs.Append( def );
	
	// add the def to the list with defs with this name and set the name pointer
	AddDefToNameList( def, name );
	
	if( ( type->Type() == ev_vector ) || ( ( type->Type() == ev_field ) && ( type->FieldType()->Type() == ev_vector ) ) )
	{
		//
		// vector
		//
		if( !strcmp( name, RESULT_STRING ) )
		{
			// <RESULT> vector defs don't need the _x, _y and _z components
			assert( scope->Type() == ev_function );
			def->value.stackOffset	= scope->value.functionPtr->locals;
			def->initialized		= idVarDef::stackVariable;
			scope->value.functionPtr->locals += type->Size();
		}
		else if( scope->TypeDef()->Inherits( &type_object ) )
		{
			idTypeDef	newtype( ev_field, NULL, "float field", 0, &type_float );
			idTypeDef	*type = GetType( newtype, true );
			
			// set the value to the variable's position in the object
			def->value.ptrOffset = scope->TypeDef()->Size();
			
			// make automatic defs for the vectors elements
			// origin can be accessed as origin_x, origin_y, and origin_z
			sprintf( element, "%s_x", def->Name() );
			def_x = AllocDef( type, element, scope, constant );
			
			sprintf( element, "%s_y", def->Name() );
			def_y = AllocDef( type, element, scope, constant );
			def_y->value.ptrOffset = def_x->value.ptrOffset + type_float.Size();
			
			sprintf( element, "%s_z", def->Name() );
			def_z = AllocDef( type, element, scope, constant );
			def_z->value.ptrOffset = def_y->value.ptrOffset + type_float.Size();
		}
		else
		{
			// make automatic defs for the vectors elements
			// origin can be accessed as origin_x, origin_y, and origin_z
			sprintf( element, "%s_x", def->Name() );
			def_x = AllocDef( &type_float, element, scope, constant );
			
			sprintf( element, "%s_y", def->Name() );
			def_y = AllocDef( &type_float, element, scope, constant );
			
			sprintf( element, "%s_z", def->Name() );
			def_z = AllocDef( &type_float, element, scope, constant );
			
			// point the vector def to the x coordinate
			def->value			= def_x->value;
			def->initialized	= def_x->initialized;
		}
	}
	else if( scope->TypeDef()->Inherits( &type_object ) )
	{
		//
		// object variable
		//
		// set the value to the variable's position in the object
		def->value.ptrOffset = scope->TypeDef()->Size();
	}
	else if( scope->Type() == ev_function )
	{
		//
		// stack variable
		//
		// since we don't know how many local variables there are,
		// we have to have them go backwards on the stack
		def->value.stackOffset	= scope->value.functionPtr->locals;
		def->initialized		= idVarDef::stackVariable;
		
		if( type->Inherits( &type_object ) )
		{
			// objects only have their entity number on the stack, not the entire object
			scope->value.functionPtr->locals += type_object.Size();
		}
		else
		{
			scope->value.functionPtr->locals += type->Size();
		}
	}
	else
	{
		//
		// global variable
		//
		def->value.bytePtr = &variables[ numVariables ];
		numVariables += def->TypeDef()->Size();
		if( numVariables > sizeof( variables ) )
		{
			throw idCompileError( va( "Exceeded global memory size (%d bytes)", sizeof( variables ) ) );
		}
		
		memset( def->value.bytePtr, 0, def->TypeDef()->Size() );
	}
	
	return def;
}