public ForNode(AstNode left, AstNode predicate, AstNode right, AstNode body) { this.Children.Add(left); this.Children.Add(predicate); this.Children.Add(right); this.Children.Add(body); }
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); } }
public Interpreter(SymbolTable symbolTable, AstNode code) { this.code = code; table = symbolTable; foreach (var entry in GetFunctions()) Globals.Add(entry.Key, entry.Value); }
public BinOpNode(BinaryOperation type, BinaryOperation assign, AstNode left, AstNode right) { BinOp = type; AssignOperation = assign; IsAssign = true; Children.Add(left); Children.Add(right); }
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); } }
public void ExecuteStatement(AstNode node) { if (CallStack.Count > 0 && CallStack.Peek().ReturnValue != null) return; if (node is CodeBlock) foreach (var anode in node.Children) ExecuteStatement(anode); else if (node is IfNode) { var ifStmt = (IfNode)(node); if ((bool)(EvaluateNode(ifStmt.Predicate))) ExecuteStatement(ifStmt.Body); else ExecuteStatement(ifStmt.ElseBody); } else if (node is WhileNode) { var whileStmt = (WhileNode)(node); if ((bool)(EvaluateNode(whileStmt.Predicate))) while ((bool)EvaluateNode(whileStmt.Predicate)) { ExecuteStatement(whileStmt.Body); } else ExecuteStatement(whileStmt.ElseBody); } else if (node is ForNode) { var forStmt = (ForNode)(node); ExecuteStatement(forStmt.Left); while ((bool)EvaluateNode(forStmt.Predicate)) { ExecuteStatement(forStmt.Body); ExecuteStatement(forStmt.Right); } } else if (node is ForEachNode) { var forStmt = (ForEachNode)(node); var needlestmt = forStmt.Needle.ToString(); var haystack = EvaluateNode(forStmt.Haystack); SetVariable(needlestmt, null); if ((haystack as IEnumerable) == null) throw new ArgumentException("'" + haystack + "' is not an array and therefore can not be used in foreach."); foreach (var needle in (IEnumerable)haystack) { SetVariable(needlestmt, needle); ExecuteStatement(forStmt.Body); } FreeVariable(needlestmt); } else if (node is TryNode) { var tryStmt = (TryNode)(node); try { ExecuteStatement(tryStmt.Body); } catch { ExecuteStatement(tryStmt.CatchBody); } finally { ExecuteStatement(tryStmt.FinallyBody); } } else if (node is ThreadNode) { var threadStmt = (ThreadNode)(node); Task.Factory.StartNew(() => ExecuteStatement(threadStmt.Node)); } else if (node is ReturnNode) { var returnStmt = (ReturnNode)(node); CallStack.Peek().ReturnValue = EvaluateNode(returnStmt.Value); } else { EvaluateNode(node); } }
public ReturnNode(AstNode value) { this.Value = value; }
public TryNode(AstNode body, AstNode catchBody) { this.Children.Add(body); this.Children.Add(catchBody); }
public FuncNode(string name, List<string> paramaters, AstNode body) { this.Parameters = paramaters; this.Name = name; this.Children.Add(body); }
public BinOpNode(BinaryOperation type, AstNode left, AstNode right) { this.BinOp = type; this.Children.Add(left); this.Children.Add(right); }
public WhileNode(AstNode predicate, AstNode body, AstNode elseBody) { this.Children.Add(predicate); this.Children.Add(body); this.Children.Add(elseBody); }
public UnaryOpNode(UnaryOperation type, AstNode value) { this.UnOp = type; this.Children.Add(value); }
private static AstNode ParseFunctionCall(Parser.Parser parser, AstNode left) { if (parser.AcceptToken(TokenType.Parentheses, "(")) { return ParseFunctionCall(parser, new FunctionCallNode(left, ArgListNode.Parse(parser))); } else if (parser.AcceptToken(TokenType.Bracket, "[")) { return ParseFunctionCall(parser, new ArrayGetNode(left, ArrayIndexerNode.Parse(parser))); } else { return left; } }
public SemanticAnalyser(AstNode code) { this.Code = code; }
public FunctionCallNode(AstNode target, ArgListNode arguments) { this.Children.Add(target); this.Children.Add(arguments); }
public object EvaluateNode(AstNode node) { if (node is NumberNode) { return ((NumberNode)node).Value; } else if (node is StringNode) { return ((StringNode)node).Value; } else if (node is BinOpNode) { if (((BinOpNode)node).IsAssign) { interpretBinaryAssign((BinOpNode)node); return null; } return interpretBinaryOp((BinOpNode)node); } else if (node is UnaryOpNode) { return interpretUnaryOp((UnaryOpNode)node); } else if (node is FunctionCallNode) { var call = (FunctionCallNode) node; var target = EvaluateNode(call.Target) as IFunction; if (target == null) throw new Exception("Attempt to run a non-valid function!"); var arguments = new object[call.Arguments.Children.Count]; for (var x = 0; x < call.Arguments.Children.Count; x++) { arguments[x] = EvaluateNode(call.Arguments.Children[x]); if (arguments[x] is double && (((double)(arguments[x])) % 1 == 0)) arguments[x] = (int)(double)arguments[x]; } return target.Invoke(arguments); } else if (node is IdentifierNode) { return GetVariable(((IdentifierNode)node).Identifier); } else if(node is ArrayInitializerNode) { return ((ArrayInitializerNode) node).Value.Select(x => EvaluateNode((AstNode)x)).ToArray(); } else if (node is ArrayGetNode) { var call = (ArrayGetNode)node; Array theArray = null; var evaluated = EvaluateNode(call.Target); if (evaluated is string) theArray = evaluated.ToString().ToArray(); else if (evaluated is Array) theArray = (Array) evaluated; else { throw new Exception("The [] operator only applies to objects of type Array or String."); } var arguments = new object[call.Arguments.Children.Count]; for (var x = 0; x < call.Arguments.Children.Count; x++) arguments[x] = EvaluateNode(call.Arguments.Children[x]); var arid = (int)double.Parse(string.Join("", arguments)); if (arid < 0 || arid >= theArray.Length) throw new ArgumentOutOfRangeException(); var retvalue = theArray.GetValue(arid); if (retvalue is AstNode) return EvaluateNode((AstNode) retvalue); else return retvalue; } else { //Raise error } return 0; }
public ThreadNode(AstNode node) { this.Children.Add(node); }
public WhileNode(AstNode predicate, AstNode body) { this.Children.Add(predicate); this.Children.Add(body); this.Children.Add(new CodeBlock()); }
public ForEachNode(AstNode needle, AstNode haystack, AstNode body) { this.Children.Add(needle); this.Children.Add(haystack); this.Children.Add(body); }