⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ast.cs

📁 charp compiler
💻 CS
📖 第 1 页 / 共 5 页
字号:
//-----------------------------------------------------------------------------
// File: AST.cs
// The abstract syntax tree
// 
// All AST nodes derive from class Node for utility purposes (dumping, 
// source file mapping, etc).
//-----------------------------------------------------------------------------

#region Comment on AST node hierarchy
//-----------------------------------------------------------------------------
// Nodes fall into 3 categories: 
// 1) Decl - declare something
// 2) Statement - statements in program
// 3) Exp - part of an expression
//
// Each node may reference its corresponding derived class from SymEntry
// The AST is pure and does not contain any resolved information besides
// the symbol table entry. All resolved data is stored on the symbol entry.
// The parser creates the AST with strings for the identifiers.
// Then the semantic checking populates the SymbolTable and does a lookup
// on the string name and sets the SymEntry fields.
//  
// The node organization is:
// + Node - root class
//    + ProgramDecl - declare a program
//    + NamespaceDecl - declare a namespace
//    + ClassDecl - declare a class
//    + MemberDecl - member within a class
//       + MethodDecl
//       + FieldDecl 
//       + VarDecl
//           + LocalVarDecl - declare a local variable
//           + ParamVarDecl - declare a parameter
//    + PropertyDecl
//
//    + Statement
//       + ReturnStatement
//       + AssignStatement
//       + IfStatement
//       + LoopStatement
//          + WhileStatement
//          + DoStatement
//
//    + Exp - nodes that form expressions
//       + LiteralExp
//           + IntExp
//           + BoolExp
//           + StringExp
//           + CharExp
//           + DoubleExp
//       + BinaryExp
//       + UnaryExp       
//       + ObjExp
//          + SimpleObjExp - apply single identifier to ObjExp
//          + DotObjExp - single identifier
//          + MethodCallExp - evaluates to a method call
//          + NewObjExp - create new objects
//          + CastObjExp - cast an expression into an object
//
//    + TypeSig - store a type
//-----------------------------------------------------------------------------
#endregion

using System;
using System.Collections;
using System.Diagnostics;
using System.Xml;

using SymbolEngine;
using Blue.Public;



//-----------------------------------------------------------------------------
/// <summary>
/// <c>Identifier</c> is a helper class to associate a string with a <c>FileRange</c>.
/// All AST references to a string-data should refer to an Identifier.
/// </summary>
//-----------------------------------------------------------------------------
public class Identifier
{
    public Identifier(string stText)
        : this(stText, null)
    {    }
    public Identifier(string stText, FileRange location)
    {
        m_stText = stText;
        m_filerange = location;
    }
    
    protected string m_stText;
    protected FileRange m_filerange;
    
    public string Text
    {
        get { return m_stText; }
    }
    
    public FileRange Location
    {
        get { return m_filerange; }
    }
}

//-----------------------------------------------------------------------------
// The Abstract Syntax Tree
//-----------------------------------------------------------------------------
namespace AST
{
#region Node, the base class for all AST nodes
//-----------------------------------------------------------------------------
// Base AST node serves for utility purposes
//-----------------------------------------------------------------------------

/// <summary>
/// <c>Node</c> is the base class for all nodes in the Abstract Syntax tree.
/// </summary>
/// <remarks>
/// <list type="bullet">
/// <item>It is associated with a <c>FileRange</c> object to guarantee that all nodes 
/// can provide line number information. </item>
/// <item>It also provides some standard utility functions to serialize a subtree to
/// XML or strings.</item>
/// </list>
/// Nodes are split into the following major categories: 
/// Declarations, Members, Statements, Expressions
/// </remarks>
public abstract class Node
{    
#region Checks

// Utility to Dump to XML file
    public static void DumpTree(Node root, XmlWriter o)
    {
        o.WriteStartDocument();
        o.WriteStartElement("AST");
        root.Dump(o);
        o.WriteEndElement(); // AST
        o.WriteEndDocument();
        o.Close();
    }

// Dump as xml. XmlWriter must be opended & document must be started
// Will not close document.
    public abstract void Dump(XmlWriter o);
   
    // Debugging function only:
    // Debugging check to be done _after_ symbol resolution
    // That way, we have a symbol table that we can verify everything against.
    // Assert everything that we can possibly think of so that CodeGen
    // has a well-resolved tree.
    // If any of the asserts do fire, that means symbolic resolution is
    // making a mistake and should be fixed.
    public abstract  void DebugCheck(ISemanticResolver s);
    
    // These flags are used during the DebugCheck() to allow features
    // that haven't been implemented to pass.
    // remove these flags (set to false) as more stuff gets resolved
    public readonly static bool m_DbgAllowNoCLRType = false;
    
    
    // Debugging facility. Dump() spits out XML which can be really tough to read,
    // and it's not clear what it should include.
    // So we have a facility to spit it out as a string.
    static string GetAsSourceString(Node n)
    {
        //System.Text.StringBuilder sb = new System.Text.StringBuilder();    
        //n.ToSource(sb);
        //return sb.ToString();
        return "empty";
    }
    
    public static void DumpSourceToStream(Node n, System.IO.TextWriter t)
    {
        Console.WriteLine("*** Begin Source dump: [");
        
        System.CodeDom.Compiler.IndentedTextWriter i = new 
            System.CodeDom.Compiler.IndentedTextWriter(t, "    ");
        
                
        n.ToSource(i);
        
        Console.WriteLine("] *** End source dump");
        
        i.Close();        
        i = null;
        
    }
    
    // Dump the string to the console.
    public static void DumpSource(Node n)
    {        
        DumpSourceToStream(n, Console.Out);     
    }
    
    // This should look like source but inject a few extra characters
    // to make it clear how it was resolved.
    public virtual void ToSource(System.CodeDom.Compiler.IndentedTextWriter sb)
    {
        //sb.Append("['" + this.GetType().ToString() + "' not implemented]");
        sb.Write("['{0}' not implemented]", this.GetType().ToString());
    }
    
#endregion   

#region Linenumber info
    // Line information.
    protected FileRange m_filerange;
    public FileRange Location
    {
        get { return m_filerange; }        
    } 
    
    // Parser has to be able to set the line number information. 
    public void SetLocation(FileRange l)
    {
        m_filerange = l;
    }
    
#endregion Linenumber info    
 
    // Shortcut helper functions.
    static public void PrintError(SymbolError.SymbolErrorException e)
    {    
        Blue.Driver.StdErrorLog.PrintError(e);
    }
    static public void ThrowError(SymbolError.SymbolErrorException e)
    {    
        Blue.Driver.StdErrorLog.ThrowError(e);
    }    
}
#endregion

#region Node for a Compilation-Unit
//-----------------------------------------------------------------------------
// Top level program
//-----------------------------------------------------------------------------

/// <summary>
/// The root AST node for an entire multi-file program.
/// </summary>
/// <remarks>
/// A ProgramDecl node contains all global namespace decls.
/// </remarks>
public class ProgramDecl : Node
{
#region Construction
    public ProgramDecl(NamespaceDecl [] nGlobal)
    {
        Debug.Assert(nGlobal != null);
        
        m_nGlobal = nGlobal;        
    }
#endregion
            
#region Checks    
    public override void Dump(XmlWriter o)
    {
        o.WriteStartElement("Program");        
        foreach(NamespaceDecl n in m_nGlobal)
            n.Dump(o);
        o.WriteEndElement();
    }

    // Debugging check
    public override void DebugCheck(ISemanticResolver s)
    {
        foreach(NamespaceDecl n in m_nGlobal)
            n.DebugCheck(s);
    }
#endregion    

#region Properties & Data
    // Source file has a single implicity global namespace
    NamespaceDecl [] m_nGlobal;
    public NamespaceDecl [] GlobalNamespaces
    {
        get { return m_nGlobal; }
    }


    // List of classes, created by flattening all classes in
    // all the namespaces.
    TypeDeclBase[] m_arClasses;
    public TypeDeclBase[] Classes
    {
        get { 
            return m_arClasses; 
        }
    }
    
#endregion
    
#region Other Functions    
    // Get a flat array of classes from the namespaces
    // The array is topologically sorted such that:
    // if (i < j) then T[i] does not depend on T[j]
    protected void CreateClassListFromNamespaces()
    {
        Debug.Assert(m_arClasses == null);
        
        ArrayList a = new ArrayList();
        
        foreach(NamespaceDecl n in m_nGlobal)
            n.ReportClasses(a);
        
        m_arClasses = new TypeDeclBase[a.Count];
        for(int i = 0; i < a.Count; i++)
            m_arClasses[i] = (TypeDeclBase) a[i];
    }
#endregion    
    
#region Resolution    
    public void ResolveNamespace(ISemanticResolver s, Scope scopeGlobal)
    {
    // First must do namespaces so that type stubs even
    // have a context.
        foreach(NamespaceDecl n in m_nGlobal)
            n.ResolveNamespace("", s, scopeGlobal);

    // Next, resolve type stubs so that using alias at least
    // has stub types to refer to
        ResolveTypeStubs(s);

    // Now resolve Using decls. Have to do this before we
    // try and use any types (since using decls will affect resolution)
        foreach(NamespaceDecl n in m_nGlobal)
            n.ResolveUsingDecls(s);
    }
    
    public void NotifyResolutionDone()
    {
    // Can't create the single class list until after
    // all symbols have been resolved
        CreateClassListFromNamespaces();
    }
    

    // Add stubs for all user types.
    public void ResolveTypeStubs(ISemanticResolver s)
    {
        foreach(NamespaceDecl n in m_nGlobal)
            n.ResolveTypesAsBlueStub(s);
    }

    // Resolve the types
    public void ResolveTypes(
        ISemanticResolver s,
        ICLRtypeProvider provider)
    {	       

    // Then go through and resolve them to CLR types.
        foreach(NamespaceDecl n in m_nGlobal)
            n.ResolveTypesAsCLR(s, provider);    
    }

    // Resolve the member declarations within a class.
    // Since these can refer to other classes, we must have
    // resolved all types before resolving any members
    public void ResolveMemberDecls(
        ISemanticResolver s,
        ICLRtypeProvider provider
    )
    {
        foreach(NamespaceDecl n in m_nGlobal)
            n.ResolveMemberDecls(s, provider);
    }
	
    // Resolve the bodies of methods
    public void ResolveBodies(ISemanticResolver s)
    {  
        foreach(NamespaceDecl n in m_nGlobal)
            n.ResolveBodies(s);
    }
#endregion
   
} // end class Program

#endregion

#region AST Nodes that go in a Namespace Decl
//-----------------------------------------------------------------------------
// Using directive
//-----------------------------------------------------------------------------
public class UsingDirective : Node
{
#region Construction
    // For alias
    public UsingDirective(string stAlias, Exp eNamespace)
    {
        Debug.Assert(stAlias != null);
        Debug.Assert(eNamespace != null);

        m_stAlias = stAlias;
        m_eNamespace = eNamespace;
    }

    // For search path
    public UsingDirective(Exp eNamespace)
    {
        Debug.Assert(eNamespace != null);

        m_stAlias = null;
        m_eNamespace = eNamespace;
    }
#endregion

#region Properties & Data
    // We have 2 types of using directives: Alias & Search.
    public bool IsAliasType
    {
        get { return m_stAlias != null; }
    }
    
    string m_stAlias;
    Exp m_eNamespace;
#endregion

#region Resolution
    // Lookup the symbol in this Using Alias/Directive.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -