This commit is contained in:
kudzu_cp 2012-06-17 04:59:52 +00:00
parent 6ff6d0439c
commit 4574e334e0
6 changed files with 82 additions and 55 deletions

View file

@ -60,8 +60,7 @@ namespace Cosmos.Compiler.XSharp {
// Skip // Skip
return; return;
} }
var xParser = new Parser(aLine, false); var xCode = mPatterns.GetCode(aLine);
var xCode = mPatterns.GetCode(xParser.Tokens);
foreach(var xLine in xCode) { foreach(var xLine in xCode) {
mOutput.WriteLine("\t\t\t" + xLine); mOutput.WriteLine("\t\t\t" + xLine);
} }

View file

@ -9,6 +9,7 @@ namespace Cosmos.Compiler.XSharp {
protected string mData; protected string mData;
protected bool mIncludeWhiteSpace; protected bool mIncludeWhiteSpace;
protected bool mAllWhitespace; protected bool mAllWhitespace;
protected bool mAllowPatterns;
protected TokenList mTokens; protected TokenList mTokens;
public TokenList Tokens { public TokenList Tokens {
@ -55,6 +56,7 @@ namespace Cosmos.Compiler.XSharp {
string xString = null; string xString = null;
char xChar1 = mData[mStart]; char xChar1 = mData[mStart];
var xToken = new Token(); var xToken = new Token();
if (mAllWhitespace && "#!".Contains(xChar1)) { if (mAllWhitespace && "#!".Contains(xChar1)) {
rPos = mData.Length; // This will account for the dummy whitespace at the end. rPos = mData.Length; // This will account for the dummy whitespace at the end.
xString = mData.Substring(mStart + 1, rPos - mStart - 1).Trim(); xString = mData.Substring(mStart + 1, rPos - mStart - 1).Trim();
@ -68,6 +70,7 @@ namespace Cosmos.Compiler.XSharp {
if (string.IsNullOrWhiteSpace(xString) && xString.Length > 0) { if (string.IsNullOrWhiteSpace(xString) && xString.Length > 0) {
xToken.Type = TokenType.WhiteSpace; xToken.Type = TokenType.WhiteSpace;
} else if (char.IsLetter(xChar1)) { } else if (char.IsLetter(xChar1)) {
string xUpper = xString.ToUpper(); string xUpper = xString.ToUpper();
if (Registers.Contains(xUpper)) { if (Registers.Contains(xUpper)) {
@ -77,9 +80,13 @@ namespace Cosmos.Compiler.XSharp {
} else { } else {
xToken.Type = TokenType.AlphaNum; xToken.Type = TokenType.AlphaNum;
} }
} else if (char.IsDigit(xChar1)) { } else if (char.IsDigit(xChar1)) {
xToken.Type = TokenType.ValueInt; xToken.Type = TokenType.ValueInt;
} else if (xString == "[") {
} else {
#region Symbols
if (xString == "[") {
xToken.Type = TokenType.BracketLeft; xToken.Type = TokenType.BracketLeft;
} else if (xString == "]") { } else if (xString == "]") {
xToken.Type = TokenType.BracketRight; xToken.Type = TokenType.BracketRight;
@ -101,10 +108,11 @@ namespace Cosmos.Compiler.XSharp {
xToken.Type = TokenType.Dot; xToken.Type = TokenType.Dot;
} else if (xString == ",") { } else if (xString == ",") {
xToken.Type = TokenType.Comma; xToken.Type = TokenType.Comma;
} else { }
xToken.Type = TokenType.Unknown; #endregion
} }
} }
xToken.Value = xString; xToken.Value = xString;
xToken.SrcPosStart = mStart; xToken.SrcPosStart = mStart;
xToken.SrcPosEnd = rPos - 1; xToken.SrcPosEnd = rPos - 1;
@ -112,6 +120,7 @@ namespace Cosmos.Compiler.XSharp {
mAllWhitespace = false; mAllWhitespace = false;
} }
mStart = rPos; mStart = rPos;
return xToken; return xToken;
} }
@ -186,9 +195,10 @@ namespace Cosmos.Compiler.XSharp {
return xResult; return xResult;
} }
public Parser(string aData, bool aIncludeWhiteSpace) { public Parser(string aData, bool aIncludeWhiteSpace, bool aAllowPatterns) {
mData = aData; mData = aData;
mIncludeWhiteSpace = aIncludeWhiteSpace; mIncludeWhiteSpace = aIncludeWhiteSpace;
mAllowPatterns = aAllowPatterns;
mAllWhitespace = true; mAllWhitespace = true;
Parse(); Parse();

View file

@ -20,7 +20,7 @@ namespace Cosmos.Compiler.XSharp {
} }
public class Token { public class Token {
public TokenType Type; public TokenType Type = TokenType.Unknown;
public string Value; public string Value;
public int SrcPosStart; public int SrcPosStart;
public int SrcPosEnd; public int SrcPosEnd;

View file

@ -25,23 +25,38 @@ namespace Cosmos.Compiler.XSharp {
} }
public bool PatternMatches(string aPattern) { public bool PatternMatches(string aPattern) {
var xParser = new Parser(aPattern, false); var xParser = new Parser(aPattern, false, true);
return PatternMatches(xParser.Tokens); return PatternMatches(xParser.Tokens);
} }
public bool PatternMatches(TokenList aObj) { public bool PatternMatches(TokenList aObj) {
// Dont compare TokenHashCodes, they take just as long to calculate // Dont compare TokenHashCodes, they take just as long to calculate
// as a full comparison. // as a full comparison. Besides this function is often called after
if (Count == aObj.Count) { // comparing hash codes already.
//
// For mathching, we assume that only the "this" side can have wildcards or lists
// and that the aObj side will have only exacts. This might need to change
// in the future, but will complicate the code a bit. Especially if both sides
// could have wildcards (Doesn't even make sense at this point)
if (Count != aObj.Count) {
return false;
}
for (int i = 0; i < aObj.Count; i++) { for (int i = 0; i < aObj.Count; i++) {
if (this[i].Type != aObj[i].Type) { var xThis = this[i];
if (xThis.Type != aObj[i].Type) {
return false; return false;
} else if (xThis.Type == TokenType.AlphaNum || xThis.Type == TokenType.Keyword) {
if (xThis.Value != null && string.Compare(xThis.Value, aObj[i].Value, true) != 0) {
//return false;
}
} else if (xThis.Type == TokenType.Register) {
} }
} }
return true; return true;
} }
return false;
}
// We could use values to further differntiate, however // We could use values to further differntiate, however
// with types alone it still provides a decent and fash hash. // with types alone it still provides a decent and fash hash.

View file

@ -31,7 +31,7 @@ namespace Cosmos.Compiler.XSharp {
protected void AddKeywords() { protected void AddKeywords() {
AddKeyword("Call", delegate(TokenList aTokens, ref List<string> rCode) { AddKeyword("Call", delegate(TokenList aTokens, ref List<string> rCode) {
string xLabel = aTokens[1].Value; string xLabel = aTokens[1].Value;
if (aTokens.PatternMatches("Call ABC")) { if (aTokens.PatternMatches("Call ABC123")) {
rCode.Add("new Call {{ DestinationLabel = " + Quoted(mGroup + "_" + xLabel) + " }};"); rCode.Add("new Call {{ DestinationLabel = " + Quoted(mGroup + "_" + xLabel) + " }};");
} else { } else {
rCode = null; rCode = null;
@ -43,7 +43,7 @@ namespace Cosmos.Compiler.XSharp {
}); });
AddKeyword("Group", delegate(TokenList aTokens, ref List<string> rCode) { AddKeyword("Group", delegate(TokenList aTokens, ref List<string> rCode) {
if (aTokens.PatternMatches("Group ABC")) { if (aTokens.PatternMatches("Group ABC123")) {
mGroup = aTokens[1].Value; mGroup = aTokens[1].Value;
} else { } else {
rCode = null; rCode = null;
@ -52,7 +52,7 @@ namespace Cosmos.Compiler.XSharp {
AddKeyword("InterruptHandler", delegate(TokenList aTokens, ref List<string> rCode) { AddKeyword("InterruptHandler", delegate(TokenList aTokens, ref List<string> rCode) {
mInIntHandler = true; mInIntHandler = true;
if (aTokens.PatternMatches("InterruptHandler ABC {")) { if (aTokens.PatternMatches("InterruptHandler ABC123 {")) {
mProcedureName = aTokens[1].Value; mProcedureName = aTokens[1].Value;
rCode.Add("new Label(\"" + mGroup + "_{1}\");"); rCode.Add("new Label(\"" + mGroup + "_{1}\");");
} else { } else {
@ -61,7 +61,7 @@ namespace Cosmos.Compiler.XSharp {
}); });
AddKeyword("Jump", delegate(TokenList aTokens, ref List<string> rCode) { AddKeyword("Jump", delegate(TokenList aTokens, ref List<string> rCode) {
if (aTokens.PatternMatches("Jump ABC")) { if (aTokens.PatternMatches("Jump ABC123")) {
rCode.Add("new Jump {{ DestinationLabel = \"" + mGroup + "_{1}\" }};"); rCode.Add("new Jump {{ DestinationLabel = \"" + mGroup + "_{1}\" }};");
} else { } else {
rCode = null; rCode = null;
@ -75,7 +75,7 @@ namespace Cosmos.Compiler.XSharp {
AddKeyword("Procedure", delegate(TokenList aTokens, ref List<string> rCode) { AddKeyword("Procedure", delegate(TokenList aTokens, ref List<string> rCode) {
mInIntHandler = false; mInIntHandler = false;
if (aTokens.PatternMatches("Procedure ABC {")) { if (aTokens.PatternMatches("Procedure ABC123 {")) {
mProcedureName = aTokens[1].Value; mProcedureName = aTokens[1].Value;
rCode.Add("new Label(\"" + mGroup + "_{1}\");"); rCode.Add("new Label(\"" + mGroup + "_{1}\");");
} else { } else {
@ -109,7 +109,7 @@ namespace Cosmos.Compiler.XSharp {
AddPattern("# Comment", AddPattern("# Comment",
"new Comment(\"{0}\");" "new Comment(\"{0}\");"
); );
AddPattern("Label:" , AddPattern("ABC123:" ,
"new Label(\"{0}\");" "new Label(\"{0}\");"
); );
@ -149,7 +149,7 @@ namespace Cosmos.Compiler.XSharp {
+ "}};" + "}};"
); );
AddPattern("Variable = REG", delegate(TokenList aTokens, ref List<string> rCode) { AddPattern("ABC123 = REG", delegate(TokenList aTokens, ref List<string> rCode) {
rCode.Add("new Mov {{" rCode.Add("new Mov {{"
+ " DestinationRef = Cosmos.Assembler.ElementReference.New(\"" + mGroup + "_{0}\"), DestinationIsIndirect = true" + " DestinationRef = Cosmos.Assembler.ElementReference.New(\"" + mGroup + "_{0}\"), DestinationIsIndirect = true"
+ " , SourceReg = RegistersEnum.{2}" + " , SourceReg = RegistersEnum.{2}"
@ -183,20 +183,23 @@ namespace Cosmos.Compiler.XSharp {
}); });
} }
public List<string> GetCode(TokenList aTokens) { public List<string> GetCode(string aLine) {
var xParser = new Parser(aLine, false, false);
var xTokens = xParser.Tokens;
CodeFunc xAction = null; CodeFunc xAction = null;
List<string> xResult = new List<string>(); List<string> xResult = new List<string>();
if (aTokens[0].Type == TokenType.Keyword) {
if (mKeywords.TryGetValue(aTokens[0].Value.ToUpper(), out xAction)) { if (xTokens[0].Type == TokenType.Keyword) {
xAction(aTokens, ref xResult); if (mKeywords.TryGetValue(xTokens[0].Value.ToUpper(), out xAction)) {
xAction(xTokens, ref xResult);
if (xResult == null) { if (xResult == null) {
throw new Exception("Unrecognized syntax for keyword: " + aTokens[0].Value); throw new Exception("Unrecognized syntax for keyword: " + xTokens[0].Value);
} }
} }
} }
if (xAction == null) { if (xAction == null) {
int xHash = aTokens.GetPatternHashCode(); int xHash = xTokens.GetPatternHashCode();
// Get a list of matching hashes, but then we have to // Get a list of matching hashes, but then we have to
// search for exact pattern match because it is possible // search for exact pattern match because it is possible
@ -205,7 +208,7 @@ namespace Cosmos.Compiler.XSharp {
var xPatterns = mPatterns.Where(q => q.Hash == xHash); var xPatterns = mPatterns.Where(q => q.Hash == xHash);
Pattern xPattern = null; Pattern xPattern = null;
foreach (var x in xPatterns) { foreach (var x in xPatterns) {
if (x.Tokens.PatternMatches(aTokens)) { if (x.Tokens.PatternMatches(xTokens)) {
xPattern = x; xPattern = x;
break; break;
} }
@ -214,11 +217,11 @@ namespace Cosmos.Compiler.XSharp {
throw new Exception("Token pattern not found."); throw new Exception("Token pattern not found.");
} }
xPattern.Code(aTokens, ref xResult); xPattern.Code(xTokens, ref xResult);
} }
for(int i = 0; i < xResult.Count; i++) { for(int i = 0; i < xResult.Count; i++) {
xResult[i] = string.Format(xResult[i], aTokens.Select(c => c.Value).ToArray()); xResult[i] = string.Format(xResult[i], xTokens.Select(c => c.Value).ToArray());
} }
return xResult; return xResult;
} }
@ -289,7 +292,7 @@ namespace Cosmos.Compiler.XSharp {
} }
protected void AddPattern(string aPattern, CodeFunc aCode) { protected void AddPattern(string aPattern, CodeFunc aCode) {
var xParser = new Parser(aPattern, false); var xParser = new Parser(aPattern, false, true);
var xTokens = ParsePatterns(xParser.Tokens); var xTokens = ParsePatterns(xParser.Tokens);
var xPattern = new Pattern() { var xPattern = new Pattern() {

View file

@ -74,7 +74,7 @@ namespace Cosmos.VS.XSharp {
void IScanner.SetSource(string aSource, int aOffset) { void IScanner.SetSource(string aSource, int aOffset) {
mTokenIdx = 0; mTokenIdx = 0;
mParser = new XSC.Parser(aSource.Substring(aOffset), true); mParser = new XSC.Parser(aSource.Substring(aOffset), true, false);
} }
} }
} }