view dmd/ScopeStatement.d @ 63:cab4c37afb89

A bunch of implementations
author korDen
date Mon, 23 Aug 2010 16:52:24 +0400
parents 10317f0c89a5
children 2e2a5c3f943a
line wrap: on
line source

module dmd.ScopeStatement;

import dmd.Statement;
import dmd.Loc;
import dmd.Scope;
import dmd.OutBuffer;
import dmd.HdrGenState;
import dmd.Expression;
import dmd.InterState;
import dmd.InlineScanState;
import dmd.ScopeDsymbol;
import dmd.ArrayTypes;
import dmd.CompoundStatement;
import dmd.IRState;
import dmd.BE;

import dmd.backend.Blockx;
import dmd.backend.BC;
import dmd.backend.Util;

class ScopeStatement : Statement
{
    Statement statement;

    this(Loc loc, Statement s)
	{
		super(loc);
		this.statement = s;
	}
	
    Statement syntaxCopy()
	{
		Statement s = statement ? statement.syntaxCopy() : null;
		s = new ScopeStatement(loc, s);
		return s;
	}
	
    void toCBuffer(OutBuffer buf, HdrGenState* hgs)
	{
		buf.writeByte('{');
		buf.writenl();

		if (statement)
			statement.toCBuffer(buf, hgs);

		buf.writeByte('}');
		buf.writenl();
	}
	
    ScopeStatement isScopeStatement() { return this; }
	
    Statement semantic(Scope sc)
	{
		ScopeDsymbol sym;

		//printf("ScopeStatement.semantic(sc = %p)\n", sc);
		if (statement)
		{	
			Statements a;

			sym = new ScopeDsymbol();
			sym.parent = sc.scopesym;
			sc = sc.push(sym);

			a = statement.flatten(sc);
			if (a)
			{
				statement = new CompoundStatement(loc, a);
			}

			statement = statement.semantic(sc);
			if (statement)
			{
				Statement sentry;
				Statement sexception;
				Statement sfinally;

				statement.scopeCode(sc, &sentry, &sexception, &sfinally);
				if (sfinally)
				{
					//printf("adding sfinally\n");
					statement = new CompoundStatement(loc, statement, sfinally);
				}
			}

			sc.pop();
		}
		return this;
	}
	
    bool hasBreak()
	{
		//printf("ScopeStatement.hasBreak() %s\n", toChars());
		return statement ? statement.hasBreak() : false;
	}
	
    bool hasContinue()
	{
		return statement ? statement.hasContinue() : false;
	}
	
    bool usesEH()
	{
		return statement ? statement.usesEH() : false;
	}
	
    BE blockExit()
	{
		//printf("ScopeStatement::blockExit(%p)\n", statement);
		return statement ? statement.blockExit() : BE.BEfallthru;
	}
	
    bool comeFrom()
	{
		//printf("ScopeStatement.comeFrom()\n");
    return statement ? statement.comeFrom() : false;
	}
	
    bool isEmpty()
	{
		//printf("ScopeStatement::isEmpty() %d\n", statement ? statement->isEmpty() : TRUE);
		return statement ? statement.isEmpty() : true;
	}
	
    Expression interpret(InterState istate)
	{
		assert(false);
	}

    Statement inlineScan(InlineScanState* iss)
	{
		if (statement)
			statement = statement.inlineScan(iss);
		return this;
	}

    void toIR(IRState* irs)
	{
		if (statement)
		{
			Blockx* blx = irs.blx;
			IRState mystate = IRState(irs,this);

			if (mystate.prev.ident)
				mystate.ident = mystate.prev.ident;

			statement.toIR(&mystate);

			if (mystate.breakBlock)
				block_goto(blx, BC.BCgoto, mystate.breakBlock);
		}
	}
}