// (C) 2008-2009 Dr. Gergo ERDI
using System.Collections.Generic;
using Alef.Runtime;
namespace Alef.Runtime
{
public class Node
{
internal NodePayload nodePayload;
public object objPayload
{
get
{
return nodePayload.objPayload;
}
}
public Node (object objPayload)
{
this.nodePayload = new NodePayload(objPayload);
}
public void Overwrite (Node node)
{
this.nodePayload = node.nodePayload;
}
public List children
{
get
{
return nodePayload.children;
}
}
public void Add (params Node[] children)
{
Add((IEnumerable)children);
}
public void Add (IEnumerable children)
{
foreach (Node child in children)
nodePayload.children.Add(child);
}
public void Print ()
{
PrintI(0, false);
}
public void PrintReduce ()
{
PrintI(0, true);
}
protected void PrintI (int depth, bool fReduce)
{
if (depth > 10 && false)
{
System.Console.WriteLine("{0}...", new string(' ', depth * 2));
return;
}
if (fReduce)
Alef.Runtime.FunctionBase.ReduceExprToCons(this);
System.Console.WriteLine("{0}{1}", new string(' ', depth * 2), this.objPayload.ToString());
foreach (Node child in this.children)
child.PrintI(depth + 1, fReduce);
}
}
public class NodePayload
{
internal object objPayload;
internal List children = new List ();
public NodePayload (object objPayload)
{
this.objPayload = objPayload;
}
}
public abstract class FunctionBase
{
internal abstract void Reduce (Node node);
internal class NoMatch: System.Exception
{
}
public static void ReduceExpr (Node node)
{
if (FConstructor (node))
return;
if (node.objPayload is Alef.LangID.Apply)
{
Node nodeFun = null;
foreach (Node nodeT in node.children)
{
if (nodeFun == null)
{
while (!FConstructor(nodeT) && !FFunction(nodeT))
ReduceExpr (nodeT);
nodeFun = new Node (nodeT.objPayload);
nodeFun.Add(nodeT.children);
}
else
{
nodeFun.Add(nodeT);
}
}
//Debug.Assert (nodeFun != null);
node.Overwrite (nodeFun);
}
else
{
FunctionTag ft = node.objPayload as FunctionTag;
ft.Reduce(node);
}
}
public static void ReduceExprToCons (Node node)
{
while (!FConstructor (node))
ReduceExpr (node);
}
private static bool FConstructor (Node node)
{
return node.objPayload is ConstructorBase || node.objPayload is decimal || node.objPayload is string;
}
private static bool FFunction (Node node)
{
return node.objPayload is FunctionTag;
}
}
public abstract class FunctionTag
{
internal abstract void Reduce (Node node);
}
public abstract class FunctionTag : FunctionTag where T: FunctionBase, new ()
{
internal override void Reduce (Node node)
{
new T().Reduce(node);
}
}
public abstract class ConstructorBase
{
}
public abstract class ConstructorTag: ConstructorBase
{
private readonly TKcons kcons;
protected ConstructorTag (TKcons kcons)
{
this.kcons = kcons;
}
public override bool Equals (object other)
{
ConstructorTag ctOther = other as ConstructorTag;
return ctOther != null && object.Equals(this.kcons, ctOther.kcons);
}
public override int GetHashCode ()
{
return this.kcons.GetHashCode();
}
public override string ToString ()
{
return kcons.ToString();
}
}
}
namespace Alef.LangID
{
class Apply
{
}
}