module volta.ir.statement

Code Map

module volta.ir.statement;


//! Base class for all statements.
class Statement : Node
{
public:
	this(nt: NodeType) { }
	this(nt: NodeType, old: Statement) { }
}

//! A block statement is a group of zero or more statements. Why these
//! exist depends on where they live.
class BlockStatement : Statement
{
public:
	statements: Node[];
	myScope: Scope;


public:
	this() { }
	this(old: BlockStatement) { }
}

//! The return statement returns execution to the caller of the current
//! function, and optionally returns a value.
class ReturnStatement : Statement
{
public:
	exp: Exp;


public:
	this() { }
	this(old: ReturnStatement) { }
}

//! The asm statement contains inline assembly. It's a list of tokens so
//! different backends can parse it however they want. It all still has to
//! lex as valid Volt, of course.
class AsmStatement : Statement
{
public:
	tokens: Token[];


public:
	this() { }
	this(old: AsmStatement) { }
}

//! The assert statement aborts if condition is flase, optionally
//! displaying message. isStatic determines whether condition is checked at
//! compile time or not.
class AssertStatement : Statement
{
public:
	condition: Exp;
	message: Exp;
	isStatic: bool;


public:
	this() { }
	this(old: AssertStatement) { }
}

//! If exp is true, execution flows to thenState. If exp is false,
//! execution flows to elseState, if it exists, otherwise it skips to the
//! end of the if statement.
class IfStatement : Statement
{
public:
	exp: Exp;
	thenState: BlockStatement;
	elseState: BlockStatement;
	autoName: string;


public:
	this() { }
	this(old: IfStatement) { }
}

//! The while statement keeps executing the statements in block, as long as
//! condition evaluates in true.
class WhileStatement : Statement
{
public:
	condition: Exp;
	block: BlockStatement;


public:
	this() { }
	this(old: WhileStatement) { }
}

//! Like a while statement, executes block while condition is true. Unlike
//! the while statement, at least one execution of block is guaranteed.
class DoStatement : Statement
{
public:
	block: BlockStatement;
	condition: Exp;


public:
	this() { }
	this(old: DoStatement) { }
}

//! The for statement is a while statement that evaluates init first
//! (optionally introducing Variables into the for's scope), and running
//! increment at the end of each block's execution. Other than that, it
//! keeps executing block while test evaluates to true.
class ForStatement : Statement
{
public:
	initVars: Variable[];
	initExps: Exp[];
	test: Exp;
	increments: Exp[];
	block: BlockStatement;


public:
	this() { }
	this(old: ForStatement) { }
}

//! The foreach statement loops over elements in an aggregate. Arrays and
//! AAs have builtin support, but users can define iteration solutions for
//! their own types too.
class ForeachStatement : Statement
{
public:
	reverse: bool;
	itervars: Variable[];
	refvars: bool[];
	aggregate: Exp;
	beginIntegerRange: Exp;
	endIntegerRange: Exp;
	block: BlockStatement;
	opApplyType: Named;
	decodeFunction: Function;


public:
	this() { }
	this(old: ForeachStatement) { }
}

//! A label statement associates a string with a position in the statement
//! stream. Goto can then be used to jump to that position and anger
//! Dijkstra.
class LabelStatement : Statement
{
public:
	label: string;
	childStatement: Node[];


public:
	this() { }
	this(old: LabelStatement) { }
}

//! An ExpStatement wraps an Expression in a Statement.
class ExpStatement : Statement
{
public:
	exp: Exp;


public:
	this() { }
	this(old: ExpStatement) { }
}

//! Represents a case in a switch statement.
class SwitchCase : Node
{
public:
	firstExp: Exp;
	originalFirstExp: Exp;
	secondExp: Exp;
	originalSecondExp: Exp;
	exps: Exp[];
	originalExps: Exp[];
	isDefault: bool;
	statements: BlockStatement;


public:
	this() { }
	this(old: SwitchCase) { }
}

//! A switch statement jumps to various case labels depending on the value
//! of its condition.
class SwitchStatement : Statement
{
public:
	isFinal: bool;
	condition: Exp;
	cases: SwitchCase[];
	withs: Exp[];
	condVar: Variable;


public:
	this() { }
	this(old: SwitchStatement) { }
}

//! The continue statement restarts a loop (while, dowhile, for, foreach).
class ContinueStatement : Statement
{
public:
	label: string;


public:
	this() { }
	this(old: ContinueStatement) { }
}

//! The break statement halts execution of a loop or a switch statement.
class BreakStatement : Statement
{
public:
	label: string;


public:
	this() { }
	this(old: BreakStatement) { }
}

//! The goto statement jumps to a label, or controls flow inside a switch
//! statement.
class GotoStatement : Statement
{
public:
	label: string;
	isDefault: bool;
	isCase: bool;
	exp: Exp;


public:
	this() { }
	this(old: GotoStatement) { }
}

//! All lookups inside of a WithStatement first check exp before performing
//! a regular lookup. Ambiguities are still errors.
class WithStatement : Statement
{
public:
	exp: Exp;
	block: BlockStatement;


public:
	this() { }
	this(old: WithStatement) { }
}

//! A synchronized statement ensures that only one thread of execution can
//! enter its block. An explicit mutex may be provided.
class SynchronizedStatement : Statement
{
public:
	exp: Exp;
	block: BlockStatement;


public:
	this() { }
	this(old: SynchronizedStatement) { }
}

//! The try statement allows the resolution of throw statements, by
//! rerouting thrown exceptions into various catch blocks.
class TryStatement : Statement
{
public:
	tryBlock: BlockStatement;
	catchVars: Variable[];
	catchBlocks: BlockStatement[];
	finallyBlock: BlockStatement;


public:
	this() { }
	this(old: TryStatement) { }
}

//! A throw statements halts the current functions execution and unwinds
//! the stack until it hits a try statement with an appropriate catch
//! statement or, failing that, it halts execution of the entire program.
class ThrowStatement : Statement
{
public:
	exp: Exp;


public:
	this() { }
	this(old: ThrowStatement) { }
}

//! ScopeStatements are executed on various conditions. Exits are always
//! executed when the given scope is left. Successes are executed when the
//! scope is left normally. Failures are executed when the scope is left by
//! way of an Exception.
class ScopeStatement : Statement
{
public:
	kind: ScopeKind;
	block: BlockStatement;


public:
	this() { }
	this(old: ScopeStatement) { }
}

//! Pragma statements do magical things. pragma(lib, "SDL"), for instance,
//! tells the compiler to link with SDL without the user having to specify
//! it on the command line. What pragmas are supported vary from compiler
//! to compiler, the only thing specified is that complying implementations
//! must die on unknown pragmas by default.
class PragmaStatement : Statement
{
public:
	type: string;
	arguments: Exp[];
	block: BlockStatement;


public:
	this() { }
	this(old: PragmaStatement) { }
}

//! A ConditionStatement provides for conditional compilation of
//! statements. If condition is true, then it is as if block was where the
//! ConditionStatement was. Otherwise, the _else block replaces it (if
//! present).
class ConditionStatement : Statement
{
public:
	condition: Condition;
	block: BlockStatement;
	_else: BlockStatement;


public:
	this() { }
	this(old: ConditionStatement) { }
}

//! The mixin statement mixes in a mixin function, mixin template or a
//! string.
class MixinStatement : Statement
{
public:
	//! Not optional for mixin("string").
	stringExp: Exp;
	//! Not optional for mixin .my.Ident!(...)
	id: QualifiedName;
	resolved: BlockStatement;


public:
	this() { }
	this(old: MixinStatement) { }
}
class Statement : Node

Base class for all statements.

class BlockStatement : Statement

A block statement is a group of zero or more statements. Why these exist depends on where they live.

class ReturnStatement : Statement

The return statement returns execution to the caller of the current function, and optionally returns a value.

class AsmStatement : Statement

The asm statement contains inline assembly. It's a list of tokens so different backends can parse it however they want. It all still has to lex as valid Volt, of course.

class AssertStatement : Statement

The assert statement aborts if condition is flase, optionally displaying message. isStatic determines whether condition is checked at compile time or not.

class IfStatement : Statement

If exp is true, execution flows to thenState. If exp is false, execution flows to elseState, if it exists, otherwise it skips to the end of the if statement.

class WhileStatement : Statement

The while statement keeps executing the statements in block, as long as condition evaluates in true.

class DoStatement : Statement

Like a while statement, executes block while condition is true. Unlike the while statement, at least one execution of block is guaranteed.

class ForStatement : Statement

The for statement is a while statement that evaluates init first (optionally introducing Variables into the for's scope), and running increment at the end of each block's execution. Other than that, it keeps executing block while test evaluates to true.

for (init; test; increment) block

class ForeachStatement : Statement

The foreach statement loops over elements in an aggregate. Arrays and AAs have builtin support, but users can define iteration solutions for their own types too.

class LabelStatement : Statement

A label statement associates a string with a position in the statement stream. Goto can then be used to jump to that position and anger Dijkstra.

class ExpStatement : Statement

An ExpStatement wraps an Expression in a Statement.

class SwitchCase : Node

Represents a case in a switch statement.

If firstExp !is null and secondExp is null: case firstExp: If firstExp !is null and secondExp !is null: case firstExp: .. case secondExp: If exps.length > 0: case exps[0], exps[1], ... exps[$-1]: If isDefault: default:

The above are all mutually exclusive.

class SwitchStatement : Statement

A switch statement jumps to various case labels depending on the value of its condition.

Fallthrough is only permitted on empty cases, unlike C and C++.

class ContinueStatement : Statement

The continue statement restarts a loop (while, dowhile, for, foreach).

class BreakStatement : Statement

The break statement halts execution of a loop or a switch statement.

class GotoStatement : Statement

The goto statement jumps to a label, or controls flow inside a switch statement.

class WithStatement : Statement

All lookups inside of a WithStatement first check exp before performing a regular lookup. Ambiguities are still errors.

class SynchronizedStatement : Statement

A synchronized statement ensures that only one thread of execution can enter its block. An explicit mutex may be provided.

class TryStatement : Statement

The try statement allows the resolution of throw statements, by rerouting thrown exceptions into various catch blocks.

class ThrowStatement : Statement

A throw statements halts the current functions execution and unwinds the stack until it hits a try statement with an appropriate catch statement or, failing that, it halts execution of the entire program.

class ScopeStatement : Statement

ScopeStatements are executed on various conditions. Exits are always executed when the given scope is left. Successes are executed when the scope is left normally. Failures are executed when the scope is left by way of an Exception.

class PragmaStatement : Statement

Pragma statements do magical things. pragma(lib, "SDL"), for instance, tells the compiler to link with SDL without the user having to specify it on the command line. What pragmas are supported vary from compiler to compiler, the only thing specified is that complying implementations must die on unknown pragmas by default.

class ConditionStatement : Statement

A ConditionStatement provides for conditional compilation of statements. If condition is true, then it is as if block was where the ConditionStatement was. Otherwise, the _else block replaces it (if present).

class MixinStatement : Statement

The mixin statement mixes in a mixin function, mixin template or a string.

stringExp: Exp

Not optional for mixin("string").

id: QualifiedName

Not optional for mixin .my.Ident!(...)