示例#1
0
        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--;
        }
示例#2
0
 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--;
 }
示例#3
0
        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");
            }
        }
示例#4
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);
                }
            }
        }
示例#5
0
        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");
            }
        }
示例#6
0
 public virtual void Visit(AST_kary n)
 {
     Console.WriteLine("Internal compiler error! This method should have been overridden");
 }
示例#7
0
 public virtual void Visit(AST_kary n)
 {
     Console.WriteLine("Internal compiler error! This method should have been overridden");
 }