Пример #1
0
        private bool ParseAndAddGlobalVariableOrFunction(Token variableType)
        {
            bool isMemberFunctionBody = false;

            _source.IgnoreAsteriskIfPresent();
            FixedOffsetVariable importedVersion = null;
            Token variableName = _source.ReadNextToken();

            if ((variableName.Type == TokenType.GlobalVariable) &&
                (variableName.Variable.IsImported) &&
                (!variableName.Variable.IsAccessed))
            {
                importedVersion = variableName.Variable;
            }
            else
            {
                ReadNameOfNewGlobalVariableOrFunction(variableName, out isMemberFunctionBody);
            }

            if (_source.NextIsKeyword(PredefinedSymbol.OpenParenthesis))
            {
                ParseAndAddFunctionDefinition(variableType, variableName, isMemberFunctionBody);
                return(true);
            }
            else
            {
                CompilerUtils.SetArrayPropertiesOnTokenFromStream(_source, variableName);
                ParseAndAddGlobalVariableDefinition(variableType, variableName, importedVersion);
            }

            return(false);
        }
Пример #2
0
        private void ParseAndAddGlobalVariableDefinition(Token variableType, Token variableName, FixedOffsetVariable importedVersion)
        {
            VerifyModifiersAgainstType(ModifierTargets.GlobalVariable);
            FixedOffsetVariable newVariable = ProcessVariableDeclaration(variableType, _output.GlobalData, null, _state.NextTokenModifiers);

            variableName.Define(TokenType.GlobalVariable, newVariable);
            if (_source.NextIsKeyword(PredefinedSymbol.SetEqual))
            {
                // TODO: Check types to ensure this is valid
                newVariable.DefaultValue = _source.ReadNextAsConstInt();
            }

            if (importedVersion != null)
            {
                if (importedVersion.CompareTo(newVariable) != 0)
                {
                    throw new CompilerMessage(ErrorCode.NewDefinitionIsDifferent, "New definition of '" + variableName.Name + "' does not match previous one");
                }
            }
        }
Пример #3
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);
        }