Beispiel #1
0
int asCBuilder::VerifyProperty(asCDataType *dt, const char *decl, asCString &name, asCDataType &type)
{
	numErrors = 0;
	numWarnings = 0;
	preMessage.isSet = false;

	if( dt )
	{
		// Verify that the object type exist
		if( dt->GetObjectType() == 0 )
			return asINVALID_OBJECT;
	}

	// Check property declaration and type
	asCScriptCode source;
	source.SetCode(TXT_PROPERTY, decl, true);

	asCParser parser(this);
	int r = parser.ParsePropertyDeclaration(&source);
	if( r < 0 )
		return asINVALID_DECLARATION;

	// Get data type and property name
	asCScriptNode *dataType = parser.GetScriptNode()->firstChild;

	asCScriptNode *nameNode = dataType->next;

	type = CreateDataTypeFromNode(dataType, &source);
	name.Assign(&decl[nameNode->tokenPos], nameNode->tokenLength);

	// Verify property name
	if( dt )
		if( CheckNameConflictMember(*dt, name.AddressOf(), nameNode, &source) < 0 )
			return asINVALID_NAME;
	else
		if( CheckNameConflict(name.AddressOf(), nameNode, &source) < 0 )
			return asINVALID_NAME;

	if( numErrors > 0 )
		return asINVALID_DECLARATION;

	return asSUCCESS;
}
Beispiel #2
0
int asCBuilder::RegisterClass(asCScriptNode *node, asCScriptCode *file)
{
	asCScriptNode *n = node->firstChild;
	GETSTRING(name, &file->code[n->tokenPos], n->tokenLength);
	
	int r, c;
	file->ConvertPosToRowCol(n->tokenPos, &r, &c);

	CheckNameConflict(name.AddressOf(), n, file);

	sClassDeclaration *decl = new sClassDeclaration;
	classDeclarations.PushLast(decl);
	decl->name = name;
	decl->script = file;
	decl->validState = 0;
	decl->node = node;

	asCObjectType *st = new asCObjectType(engine);
	st->arrayType = 0;
	st->flags = asOBJ_CLASS_CDA | asOBJ_SCRIPT_STRUCT;
	st->size = sizeof(asCScriptStruct);
	st->name = name;
	st->tokenType = ttIdentifier;
	module->classTypes.PushLast(st);
	engine->classTypes.PushLast(st);
	st->refCount++;
	decl->objType = st;

	// Use the default script class behaviours
	st->beh.construct = engine->scriptTypeBehaviours.beh.construct;
	st->beh.constructors.PushLast(st->beh.construct);
	st->beh.addref = engine->scriptTypeBehaviours.beh.addref;
	st->beh.release = engine->scriptTypeBehaviours.beh.release;
	st->beh.copy = engine->scriptTypeBehaviours.beh.copy;
	st->beh.operators.PushLast(ttAssignment);
	st->beh.operators.PushLast(st->beh.copy);

	return 0;
}
Beispiel #3
0
int asCBuilder::RegisterGlobalVar(asCScriptNode *node, asCScriptCode *file)
{
	// What data type is it?
	asCDataType type = CreateDataTypeFromNode(node->firstChild, file);

	if( type.GetSizeOnStackDWords() == 0 || 
		(type.IsObject() && !type.IsObjectHandle() && type.GetSizeInMemoryBytes() == 0) )
	{
		asCString str;
		// TODO: Change to "'type' cannot be declared as variable"
		str.Format(TXT_DATA_TYPE_CANT_BE_s, type.Format().AddressOf());
		
		int r, c;
		file->ConvertPosToRowCol(node->tokenPos, &r, &c);
		
		WriteError(file->name.AddressOf(), str.AddressOf(), r, c);
	}

	asCScriptNode *n = node->firstChild->next;

	while( n )
	{
		// Verify that the name isn't taken
		GETSTRING(name, &file->code[n->tokenPos], n->tokenLength);
		CheckNameConflict(name.AddressOf(), n, file);

		// Register the global variable
		sGlobalVariableDescription *gvar = new sGlobalVariableDescription;
		globVariables.PushLast(gvar);

		gvar->script     = file;
		gvar->name       = name;
		gvar->isCompiled = false;
		gvar->datatype   = type;

		// TODO: Give error message if wrong
		assert(!gvar->datatype.IsReference());

		// Allocate space on the global memory stack
		gvar->index = module->AllocGlobalMemory(gvar->datatype.GetSizeOnStackDWords());
		gvar->node = 0;
		if( n->next && 
			(n->next->nodeType == snAssignment ||
			 n->next->nodeType == snArgList    || 
			 n->next->nodeType == snInitList     ) )
		{
			gvar->node = n->next;
			n->next->DisconnectParent();
		}

		// Add script variable to engine
		asCProperty *prop = new asCProperty;
		prop->index      = gvar->index;
		prop->name       = name;
		prop->type       = gvar->datatype;
		module->scriptGlobals.PushLast(prop);

		gvar->property = prop;

		n = n->next;
	}

	delete node;

	return 0;
}
Beispiel #4
0
int asCBuilder::RegisterImportedFunction(int importID, asCScriptNode *node, asCScriptCode *file)
{
	// Find name 
	asCScriptNode *f = node->firstChild;
	asCScriptNode *n = f->firstChild->next->next;

	// Check for name conflicts
	GETSTRING(name, &file->code[n->tokenPos], n->tokenLength);
	CheckNameConflict(name.AddressOf(), n, file);

	// Initialize a script function object for registration
	asCDataType returnType;
	returnType = CreateDataTypeFromNode(f->firstChild, file);
	returnType = ModifyDataTypeFromNode(returnType, f->firstChild->next, file, 0, 0);
		
	asCArray<asCDataType> parameterTypes;
	asCArray<int> inOutFlags;
	n = n->next->firstChild;
	while( n )
	{
		int inOutFlag;
		asCDataType type = CreateDataTypeFromNode(n, file);
		type = ModifyDataTypeFromNode(type, n->next, file, &inOutFlag, 0);

		// Store the parameter type
		n = n->next->next;
		parameterTypes.PushLast(type);
		inOutFlags.PushLast(inOutFlag);

		// Move to next parameter
		if( n && n->nodeType == snIdentifier )
			n = n->next;
	}

	// Check that the same function hasn't been registered already
	asCArray<int> funcs;
	GetFunctionDescriptions(name.AddressOf(), funcs);
	if( funcs.GetLength() )
	{
		for( asUINT n = 0; n < funcs.GetLength(); ++n )
		{
			asCScriptFunction *func = GetFunctionDescription(funcs[n]);

			// TODO: Isn't the name guaranteed to be equal, because of GetFunctionDescriptions()?
			if( name == func->name && 
				parameterTypes.GetLength() == func->parameterTypes.GetLength() )
			{
				bool match = true;
				for( asUINT p = 0; p < parameterTypes.GetLength(); ++p )
				{
					if( parameterTypes[p] != func->parameterTypes[p] )
					{
						match = false;
						break;
					}
				}

				if( match )
				{
					int r, c;
					file->ConvertPosToRowCol(node->tokenPos, &r, &c);

					WriteError(file->name.AddressOf(), TXT_FUNCTION_ALREADY_EXIST, r, c);
					break;
				}
			}
		}
		
	}

	// Read the module name as well
	n = node->firstChild->next;
	int moduleNameString = module->AddConstantString(&file->code[n->tokenPos+1], n->tokenLength-2);

	delete node;

	// Register the function
	module->AddImportedFunction(importID, name.AddressOf(), returnType, parameterTypes.AddressOf(), inOutFlags.AddressOf(), (asUINT)parameterTypes.GetLength(), moduleNameString);

	return 0;
}
Beispiel #5
0
int asCBuilder::RegisterScriptFunction(int funcID, asCScriptNode *node, asCScriptCode *file, asCObjectType *objType, bool isInterface)
{
	// Find name 
	bool isConstructor = false;
	asCScriptNode *n = 0;
	if( node->firstChild->nodeType == snDataType )
		n = node->firstChild->next->next;
	else
	{
		n = node->firstChild;
		isConstructor = true;
	}

	// Check for name conflicts
	GETSTRING(name, &file->code[n->tokenPos], n->tokenLength);
	if( !isConstructor )
		CheckNameConflict(name.AddressOf(), n, file);
	else
	{
		// Verify that the name of the function is the same as the class
		if( name != objType->name )
		{
			int r, c;
			file->ConvertPosToRowCol(n->tokenPos, &r, &c);
			WriteError(file->name.AddressOf(), TXT_CONSTRUCTOR_NAME_ERROR, r, c);
		}
	}

	if( !isInterface )
	{
		sFunctionDescription *func = new sFunctionDescription;
		functions.PushLast(func);

		func->script  = file;
		func->node    = node;
		func->name    = name;
		func->objType = objType;
		func->funcId  = funcID;
	}

	// Initialize a script function object for registration
	asCDataType returnType = asCDataType::CreatePrimitive(ttVoid, false);
	if( !isConstructor )
	{
		returnType = CreateDataTypeFromNode(node->firstChild, file);
		returnType = ModifyDataTypeFromNode(returnType, node->firstChild->next, file, 0, 0);

		module->RefConfigGroupForObjectType(returnType.GetObjectType());
	}

	asCArray<asCDataType> parameterTypes;
	asCArray<int> inOutFlags;
	n = n->next->firstChild;
	while( n )
	{
		int inOutFlag;
		asCDataType type = CreateDataTypeFromNode(n, file);
		type = ModifyDataTypeFromNode(type, n->next, file, &inOutFlag, 0);

		module->RefConfigGroupForObjectType(type.GetObjectType());

		// Store the parameter type
		parameterTypes.PushLast(type);
		inOutFlags.PushLast(inOutFlag);

		// Move to next parameter
		n = n->next->next;
		if( n && n->nodeType == snIdentifier )
			n = n->next;
	}

	// Check that the same function hasn't been registered already
	asCArray<int> funcs;
	GetFunctionDescriptions(name.AddressOf(), funcs);
	if( funcs.GetLength() )
	{
		for( asUINT n = 0; n < funcs.GetLength(); ++n )
		{
			asCScriptFunction *func = GetFunctionDescription(funcs[n]);

			if( parameterTypes.GetLength() == func->parameterTypes.GetLength() )
			{
				bool match = true;
				for( asUINT p = 0; p < parameterTypes.GetLength(); ++p )
				{
					if( parameterTypes[p] != func->parameterTypes[p] )
					{
						match = false;
						break;
					}
				}

				if( match )
				{
					int r, c;
					file->ConvertPosToRowCol(node->tokenPos, &r, &c);

					WriteError(file->name.AddressOf(), TXT_FUNCTION_ALREADY_EXIST, r, c);
					break;
				}
			}
		}
	}

	// Register the function
	module->AddScriptFunction(file->idx, funcID, name.AddressOf(), returnType, parameterTypes.AddressOf(), inOutFlags.AddressOf(), (asUINT)parameterTypes.GetLength(), isInterface, objType);

	if( objType )
	{
		if( isConstructor )
		{
			if( parameterTypes.GetLength() == 0 )
			{
				// Overload the default constructor
				objType->beh.construct = funcID;
				objType->beh.constructors[0] = funcID;
			}
			else
				objType->beh.constructors.PushLast(funcID);
		}
		else
			objType->methods.PushLast(funcID);
	}

	// We need to delete the node already if this is an interface method
	if( isInterface && node )
		delete node;

	return 0;
}
Beispiel #6
0
int asCBuilder::RegisterScriptFunction(int funcID, asCScriptNode *node, asCScriptCode *file)
{
	// Find name 
	asCScriptNode *n = node->firstChild->next->next;

	// Check for name conflicts
	GETSTRING(name, &file->code[n->tokenPos], n->tokenLength);
	CheckNameConflict(name.AddressOf(), n, file);

	sFunctionDescription *func = new sFunctionDescription;
	functions.PushLast(func);

	func->script = file;
	func->node   = node;
	func->name   = name;

	// Initialize a script function object for registration
	asCDataType returnType;
	returnType = CreateDataTypeFromNode(node->firstChild, file);
	returnType = ModifyDataTypeFromNode(returnType, node->firstChild->next, 0, 0);
		
	module->RefConfigGroupForObjectType(returnType.GetObjectType());

	asCArray<asCDataType> parameterTypes;
	asCArray<int> inOutFlags;
	n = n->next->firstChild;
	while( n )
	{
		int inOutFlag;
		asCDataType type = CreateDataTypeFromNode(n, file);
		type = ModifyDataTypeFromNode(type, n->next, &inOutFlag, 0);

		module->RefConfigGroupForObjectType(type.GetObjectType());

		// Store the parameter type
		parameterTypes.PushLast(type);
		inOutFlags.PushLast(inOutFlag);

		// Move to next parameter
		n = n->next->next;
		if( n && n->nodeType == snIdentifier )
			n = n->next;
	}

	// Check that the same function hasn't been registered already
	asCArray<int> funcs;
	GetFunctionDescriptions(name.AddressOf(), funcs);
	if( funcs.GetLength() )
	{
		for( asUINT n = 0; n < funcs.GetLength(); ++n )
		{
			asCScriptFunction *func = GetFunctionDescription(funcs[n]);

			if( parameterTypes.GetLength() == func->parameterTypes.GetLength() )
			{
				bool match = true;
				for( asUINT p = 0; p < parameterTypes.GetLength(); ++p )
				{
					if( parameterTypes[p] != func->parameterTypes[p] )
					{
						match = false;
						break;
					}
				}

				if( match )
				{
					int r, c;
					file->ConvertPosToRowCol(node->tokenPos, &r, &c);

					WriteError(file->name.AddressOf(), TXT_FUNCTION_ALREADY_EXIST, r, c);
					break;
				}
			}
		}
	}

	// Register the function
	module->AddScriptFunction(file->idx, funcID, func->name.AddressOf(), returnType, parameterTypes.AddressOf(), inOutFlags.AddressOf(), parameterTypes.GetLength());

	return 0;
}