mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-21 05:18:38 +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
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ namespace Cosmos.Compiler.XSharp {
|
|||
protected void AddKeywords() {
|
||||
AddKeyword("Call", delegate(TokenList aTokens, ref List<string> 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<string> 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<string> 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<string> 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<string> 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<string> rCode) {
|
||||
AddPattern("ABC123 = REG", delegate(TokenList aTokens, ref List<string> 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<string> GetCode(TokenList aTokens) {
|
||||
public List<string> GetCode(string aLine) {
|
||||
var xParser = new Parser(aLine, false, false);
|
||||
var xTokens = xParser.Tokens;
|
||||
CodeFunc xAction = null;
|
||||
List<string> xResult = new List<string>();
|
||||
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() {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue