예제 #1
0
        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() + "'");
        }
예제 #2
0
        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);
        }
예제 #3
0
		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;
		}
예제 #4
0
        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
        }
예제 #5
0
        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() + "'");
        }
예제 #6
0
        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
        }
예제 #7
0
        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));
            }
        }
예제 #8
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);
        }