using System; using System.Collections; using System.Collections.Generic; namespace arookas { public class sunSourceLocation { public string File { get; private set; } public int Line { get; private set; } public int Column { get; private set; } public sunSourceLocation(string file, int line, int column) { File = file; Line = line; Column = column; } public override string ToString() { return String.Format("\"{0}\", ({1},{2})", File, Line, Column); } } class sunNode : IEnumerable { List children; public sunNode Parent { get; private set; } public sunSourceLocation Location { get; private set; } public int Count { get { return children.Count; } } public sunNode this[int index] { get { return index >= 0 && index < Count ? children[index] : null; } } public bool IsRoot { get { return Parent == null; } } public bool IsBranch { get { return Count > 0; } } public bool IsLeaf { get { return Count < 1; } } public sunNode(sunSourceLocation location) { children = new List(5); Location = location; } public void Add(sunNode node) { if (node == null) { throw new ArgumentNullException("node"); } if (node.Parent != null) { node.Parent.Remove(node); } node.Parent = this; children.Add(node); } public void Remove(sunNode node) { if (node == null) { throw new ArgumentNullException("node"); } if (node.Parent == this) { children.Remove(node); node.Parent = null; } } public void Clear() { foreach (var child in this) { child.Parent = null; } children.Clear(); } public virtual void Compile(sunContext context) { // Simply compile all children nodes by default. This is here for the transcient nodes' implementations // (sunStatement, sunCompoundStatement, etc.) so I only have to type this once. sunExpression is careful // to override this with the custom shunting-yard algorithm implementation. foreach (var child in this) { child.Compile(context); } } protected bool TryCompile(sunNode node, sunContext context) { if (node != null) { node.Compile(context); return true; } return false; } public IEnumerator GetEnumerator() { return children.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } abstract class sunToken : sunNode { public TValue Value { get; private set; } protected sunToken(sunSourceLocation location, string token) : base(location) { Value = ParseValue(token); } protected abstract TValue ParseValue(string token); } abstract class sunRawToken : sunToken { protected sunRawToken(sunSourceLocation location, string token) : base(location, token) { } protected override string ParseValue(string token) { return token; } } }