示例#1
0
        public MinceObject Factor()
        {
            if (new List <string>()
            {
                "NUMBER", "STRING", "BOOL", "CHAR"
            }.Contains(interpreter.currentToken.type))
            {
                return((MinceObject)interpreter.Eat());
            }
            else if (interpreter.currentToken.type == "L_BRACKET")
            {
                interpreter.Eat("L_BRACKET");
                MinceObject result = Evaluate();
                interpreter.Eat("R_BRACKET");
                return(result);
            }
            else if (interpreter.currentToken.type == "IDENTIFIER")
            {
                string name = interpreter.Eat().ToString();
                if (interpreter.variables.Exists(name))
                {
                    var result = interpreter.variables.Get(name).GetValue();

                    if (result.GetType() == typeof(MinceUserFunction))
                    {
                        if (interpreter.currentToken.type == "L_BRACKET")
                        {
                            var func = result as MinceUserFunction;

                            interpreter.Eat();
                            MinceObject[] args = interpreter.GetParameters();
                            interpreter.Eat("R_BRACKET");

                            return(func.call(args));
                        }
                        else
                        {
                            return(result);
                        }
                    }
                    else
                    {
                        return(result);
                    }
                }
                else
                {
                    throw new InterpreterException(interpreter.currentToken, "'" + name + "' does not exist in this context");
                }
            }
            else if (interpreter.currentToken.type == "NEW")
            {
                interpreter.Eat();

                var func = Interpreter.types[interpreter.Eat("IDENTIFIER").ToString()];
                interpreter.Eat("L_BRACKET");
                var p = interpreter.GetParameters();
                interpreter.Eat("R_BRACKET");

                return(func.Invoke(p));
            }
            else if (interpreter.currentToken.type == "NOT")
            {
                interpreter.Eat();
                return(new MinceBool(!(bool)(this.Evaluate() as MinceBool).value));
            }
            else if (interpreter.currentToken.type == "NULL")
            {
                interpreter.Eat();
                return(new MinceNull());
            }
            else if (interpreter.currentToken.type == "FUNCTION")
            {
                int initialDepth = interpreter.depth;

                interpreter.Eat();

                MinceUserFunction userFunc = new MinceUserFunction();

                List <Token> tokens = new List <Token>();

                List <string> paramNames = new List <string>();

                if (interpreter.currentToken.type == "COLON")
                {
                    interpreter.Eat();

                    while (interpreter.currentToken.type == "IDENTIFIER")
                    {
                        string name = interpreter.Eat().ToString();

                        if (interpreter.variables.Exists(name))
                        {
                            throw new InterpreterException(interpreter.currentToken, "A variable called '" + name + "' already exists!");
                        }

                        paramNames.Add(name);

                        if (interpreter.currentToken.type == "L_CURLY_BRACE")
                        {
                            break;
                        }
                        else if (interpreter.currentToken.type == "COMMA")
                        {
                            interpreter.Eat();
                        }
                        else
                        {
                            throw new InterpreterException(interpreter.currentToken, "Expected ',' or '{' after parameter name");
                        }
                    }
                }

                interpreter.Eat("L_CURLY_BRACE");
                interpreter.depth++;

                tokens.Add(new Token(0, 0, "L_CURLY_BRACE"));

                tokens = tokens.Concat(interpreter.SkipBlock()).ToList();

                userFunc.value         = tokens;
                userFunc.variableNames = paramNames;

                return(userFunc);
            }
            else if (interpreter.currentToken.type == "L_SQUARE_BRACKET")
            {
                MinceArray ar = new MinceArray(new MinceObject[0]);
                interpreter.Eat();

                while (interpreter.currentToken.type != "R_SQUARE_BRACKET")
                {
                    ar.add(Evaluate());

                    if (interpreter.currentToken.type != "R_SQUARE_BRACKET")
                    {
                        interpreter.Eat("COMMA");
                    }
                }

                interpreter.Eat();

                return(ar);
            }
            else if (interpreter.currentToken.type == "L_CURLY_BRACE")
            {
                MinceDynamic d = new MinceDynamic();
                interpreter.Eat();

                while (interpreter.currentToken.type == "IDENTIFIER")
                {
                    string name = interpreter.Eat().ToString();

                    interpreter.Eat("EQUALS");

                    MinceObject value = Evaluate();

                    Variable v = new Variable(name, value, true);

                    d.members.Add(v);

                    if (interpreter.currentToken.type != "COMMA")
                    {
                        break;
                    }

                    interpreter.Eat();
                }

                interpreter.Eat("R_CURLY_BRACE");

                return(d);
            }
            else if (interpreter.currentToken.type == "EOF")
            {
                return(new MinceNull());
            }

            throw new InterpreterException(interpreter.currentToken,
                                           "Unexpected token " + interpreter.currentToken.ToString() + " found when looking for a factor at token #" + interpreter.pointer);
        }
示例#2
0
        public override MinceObject Evaluate(Interpreter interpreter)
        {
            int pos          = interpreter.pointer;
            int initialDepth = interpreter.depth;

            interpreter.Eat();

            string varName = interpreter.Eat("IDENTIFIER").ToString();

            if (interpreter.variables.Exists(varName))
            {
                throw new Exception("A variable named '" + varName + "' already exists in this scope");
            }

            interpreter.Eat("COLON");

            MinceArray array = (MinceArray)interpreter.evaluation.Evaluate();

            interpreter.Eat("L_CURLY_BRACE");
            interpreter.depth++;

            if (interpreter.loopPositions.Count <= 0 || interpreter.loopPositions[0].depth != initialDepth)
            {
                interpreter.loopPositions.Insert(0, new LoopPosition(pos, initialDepth)
                {
                    index = 0
                });
            }

            if ((array.value as List <MinceObject>).Count == 0)
            {
                interpreter.SkipBlock();
                interpreter.loopPositions.RemoveAt(0);
                return(new MinceNull());
            }

            Variable indexVar = new Variable(varName, (array.value as List <MinceObject>)[interpreter.loopPositions[0].index], true, interpreter.depth);

            interpreter.variables.variables.Add(indexVar);

            interpreter.EvaluateBlock();

            if (interpreter.loopPositions.Count < 1 || interpreter.loopPositions[0].depth != initialDepth)
            {
                interpreter.variables.variables.Remove(indexVar);
                return(new MinceNull());
            }

            interpreter.loopPositions[0].index++;
            interpreter.variables.variables.Remove(indexVar);

            if (interpreter.loopPositions[0].index >= (array.value as List <MinceObject>).Count)
            {
                interpreter.loopPositions.RemoveAt(0);
            }
            else
            {
                interpreter.depth = interpreter.loopPositions[0].depth;
                interpreter.GoTo(interpreter.loopPositions[0].pointer);
            }

            return(new MinceNull());
        }