127 lines
2.8 KiB
C#
127 lines
2.8 KiB
C#
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<sunNode>
|
|
{
|
|
List<sunNode> 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<sunNode>(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<sunNode> GetEnumerator() { return children.GetEnumerator(); }
|
|
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
|
|
}
|
|
|
|
abstract class sunToken<TValue> : 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<string>
|
|
{
|
|
protected sunRawToken(sunSourceLocation location, string token)
|
|
: base(location, token)
|
|
{
|
|
|
|
}
|
|
|
|
protected override string ParseValue(string token) { return token; }
|
|
}
|
|
}
|