diff --git a/source2/Compiler/Cosmos.XSharp/Generator.cs b/source2/Compiler/Cosmos.XSharp/Generator.cs index 36d0223ef..1ca39b11e 100644 --- a/source2/Compiler/Cosmos.XSharp/Generator.cs +++ b/source2/Compiler/Cosmos.XSharp/Generator.cs @@ -60,8 +60,7 @@ namespace Cosmos.Compiler.XSharp { // Skip return; } - var xParser = new Parser(aLine, false); - var xCode = mPatterns.GetCode(xParser.Tokens); + var xCode = mPatterns.GetCode(aLine); foreach(var xLine in xCode) { mOutput.WriteLine("\t\t\t" + xLine); } diff --git a/source2/Compiler/Cosmos.XSharp/Parser.cs b/source2/Compiler/Cosmos.XSharp/Parser.cs index 88eb0e3e6..e3a7f7f4f 100644 --- a/source2/Compiler/Cosmos.XSharp/Parser.cs +++ b/source2/Compiler/Cosmos.XSharp/Parser.cs @@ -9,6 +9,7 @@ namespace Cosmos.Compiler.XSharp { protected string mData; protected bool mIncludeWhiteSpace; protected bool mAllWhitespace; + protected bool mAllowPatterns; protected TokenList mTokens; public TokenList Tokens { @@ -55,6 +56,7 @@ namespace Cosmos.Compiler.XSharp { string xString = null; char xChar1 = mData[mStart]; var xToken = new Token(); + if (mAllWhitespace && "#!".Contains(xChar1)) { rPos = mData.Length; // This will account for the dummy whitespace at the end. xString = mData.Substring(mStart + 1, rPos - mStart - 1).Trim(); @@ -68,6 +70,7 @@ namespace Cosmos.Compiler.XSharp { if (string.IsNullOrWhiteSpace(xString) && xString.Length > 0) { xToken.Type = TokenType.WhiteSpace; + } else if (char.IsLetter(xChar1)) { string xUpper = xString.ToUpper(); if (Registers.Contains(xUpper)) { @@ -77,34 +80,39 @@ namespace Cosmos.Compiler.XSharp { } else { xToken.Type = TokenType.AlphaNum; } + } else if (char.IsDigit(xChar1)) { xToken.Type = TokenType.ValueInt; - } else if (xString == "[") { - xToken.Type = TokenType.BracketLeft; - } else if (xString == "]") { - xToken.Type = TokenType.BracketRight; - } else if (xString == "{") { - xToken.Type = TokenType.CurlyLeft; - } else if (xString == "}") { - xToken.Type = TokenType.CurlyRight; - } else if (xString == "+") { - xToken.Type = TokenType.Plus; - } else if (xString == "-") { - xToken.Type = TokenType.Minus; - } else if (xString == "=") { - xToken.Type = TokenType.Assignment; - } else if (xString == ":") { - xToken.Type = TokenType.Colon; - } else if (xString == "$") { - xToken.Type = TokenType.Dollar; - } else if (xString == ".") { - xToken.Type = TokenType.Dot; - } else if (xString == ",") { - xToken.Type = TokenType.Comma; + } else { - xToken.Type = TokenType.Unknown; + #region Symbols + if (xString == "[") { + xToken.Type = TokenType.BracketLeft; + } else if (xString == "]") { + xToken.Type = TokenType.BracketRight; + } else if (xString == "{") { + xToken.Type = TokenType.CurlyLeft; + } else if (xString == "}") { + xToken.Type = TokenType.CurlyRight; + } else if (xString == "+") { + xToken.Type = TokenType.Plus; + } else if (xString == "-") { + xToken.Type = TokenType.Minus; + } else if (xString == "=") { + xToken.Type = TokenType.Assignment; + } else if (xString == ":") { + xToken.Type = TokenType.Colon; + } else if (xString == "$") { + xToken.Type = TokenType.Dollar; + } else if (xString == ".") { + xToken.Type = TokenType.Dot; + } else if (xString == ",") { + xToken.Type = TokenType.Comma; + } + #endregion } } + xToken.Value = xString; xToken.SrcPosStart = mStart; xToken.SrcPosEnd = rPos - 1; @@ -112,6 +120,7 @@ namespace Cosmos.Compiler.XSharp { mAllWhitespace = false; } mStart = rPos; + return xToken; } @@ -186,9 +195,10 @@ namespace Cosmos.Compiler.XSharp { return xResult; } - public Parser(string aData, bool aIncludeWhiteSpace) { + public Parser(string aData, bool aIncludeWhiteSpace, bool aAllowPatterns) { mData = aData; mIncludeWhiteSpace = aIncludeWhiteSpace; + mAllowPatterns = aAllowPatterns; mAllWhitespace = true; Parse(); diff --git a/source2/Compiler/Cosmos.XSharp/Token.cs b/source2/Compiler/Cosmos.XSharp/Token.cs index d7a21dfe5..a941dc2a0 100644 --- a/source2/Compiler/Cosmos.XSharp/Token.cs +++ b/source2/Compiler/Cosmos.XSharp/Token.cs @@ -20,7 +20,7 @@ namespace Cosmos.Compiler.XSharp { } public class Token { - public TokenType Type; + public TokenType Type = TokenType.Unknown; public string Value; public int SrcPosStart; public int SrcPosEnd; diff --git a/source2/Compiler/Cosmos.XSharp/TokenList.cs b/source2/Compiler/Cosmos.XSharp/TokenList.cs index b68b0afc9..171338641 100644 --- a/source2/Compiler/Cosmos.XSharp/TokenList.cs +++ b/source2/Compiler/Cosmos.XSharp/TokenList.cs @@ -25,22 +25,37 @@ namespace Cosmos.Compiler.XSharp { } public bool PatternMatches(string aPattern) { - var xParser = new Parser(aPattern, false); + var xParser = new Parser(aPattern, false, true); return PatternMatches(xParser.Tokens); } public bool PatternMatches(TokenList aObj) { // Dont compare TokenHashCodes, they take just as long to calculate - // as a full comparison. - if (Count == aObj.Count) { - for (int i = 0; i < aObj.Count; i++) { - if (this[i].Type != aObj[i].Type) { - return false; - } - } - return true; + // as a full comparison. Besides this function is often called after + // 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; } - return false; + + for (int i = 0; i < aObj.Count; i++) { + var xThis = this[i]; + if (xThis.Type != aObj[i].Type) { + 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; } // We could use values to further differntiate, however diff --git a/source2/Compiler/Cosmos.XSharp/TokenPatterns.cs b/source2/Compiler/Cosmos.XSharp/TokenPatterns.cs index a50598bcc..b0e42df05 100644 --- a/source2/Compiler/Cosmos.XSharp/TokenPatterns.cs +++ b/source2/Compiler/Cosmos.XSharp/TokenPatterns.cs @@ -31,7 +31,7 @@ namespace Cosmos.Compiler.XSharp { protected void AddKeywords() { AddKeyword("Call", delegate(TokenList aTokens, ref List rCode) { string xLabel = aTokens[1].Value; - if (aTokens.PatternMatches("Call ABC")) { + if (aTokens.PatternMatches("Call ABC123")) { rCode.Add("new Call {{ DestinationLabel = " + Quoted(mGroup + "_" + xLabel) + " }};"); } else { rCode = null; @@ -43,7 +43,7 @@ namespace Cosmos.Compiler.XSharp { }); AddKeyword("Group", delegate(TokenList aTokens, ref List rCode) { - if (aTokens.PatternMatches("Group ABC")) { + if (aTokens.PatternMatches("Group ABC123")) { mGroup = aTokens[1].Value; } else { rCode = null; @@ -52,7 +52,7 @@ namespace Cosmos.Compiler.XSharp { AddKeyword("InterruptHandler", delegate(TokenList aTokens, ref List rCode) { mInIntHandler = true; - if (aTokens.PatternMatches("InterruptHandler ABC {")) { + if (aTokens.PatternMatches("InterruptHandler ABC123 {")) { mProcedureName = aTokens[1].Value; rCode.Add("new Label(\"" + mGroup + "_{1}\");"); } else { @@ -61,7 +61,7 @@ namespace Cosmos.Compiler.XSharp { }); AddKeyword("Jump", delegate(TokenList aTokens, ref List rCode) { - if (aTokens.PatternMatches("Jump ABC")) { + if (aTokens.PatternMatches("Jump ABC123")) { rCode.Add("new Jump {{ DestinationLabel = \"" + mGroup + "_{1}\" }};"); } else { rCode = null; @@ -75,7 +75,7 @@ namespace Cosmos.Compiler.XSharp { AddKeyword("Procedure", delegate(TokenList aTokens, ref List rCode) { mInIntHandler = false; - if (aTokens.PatternMatches("Procedure ABC {")) { + if (aTokens.PatternMatches("Procedure ABC123 {")) { mProcedureName = aTokens[1].Value; rCode.Add("new Label(\"" + mGroup + "_{1}\");"); } else { @@ -109,7 +109,7 @@ namespace Cosmos.Compiler.XSharp { AddPattern("# Comment", "new Comment(\"{0}\");" ); - AddPattern("Label:" , + AddPattern("ABC123:" , "new Label(\"{0}\");" ); @@ -149,7 +149,7 @@ namespace Cosmos.Compiler.XSharp { + "}};" ); - AddPattern("Variable = REG", delegate(TokenList aTokens, ref List rCode) { + AddPattern("ABC123 = REG", delegate(TokenList aTokens, ref List rCode) { rCode.Add("new Mov {{" + " DestinationRef = Cosmos.Assembler.ElementReference.New(\"" + mGroup + "_{0}\"), DestinationIsIndirect = true" + " , SourceReg = RegistersEnum.{2}" @@ -183,20 +183,23 @@ namespace Cosmos.Compiler.XSharp { }); } - public List GetCode(TokenList aTokens) { + public List GetCode(string aLine) { + var xParser = new Parser(aLine, false, false); + var xTokens = xParser.Tokens; CodeFunc xAction = null; List xResult = new List(); - if (aTokens[0].Type == TokenType.Keyword) { - if (mKeywords.TryGetValue(aTokens[0].Value.ToUpper(), out xAction)) { - xAction(aTokens, ref xResult); + + if (xTokens[0].Type == TokenType.Keyword) { + if (mKeywords.TryGetValue(xTokens[0].Value.ToUpper(), out xAction)) { + xAction(xTokens, ref xResult); 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) { - int xHash = aTokens.GetPatternHashCode(); + int xHash = xTokens.GetPatternHashCode(); // Get a list of matching hashes, but then we have to // 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); Pattern xPattern = null; foreach (var x in xPatterns) { - if (x.Tokens.PatternMatches(aTokens)) { + if (x.Tokens.PatternMatches(xTokens)) { xPattern = x; break; } @@ -214,11 +217,11 @@ namespace Cosmos.Compiler.XSharp { 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++) { - 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; } @@ -289,7 +292,7 @@ namespace Cosmos.Compiler.XSharp { } 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 xPattern = new Pattern() { diff --git a/source2/VSIP/Cosmos.VS.XSharp/Scanner.cs b/source2/VSIP/Cosmos.VS.XSharp/Scanner.cs index 58a864f45..92cbac4ef 100644 --- a/source2/VSIP/Cosmos.VS.XSharp/Scanner.cs +++ b/source2/VSIP/Cosmos.VS.XSharp/Scanner.cs @@ -74,7 +74,7 @@ namespace Cosmos.VS.XSharp { void IScanner.SetSource(string aSource, int aOffset) { mTokenIdx = 0; - mParser = new XSC.Parser(aSource.Substring(aOffset), true); + mParser = new XSC.Parser(aSource.Substring(aOffset), true, false); } } }