view sema/DType.d @ 68:381975d76baf new_gen

A LOT of bug fixing - also implemented implicit casts. If you do a --ast-dump-code on a target with some algebra of differant types, you should now see the type casts being made. Also, Tests are again back with only switches failing...
author Anders Johnsen <skabet@gmail.com>
date Thu, 01 May 2008 19:25:49 +0200
parents 91f10c34cd7b
children 628cb46ab13b
line wrap: on
line source

module sema.DType;

import lexer.Token,
       ast.Exp;

import tango.io.Stdout;

class DType
{
    private char[] id;
    private Location loc;
    public DType actual;

    this(Identifier id, DType actual = null)
    {
        Token temp = id.token;
        this.id = temp.get;
        this.loc = temp.location;
        this.actual = actual is null? this : actual;
    }

    this(char[] id, DType actual = null)
    {
        this.id = id;
        this.actual = actual is null? this : actual;
    }

    /// Is this type a DStruct
    bool isStruct() { return false; }
    /// Return a DStruct if this is one, otherwise return null
    DStruct asStruct() { return null; }

    /// Is this type a DFunction
    bool isFunction() { return false; }
    /// Return a DFunction if this is one, otherwise return null
    DFunction asFunction() { return null; }

    /// Is this type a DInteger
    bool isInteger() { return false; }
    /// Return a DInteger if this is one, otherwise return null
    DInteger asInteger() { return null; }

    // Is this type a DPointer
    //bool isPointer() { return false; }
    // DPointer asPointer() { return null; }

    int opEquals(Object o)
    {
        if (auto t = cast(DType)o)
            return this.actual is t.actual;
        return 0;
    }

    int opCmp(Object o)
    {
        if (auto t = cast(DType)o)
            return cast(void*)this.actual - cast(void*)t.actual;
        return 0;
    }

    /**
      Hashing is done by casting the reference to a void* and taking that
      value, but this gives a bad distribution of hash-values.

      Multiple DType's allocated close to each other will only have a
      difference in the lower bits of their hashes.
     */
    hash_t toHash()
    {
        return cast(hash_t)(cast(void*)this);
    }

    char[] name() { return id; }
    Location getLoc() { return loc; }
    int byteSize() { return 0; }

    /**
      Can this type legally be converted to that type with no casts?
      True for short -> int etc.
     */
    bool hasImplicitConversionTo(DType that) { return false; }

    static DInteger
        Bool,
        Byte, UByte, Short, UShort,
        Int, UInt, Long, ULong;

    static DType Void;

    static this()
    {
        Void   = new DType("void");

        Bool   = new DInteger("bool",    1, false);
        Byte   = new DInteger("byte",    8, false);
        UByte  = new DInteger("ubyte",   8, true);
        Short  = new DInteger("short",  16, false);
        UShort = new DInteger("ushort", 16, true);
        Int    = new DInteger("int",    32, false);
        UInt   = new DInteger("uint",   32, true);
        Long   = new DInteger("long",   64, false);
        ULong  = new DInteger("ulong",  64, true);
    }
}

/**
  Class to represent the built-in integer types, from byte to long.
 */
class DInteger : DType
{
    this(char[] name, int bits, bool unsigned)
    {
        super(name, null);
        this.bits = bits;
        this.unsigned = unsigned;
    }

    override int byteSize() { return bits / 8; }

    override bool hasImplicitConversionTo(DType that)
    {
        if (auto o = cast(DInteger)that)
            return true;
//            return this.bits >= o.bits;
        return false;
    }

    override bool isInteger() { return true; }
    override DInteger asInteger() { return this; }

    int bits;
    bool unsigned;
}

class DStruct : DType
{
    this(Identifier id, DType actual = null)
    {
        super(id, actual);
    }

    int byteSize() { return bytes_total; }

    override bool isStruct() { return true; }
    override DStruct asStruct() { return this; }

    void addMember(DType type, char[] name)
    {
        auto s = DStructMember(type, members.length);
        members[name] = s;

        bytes_total += type.byteSize();
    }

    int indexOf(char[] name)
    {
        if(name in members)
            return members[name].index;

        return -1;
    }

    DType typeOf(char[] name)
    {
        if (auto res = name in members)
            return res.type;
        return null;
    }

    DStructMember[char[]] members;
    private int bytes_total;

    struct DStructMember
    {
        DType type;
        int index;
    }
}

class DFunction : DType
{
    this(Identifier id, DType actual = null)
    {
        super(id, actual);
    }

    override bool isFunction() { return true; }
    override DFunction asFunction() { return this; }

    DType[] params;
    DType returnType;
    bool firstParamIsReturnValue = false;
}