/**
 * Authors: k.inaba
 * License: NYSL 0.9982 http://www.kmonos.net/nysl/
 *
 * Definition of constants related to the layers.
 */
module polemy.layer;
import polemy._common;

/// Type for the layer ID

alias string Layer;

enum : Layer
{
	LiftLayer     = "(lift)",     /// Predefined layer for storing lift functions
	NoopLayer     = "(noop)",     /// Predefined layer for just allocating a slot for table
	ValueLayer    = "@value",     /// Predefined layer for normal run
	MacroLayer    = "@macro",     /// Predefined layer for macro run (@lay() changes layer)
	RawMacroLayer = "(rawmacro)", /// Predefined layer for macro run (@lay() becomes AST)
}

/// True if it is a user-defined layer

bool isUserDefinedLayer( Layer lay )
{
	return lay!=NoopLayer && lay!=LiftLayer && lay!=ValueLayer && lay!=MacroLayer && lay!=RawMacroLayer;
}

unittest
{
	assert( !isUserDefinedLayer(NoopLayer) );
	assert( !isUserDefinedLayer(LiftLayer) );
	assert( !isUserDefinedLayer(ValueLayer) );
	assert( !isUserDefinedLayer(MacroLayer) );
	assert( !isUserDefinedLayer(RawMacroLayer) );
	assert( isUserDefinedLayer("@foo") );
}

/// True if it is macro-like layer that basically generates syntax tree

bool isASTLayer( Layer lay )
{
	return lay==MacroLayer || lay==RawMacroLayer;
}

unittest
{
	assert( !isASTLayer(NoopLayer) );
	assert( !isASTLayer(LiftLayer) );
	assert( !isASTLayer(ValueLayer) );
	assert( isASTLayer(MacroLayer) );
	assert( isASTLayer(RawMacroLayer) );
}

/// True if in the specified layer @lay(...) has no effect and merely produces a syntax tree

bool isNoLayerChangeLayer( Layer lay )
{
	return lay==RawMacroLayer;
}

unittest
{
	assert( !isNoLayerChangeLayer(NoopLayer) );
	assert( !isNoLayerChangeLayer(LiftLayer) );
	assert( !isNoLayerChangeLayer(ValueLayer) );
	assert( !isNoLayerChangeLayer(MacroLayer) );
	assert( isNoLayerChangeLayer(RawMacroLayer) );
}

/// True if do macro expanstion

bool isMacroLayer( Layer lay )
{
	return lay==MacroLayer || lay==RawMacroLayer;
}

unittest
{
	assert( !isMacroLayer(NoopLayer) );
	assert( !isMacroLayer(LiftLayer) );
	assert( !isMacroLayer(ValueLayer) );
	assert( isMacroLayer(MacroLayer) );
	assert( isMacroLayer(RawMacroLayer) );
}
