예제 #1
0
        public virtual TreeNode OnWhile(TreeNode [] args)
        {
            if(args == null || args.Length < 1 || args.Length > 2) {
                throw new ArgumentException("while accepts a condition and an expression or just an expression");
            }

            while(true) {
                if(args.Length == 2) {
                    TreeNode result = Evaluate(args[0]);
                    if(!(result is BooleanLiteral)) {
                        throw new ArgumentException("condition is not boolean");
                    }

                    if(!(result as BooleanLiteral).Value) {
                        break;
                    }
                }

                try {
                    Evaluate(args[args.Length - 1]);
                } catch(Exception e) {
                    if(BreakHandler(e)) {
                        break;
                    }
                }
            }

            return new VoidLiteral();
        }
예제 #2
0
        public virtual TreeNode OnDefine(TreeNode [] args)
        {
            if(args.Length < 2 || args.Length > 3) {
                throw new ArgumentException("define must have two or three arguments");
            }

            if(!(args[0] is FunctionNode)) {
                throw new ArgumentException("first define argument must be a variable");
            }

            FunctionNode function = new FunctionNode((args[0] as FunctionNode).Function, args[args.Length - 1]);

            if(args.Length == 3 && args[1].HasChildren) {
                foreach(TreeNode function_arg in args[1].Children) {
                    if(!(function_arg is FunctionNode)) {
                        throw new ArgumentException("define function arguments must be variable tokens");
                    }

                    function.RegisterFunction((function_arg as FunctionNode).Function, new VoidLiteral());
                }
            }

            TreeNode parent = args[0].Parent;
            parent = parent.Parent ?? parent;

            parent.RegisterFunction(function.Function, function);

            return new VoidLiteral();
        }
예제 #3
0
        public static TreeNode Compare(EvaluatorBase evaluator, TreeNode a, TreeNode b)
        {
            TreeNode arg_a = evaluator.Evaluate(a);
            TreeNode arg_b = evaluator.Evaluate(b);

            if(arg_a.GetType() != arg_b.GetType()) {
                throw new ArgumentException("arguments must be of the same type to compare");
            }

            int result = 0;

            if(arg_a is IntLiteral) {
                result = (arg_a as IntLiteral).Value.CompareTo(
                    (arg_b as IntLiteral).Value);
            } else if(arg_a is DoubleLiteral) {
                result = (arg_a as DoubleLiteral).Value.CompareTo(
                    (arg_b as DoubleLiteral).Value);
            } else if(arg_a is StringLiteral) {
                result = (arg_a as StringLiteral).Value.CompareTo(
                    (arg_b as StringLiteral).Value);
            } else if(arg_a is BooleanLiteral) {
                result = (arg_a as BooleanLiteral).Value.CompareTo(
                    (arg_b as BooleanLiteral).Value);
            } else {
                throw new ArgumentException("invalid type for comparison");
            }

            return new IntLiteral(result);
        }
예제 #4
0
        public TreeNode Flatten()
        {
            TreeNode result_node = new TreeNode();
            Flatten(result_node, this);

            return result_node.ChildCount == 1 ? result_node.Children[0] : result_node;
        }
예제 #5
0
 private void CheckArgumentCount(TreeNode [] args, int expected_min, int expected_max)
 {
     if(args.Length < expected_min || args.Length > expected_max) {
         throw new ArgumentException("expects " + expected_min + " <= args <= "
             + expected_max + " arguments");
     }
 }
예제 #6
0
        private TreeNode OnAndOr(TreeNode [] args, bool and)
        {
            if(args.Length < 2) {
                throw new ArgumentException("must have two or more boolean arguments");
            }

            bool result = false;

            for(int i = 0; i < args.Length; i++) {
                TreeNode node = Evaluate(args[i]);
                if(!(node is BooleanLiteral)) {
                    throw new ArgumentException("arguments must be boolean");
                }

                BooleanLiteral arg = (BooleanLiteral)node;

                if(i == 0) {
                    result = arg.Value;
                    continue;
                }

                if(and) {
                    result &= arg.Value;
                } else {
                    result |= arg.Value;
                }
            }

            return new BooleanLiteral(result);
        }
예제 #7
0
        public virtual TreeNode OnCompareTo(TreeNode [] args)
        {
            if(args.Length != 2) {
                throw new ArgumentException("must have two arguments");
            }

            return Compare(Evaluator, args[0], args[1]);
        }
예제 #8
0
        public virtual TreeNode OnDump(TreeNode [] args)
        {
            foreach(TreeNode arg in args) {
                Evaluate(arg).Dump();
            }

            return new VoidLiteral();
        }
예제 #9
0
        private int GetArgumentInteger(TreeNode [] args, int index)
        {
            TreeNode node = Evaluate(args[index]);
            if(!(node is IntLiteral)) {
                throw new ArgumentException("argument " + index + " must be an integer");
            }

            return (node as IntLiteral).Value;
        }
예제 #10
0
        private string GetArgumentString(TreeNode [] args, int index)
        {
            TreeNode node = Evaluate(args[index]);
            if(!(node is StringLiteral)) {
                throw new ArgumentException("argument " + index + " must be a string");
            }

            return (node as StringLiteral).Value;
        }
예제 #11
0
        public virtual TreeNode OnPrintType(TreeNode [] args)
        {
            if(args.Length != 1) {
                throw new ArgumentException("print-type must have only one argument");
            }

            Console.WriteLine(Evaluate(args[0]).GetType());

            return new VoidLiteral();
        }
예제 #12
0
        public virtual TreeNode OnPerformArithmetic(TreeNode [] args, ArithmeticOperation operation)
        {
            double result = 0.0;
            bool as_int = true;

            for(int i = 0; i < args.Length; i++) {
                TreeNode arg = Evaluate(args[i]);

                if(arg is IntLiteral || arg is DoubleLiteral) {
                    double arg_value;

                    if(arg is DoubleLiteral) {
                        as_int = false;
                        arg_value = (arg as DoubleLiteral).Value;
                    } else {
                        arg_value = (int)(arg as IntLiteral).Value;
                    }

                    if(i == 0) {
                        result = arg_value;
                        continue;
                    }

                    switch(operation) {
                        case ArithmeticOperation.Add:
                            result += arg_value;
                            break;
                        case ArithmeticOperation.Subtract:
                            result -= arg_value;
                            break;
                        case ArithmeticOperation.Multiply:
                            result *= arg_value;
                            break;
                        case ArithmeticOperation.Divide:
                            result /= arg_value;
                            break;
                        case ArithmeticOperation.Modulo:
                            if(!(arg is IntLiteral)) {
                                throw new ArgumentException("Modulo requires int arguments");
                            }

                            result %= (int)arg_value;
                            break;
                    }
                } else {
                    throw new ArgumentException("arguments must be double or int");
                }
            }

            return as_int ?
                ((TreeNode)new IntLiteral((int)result)) :
                ((TreeNode)new DoubleLiteral(result));
        }
예제 #13
0
        public static TreeNode ConcatenateStrings(EvaluatorBase evaluator, TreeNode [] args)
        {
            StringBuilder result = new StringBuilder();

            foreach(TreeNode arg in args) {
                TreeNode eval_arg = evaluator.Evaluate(arg);
                if(!(eval_arg is VoidLiteral)) {
                    result.Append(eval_arg);
                }
            }

            return new StringLiteral(result.ToString());
        }
예제 #14
0
        public virtual TreeNode OnNot(TreeNode [] args)
        {
            if(args.Length != 1) {
                throw new ArgumentException("not must have only one argument");
            }

            TreeNode arg = Evaluate(args[0]);

            if(!(arg is BooleanLiteral)) {
                throw new ArgumentException("can only not a boolean");
            }

            return new BooleanLiteral(!(arg as BooleanLiteral).Value);
        }
예제 #15
0
        private void Flatten(TreeNode result_node, TreeNode node)
        {
            if(node == null) {
                return;
            }

            if(!node.HasChildren && !(node is VoidLiteral)) {
                result_node.AddChild(node);
                return;
            }

            foreach(TreeNode child_node in node.Children) {
                Flatten(result_node, child_node);
            }
        }
예제 #16
0
        public virtual TreeNode OnItemAt(TreeNode [] args)
        {
            TreeNode list = Evaluate(args[0]);
            CheckList(list);

            TreeNode node = Evaluate(args[1]);
            int index = 0;

            if(!(node is IntLiteral)) {
                throw new ArgumentException("argument must be an index");
            }

            index = (node as IntLiteral).Value;

            return Evaluate(list.Children[index]);
        }
예제 #17
0
        public virtual TreeNode OnCastString(TreeNode [] args)
        {
            if(args.Length != 1) {
                throw new ArgumentException("cast must have only one argument");
            }

            TreeNode arg = Evaluate(args[0]);

            if(arg is DoubleLiteral) {
                return new StringLiteral(Convert.ToString((arg as DoubleLiteral).Value));
            } else if(arg is IntLiteral) {
                return new StringLiteral(Convert.ToString((arg as IntLiteral).Value));
            } else if(arg is StringLiteral) {
                return arg;
            }

            throw new ArgumentException("can only cast double, int, or string literals");
        }
예제 #18
0
        public virtual TreeNode OnIf(TreeNode [] args)
        {
            if(args == null || args.Length < 2 || args.Length > 3) {
                throw new ArgumentException("if accepts 2 or 3 arguments");
            }

            TreeNode arg = Evaluate(args[0]);
            if(!(arg is BooleanLiteral)) {
                throw new ArgumentException("first if argument must be boolean");
            }

            BooleanLiteral conditional = (BooleanLiteral)arg;

            if(conditional.Value) {
                return Evaluate(args[1]);
            } else if(args.Length == 3) {
                return Evaluate(args[2]);
            }

            return new VoidLiteral();
        }
예제 #19
0
        public TreeNode Evaluate(EvaluatorBase evaluator, TreeNode [] args)
        {
            if(args != null && args.Length != FunctionCount && RequiresArguments) {
                throw new ArgumentException("Function " + function + " takes "
                    + FunctionCount + " arguments, not " + args.Length);
            }

            if(args != null && RequiresArguments) {
                int i = 0;
                string [] names = new string[args.Length];

                foreach(KeyValuePair<string, FunctionNode> var in Functions) {
                    names[i++] = var.Key;
                }

                for(i = 0; i < args.Length; i++) {
                    (body as TreeNode).RegisterFunction(names[i], evaluator.Evaluate(args[i]));
                }
            }

            return evaluator.Evaluate(ResolveBody(evaluator));
        }
예제 #20
0
        public static TreeNode VariableSet(EvaluatorBase evaluator, TreeNode [] args, bool update)
        {
            if(args.Length != 2) {
                throw new ArgumentException("must have two arguments");
            }

            if(!(args[0] is FunctionNode)) {
                throw new ArgumentException("first argument must be a variable");
            }

            FunctionNode variable_node = evaluator.ResolveFunction(args[0] as FunctionNode);
            if(variable_node != null) {
                variable_node.Body = evaluator.Evaluate(args[1]);
            } else {
                TreeNode parent = args[0].Parent;
                parent = parent.Parent ?? parent;

                parent.RegisterFunction((args[0] as FunctionNode).Function, evaluator.Evaluate(args[1]));
            }

            return new VoidLiteral();
        }
예제 #21
0
파일: Parser.cs 프로젝트: Yetangitu/f-spot
        public TreeNode Parse(StreamReader reader)
        {
            this.reader = reader;

            current_token = new StringBuilder();
            root_node = new TreeNode();
            current_parent = root_node;
            scope = 0;
            line = 1;
            column = 0;

            try {
                Tokenize();

                if(scope != 0) {
                    throw new ApplicationException("Scope does pop back to zero");
                }
            } catch(Exception e) {
                throw new ParserException(current_token.ToString(), line, column, e);
            }

            return root_node;
        }
예제 #22
0
 public virtual TreeNode OnIsList(TreeNode [] args)
 {
     return new BooleanLiteral(IsList(args[0]));
 }
예제 #23
0
 public void CheckList(TreeNode node)
 {
     if(!IsList(node)) {
         throw new ArgumentException("argument must be a list");
     }
 }
예제 #24
0
        // FIXME: Why is this here? --Aaron
        //
        // private TreeNode EvaluateList(TreeNode node)
        // {
        //    TreeNode list = new TreeNode();
        //
        //    foreach(TreeNode child in node.Children) {
        //        list.AddChild(Evaluate(child));
        //    }
        //
        //    return list;
        // }

        private bool IsList(TreeNode node)
        {
            return !(node is LiteralNodeBase) && !(node is FunctionNode);
        }
예제 #25
0
        public virtual TreeNode OnForeach(TreeNode [] args)
        {
            TreeNode list = Evaluate(args[1]);
            CheckList(list);
            FunctionNode item_variable = (FunctionNode)args[0];
            TreeNode function = args[2];

            TreeNode self = args[0].Parent.Children[0];
            self.Parent.RegisterFunction(item_variable.Function, item_variable);

            foreach(TreeNode child in list.Children) {
                item_variable.Body = child;

                try {
                    if(function is FunctionNode) {
                        FunctionNode function_impl = Evaluator.ResolveFunction(function as FunctionNode);
                        function_impl.Evaluate(Evaluator, new TreeNode [] { child });
                    } else {
                        Evaluate(function);
                    }
                } catch(Exception e) {
                    if(ControlFunctionSet.BreakHandler(e)) {
                        break;
                    }
                }
            }

            return new VoidLiteral();
        }
예제 #26
0
 public virtual TreeNode OnPrepend(TreeNode [] args)
 {
     TreeNode list = Evaluate(args[0]);
     CheckList(list);
     list.Children.Insert(0, Evaluate(args[1]));
     return list;
 }
예제 #27
0
 public virtual TreeNode OnAppend(TreeNode [] args)
 {
     TreeNode list = Evaluate(args[0]);
     CheckList(list);
     list.Children.Add(Evaluate(args[1]));
     return list;
 }
예제 #28
0
        public virtual TreeNode OnRemove(TreeNode [] args)
        {
            TreeNode list = Evaluate(args[0]);
            CheckList(list);

            TreeNode node = Evaluate(args[1]);

            foreach(TreeNode compare_node in list.Children) {
                if(((IntLiteral)CompareFunctionSet.Compare(Evaluator, node, compare_node)).Value == 0) {
                    list.Children.Remove(compare_node);
                    break;
                }
            }

            return list;
        }
예제 #29
0
 public TreeNode Evaluate(TreeNode node)
 {
     return evaluator.Evaluate(node);
 }
예제 #30
0
 public Evaluator(TreeNode expression) : base(expression)
 {
     RegisterFunctions();
 }