public override void Visit(AST_kary node) { printTag(node); f.WriteLine(); int arity = node.NumChildren; indent++; for (int i = 0; i < arity; i++) { AST ch = node[i]; if (ch != null) { ch.Accept(this); } else { f.WriteLine("{0}-- missing child --", indentString(indent)); } } if (arity == 0) { f.WriteLine("{0}-- no children --", indentString(indent)); } indent--; }
public override void Visit(AST_kary node) { printTag(node); f.WriteLine(); int arity = node.NumChildren; indent++; for( int i = 0; i < arity; i++ ) { AST ch = node[i]; if (ch != null) ch.Accept(this); else f.WriteLine("{0}-- missing child --", indentString(indent)); } if (arity == 0) f.WriteLine("{0}-- no children --", indentString(indent)); indent--; }
public override void Visit(AST_kary node) { int children = node.NumChildren; switch(node.Tag) { case NodeType.UsingList: for (int i = 0; i < children; i++) { if (((AST_leaf)node[i]).Sval != "CbRuntime") ReportError(node[0].LineNumber, "Invalid using identifier: '{0}' (only allowed identifier is CbRuntime)", ((AST_leaf)node[i]).Sval); } break; case NodeType.DeclList: for (int i = 0; i < children; i++) { node[i].Accept(this); } break; case NodeType.FieldList: // already handled by prePass break; case NodeType.IdList: // already handled in NodeType.LocalDecl break; case NodeType.Formals: // visit all statements for (int i = 0; i < children; i++) node[i].Accept(this); break; case NodeType.Block: // change scope localSymbols.Enter(); // accept all statements for (int i = 0; i < children; i++) { node[i].Accept(this); } // change scope localSymbols.Exit(); break; case NodeType.Actuals: node.Type = CbType.Void; // visit all parameters for (int i = 0; i < children; i++) { node[i].Accept(this); if (node[i].Type == CbType.Error) node.Type = CbType.Error; } break; case NodeType.Return: node.Type = CbType.Void; if (node.NumChildren > 0) { node[0].Accept(this); node.Type = node[0].Type; } break; default: throw new Exception("{0} is not a tag compatible with an AST_kary node"); } }
// Makes two shallow passes over the declarations inside a class to obtain // the names and types of all consts, methods and structs declared at the // top level; without this info, typechecking cannot begin. private void prePass(AST node) { addPredeclared(); AST_kary decls = node as AST_kary; if (decls == null || decls.Tag != NodeType.DeclList) { throw new Exception("Bad argument passed to prePass"); } // make one pass over the declarations just to enter the names of structs into // the Structs table int arity = decls.NumChildren; for (int i = 0; i < arity; i++) { AST ch = decls[i]; if (ch.Tag != NodeType.Struct) { continue; // it was not a struct declaration } string name = ((AST_leaf)(ch[0])).Sval; if (Structs.ContainsKey(name)) { ReportError(ch[0].LineNumber, "Duplicate declaration of struct {0}", name); } else { Structs.Add(name, new CbStruct(name)); } } // now make a second pass over the declarations to // 1. add const declarations to the Consts table // 2. add method declarations to the Methods table // 3. fill in the field details for each struct in the Structs table for (int i = 0; i < arity; i++) { AST ch = decls[i]; string name; CbType typ; int argsize; switch (ch.Tag) { case NodeType.Struct: CbStruct str; name = ((AST_leaf)(ch[0])).Sval; // find existing struct Structs.TryGetValue(name, out str); // do error checking AST fldlst = ch[1]; AST fld; AST idlst; argsize = fldlst.NumChildren; int idsize; // iterate through the field list for (int j = 0; j < argsize; j++) { // get field declaration fld = fldlst[j]; // find declaration type typ = lookUpType(fld[0]); // get list of variables declared idlst = fld[1]; idsize = idlst.NumChildren; // add all declared variables to the struct for (int k = 0; k < idsize; k++) { str.AddField(((AST_leaf)(idlst[k])).Sval, typ); } } break; case NodeType.Const: // Add the name and type of this constant to the Consts table name = ((AST_leaf)(ch[1])).Sval; typ = lookUpType(ch[0]); if (Consts.ContainsKey(name)) { ReportError(ch[0].LineNumber, "Duplicate declaration of const {0}", name); } else { Consts.Add(name, typ); } break; case NodeType.Method: name = ((AST_leaf)(ch[1])).Sval; ch[2].Accept(this); // check for duplicate method CbMethod existing = getMethod(name, ch[2], false); if (existing != null) { ReportError(ch[0].LineNumber, "Duplicate declaration of method {0}", name); break; } CbType typm = CbType.Void; // create new CbMethod if (ch[0] != null) { typm = lookUpType(ch[0]); } CbMethod method = new CbMethod(name, typm); // add argument list (full signature) to CbMethod AST args = ch[2]; for (int j = 0; j < args.NumChildren; j++) { method.ArgType.Add(lookUpType(args[j][0])); } // get list of overloaded methods sharing same name List <CbMethod> methods; if (!Methods.TryGetValue(name, out methods)) // if none exist create new list { methods = new List <CbMethod>(); } // add method to list methods.Add(method); // replace old list of methods with this name with new list Methods[name] = methods; break; default: throw new Exception("Unexpected node type " + ch.Tag); } } }
public override void Visit(AST_kary node) { int children = node.NumChildren; switch (node.Tag) { case NodeType.UsingList: for (int i = 0; i < children; i++) { if (((AST_leaf)node[i]).Sval != "CbRuntime") { ReportError(node[0].LineNumber, "Invalid using identifier: '{0}' (only allowed identifier is CbRuntime)", ((AST_leaf)node[i]).Sval); } } break; case NodeType.DeclList: for (int i = 0; i < children; i++) { node[i].Accept(this); } break; case NodeType.FieldList: // already handled by prePass break; case NodeType.IdList: // already handled in NodeType.LocalDecl break; case NodeType.Formals: // visit all statements for (int i = 0; i < children; i++) { node[i].Accept(this); } break; case NodeType.Block: // change scope localSymbols.Enter(); // accept all statements for (int i = 0; i < children; i++) { node[i].Accept(this); } // change scope localSymbols.Exit(); break; case NodeType.Actuals: node.Type = CbType.Void; // visit all parameters for (int i = 0; i < children; i++) { node[i].Accept(this); if (node[i].Type == CbType.Error) { node.Type = CbType.Error; } } break; case NodeType.Return: node.Type = CbType.Void; if (node.NumChildren > 0) { node[0].Accept(this); node.Type = node[0].Type; } break; default: throw new Exception("{0} is not a tag compatible with an AST_kary node"); } }
public virtual void Visit(AST_kary n) { Console.WriteLine("Internal compiler error! This method should have been overridden"); }