mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-27 14:02:19 +00:00
X#
This commit is contained in:
parent
6ff6d0439c
commit
4574e334e0
6 changed files with 82 additions and 55 deletions
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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() {
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue