view sema/Symbol.d @ 168:7982eb63c0eb

Some changes to get function overloading to work. Also class inherit works now - to some extend. needs vtables and all the complex stuff of it.
author Anders Johnsen <skabet@gmail.com>
date Thu, 24 Jul 2008 12:06:48 +0200
parents 57b0b4464a0b
children
line wrap: on
line source

module sema.Symbol;

import tango.text.convert.Integer : format;
import tango.io.Stdout;

import sema.DType;

import ast.Decl;

///
class Symbol
{
    /// Create a root symbol - representing a module
    this() { actual = this; }

    /// Get a simple human readable name (bar)
    char[] getName() { return name; }

    /// Get a human readable name (foo.bar)
    char[] getFQN()
    {
        char[] prefix;
        if (parent !is null && parent.name !is null)
            prefix ~= parent.getFQN() ~ ".";
        return prefix ~ name;
    }

    /// Get a machine readable name (_D3foo3barFZi)
    char[] getMangledFQN()
    {
        char[] n = `_D`;
        Symbol p = parent;
        while (p !is null) {
            n ~= p.internalFQN();
            p = p.parent;
        }
        n ~= internalFQN();
        n ~= type.mangle();
        return n;
    }

    /**
      Try to find a contained symbol with the given name
     **/
    Symbol[] findMembers(char[] member)
    {
        Symbol[] res;
        foreach (possible; actual.contained)
            if (possible.name == member)
                res ~= possible;

        if (!res.length && actual.type.isClass)
        {
            foreach (base ; (cast(ClassDecl)actual.decl).baseClasses)
                if (base.type.isClass)
                    res ~= base.getSymbol.findMembers(member);
        }
        return res;
    }

    /**
      Try to find a contained symbol with the given name, who's type is a DFunction
     **/
    Symbol[] findFunctionMembers(char[] member)
    {
        Symbol[] res;
        foreach (possible; actual.contained)
            if (possible.name == member && possible.type.isFunction)
                res ~= possible;
        return res;
    }

    /**
      Get the members of the symbol
     **/
    Symbol[] getMembers()
    {
        return actual.contained;
    }

    void dump()
    {
        Stdout("Symbol: ");
        Symbol p = parent;
        while (p !is null) {
            Stdout.format("{}.", p.name);
            p = p.parent;
        }
        Stdout.formatln("{}", name);
    }

    /// Create a member with the given name and type
    Symbol createMember(char[] member, DType type, Decl decl)
    {
        auto res = new Symbol(member, type, this);
        res.decl = decl;
        actual.contained ~= res;
        return res;
    }

    /**
      Create an alias of another symbol with the given name.

      The target symbol can be a member of another symbol
     **/
    Symbol createAlias(char[] aliasedName, Symbol target, Decl decl)
    {
        auto res = new Symbol(aliasedName, target, this);
        res.decl = decl;
        actual.contained ~= res;
        return res;
    }

    // The type of this symbol
    DType type;
    // The declaration of this symbol
    Decl decl;
    // If the symbol is an alias, this will point to the actual symbol
    Symbol actual;
    // If this symbol is contained within a struct or similar this will point
    // to that symbol
    Symbol parent;

    char[] toString()
    {
        return getMangledFQN;
    }

private:
    // Helper for getMangledFQN - gets the FQN without _D and the type
    char[] internalFQN()
    {
        if (actual.name !is null && actual.name.length > 0)
        {
            char[32] len;
            return format(len, actual.name.length) ~ actual.name;
        }
        return "";
    }

    this(char[] name, Symbol actual, Symbol parent)
    {
        this.name = name;
        this.actual = actual;
        this.parent = parent;
        this.type = actual.type;
    }

    this(char[] name, DType type, Symbol parent)
    {
        this.name = name;
        this.actual = this;
        this.parent = parent;
        this.type = type;
    }

private:
    char[] name;

    // All the symbols contained within this symbol
    Symbol[] contained;

    // The module that contains this symbol (root of the parent-chain)
    // DModule mod;
}