|
/// Public domain code by Christopher Diggins
/// http://www.cat-language.com
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
namespace Cat
{
/// <summary>
/// This class behaves somewhat like an IEnumerator interface. The difference
/// is that it is created in an initialized state, and has a slightly different
/// interfaces. A common idiom for using a TypeIterator is as follows:
///
/// for (TypeIterator iter = new TypeIterator(myTypeStack);
/// !iter.AtEnd();
/// iter.GotoNext)
/// { ... }
///
/// </summary>
public class TypeIterator
{
#region fields
private IEnumerator<CatType> m = null;
private bool mbEnd = true;
private int mnIndex = 0;
private TypeStack mpStack = null;
#endregion
#region constructor
public TypeIterator(TypeStack stk)
{
mpStack = stk;
m = mpStack.GetEnumerator();
Reset();
}
#endregion
#region public functions
public CatType GetValue()
{
if (AtEnd()) return null;
if (m.Current == null) throw new Exception("TypeStack contains null type");
return m.Current;
}
public bool AtEnd()
{
return mbEnd;
}
public void GotoNext()
{
if (AtEnd()) return;
mnIndex++;
mbEnd = !m.MoveNext();
}
public void Reset()
{
m.Reset();
mnIndex = 0;
mbEnd = !m.MoveNext();
}
public TypeStack GetStack()
{
return mpStack;
}
public int GetIndex()
{
return mnIndex;
}
public void InsertBefore(CatType t)
{
mpStack.InsertAt(mnIndex, t);
}
#endregion
#region overrides
/// <summary>
/// This is only intended for use during debugging.
/// </summary>
public override string ToString()
{
return mnIndex.ToString() + ":" + mpStack.ToString();
}
#endregion
}
/// <summary>
/// A type stack is a valid CatType, for the purposes of the code base. Users
/// can't declarae TypeStacks. A type variable which maps to multiple types
/// is implemented using a TypeStack. TypeStacks are also used in the implementation
/// of FxnType objects to represent the primary and auxiliary consumption and
/// production of a function.
/// </summary>
public class TypeStack : CatType, IEnumerable<CatType>
{
#region fields
private List<CatType> list = new List<CatType>();
#endregion
#region constructor
public TypeStack()
{
}
public TypeStack(AstNode pNode)
{
if ((pNode == null) || (pNode.node_type != NodeType.StackState))
Parser.Error(pNode, "Expected paranthesized type expression");
foreach (AstNode pChild in pNode.children)
Push(CatType.MakeCatType(pChild));
}
#endregion
#region public functions
public IEnumerator<CatType> GetEnumerator()
{
return list.GetEnumerator();
}
public TypeIterator GetTypeIterator()
{
return new TypeIterator(this);
}
public bool IsEmpty()
{
return Count == 0;
}
public void Push(CatType t)
{
if (t == null)
throw new Exception("Attempting to push null onto stack");
if (t is TypeStack)
{
TypeStack ts = t as TypeStack;
for (int i=0; i < ts.Count; ++i)
Push(ts[ts.Count - 1 - i]);
}
else
{
list.Insert(0, t);
}
}
public void PushFront(CatType t)
{
if (t == null)
throw new Exception("attempting to push null onto stack");
if (t is TypeStack)
{
TypeStack ts = t as TypeStack;
for (int i=0; i < ts.Count; ++i)
Push(ts[i]);
}
else
{
list.Add(t);
}
}
public CatType Peek()
{
if (IsEmpty())
throw new Exception("attempting to peek from an empty stack");
CatType t = this[0];
if (t == null)
throw new Exception("top of stack contains null");
return t;
}
public CatType Pop()
{
if (IsEmpty())
throw new Exception("attempting to pop from an empty stack");
CatType result = Peek();
list.RemoveAt(0);
return result;
}
public CatType PopFront()
{
if (Count < 1)
throw new Exception("can not pop from an empty stack");
int n = Count - 1;
CatType ret = list[n];
list.RemoveAt(n);
return ret;
}
/// <summary>
/// This function places the type at position n, and if the type is
/// a TypeStack, it places all of the contents of the TypeStack in
/// the type.
/// </summary>
public void ReplaceAndExpand(int n, CatType t)
{
if (t is TypeStack)
{
TypeStack stk = t as TypeStack;
list.RemoveAt(n);
for (int i = stk.Count - 1; i >= 0; --i)
{
list.Insert(n, stk[i]);
}
}
else
{
list[n] = t;
}
}
public void ReplaceAt(int n, CatType t)
{
list[n] = t;
}
public void InsertAt(int nIndex, CatType t)
{
list.Insert(nIndex, t);
}
#endregion
#region overrides
public override CatType Clone()
{
TypeStack ret = new TypeStack();
foreach (CatType t in this)
ret.PushFront(t.Clone());
return ret;
}
public override bool IsTypeEq(CatType t)
{
if (t == this) return true;
if (!(t is TypeStack)) return false;
TypeStack that = t as TypeStack;
if (that.Count != Count) return false;
for (int i = 0; i < that.Count; ++i)
if (!this[i].IsTypeEq(that[i]))
return false;
return true;
}
public override string ToString()
{
string s = "( ";
for (int i=Count - 1; i >= 0; --i)
{
CatType t = this[i];
s += t.ToString() + " ";
}
s += ")";
return s;
}
#endregion
public CatType this[int index]
{
get
{
return list[index];
}
set
{
list[index] = value;
}
}
public int Count
{
get { return list.Count; }
}
public void Clear()
{
list.Clear();
}
#region IEnumerable<CatType> Members
IEnumerator<CatType> IEnumerable<CatType>.GetEnumerator()
{
return list.GetEnumerator();
}
#endregion
#region IEnumerable Members
IEnumerator IEnumerable.GetEnumerator()
{
return list.GetEnumerator();
}
#endregion
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.