public object VisitProgram(AST.Program Node) { this.CallStack.Push(new StackFrame("global", 1)); foreach (object Child in Node.Compound.Children) { if (!(Child is AST.SubroutineDeclaration)) { this.Visit(Child); } else { AST.SubroutineDeclaration subroutine = Child as AST.SubroutineDeclaration; string subname = (string)subroutine.SubroutineName.Value; if (null != subroutine.Body) { this.Subroutines.Add(subname, subroutine); } } } object result = this.VisitSubroutineDeclaration(this.Subroutines["main"]); this.CallStack.Pop(); return(result); }
public object VisitSubroutineDeclaration(AST.SubroutineDeclaration Node, AST.Call Call = null) { StackFrame sf = new StackFrame( (string)Node.SubroutineName.Value, this.CallStack.Peek().Level + 1, Node.Params, this.CallStack.Peek()); if (null != Call) { for (int i = 0; i < Call.Params.Count; i++) { string varname = (string)Node.Params[i].VariableNode.Value; string vartype = (string)Node.Params[i].TypeNode.Value; object value = this.ConvertAppr(this.Visit(Call.Params[i]), vartype); sf.Assign(varname, value); } } this.CallStack.Push(sf); this.VisitCompound(Node.Body); if (null == this.CallStack.Peek().ret) { this.Error( String.Format(Messages.MISSING_RETURN_STMT, Node.SubroutineName.Value), Node.SubroutineName.Token.Position); } object ret = (this.CallStack.Pop()).ret; string rettype = (string)Node.ReturnType.Value; return(this.ConvertAppr(ret, rettype)); }