/**
 * Authors: k.inaba
 * License: NYSL 0.9982 http://www.kmonos.net/nysl/
 *
 * Syntax tree for Polemy programming language.
 */
module polemy.ast;
import polemy._common;
import polemy.failure;
import polemy.layer;

///
abstract class AST
{
	LexPosition pos;

	mixin SimpleConstructor;
}

///
class Int : AST
{
	BigInt data;

	mixin SimpleClass;
	this(LexPosition pos, int n) {super(pos); data = n;}
	this(LexPosition pos, long n) {super(pos); data = n;}
	this(LexPosition pos, BigInt n) {super(pos); data = n;}
	this(LexPosition pos, string n) {super(pos); data = BigInt(n);}
}

///
class Str : AST
{
	string data;

	mixin SimpleClass;
}

///
class Var : AST
{
	string name;

	mixin SimpleClass;
}

///
class Lay : AST
{
	Layer layer;
	AST   expr;

	mixin SimpleClass;
}

///
class Let : AST
{
	string name;
	Layer  layer;
	AST    init;
	AST    expr;

	mixin SimpleClass;
}

///
class App : AST
{
	AST   fun;
	AST[] args;

	mixin SimpleClass;
	this(LexPosition pos, AST fun, AST[] args...) { super(pos); this.fun=fun; this.args=args.dup; }
}

///
class Parameter
{
	string  name;
	Layer[] layers;

	mixin SimpleClass;
}

///
class Fun : AST
{
	Parameter[] params;
	AST         funbody;

	mixin SimpleClass;
}

/// Handy Generator for AST nodes. To use this, mixin EasyAst;

/*mixin*/
template EasyAST()
{
	///
	template genEast(T)
		{ T genEast(P...)(P ps) { return new T(LexPosition.dummy, ps); } }

	alias genEast!Str strl; ///
	alias genEast!Int intl; ///
	auto fun(string[] xs, AST ps) {
		return genEast!Fun(array(map!((string x){return new Parameter(x,[]);})(xs)),ps); }
	auto funp(Parameter[] xs, AST ps) { return genEast!Fun(xs,ps); } ///
	alias genEast!Var var; ///
	alias genEast!Lay lay; ///
	alias genEast!Let let; ///
	alias genEast!App call; ///
	auto param(string name, string[] lay...) { return new Parameter(name, lay); } ///
}
