// (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 { } }