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); }
private Expression ReadExpression(ScriptReader source, bool readTerminatingSymbolFromStream, params PredefinedSymbol[] endsWithSymbols) { Expression expression = new Expression(); int bracketLevel = 0; while (bracketLevel >= 0) { foreach (PredefinedSymbol terminatingSymbol in endsWithSymbols) { if ((bracketLevel == 0) && (source.NextIsKeyword(terminatingSymbol, !readTerminatingSymbolFromStream))) { return(expression); } } Token thisToken = source.PeekNextToken(); if (thisToken is EndOfStreamToken) { throw new CompilerMessage(ErrorCode.EndOfInputReached, "End of script reached in the middle of an expression"); } CompilerUtils.AdjustBracketLevelIfTokenIsBracket(thisToken, ref bracketLevel); if (bracketLevel >= 0) { expression.Add(source.ReadNextToken()); } } throw new CompilerMessage(ErrorCode.UnexpectedToken, "Unexpected '" + source.ReadNextToken() + "'"); }
private void ParseFunctionParameterList(ScriptFunction func) { Modifiers modifiers; bool atEndOfParameterList = false; while ((!atEndOfParameterList) && (!_source.NextIsKeyword(PredefinedSymbol.CloseParenthesis))) { modifiers = new Modifiers(); while (_source.PeekNextToken() is ModifierToken) { modifiers.Add((ModifierToken)_source.ReadNextToken()); } if (_source.NextIsKeyword(PredefinedSymbol.VariableArguments)) { func.VariableArguments = true; _source.ExpectKeyword(PredefinedSymbol.CloseParenthesis, "Variable arguments must be the last parameter"); break; } Token parameterType = _source.ReadNextAsVariableType(); Token parameterName = null; _source.IgnoreAsteriskIfPresent(); CompilerUtils.VerifyModifiersAgainstType(ModifierTargets.FunctionParameter, modifiers); VerifyParameterTypeValidForFunction(parameterType); if (!_source.PeekNextToken().Defined) { parameterName = _source.ReadNextTokenAndThrowIfAlreadyDefined(); } else { func.IsPrototypeOnly = true; } FunctionParameter parameter = new FunctionParameter(parameterType, parameterName); parameter.Modifiers = modifiers; if (_source.NextIsKeyword(PredefinedSymbol.SetEqual)) { parameter.DefaultValue = _source.ReadNextAsConstInt(); } if (_source.NextIsKeyword(PredefinedSymbol.CloseParenthesis)) { atEndOfParameterList = true; } else { _source.ExpectKeyword(PredefinedSymbol.Comma); } func.Parameters.Add(parameter); } }
private void DeclareLocalVariable(Token variableType) { _source.IgnoreAsteriskIfPresent(); Token variableName = _source.ReadNextTokenAndThrowIfAlreadyDefined(); CompilerUtils.SetArrayPropertiesOnTokenFromStream(_source, variableName); CompilerUtils.VerifyModifiersAgainstType(ModifierTargets.LocalVariable, _state.NextTokenModifiers); /* TODO: get this working * ScriptVariable newVariable = ProcessVariableDeclaration(variableType, _output.GlobalData, null, _state.NextTokenModifiers); * * variableName.Define(TokenType.LocalVariable, newVariable); */ if (_source.NextIsKeyword(PredefinedSymbol.SetEqual)) { Expression setEqualTo = ReadExpression(false, PredefinedSymbol.Semicolon, PredefinedSymbol.Comma); // TODO: check types, assign result to variable } }
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); } }
private int FindIndexOfLowestPrecedenceOperator() { int foundIndex = -1; int foundPrecedence = -1; int bracketLevel = 0; for (int i = 0; i < this.Count; i++) { if (CompilerUtils.AdjustBracketLevelIfTokenIsBracket(this[i], ref bracketLevel)) { // do nothing, the bracketlevel has been changed } else if (bracketLevel == 0) { if (this[i] is OperatorToken) { int thisPrecedence = ((OperatorToken)this[i]).Precedence; if (thisPrecedence > foundPrecedence) { foundPrecedence = thisPrecedence; foundIndex = i; } } else if (this[i] is KeywordToken) { if (((KeywordToken)this[i]).IsModificationOperator) { if (MODIFICATION_OPERATOR_PRECEDENCE > foundPrecedence) { foundPrecedence = MODIFICATION_OPERATOR_PRECEDENCE; foundIndex = i; } } } } } return(foundIndex); }
private Token GetTokenForStructMember(Token structName, Token memberName, out string mangledName) { return(CompilerUtils.GetTokenForStructMember(_tokenizedScript, structName, memberName, out mangledName)); }
private void VerifyModifiersAgainstType(ModifierTargets target) { CompilerUtils.VerifyModifiersAgainstType(target, _state.NextTokenModifiers); }