view ast/Decl.d @ 126:c3b24e7e8cf8

Carius changes to the parser. Parsing attributes, lexing many keywords(not all yet).
author Anders Johnsen <skabet@gmail.com>
date Tue, 27 May 2008 10:32:31 +0200
parents 189c049cbfcc
children ed815b31479b
line wrap: on
line source

module ast.Decl;

import ast.Exp,
       ast.Stmt;

import lexer.Token;

import tango.io.Stdout;

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

enum DeclType
{
    VarDecl,
    ImportDecl,
    FuncDecl,
    StructDecl,
}

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

    void simplify()
    {
    }

    DType type() { return null; }

    DeclType declType;
    Scope env;
    Attribute att;
}

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

    void simplify()
    {
    }

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

    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(Identifier type, Identifier identifier)
    {
        super(DeclType.FuncDecl);
        this.returnType = type;
        this.identifier = identifier;
    }

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

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

    void simplify()
    {
        if(auto t = cast(DFunction)env.find(identifier).type)
        {
            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 DFunction type()
    {
        if (myType !is null)
            return myType;

        auto t = new DFunction(identifier);
        t.returnType = env.findType(returnType);
        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 DType type()
    {
        return env.findType(identifier);
    }

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