Cosmos/source2/Compiler/Cosmos.XSharp/TokenPattern.cs
kudzu_cp 2b7279bce9 X#
2012-06-13 14:04:49 +00:00

96 lines
2.8 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace Cosmos.Compiler.XSharp {
public class TokenPattern {
protected TokenType[] mTokenTypes;
// Since we make our contents immutable, we can cache the hash code
protected int mHashCode;
public TokenPattern(string aTokenPattern) {
var xRegex = new Regex(@"(\W)");
var xParts = xRegex.Split(aTokenPattern);
var xTokenTypes = new List<TokenType>();
foreach (string xPart in xParts) {
if (string.IsNullOrWhiteSpace(xPart)) {
continue;
}
TokenType xTokenType;
if (string.Compare(xPart, "REG") == 0) {
xTokenType = TokenType.Register;
} else if (string.Compare(xPart, "ABC") == 0) {
xTokenType = TokenType.AlphaNum;
} else if (char.IsDigit(xPart[0])) {
xTokenType = TokenType.ValueNumberInt;
} else if (xPart == "=") {
xTokenType = TokenType.Assignment;
} else if (xPart == "[") {
xTokenType = TokenType.BracketLeft;
} else if (xPart == "]") {
xTokenType = TokenType.BracketRight;
} else if (xPart == "+") {
xTokenType = TokenType.Plus;
} else if (xPart == "-") {
xTokenType = TokenType.Minus;
} else {
throw new Exception("Unrecognized string token: " + xPart);
}
xTokenTypes.Add(xTokenType);
}
mTokenTypes = xTokenTypes.ToArray();
Init();
}
public TokenPattern(TokenType[] aTokenTypes) {
// We dont copy the array, so technically it is mutable but in our usage
// constant arrays are passed in.
mTokenTypes = aTokenTypes;
Init();
}
protected void Init() {
mHashCode = CalcHashCode();
}
public override bool Equals(object aObj) {
if (aObj is TokenPattern) {
var xObj = (TokenPattern)aObj;
if (mTokenTypes.Length == xObj.mTokenTypes.Length) {
for (int i = 0; i < xObj.mTokenTypes.Length; i++) {
if (mTokenTypes[i] != xObj.mTokenTypes[i]) {
return false;
}
}
return true;
}
}
return false;
}
public override int GetHashCode() {
return mHashCode;
}
protected int CalcHashCode() {
int xResult = 0;
var xBytes = new byte[4];
for (int i = 0; i < mTokenTypes.Length; i = i + 4) {
for (int j = 0; j < 4; j++) {
if (j < mTokenTypes.Length) {
xBytes[j] = (byte)mTokenTypes[i];
} else {
xBytes[j] = 0;
}
}
xResult = xResult ^ BitConverter.ToInt32(xBytes, 0);
}
return xResult;
}
}
}