Exemple #1
0
        private void ParseAndAddMemberToStruct(Token variableType, Token structName, ScriptStruct structDefinition, Token parentStruct)
        {
            _source.IgnoreAsteriskIfPresent();
            Token memberName = _source.ReadNextToken();

            if ((memberName is KeywordToken) || (memberName is OperatorToken) ||
                (memberName is ModifierToken))
            {
                throw new CompilerMessage(ErrorCode.TokenAlreadyDefined, "Cannot use '" + memberName.Name + "' as variable name since it has another meaning");
            }

            string mangledName;

            memberName = GetTokenForStructMember(structName, memberName, out mangledName);
            if (memberName != null)
            {
                throw new CompilerMessage(ErrorCode.TokenAlreadyDefined, "Member '" + mangledName + "' already exists");
            }
            memberName = new Token(mangledName, true);
            // TODO: Set necessary fields on new token for this struct member
            _tokenizedScript.AddToken(memberName);

            CompilerUtils.SetArrayPropertiesOnTokenFromStream(_source, memberName);

            if (_source.NextIsKeyword(PredefinedSymbol.OpenParenthesis))
            {
                VerifyModifiersAgainstType(ModifierTargets.MemberFunction);
                VerifyReturnTypeValidForFunction(variableType);

                ScriptFunction func = new ScriptFunction(variableType, memberName);
                ParseFunctionParameterList(func);

                func.IsPrototypeOnly = true;
            }
            else
            {
                VerifyModifiersAgainstType(ModifierTargets.MemberVariable);
                ProcessVariableDeclaration(variableType, structDefinition, parentStruct, _state.NextTokenModifiers);
            }
        }
Exemple #2
0
        private FixedOffsetVariable ProcessVariableDeclaration(Token variableType, DataGroup container, Token parent, Modifiers modifiers)
        {
            FixedOffsetVariable newVariable;
            int thisSize = 0;

            if (variableType.Type == TokenType.StructType)
            {
                ScriptStruct childStruct = (ScriptStruct)variableType.Value;
                if (childStruct.IsManaged)
                {
                    thisSize    = FixedOffsetVariable.POINTER_SIZE_IN_BYTES;
                    newVariable = new FixedOffsetVariable(variableType, container.SizeInBytes, true);

                    if ((childStruct != container) &&
                        (parent != null) &&
                        (childStruct.HasNonImportedMemberOfType(parent)))
                    {
                        throw new CompilerMessage(ErrorCode.CircularReference, "The type '" + childStruct.Name + "' has a reference to this struct, so you cannot also have a reference this way round");
                    }
                }
                else if (childStruct == container)
                {
                    throw new CompilerMessage(ErrorCode.StructInsideItself, "A struct cannot be contained within itself");
                }
                else
                {
                    thisSize    = childStruct.SizeInBytes;
                    newVariable = new FixedOffsetVariable(variableType, container.SizeInBytes, thisSize);
                }
            }
            else if (variableType is ScalarVariableTypeToken)
            {
                thisSize    = ((ScalarVariableTypeToken)variableType).SizeInBytes;
                newVariable = new FixedOffsetVariable(variableType, container.SizeInBytes, thisSize);
            }
            else if (variableType.Type == TokenType.EnumType)
            {
                thisSize    = FixedOffsetVariable.ENUM_SIZE_IN_BYTES;
                newVariable = new FixedOffsetVariable(variableType, container.SizeInBytes, thisSize);
            }
            else
            {
                throw new CompilerMessage(ErrorCode.CannotUseTypeInStruct, "Cannot add variable of type '" + variableType.Name + "' to struct");
            }
            newVariable.IsAttributeProperty = modifiers.HasModifier(Modifiers.ATTRIBUTE);
            newVariable.IsImported          = modifiers.HasModifier(Modifiers.IMPORT);

            if ((newVariable.IsAttributeProperty) &&
                (!newVariable.IsImported))
            {
                throw new CompilerMessage(ErrorCode.AttributesMustBeImported, "Attribute types must be imported");
            }

            if ((newVariable.IsImported) &&
                (!newVariable.IsAttributeProperty) &&
                (parent != null))
            {
                throw new CompilerMessage(ErrorCode.InvalidUseOfKeyword, "'import' is invalid in this context");
            }

            if (newVariable.IsImported)
            {
                // No memory needed for imported vars
                newVariable.Offset = 0;
                thisSize           = 0;
            }

            container.Members.Add(newVariable);
            container.SizeInBytes += thisSize;
            return(newVariable);
        }
Exemple #3
0
        private ScriptStruct ProcessStructDeclaration()
        {
            VerifyModifiersAgainstType(ModifierTargets.Struct);

            Modifiers prototypeModifiers = null;
            Token     structName         = _source.ReadNextToken();

            if (structName.Defined)
            {
                if ((structName.Type == TokenType.StructType) &&
                    (structName.StructType.PrototypeOnly))
                {
                    prototypeModifiers = structName.StructType.Modifiers;
                }
                else
                {
                    throw new CompilerMessage(ErrorCode.TokenAlreadyDefined, "Token '" + structName.Name + "' is already defined");
                }
            }

            ScriptStruct structDefinition = new ScriptStruct(structName.Name);

            structDefinition.Modifiers = _state.NextTokenModifiers;
            structName.Define(TokenType.StructType, structDefinition);
            structName.IsVariableType = true;

            if (_state.IsModifierPresent(PredefinedSymbol.Managed))
            {
                structDefinition.IsManaged = true;
            }

            _state.NextTokenModifiers = new Modifiers();

            if (_source.NextIsKeyword(PredefinedSymbol.Semicolon))
            {
                structDefinition.PrototypeOnly = true;
                return(structDefinition);
            }

            if (prototypeModifiers != null)
            {
                if (!structDefinition.Modifiers.HasSameModifiers(prototypeModifiers))
                {
                    RecordError(ErrorCode.DifferentModifierInPrototype, "This struct has different modifiers to the prototype");
                }
            }

            if (_source.NextIsKeyword(PredefinedSymbol.Extends))
            {
                Token structToExtend = _source.ReadNextAsVariableType();
                if (structToExtend.Type != TokenType.StructType)
                {
                    RecordError(ErrorCode.StructNameExpected, "Struct name expected at '" + structToExtend.Name + "'");
                }
                else
                {
                    ScriptStruct baseStructDefinition = ((ScriptStruct)structToExtend.Value);
                    if (baseStructDefinition.PrototypeOnly)
                    {
                        RecordError(ErrorCode.CannotExtendPrototypeStruct, "Cannot extend struct '" + baseStructDefinition.Name + "' because it is only a prototype");
                    }
                    structDefinition.Extends     = baseStructDefinition;
                    structDefinition.SizeInBytes = baseStructDefinition.SizeInBytes;
                    structDefinition.Members.AddRange(baseStructDefinition.Members);

                    if (!structDefinition.Modifiers.HasSameModifiers(baseStructDefinition.Modifiers))
                    {
                        RecordError(ErrorCode.DifferentModifierInPrototype, "This struct has different modifiers to the base type");
                    }
                }
            }

            _source.ExpectKeyword(PredefinedSymbol.OpenBrace);

            while (!_source.NextIsKeyword(PredefinedSymbol.CloseBrace))
            {
                Token token = _source.ReadNextToken();
                if (token is ModifierToken)
                {
                    _state.NextTokenModifiers.Add((ModifierToken)token);
                }
                else if (token.IsVariableType)
                {
                    do
                    {
                        ParseAndAddMemberToStruct(token, structName, structDefinition, structName);
                    }while (_source.NextIsKeyword(PredefinedSymbol.Comma));

                    _source.ExpectKeyword(PredefinedSymbol.Semicolon);
                    _state.NextTokenModifiers.Clear();
                }
                else
                {
                    RecordError(ErrorCode.UnexpectedToken, "Unexpected " + token.Name);
                }
            }

            _source.ExpectKeyword(PredefinedSymbol.Semicolon);

            return(structDefinition);
        }
Exemple #4
0
 public void AddStruct(ScriptStruct newStruct)
 {
     _structs.Add(newStruct);
 }
Exemple #5
0
		private void ParseAndAddMemberToStruct(Token variableType, Token structName, ScriptStruct structDefinition, Token parentStruct)
		{
            _source.IgnoreAsteriskIfPresent();
			Token memberName = _source.ReadNextToken();
            if ((memberName is KeywordToken) || (memberName is OperatorToken) ||
                (memberName is ModifierToken))
            {
                throw new CompilerMessage(ErrorCode.TokenAlreadyDefined, "Cannot use '" + memberName.Name + "' as variable name since it has another meaning");
            }

            string mangledName;
            memberName = GetTokenForStructMember(structName, memberName, out mangledName);
			if (memberName != null)
			{
				throw new CompilerMessage(ErrorCode.TokenAlreadyDefined, "Member '" + mangledName + "' already exists");
			}
			memberName = new Token(mangledName, true);
			// TODO: Set necessary fields on new token for this struct member
			_tokenizedScript.AddToken(memberName);

			CompilerUtils.SetArrayPropertiesOnTokenFromStream(_source, memberName);

			if (_source.NextIsKeyword(PredefinedSymbol.OpenParenthesis))
			{
                VerifyModifiersAgainstType(ModifierTargets.MemberFunction);
                VerifyReturnTypeValidForFunction(variableType);

                ScriptFunction func = new ScriptFunction(variableType, memberName);
                ParseFunctionParameterList(func);

                func.IsPrototypeOnly = true;
            }
			else
			{
                VerifyModifiersAgainstType(ModifierTargets.MemberVariable);
                ProcessVariableDeclaration(variableType, structDefinition, parentStruct, _state.NextTokenModifiers);
			}
		}
Exemple #6
0
        private ScriptStruct ProcessStructDeclaration()
		{
			VerifyModifiersAgainstType(ModifierTargets.Struct);

            Modifiers prototypeModifiers = null;
			Token structName = _source.ReadNextToken();
            if (structName.Defined)
            {
                if ((structName.Type == TokenType.StructType) &&
                    (structName.StructType.PrototypeOnly))
                {
                    prototypeModifiers = structName.StructType.Modifiers;
                }
                else
                {
                    throw new CompilerMessage(ErrorCode.TokenAlreadyDefined, "Token '" + structName.Name + "' is already defined");
                }
            }

			ScriptStruct structDefinition = new ScriptStruct(structName.Name);
            structDefinition.Modifiers = _state.NextTokenModifiers;
			structName.Define(TokenType.StructType, structDefinition);
			structName.IsVariableType = true;

            if (_state.IsModifierPresent(PredefinedSymbol.Managed))
            {
                structDefinition.IsManaged = true;
            }

            _state.NextTokenModifiers = new Modifiers();

            if (_source.NextIsKeyword(PredefinedSymbol.Semicolon))
            {
                structDefinition.PrototypeOnly = true;
                return structDefinition;
            }

            if (prototypeModifiers != null)
            {
                if (!structDefinition.Modifiers.HasSameModifiers(prototypeModifiers))
                {
                    RecordError(ErrorCode.DifferentModifierInPrototype, "This struct has different modifiers to the prototype");
                }
            }

            if (_source.NextIsKeyword(PredefinedSymbol.Extends))
			{
				Token structToExtend = _source.ReadNextAsVariableType();
				if (structToExtend.Type != TokenType.StructType)
				{
					RecordError(ErrorCode.StructNameExpected, "Struct name expected at '" + structToExtend.Name + "'");
				}
				else
				{
					ScriptStruct baseStructDefinition = ((ScriptStruct)structToExtend.Value);
                    if (baseStructDefinition.PrototypeOnly)
                    {
                        RecordError(ErrorCode.CannotExtendPrototypeStruct, "Cannot extend struct '" + baseStructDefinition.Name + "' because it is only a prototype");
                    }
					structDefinition.Extends = baseStructDefinition;
                    structDefinition.SizeInBytes = baseStructDefinition.SizeInBytes;
					structDefinition.Members.AddRange(baseStructDefinition.Members);

                    if (!structDefinition.Modifiers.HasSameModifiers(baseStructDefinition.Modifiers))
                    {
                        RecordError(ErrorCode.DifferentModifierInPrototype, "This struct has different modifiers to the base type");
                    }
				}
			}

			_source.ExpectKeyword(PredefinedSymbol.OpenBrace);

			while (!_source.NextIsKeyword(PredefinedSymbol.CloseBrace))
			{
				Token token = _source.ReadNextToken();
				if (token is ModifierToken)
				{
					_state.NextTokenModifiers.Add((ModifierToken)token);
				}
				else if (token.IsVariableType)
				{
					do
					{
						ParseAndAddMemberToStruct(token, structName, structDefinition, structName);
					}
					while (_source.NextIsKeyword(PredefinedSymbol.Comma));

					_source.ExpectKeyword(PredefinedSymbol.Semicolon);
					_state.NextTokenModifiers.Clear();
				}
				else
				{
					RecordError(ErrorCode.UnexpectedToken, "Unexpected " + token.Name);
				}
			}

			_source.ExpectKeyword(PredefinedSymbol.Semicolon);

            return structDefinition;
		}
Exemple #7
0
 public void AddStruct(ScriptStruct newStruct)
 {
     _structs.Add(newStruct);
 }