view sema/Symbol.d @ 136:2be29b296081

Lots of changes: - Parsing classes and interfaces - Fixed some seg faults in sema - Supporting "private" to some extend - And a lot of other small fixes
author johnsen@johnsen-laptop
date Fri, 11 Jul 2008 21:47:57 +0200
parents 9869194de9b7
children 57b0b4464a0b
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 - returns null if not
      found
     **/
    Symbol findMember(char[] member)
    {
        foreach (possible; actual.contained)
            if (possible.name == member)
                return possible;
        return null;
    }

    /**
      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;

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;
}