Ejemplo n.º 1
0
        public MinceObject Index()
        {
            MinceObject result = Add();

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

                interpreter.Eat();
                MinceObject index = 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");

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

                continue;
            }

            return(result);
        }
Ejemplo n.º 2
0
        public override MinceObject Evaluate(Interpreter interpreter)
        {
            interpreter.Eat();
            MinceObject returnValue = interpreter.evaluation.Evaluate();

            interpreter.Eat("SEMICOLON");
            return(returnValue);
        }
Ejemplo n.º 3
0
        public MinceObject Exponent()
        {
            MinceObject result = Members();

            while (interpreter.currentToken.type == "EXPONENT")
            {
                interpreter.Eat();
                result = result.Exponent(Members());
            }

            return(result);
        }
Ejemplo n.º 4
0
        public override MinceObject Evaluate(Interpreter interpreter)
        {
            interpreter.Eat();
            string name = interpreter.Eat("IDENTIFIER").ToString();

            interpreter.Eat("EQUALS");
            MinceObject value = interpreter.evaluation.Evaluate();

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

            interpreter.variables.variables.Add(v);

            interpreter.Eat("SEMICOLON");

            return(new MinceNull());
        }
Ejemplo n.º 5
0
        public MinceObject Compare()
        {
            MinceObject result = Index();

            while (
                new List <string>()
            {
                "IS_EQUAL", "NOT_EQUAL", "GREATER_THAN", "LESS_THAN", "GREATER_OR_EQUAL", "LESS_OR_EQUAL"
            }.Contains(interpreter.currentToken.type))
            {
                switch (interpreter.currentToken.type)
                {
                case "IS_EQUAL":
                    interpreter.Eat();
                    result = result.EqualTo(Add());
                    break;

                case "NOT_EQUAL":
                    interpreter.Eat();
                    result = result.NotEqualTo(Add());
                    break;

                case "GREATER_THAN":
                    interpreter.Eat();
                    result = result.GreaterThan(Add());
                    break;

                case "LESS_THAN":
                    interpreter.Eat();
                    result = result.LessThan(Add());
                    break;

                case "GREATER_OR_EQUAL":
                    interpreter.Eat();
                    result = result.GreaterOrEqual(Add());
                    break;

                case "LESS_OR_EQUAL":
                    interpreter.Eat();
                    result = result.LessOrEqual(Add());
                    break;
                }
            }

            return(result);
        }
Ejemplo n.º 6
0
        public MinceObject AndOr()
        {
            MinceObject result = Compare();

            while (interpreter.currentToken.type == "AND" || interpreter.currentToken.type == "OR")
            {
                switch (interpreter.currentToken.type)
                {
                case "AND":
                    interpreter.Eat();
                    result = result.And((MinceBool)Compare());
                    break;

                case "OR":
                    interpreter.Eat();
                    result = result.Or((MinceBool)Compare());
                    break;
                }
            }
            return(result);
        }
Ejemplo n.º 7
0
        public MinceObject Multiply()
        {
            MinceObject result = Exponent();

            while (interpreter.currentToken.type == "MULTIPLY" || interpreter.currentToken.type == "DIVIDE")
            {
                switch (interpreter.currentToken.type)
                {
                case "MULTIPLY":
                    interpreter.Eat();
                    result = result.Multiply(Exponent());
                    break;

                case "DIVIDE":
                    interpreter.Eat();
                    result = result.Divide(Exponent());
                    break;
                }
            }

            return(result);
        }
Ejemplo n.º 8
0
        public MinceObject Add()
        {
            MinceObject result = Multiply();

            while (interpreter.currentToken.type == "PLUS" || interpreter.currentToken.type == "MINUS")
            {
                switch (interpreter.currentToken.type)
                {
                case "PLUS":
                    interpreter.Eat();
                    result = result.Plus(Multiply());
                    break;

                case "MINUS":
                    interpreter.Eat();
                    result = result.Minus(Multiply());
                    break;
                }
            }

            return(result);
        }
Ejemplo n.º 9
0
        public MinceObject NewClass(MinceObject original, MinceObject[] args)
        {
            MinceObject obj = original.clone();

            foreach (var member in obj.members)
            {
                if (member.GetType() == typeof(Property))
                {
                    Property prop = (Property)member;
                    prop.getFunc.parent = obj;

                    if (prop.setFunc != null)
                    {
                        prop.setFunc.parent = obj;
                    }

                    prop.Init();
                }
                else if (member.GetValue().GetType() == typeof(MinceUserFunction))
                {
                    ((MinceUserFunction)member.GetValue()).parent = obj;
                }
            }

            foreach (var method in obj.members)
            {
                if (method.GetType() == typeof(Variable) && method.GetValue().GetType() == typeof(MinceUserFunction) && method.name == "new")
                {
                    ((MinceUserFunction)method.GetValue()).call(args);
                    obj.members.Remove(method);
                    break;
                }
            }

            return(obj);
        }
Ejemplo n.º 10
0
 public void SetParent(MinceObject parent)
 {
     this.parent = parent;
     variables.variables.Add(new Variable("this", this.parent, true, depth));
 }
Ejemplo n.º 11
0
        public void LoadAssemblies()
        {
            Type[] classes = Assembly.GetExecutingAssembly().GetTypes().Where(t => String.Equals(t.Namespace, "Mince.Types", StringComparison.Ordinal)).ToArray();
            foreach (Type c in classes)
            {
                foreach (Attribute attr in c.GetCustomAttributes(true))
                {
                    if (attr.GetType() == typeof(StaticClass))
                    {
                        var st = (StaticClass)attr;

                        MinceObject value = (MinceObject)Activator.CreateInstance(c);

                        Variable v = new Variable(st.name, value);
                        variables.variables.Add(v);
                        break;
                    }
                    else if (attr.GetType() == typeof(Instantiatable))
                    {
                        if (c.GetConstructor(new Type[0]) == null)
                        {
                            Console.WriteLine("Could not load " + c + ". All instantiatable types must have a parameterless constructor.");
                        }
                        Func <MinceObject[], MinceObject> func = args => (MinceObject)Activator.CreateInstance(c, args, new object[0]);
                        string name = ((Instantiatable)attr).name;

                        types.Add(name, func);
                        break;
                    }
                }
            }

            foreach (string file in dlls)
            {
                Assembly assembly;

                try
                {
                    assembly = Assembly.LoadFile(file);
                }
                catch
                {
                    Console.WriteLine("Couldn't load lib/" + file.Substring(file.LastIndexOf("\\") + 1));
                    continue;
                }

                foreach (Type c in assembly.GetTypes())
                {
                    foreach (Attribute attr in c.GetCustomAttributes(true))
                    {
                        if (attr.GetType() == typeof(StaticClass))
                        {
                            var st = (StaticClass)attr;

                            MinceObject value = (MinceObject)Activator.CreateInstance(c);

                            Variable v = new Variable(st.name, value);
                            variables.variables.Add(v);
                            break;
                        }
                        else if (attr.GetType() == typeof(Instantiatable))
                        {
                            Func <MinceObject[], MinceObject> func = args => (MinceObject)Activator.CreateInstance(c, args, new object[0]);
                            string name = ((Instantiatable)attr).name;

                            types.Add(name, func);
                            break;
                        }
                    }
                }
            }
        }
Ejemplo n.º 12
0
        public override MinceObject Evaluate(Interpreter interpreter)
        {
            string identifier = interpreter.Eat().ToString();

            if (interpreter.variables.Exists(identifier))
            {
                interpreter.pointer--;
                VariableTree tree = Identifier.GetTree(interpreter);

                if (!tree.lastWasFunc)
                {
                    if (interpreter.currentToken.type == "EQUALS")
                    {
                        if (tree.lastVariable.isReadOnly)
                        {
                            throw new InterpreterException(interpreter.previousToken, "'" + tree.lastVariable.name + "' is readonly!");
                        }

                        interpreter.Eat();

                        MinceObject result = interpreter.evaluation.Evaluate();

                        tree.lastVariable.SetValue(result);
                    }
                    else if (interpreter.currentToken.type == "PLUS" && interpreter.tokens[interpreter.pointer + 1].type == "PLUS")
                    {
                        if (tree.lastVariable.GetValue().GetType() != typeof(MinceNumber))
                        {
                            throw new InterpreterException(interpreter.previousToken, "Can only increment a MinceNumber, not a " + tree.lastVariable.GetValue().GetType().Name);
                        }

                        interpreter.Eat();
                        interpreter.Eat();

                        ((MinceNumber)tree.lastVariable.GetValue()).inc();
                    }
                    else if (interpreter.currentToken.type == "MINUS" && interpreter.tokens[interpreter.pointer + 1].type == "MINUS")
                    {
                        if (tree.lastVariable.GetValue().GetType() != typeof(MinceNumber))
                        {
                            throw new InterpreterException(interpreter.previousToken, "Can only increment a MinceNumber, not a " + tree.lastVariable.GetValue().GetType().Name);
                        }

                        interpreter.Eat();
                        interpreter.Eat();

                        MinceNumber num = (MinceNumber)tree.lastVariable.GetValue();
                        tree.lastVariable.SetValue(num.Minus(new MinceNumber(1)));
                    }
                }

                interpreter.Eat("SEMICOLON");
            }
            else
            {
                Variable variable = new Variable();
                variable.name  = identifier;
                variable.depth = interpreter.depth;

                interpreter.Eat("EQUALS");

                MinceObject value = interpreter.evaluation.Evaluate();

                variable.SetValue(value);

                interpreter.variables.variables.Add(variable);
                interpreter.Eat("SEMICOLON");
            }

            return(new MinceNull());
        }
Ejemplo n.º 13
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.º 14
0
 public override void SetValue(MinceObject assignment)
 {
     property.SetValue(instance, assignment);
 }
Ejemplo n.º 15
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);
        }
Ejemplo n.º 16
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);
        }