Esempio n. 1
0
        public FunctionFrame CloneTemplate()
        {
            FunctionFrame functionStructure = new FunctionFrame(Identifier);

            functionStructure.SetArgumentParameters(argument_identifiers);
            functionStructure.SetArguments(LocalVariables.Values.ToList());
            return(functionStructure);
        }
Esempio n. 2
0
        //executes a single statement
        void ExecuteNextStatement()
        {
            Token keyword = lastToken;

            expressionMarker = (Marker)lexer.Position.Clone();
            ReadNextToken();
            Value         expr;
            IfElifFrame   prevElifFrame;
            FunctionFrame functionFrame;

            switch (keyword)
            {
            case Token.Global:
                MatchToken(Token.Identifier);
                GlobalVariables.Add(lexer.TokenIdentifier, Value.Null);
                ReadNextToken();
                break;

            case Token.Abstract:
                MatchToken(Token.Identifier);
                GlobalVariables.Add(lexer.TokenIdentifier, new Value(new Expression(lexer.TokenIdentifier)));
                ReadNextToken();
                break;

            case Token.Identifier:
                string id = lexer.TokenIdentifier;
                if (lastToken == Token.Set)
                {
                    if (ReadOnlyVariables.Contains(id))
                    {
                        throw new Exception("FastCode cannot write to a read only variable.");
                    }
                    ReadNextToken();
                    expr = EvaluateNextExpression();
                    if (expr == null)
                    {
                        return;
                    }
                    if (GlobalVariables.ContainsKey(id))
                    {
                        GlobalVariables[id] = expr;
                        break;
                    }
                    else
                    {
                        functionFrame = GetCurrentContext();
                        if (functionFrame.LocalVariables.ContainsKey(id))
                        {
                            functionFrame.LocalVariables[id] = expr;
                        }
                        else
                        {
                            functionFrame.LocalVariables.Add(id, expr);
                        }
                    }
                    break;
                }
                else if (lastToken == Token.OpenParenthesis)
                {
                    if (functions.ContainsKey(id) || builtInFunctions.ContainsKey(id))
                    {
                        lexer.ShiftCurrentPosition(keywordMarker);
                        ReadNextToken();
                        EvaluateNextExpression();
                        break;
                    }
                }
                else if (lastToken == Token.OpenBracket)
                {
                    ReadNextToken();
                    Value indexValue = EvaluateNextExpression();
                    if (indexValue == null)
                    {
                        return;
                    }
                    if (indexValue.Type != ValueType.Double)
                    {
                        throw new Exception("Indicie's must be of type double.");
                    }
                    MatchToken(Token.CloseBracket);
                    ReadNextToken();
                    MatchToken(Token.Set);
                    ReadNextToken();
                    Value setval = EvaluateNextExpression();
                    if (setval == null)
                    {
                        return;
                    }
                    if (GlobalVariables.ContainsKey(id))
                    {
                        if (GlobalVariables[id].Type == ValueType.Array)
                        {
                            GlobalVariables[id].Array[(int)indexValue.Double] = setval;
                            break;
                        }
                        else if (GlobalVariables[id].Type == ValueType.String)
                        {
                            if (setval.Type != ValueType.Character)
                            {
                                throw new Exception("Strings can only index characters.");
                            }
                            char[] str = GlobalVariables[id].String.ToCharArray();
                            str[(int)indexValue.Double] = setval.Character;
                            GlobalVariables[id]         = new Value(new string(str));
                            break;
                        }
                    }
                    else
                    {
                        functionFrame = GetCurrentContext();
                        if (functionFrame.LocalVariables[id].Type == ValueType.Array)
                        {
                            functionFrame.LocalVariables[id].Array[(int)indexValue.Double] = setval;
                            break;
                        }
                        else if (functionFrame.LocalVariables[id].Type == ValueType.String)
                        {
                            if (setval.Type != ValueType.Character)
                            {
                                throw new Exception("Strings can only index characters.");
                            }
                            char[] str = functionFrame.LocalVariables[id].String.ToCharArray();
                            str[(int)indexValue.Double]      = setval.Character;
                            functionFrame.LocalVariables[id] = new Value(new string(str));
                            break;
                        }
                    }
                }
                throw new Exception("Identifier \"" + id + "\" cannot stand alone without a keyword.");

            case Token.Break:
                int i = 0;
                while (!(CallStack.Peek().GetType() == typeof(WhileFrame) || CallStack.Peek().GetType() == typeof(ForFrame)))
                {
                    if (CallStack.Peek().GetType() == typeof(FunctionFrame))
                    {
                        throw new UnexpectedStatementException(Token.Break.ToString());
                    }
                    i++;
                    prevCallFrame = CallStack.Pop();
                }
                prevCallFrame = CallStack.Pop();
                SkipCallFrame(i);
                break;

            case Token.Return:
                functionFrame = null;
                int j = 0;
                while (CallStack.Count != 0)
                {
                    if (CallStack.Peek().GetType() == typeof(FunctionFrame))
                    {
                        functionFrame = (FunctionFrame)CallStack.Pop();
                        if (functionFrame.Identifier == "MAINSTRUCTURE")
                        {
                            throw new Exception("Only functions may return values.");
                        }
                        break;
                    }
                    CallStack.Pop();
                    j++;
                }
                if (PeekNextToken() != Token.Newline && PeekNextToken() != Token.Semicolon)
                {
                    CallStack.Push(functionFrame);
                    expr = EvaluateNextExpression();
                    if (expr == null)
                    {
                        return;
                    }
                    functionFrame = (FunctionFrame)CallStack.Pop();
                    functionFrame.ReturnResult = expr;
                }
                CallStack.Push(functionFrame);
                SkipCallFrame(j, true);
                ExecuteNextStatement();
                break;

            case Token.Stop:
                Exit = true;
                return;

            case Token.Import:
                MatchToken(Token.Value);
                if (lexer.TokenValue.Type != ValueType.String)
                {
                    throw new Exception("Expected string, got " + lexer.TokenValue.Type);
                }

                ReadNextToken();
                break;

            case Token.EndOfFile:
                Exit = true;
                return;

            case Token.If:
                IfElifFrame ifFrame = new IfElifFrame();
                expr = EvaluateNextExpression();
                if (expr == null)
                {
                    return;
                }
                ifFrame.Result = (expr.PerformBinaryOperation(Token.Equals, new Value(0)).Double == 1);     //not not the actual result, it just checks if the condition failed so it can skip that section. Kinda misleading if you didn't know - just refer to the assertion token's case.
                CallStack.Push(ifFrame);

                readTillCallFrameStart();     //read till open bracket

                if (ifFrame.Result == true)   //skip till close bracket.
                {
                    SkipCallFrame();
                    prevCallFrame = CallStack.Pop();
                }

                break;

            case Token.Else:     //not if results are inverted
                if (prevCallFrame.GetType() != typeof(IfElifFrame))
                {
                    throw new UnexpectedStatementException(keyword.ToString());
                }
                prevElifFrame = (IfElifFrame)prevCallFrame;
                if (prevElifFrame.Result == true)     //skip all the crap
                {
                    CallStack.Push(new ElseFrame());
                    readTillCallFrameStart();
                }
                else if (prevElifFrame.Result == false)
                {
                    CallStack.Push(new ElseFrame());
                    readTillCallFrameStart();
                    SkipCallFrame();
                    prevCallFrame = CallStack.Pop();
                }
                break;

            case Token.Elif:
                if (prevCallFrame.GetType() != typeof(IfElifFrame))
                {
                    throw new UnexpectedStatementException(keyword.ToString());
                }
                IfElifFrame elifFrame = new IfElifFrame();
                prevElifFrame = (IfElifFrame)prevCallFrame;
                if (prevElifFrame.Result == true)
                {
                    expr = EvaluateNextExpression();
                    if (expr == null)
                    {
                        return;
                    }
                    elifFrame.Result = (expr.PerformBinaryOperation(Token.Equals, new Value(0)).Double == 1);
                    CallStack.Push(elifFrame);
                    readTillCallFrameStart();
                    if (elifFrame.Result == true)
                    {
                        SkipCallFrame();
                        prevCallFrame = CallStack.Pop();
                    }
                }
                else
                {
                    CallStack.Push(elifFrame);
                    readTillCallFrameStart();
                    SkipCallFrame();
                    prevCallFrame = CallStack.Pop();
                }
                break;

            case Token.While:
                WhileFrame whileFrame = new WhileFrame();
                whileFrame.ExpressionMarker = (Marker)expressionMarker.Clone();
                expr = EvaluateNextExpression();
                if (expr == null)
                {
                    return;
                }
                CallStack.Push(whileFrame);
                readTillCallFrameStart();
                if (expr.PerformBinaryOperation(Token.Equals, new Value(0)).Double == 1)
                {
                    SkipCallFrame();
                    prevCallFrame = CallStack.Pop();
                }
                break;

            case Token.For:
                ForFrame forFrame = new ForFrame();
                MatchToken(Token.Identifier);
                forFrame.IndexerIdentifier = lexer.TokenIdentifier;
                ReadNextToken();
                MatchToken(Token.In);
                ReadNextToken();
                expr = EvaluateNextExpression();
                if (expr == null)
                {
                    return;
                }
                if (expr.Type == ValueType.Array)
                {
                    forFrame.Values = expr.Array;
                }
                else if (expr.Type == ValueType.String)
                {
                    forFrame.Values = new List <Value>();
                    for (int k = 0; k < expr.String.Length; k++)
                    {
                        forFrame.Values.Add(new Value(expr.String[k]));
                    }
                }
                else
                {
                    throw new Exception("Fastcode can only iterate through an array or string.");
                }
                forFrame.currentIndex = 0;
                functionFrame         = GetCurrentContext();
                if (forFrame.Values.Count > 0)
                {
                    if (functionFrame.LocalVariables.ContainsKey(forFrame.IndexerIdentifier))
                    {
                        functionFrame.LocalVariables[forFrame.IndexerIdentifier] = forFrame.Values[0];
                    }
                    else
                    {
                        functionFrame.LocalVariables.Add(forFrame.IndexerIdentifier, forFrame.Values[0]);
                    }
                }

                CallStack.Push(forFrame);
                readTillCallFrameStart();
                if (forFrame.currentIndex >= forFrame.Values.Count)
                {
                    SkipCallFrame();
                    prevCallFrame = CallStack.Pop();
                }
                break;

            case Token.Function:
                MatchToken(Token.Identifier);
                string fid = lexer.TokenIdentifier;
                if (functions.ContainsKey(fid) || GlobalVariables.ContainsKey(fid) || builtInFunctions.ContainsKey(fid))
                {
                    throw new Exception("Identifiers must be unique");
                }
                functionFrame = new FunctionFrame(fid);
                ReadNextToken();
                MatchToken(Token.OpenParenthesis);
                List <string> argument_identifiers = new List <string>();
                while (lastToken != Token.CloseParenthesis)
                {
                    ReadNextToken();
                    if (lastToken == Token.Comma || lastToken == Token.CloseParenthesis)
                    {
                        continue;
                    }
                    else if (lastToken == Token.Identifier)
                    {
                        if (argument_identifiers.Contains(lexer.TokenIdentifier) || GlobalVariables.ContainsKey(lexer.TokenIdentifier))
                        {
                            throw new Exception("Argument identifiers must be unique.");
                        }
                        argument_identifiers.Add(lexer.TokenIdentifier);
                    }
                    else if (lastToken == Token.CloseParenthesis)
                    {
                        break;
                    }
                    else
                    {
                        throw new UnexpectedStatementException("an identifier", lastToken.ToString());
                    }
                }
                functionFrame.SetArgumentParameters(argument_identifiers);
                CallStack.Push(functionFrame);
                readTillCallFrameStart();
                functionFrame  = (FunctionFrame)CallStack.Pop();
                functions[fid] = functionFrame;
                SkipCallFrame();
                break;

            case Token.CloseBrace:     //checks to return or repeat.
                if (CallStack.Peek().GetType() == typeof(WhileFrame))
                {
                    Marker currentpos = (Marker)lexer.Position.Clone();
                    lexer.ShiftCurrentPosition(((WhileFrame)CallStack.Peek()).ExpressionMarker);
                    ReadNextToken();
                    expr = EvaluateNextExpression();
                    if (expr == null)
                    {
                        return;
                    }
                    if (expr.PerformBinaryOperation(Token.Equals, new Value(0)).Double == 1)
                    {
                        prevCallFrame = CallStack.Pop();
                        lexer.ShiftCurrentPosition(currentpos);
                    }
                    else
                    {
                        lexer.ShiftCurrentPosition(CallStack.Peek().StartPosition);
                        ReadNextToken();
                    }
                }
                else if (CallStack.Peek().GetType() == typeof(ForFrame))
                {
                    ForFrame forStructure2 = (ForFrame)CallStack.Pop();
                    forStructure2.currentIndex++;
                    functionFrame = GetCurrentContext();
                    if (forStructure2.currentIndex < forStructure2.Values.Count)
                    {
                        functionFrame.LocalVariables[forStructure2.IndexerIdentifier] = forStructure2.Values[forStructure2.currentIndex];
                        CallStack.Push(forStructure2);
                        lexer.ShiftCurrentPosition(CallStack.Peek().StartPosition);
                        ReadNextToken();
                    }
                    else
                    {
                        functionFrame.LocalVariables.Remove(forStructure2.IndexerIdentifier);
                    }
                }
                else if (CallStack.Peek().GetType() == typeof(FunctionFrame))
                {
                    functionFrame = (FunctionFrame)CallStack.Pop();
                    lexer.ShiftCurrentPosition(functionFrame.ReturnPosition);
                    GetCurrentContext().functionResults.Enqueue(functionFrame.ReturnResult);
                }
                else
                {
                    prevCallFrame = CallStack.Pop();
                }

                break;

            default:
                throw new UnexpectedStatementException(keyword.ToString());
            }
            if (lastToken == Token.Semicolon)
            {
                keywordMarker = (Marker)lexer.Position.Clone();
                ReadNextToken();
                while (lastToken == Token.Newline)
                {
                    ReadNextToken();
                }
                ExecuteNextStatement();
            }
        }