Ejemplo n.º 1
0
        public static VariableTree GetTree(Interpreter interpreter)
        {
            VariableTree tree = new VariableTree();

            string identifier = interpreter.Eat().ToString();

            if (interpreter.variables.Exists(identifier))
            {
                Variable    variable    = interpreter.variables.Get(identifier);
                MinceObject value       = variable.GetValue();
                bool        lastWasFunc = value.GetType() == typeof(MinceFunction) || value.GetType() == typeof(MinceUserFunction);

                tree.Add(variable);

                while (true)
                {
                    if (interpreter.currentToken.type == "L_BRACKET")
                    {
                        interpreter.Eat();
                        MinceObject[] args = interpreter.GetParameters();
                        interpreter.Eat("R_BRACKET");

                        if (value.GetType() == typeof(MinceUserFunction))
                        {
                            value = (value as MinceUserFunction).call(args);
                        }
                        else if (value.GetType() == typeof(MinceFunction))
                        {
                            value = (value as MinceFunction).Call(args);
                        }
                        else
                        {
                            throw new InterpreterException(interpreter.currentToken, variable.name + " is not a function! It is a " + value.GetType().Name);
                        }

                        lastWasFunc = true;
                        continue;
                    }

                    if (interpreter.currentToken.type == "L_SQUARE_BRACKET")
                    {
                        if (value.GetType() != typeof(MinceArray))
                        {
                            throw new InterpreterException(interpreter.currentToken, "Can only apply an index to an Array, not a " + value.GetType().Name);
                        }

                        interpreter.Eat();
                        MinceObject index = interpreter.evaluation.Evaluate();

                        if (index.GetType() != typeof(MinceNumber))
                        {
                            throw new InterpreterException(interpreter.currentToken, "Index must be a number! Not a " + index.GetType().Name);
                        }

                        interpreter.Eat("R_SQUARE_BRACKET");

                        value = ((MinceArray)value).get((MinceNumber)index);

                        continue;
                    }

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

                        if (value.MemberExists(name))
                        {
                            variable = value.GetMember(name);
                            tree.Add(variable);

                            if (variable.isPrivate)
                            {
                                if (interpreter.parent == null || !object.ReferenceEquals(value, interpreter.parent))
                                {
                                    throw new InterpreterException(interpreter.previousToken, "'" + variable.name + "' is private!");
                                }
                            }

                            value = variable.GetValue();
                        }
                        else if (value.GetType() == typeof(MinceDynamic))
                        {
                            Variable v = new Variable(name, new MinceDynamic(), false, -1);
                            value.members.Add(v);

                            variable = v;
                            tree.Add(variable);
                        }
                        else
                        {
                            throw new InterpreterException(interpreter.previousToken, "'" + variable.name + "' (" + variable.GetValue().GetType().Name + ") does not contain member '" + name + "'");
                        }

                        lastWasFunc = false;
                    }
                    else
                    {
                        break;
                    }
                }

                tree.lastWasFunc = false;

                return(tree);
            }
            else
            {
                throw new InterpreterException(interpreter.previousToken, "Variable '" + identifier + "' does not exist!");
            }
        }
Ejemplo n.º 2
0
        public MinceObject Members()
        {
            MinceObject result = Factor();

            while (interpreter.currentToken.type == "DOT")
            {
                interpreter.Eat();

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

                if (result.MemberExists(memberName))
                {
                    if (result.GetMember(memberName).isPrivate)
                    {
                        if (interpreter.parent == null || !object.ReferenceEquals(result, interpreter.parent))
                        {
                            throw new InterpreterException(interpreter.currentToken, "'" + result.GetMember(memberName).name + "' is private!");
                        }
                    }

                    if (interpreter.currentToken.type == "L_BRACKET")
                    {
                        var member = result.GetMember(memberName).GetValue();

                        if (member.GetType() == typeof(MinceUserFunction))
                        {
                            var func = member as MinceUserFunction;

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

                            result = func.call(args);
                        }
                        else if (member.GetType() == typeof(MinceFunction))
                        {
                            interpreter.Eat("L_BRACKET");

                            MinceObject[] p = interpreter.GetParameters();
                            result = (result.GetMember(memberName).GetValue() as MinceFunction).Call(p);

                            interpreter.Eat("R_BRACKET");
                        }
                        else
                        {
                            throw new InterpreterException(interpreter.currentToken, "You can only call functions, not " + member.GetType());
                        }
                    }
                    else
                    {
                        result = result.GetMember(memberName).GetValue();
                    }
                }
                else
                {
                    throw new InterpreterException(interpreter.currentToken, "'" + memberName + "' is inaccessible.");
                }
            }

            return(result);
        }