view ast/Decl.d @ 173:50b98a06a200

Start of support for virtual functions
author Anders Halager <halager@gmail.com>
date Thu, 24 Jul 2008 20:40:04 +0200
parents 01c2c49775ef
children 08f68d684047
line wrap: on
line source

module ast.Decl;

import ast.Exp,
       ast.Stmt;

import lexer.Token;

import tango.io.Stdout;

import sema.Scope,
       sema.Symbol,
       sema.DType,
       sema.VC,
       basic.SmallArray,
       basic.Attribute;

enum DeclType
{
    VarDecl,
    DummyDecl,
    ImportDecl,
    FuncDecl,
    StructDecl,
    ClassDecl,
    InterfaceDecl,
}

class Decl
{
    this(DeclType declType)
    {
        this.declType = declType;
    }

    void simplify()
    {
    }

    void verify(VC vc)
    {
    }

    DType type()
    {
        if (sym !is null)
            return sym.type;
        return null;
    }

    Identifier getIdentifier()
    {
        switch(declType)
        {
            case DeclType.VarDecl:
                return (cast(VarDecl)this).identifier;
            case DeclType.FuncDecl:
                return (cast(FuncDecl)this).identifier;
            default:
                assert(0, "Invalid DeclType for getting a identifier");
        }
    }

    DeclType declType;
    Scope env;
    Symbol sym;
    Attribute att;
}

class DummyDecl : Decl
{
    this()
    {
        super(DeclType.DummyDecl);
    }
}

class VarDecl : Decl
{
    this(IdentifierTypeExp type, Identifier identifier,
            Exp e = null)
    {
        super(DeclType.VarDecl);
        this.varType = type;
        this.identifier = identifier;
        this.init = e;
    }

    override DType type()
    {
        return env.findType(varType.get);
    }

    Identifier varType, identifier;
    Exp init;
}

class ImportDecl : Decl
{
    this()
    {
        super(DeclType.ImportDecl);
    }

    char[] get()
    {
        char[] res;
        foreach(i ; packages)
            res ~= i.get ~ ".";
        res ~= name.get;
        return res;
    }

    bool isStatic = false;

    Identifier[] packages;
    Identifier name;
    Identifier aliasedName;

    Identifier[2][] explicitSymbols;
}

class FuncDecl : Decl
{
    this(IdentifierTypeExp type, Identifier identifier)
    {
        super(DeclType.FuncDecl);
        this.returnType = type;
        this.identifier = identifier;
    }

    void addParam(IdentifierTypeExp type, Identifier name = null)
    {
        funcArgs ~= new VarDecl(type, name, null);
    }

    void setBody(CompoundStatement stmts)
    {
        statements = stmts.statements;
        emptyFunction = false;
    }

    void simplify()
    {
        /*
        if(auto t = env.find(identifier).type.asFunction())
        {
            if(auto s = cast(DStruct)t.returnType)
            {
                VarDecl[] funcArgs;
                auto i = new Identifier("ret.val");
                i.env = env;
                i.env.add(i);
                i.env.find(i).setType( s );
                auto var = new VarDecl(returnType, i);
                var.env = env;
                funcArgs ~= var;
                funcArgs ~= this.funcArgs;
                this.funcArgs = funcArgs;
                t.returnType = DType.Void;
                this.returnType = new Identifier("void");
                env.find(identifier).setType(t);
                sret = true;

                myType = null;
            }
        }
        */

        foreach (funcArg; funcArgs)
            funcArg.simplify();
        foreach (stmt; statements)
            stmt.simplify();
    }

    override void verify(VC vc)
    {
        foreach (stmt; statements)
            stmt.verify(vc);
    }

    override DFunction type()
    {
        if (myType !is null)
            return myType;

        auto t = new DFunction(identifier);
        if ( identifier.get == "this" )
            t.returnType = DType.Void;
        else
            t.returnType = env.findType(returnType.get);
        SmallArray!(DType) array;
        foreach (a; funcArgs)
            array ~= a.type();
        t.params = array.safe();
        t.firstParamIsReturnValue = this.sret;
        myType = t;
        return myType;
    }

    Identifier returnType, identifier;
    VarDecl[] funcArgs;
    Stmt[] statements;
    bool sret = false;
    bool emptyFunction = true;
    private DFunction myType;
}

class StructDecl : Decl
{
    this(Identifier identifier)
    {
        super(DeclType.StructDecl);
        this.identifier = identifier;
    }

    void addMember(Decl decl)
    {
        decls ~= decl;
    }

    void simplify()
    {
    }

    override void verify(VC vc)
    {
        foreach (decl; decls)
            decl.verify(vc);
    }

    override DType type()
    {
        return env.findType(identifier.get);
    }

    Identifier identifier;
    Decl[] decls;
    private DType myType;
}

class ClassDecl : Decl
{
    this(Identifier identifier)
    {
        super(DeclType.ClassDecl);
        this.identifier = identifier;
        
        auto name = new Identifier(identifier.loc, "__vptr");
        auto type = new IdentifierTypeExp(identifier.loc, "byte");
        auto p_type = new PointerTypeExp(type);
        decls ~= new VarDecl(p_type, name, null);
    }

    void addMember(Decl decl)
    {
        decls ~= decl;
    }

    void addBaseClass(Identifier identifier)
    {
        baseClasses ~= identifier;
    }

    void simplify()
    {
    }

    override DType type()
    {
        return env.findType(identifier.get);
    }

    Identifier identifier;
    Identifier[] baseClasses;
    Decl[] decls;
    private DType myType;
}

class InterfaceDecl : Decl
{
    this(Identifier identifier)
    {
        super(DeclType.InterfaceDecl);
        this.identifier = identifier;
    }

    void addMember(Decl decl)
    {
        decls ~= decl;
    }

    void addBaseClass(Identifier identifier)
    {
        baseClasses ~= identifier;
    }

    void simplify()
    {
    }

    override DType type()
    {
        return env.findType(identifier.get);
    }

    Identifier identifier;
    Identifier[] baseClasses;
    Decl[] decls;
    private DType myType;
}