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() + "'"); }
public CompileResults CompileScript(string script) { ITokenizer tokenizer = CompilerFactory.CreateTokenizer(); _tokenizedScript = tokenizer.TokenizeScript(script); _source = new ScriptReader(_tokenizedScript); _output = new CompiledScript(); while (true) { Token thisToken = _source.ReadNextToken(); if (thisToken is EndOfStreamToken) { break; } try { ProcessTokenAtTopLevel(thisToken); } catch (CompilerMessage error) { RecordError(error.Code, error.Message); break; } } return(_results); }
public CompileResults CompileScript(string script) { ITokenizer tokenizer = CompilerFactory.CreateTokenizer(); _tokenizedScript = tokenizer.TokenizeScript(script); _source = new ScriptReader(_tokenizedScript); _output = new CompiledScript(); while (true) { Token thisToken = _source.ReadNextToken(); if (thisToken is EndOfStreamToken) { break; } try { ProcessTokenAtTopLevel(thisToken); } catch (CompilerMessage error) { RecordError(error.Code, error.Message); break; } } return _results; }
private void GenerateCodeForExpressionWithoutOperator(Expression expression) { System.Diagnostics.Trace.WriteLine(expression.ToString()); ScriptReader reader = new ScriptReader(expression, _source.LineNumber); Token firstToken = reader.ReadNextToken(); Token memberName = null; bool staticAccess = false; if (firstToken.IsVariableType) { staticAccess = true; } else if (reader.NextIsKeyword(PredefinedSymbol.OpenSquareBracket)) { Expression arrayIndex = ReadExpression(reader, true, PredefinedSymbol.CloseSquareBracket); GenerateCodeForExpression(arrayIndex); // TODO: Array access } if (reader.NextIsKeyword(PredefinedSymbol.Dot)) { if ((firstToken.Type != TokenType.LocalVariable) && (firstToken.Type != TokenType.GlobalVariable) && (firstToken.Type != TokenType.StructType)) { throw new CompilerMessage(ErrorCode.ParentIsNotAStruct, "'" + firstToken.Name + "' is not a struct"); } memberName = reader.ReadNextToken(); // TODO: struct member stuff if (staticAccess) { } } else if (staticAccess) { throw new CompilerMessage(ErrorCode.InvalidUseOfStruct, "Struct cannot be used in this way"); } else { // TODO: just read the variable itself / execute the function } // TODO: Code this }
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 ProcessNextCodeStatement(bool allowVariableDeclarations) { Token nextToken = _source.PeekNextToken(); while (nextToken is ModifierToken) { _source.ReadNextToken(); _state.NextTokenModifiers.Add((ModifierToken)nextToken); nextToken = _source.PeekNextToken(); } if (nextToken is EndOfStreamToken) { throw new CompilerMessage(ErrorCode.EndOfInputReached, "The end of the script was reached in the middle of a function"); } if ((nextToken is KeywordToken) && (((KeywordToken)nextToken).SymbolType == PredefinedSymbol.OpenBrace)) { ProcessCodeBlock(); } else if (nextToken is KeywordToken) { _source.ReadNextToken(); ProcessKeyword((KeywordToken)nextToken); } else if (nextToken.IsVariableType) { _source.PushLocation(); Token variableType = _source.ReadNextToken(); if (_source.NextIsKeyword(PredefinedSymbol.Dot)) { // it's a static member access _source.PopLocation(); GenerateCodeForExpression(ReadExpression(true, PredefinedSymbol.Semicolon)); } else { _source.DeletePushedLocation(); if (!allowVariableDeclarations) { throw new CompilerMessage(ErrorCode.VariableDeclarationNotAllowedHere, "The variable would go out of scope as soon as it was declared"); } do { DeclareLocalVariable(variableType); }while (_source.NextIsKeyword(PredefinedSymbol.Comma)); _source.ExpectKeyword(PredefinedSymbol.Semicolon); _state.NextTokenModifiers.Clear(); } } else { GenerateCodeForExpression(ReadExpression(true, 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); }