Beispiel #1
0
        public CbMethod getMethod(String mname, AST args, bool lookup)
        {
            // get method from dictionary
            List<CbMethod> methods;

            if (mname == null || !(Methods.TryGetValue(mname, out methods)))
            {
            if (lookup)
                ReportError(args.LineNumber, "Invalid method: '{0}'", mname);
            return null;
            }

            int desiredArgs = args.NumChildren;
            // compare parameters
            foreach (CbMethod method in methods)
            {
            int numArgs = method.ArgType.Count;
            if (numArgs != desiredArgs)
            {
                continue;
            }
            else
            {
                bool matches = true;
                // compare argument types
                for (int i = 0; i < numArgs; i++)
                {
                    if (method.ArgType[i] != args[i].Type)
                        matches = false;
                }
                if (matches)
                    return method;
            }
            }

            // report error if function is called with the lookup flag
            if (lookup)
            ReportError(args.LineNumber, "Invalid method or method parameter(s): '{0}'", mname);

            return null;
        }
Beispiel #2
0
        // 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);
            }
            }
        }
Beispiel #3
0
 // given an Ident or an Array node, look up the type representation
 private CbType lookUpType(AST node)
 {
     CbType result = CbType.Error;
     if (node.Tag == NodeType.Array)
     {
     CbType elemType = lookUpType(node[0]);
     result = CbType.Array(elemType);
     }
     else
     {
     // it has to be an Ident node
     result = lookUpIdenType(node);
     if (result == CbType.Error)
     {
         // check if it's a struct
         string name = ((AST_leaf)node).Sval;
         if (Structs.ContainsKey(name))
             result = Structs[name];  // it's a struct type
         else
             ReportError(node.LineNumber, "Unknown type {0}", name);
     }
     }
     node.Type = result; //annotate the node
     return result;
 }
Beispiel #4
0
 private CbType lookUpIdenType(AST node)
 {
     string iden = ((AST_leaf)node).Sval;
     if (iden == "int")
     return CbType.Int;
     else if (iden == "string")
     return CbType.String;
     else
     return CbType.Error;
 }
Beispiel #5
0
 private void printTag( AST node )
 {
     f.Write("{0}{1}  [line {2}]", indentString(indent), node.Tag, node.LineNumber);
     if (node.Type != null)
     f.Write(", type {0}", node.Type);
 }
Beispiel #6
0
 public override void AddChild( AST newchild )
 {
     children.Add(newchild);
 }
Beispiel #7
0
 public virtual void AddChild( AST ch )
 {
     throw new Exception("AddChild only supported for k-ary nodes");
 }