private void checkout(AstNode theNode) { foreach (AstNode node in theNode.Children) { if (node is BinOpNode) { BinOpNode bnode = ((BinOpNode)node); if (((BinOpNode)node).BinOp == BinaryOperation.Assignment) { if (!result.Symbols.Contains(bnode.Left.ToString())) { result.Symbols.Add(bnode.Left.ToString()); } } } else { checkout(node); } } foreach (AstNode node in theNode.Children) { if (node is FuncNode) { FuncNode fnode = ((FuncNode)node); currentLocalScope = new LocalScope(); result.ChildScopes[fnode.Name] = currentLocalScope; currentLocalScope.Symbols.AddRange(fnode.Parameters); analyseLocalCode(fnode.Body); } } }
private void analyseLocalCode(AstNode theNode) { foreach (AstNode node in theNode.Children) { if (node is BinOpNode) { BinOpNode bnode = ((BinOpNode)node); if (bnode.BinOp == BinaryOperation.Assignment) { if (!result.Symbols.Contains(bnode.Left.ToString()) && !currentLocalScope.Symbols.Contains(bnode.Left.ToString())) { currentLocalScope.Symbols.Add(bnode.Left.ToString()); } } } else { analyseLocalCode(node); } } }
private object interpretBinaryOp(BinOpNode node, bool isAssign = false) { switch (isAssign ? node.AssignOperation : node.BinOp) { case BinaryOperation.Addition: if (EvaluateNode(node.Left) is string || EvaluateNode(node.Right) is string) return EvaluateNode(node.Left) + EvaluateNode(node.Right).ToString(); return Convert.ToDouble((EvaluateNode(node.Left))) + Convert.ToDouble((EvaluateNode(node.Right))); case BinaryOperation.Subtraction: return Convert.ToDouble((EvaluateNode(node.Left))) - Convert.ToDouble((EvaluateNode(node.Right))); case BinaryOperation.Division: return Convert.ToDouble((EvaluateNode(node.Left))) / Convert.ToDouble((EvaluateNode(node.Right))); case BinaryOperation.Multiplication: if ((EvaluateNode(node.Left) is string && EvaluateNode(node.Right) is double) || EvaluateNode(node.Right) is string && EvaluateNode(node.Left) is double) { var p1 = EvaluateNode(node.Left); var p2 = EvaluateNode(node.Right); if (p1 is string) return string.Concat(Enumerable.Repeat(p1, Convert.ToInt32(p2))); else return string.Concat(Enumerable.Repeat(p2, Convert.ToInt32(p1))); } return Convert.ToDouble((EvaluateNode(node.Left))) * Convert.ToDouble((EvaluateNode(node.Right))); case BinaryOperation.Assignment: if (!(node.Left is IdentifierNode)) throw new Exception("Not a valid identifier"); var right = EvaluateNode(node.Right); SetVariable(node.Left.ToString(), right); return right; case BinaryOperation.Equals: return EvaluateNode(node.Left).GetHashCode() == EvaluateNode(node.Right).GetHashCode(); case BinaryOperation.And: return Convert.ToBoolean(EvaluateNode(node.Left)) && Convert.ToBoolean(EvaluateNode(node.Right)); case BinaryOperation.Or: return Convert.ToBoolean(EvaluateNode(node.Left)) || Convert.ToBoolean(EvaluateNode(node.Right)); case BinaryOperation.NotEqualTo: return EvaluateNode(node.Left).GetHashCode() != EvaluateNode(node.Right).GetHashCode(); case BinaryOperation.LessThan: return Convert.ToDouble(EvaluateNode(node.Left)) < Convert.ToDouble(EvaluateNode(node.Right)); case BinaryOperation.GreaterThan: return Convert.ToDouble(EvaluateNode(node.Left)) > Convert.ToDouble(EvaluateNode(node.Right)); case BinaryOperation.GreaterOrEqual: return Convert.ToDouble(EvaluateNode(node.Left)) >= Convert.ToDouble(EvaluateNode(node.Right)); case BinaryOperation.LesserOrEqual: return Convert.ToDouble(EvaluateNode(node.Left)) <= Convert.ToDouble(EvaluateNode(node.Right)); case BinaryOperation.Xor: return Convert.ToBoolean(EvaluateNode(node.Left)) ^ Convert.ToBoolean(EvaluateNode(node.Right)); case BinaryOperation.BitshiftLeft: return Convert.ToInt32(EvaluateNode(node.Left)) << Convert.ToInt32(EvaluateNode(node.Right)); case BinaryOperation.BitshiftRight: return Convert.ToInt32(EvaluateNode(node.Left)) >> Convert.ToInt32(EvaluateNode(node.Right)); case BinaryOperation.Modulus: return Convert.ToDouble(EvaluateNode(node.Left)) % Convert.ToDouble(EvaluateNode(node.Right)); case BinaryOperation.Pow: return Math.Pow(Convert.ToDouble(EvaluateNode(node.Left)), Convert.ToDouble(EvaluateNode(node.Right))); case BinaryOperation.Root: return Math.Pow(Convert.ToDouble(EvaluateNode(node.Left)), 1.0 / Convert.ToDouble(EvaluateNode(node.Right))); } // Raise error return -1; }
private void interpretBinaryAssign(BinOpNode node) { SetVariable(node.Left.ToString(), interpretBinaryOp(node, true), false, true); }
private object interpretBinaryOp(BinOpNode node, bool isAssign = false) { switch (isAssign ? node.AssignOperation : node.BinOp) { case BinaryOperation.Addition: if (EvaluateNode(node.Left) is string || EvaluateNode(node.Right) is string) { return(EvaluateNode(node.Left) + EvaluateNode(node.Right).ToString()); } return(Convert.ToDouble((EvaluateNode(node.Left))) + Convert.ToDouble((EvaluateNode(node.Right)))); case BinaryOperation.Subtraction: return(Convert.ToDouble((EvaluateNode(node.Left))) - Convert.ToDouble((EvaluateNode(node.Right)))); case BinaryOperation.Division: return(Convert.ToDouble((EvaluateNode(node.Left))) / Convert.ToDouble((EvaluateNode(node.Right)))); case BinaryOperation.Multiplication: if ((EvaluateNode(node.Left) is string && EvaluateNode(node.Right) is double) || EvaluateNode(node.Right) is string && EvaluateNode(node.Left) is double) { var p1 = EvaluateNode(node.Left); var p2 = EvaluateNode(node.Right); if (p1 is string) { return(string.Concat(Enumerable.Repeat(p1, Convert.ToInt32(p2)))); } else { return(string.Concat(Enumerable.Repeat(p2, Convert.ToInt32(p1)))); } } return(Convert.ToDouble((EvaluateNode(node.Left))) * Convert.ToDouble((EvaluateNode(node.Right)))); case BinaryOperation.Assignment: if (!(node.Left is IdentifierNode)) { throw new Exception("Not a valid identifier"); } var right = EvaluateNode(node.Right); SetVariable(node.Left.ToString(), right); return(right); case BinaryOperation.Equals: return(EvaluateNode(node.Left).GetHashCode() == EvaluateNode(node.Right).GetHashCode()); case BinaryOperation.And: return(Convert.ToBoolean(EvaluateNode(node.Left)) && Convert.ToBoolean(EvaluateNode(node.Right))); case BinaryOperation.Or: return(Convert.ToBoolean(EvaluateNode(node.Left)) || Convert.ToBoolean(EvaluateNode(node.Right))); case BinaryOperation.NotEqualTo: return(EvaluateNode(node.Left).GetHashCode() != EvaluateNode(node.Right).GetHashCode()); case BinaryOperation.LessThan: return(Convert.ToDouble(EvaluateNode(node.Left)) < Convert.ToDouble(EvaluateNode(node.Right))); case BinaryOperation.GreaterThan: return(Convert.ToDouble(EvaluateNode(node.Left)) > Convert.ToDouble(EvaluateNode(node.Right))); case BinaryOperation.GreaterOrEqual: return(Convert.ToDouble(EvaluateNode(node.Left)) >= Convert.ToDouble(EvaluateNode(node.Right))); case BinaryOperation.LesserOrEqual: return(Convert.ToDouble(EvaluateNode(node.Left)) <= Convert.ToDouble(EvaluateNode(node.Right))); case BinaryOperation.Xor: return(Convert.ToBoolean(EvaluateNode(node.Left)) ^ Convert.ToBoolean(EvaluateNode(node.Right))); case BinaryOperation.BitshiftLeft: return(Convert.ToInt32(EvaluateNode(node.Left)) << Convert.ToInt32(EvaluateNode(node.Right))); case BinaryOperation.BitshiftRight: return(Convert.ToInt32(EvaluateNode(node.Left)) >> Convert.ToInt32(EvaluateNode(node.Right))); case BinaryOperation.Modulus: return(Convert.ToDouble(EvaluateNode(node.Left)) % Convert.ToDouble(EvaluateNode(node.Right))); case BinaryOperation.Pow: return(Math.Pow(Convert.ToDouble(EvaluateNode(node.Left)), Convert.ToDouble(EvaluateNode(node.Right)))); case BinaryOperation.Root: return(Math.Pow(Convert.ToDouble(EvaluateNode(node.Left)), 1.0 / Convert.ToDouble(EvaluateNode(node.Right)))); } // Raise error return(-1); }