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"); } } }
private void ProcessEnumDeclaration() { Token enumName = _source.ReadNextTokenAndThrowIfAlreadyDefined(); ScriptEnum enumDefinition = new ScriptEnum(enumName.Name); enumName.Define(TokenType.EnumType, enumDefinition); enumName.IsVariableType = true; _source.ExpectKeyword(PredefinedSymbol.OpenBrace); int nextEnumValue = 0; while (!_source.NextIsKeyword(PredefinedSymbol.CloseBrace)) { Token enumEntry = _source.ReadNextTokenAndThrowIfAlreadyDefined(); KeywordToken nextToken = _source.ReadNextAsKeyword(); if (nextToken.SymbolType == PredefinedSymbol.SetEqual) { nextEnumValue = _source.ReadNextAsConstInt(); nextToken = _source.ReadNextAsKeyword(); } enumDefinition.Values.Add(enumEntry.Name, nextEnumValue); enumEntry.Define(TokenType.Constant, nextEnumValue); nextEnumValue++; if (nextToken.SymbolType == PredefinedSymbol.CloseBrace) { break; } else if (nextToken.SymbolType != PredefinedSymbol.Comma) { throw new CompilerMessage(ErrorCode.UnexpectedToken, "Expected comma at '" + nextToken.Name + "'"); } } _source.ExpectKeyword(PredefinedSymbol.Semicolon); }
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); }