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(); }
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(); }
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); }
public TreeNode Flatten() { TreeNode result_node = new TreeNode(); Flatten(result_node, this); return result_node.ChildCount == 1 ? result_node.Children[0] : result_node; }
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"); } }
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); }
public virtual TreeNode OnCompareTo(TreeNode [] args) { if(args.Length != 2) { throw new ArgumentException("must have two arguments"); } return Compare(Evaluator, args[0], args[1]); }
public virtual TreeNode OnDump(TreeNode [] args) { foreach(TreeNode arg in args) { Evaluate(arg).Dump(); } return new VoidLiteral(); }
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; }
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; }
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(); }
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)); }
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()); }
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); }
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); } }
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]); }
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"); }
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(); }
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)); }
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(); }
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; }
public virtual TreeNode OnIsList(TreeNode [] args) { return new BooleanLiteral(IsList(args[0])); }
public void CheckList(TreeNode node) { if(!IsList(node)) { throw new ArgumentException("argument must be a list"); } }
// 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); }
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(); }
public virtual TreeNode OnPrepend(TreeNode [] args) { TreeNode list = Evaluate(args[0]); CheckList(list); list.Children.Insert(0, Evaluate(args[1])); return list; }
public virtual TreeNode OnAppend(TreeNode [] args) { TreeNode list = Evaluate(args[0]); CheckList(list); list.Children.Add(Evaluate(args[1])); return list; }
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; }
public TreeNode Evaluate(TreeNode node) { return evaluator.Evaluate(node); }
public Evaluator(TreeNode expression) : base(expression) { RegisterFunctions(); }