view ast/Decl.d @ 92:771ac63898e2 new_gen

A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
author Anders Johnsen <skabet@gmail.com>
date Mon, 05 May 2008 18:44:20 +0200
parents 29f486ccc203
children 621cedba53ea
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;

enum DeclType
{
    VarDecl,
    FuncDecl,
    StructDecl,
}

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

    void simplify()
    {
    }

    DType type() { return null; }

    DeclType declType;
    Scope env;
}

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 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).type = 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).type = 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;
        this.vars = vars;
    }

    void addMember(Identifier type, Identifier name, Exp exp)
    {
        vars ~= new VarDecl(type, name, exp);
    }

    void simplify()
    {
    }

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

    Identifier identifier;
    VarDecl[] vars;
    private DType myType;
}