Cosmos/source2/Compiler/Cosmos.XSharp/Generator.cs
kudzu_cp 3ac190b748
2012-06-07 14:16:16 +00:00

148 lines
No EOL
4.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
namespace Cosmos.Compiler.XSharp {
public class Generator {
public static void Execute(TextReader input, string inputFilename, TextWriter output, string defaultNamespace) {
var xGenerator = new Generator();
xGenerator.Name = Path.GetFileNameWithoutExtension(inputFilename);
xGenerator.Namespace = defaultNamespace;
xGenerator.Execute(input, output);
}
public string Namespace {
get;
set;
}
public string Name {
get;
set;
}
private void EnsureHeaderWritten() {
if (mHeaderWritten) {
return;
}
mHeaderWritten = true;
EmitHeader();
}
private bool mHeaderWritten = false;
private TextReader mInput;
private TextWriter mOutput;
public void Execute(TextReader aInput, TextWriter aOutput) {
mInput = aInput;
mOutput = aOutput;
while (true) {
string xLine = aInput.ReadLine();
if (xLine == null) {
break;
}
ProcessLine(xLine);
}
EmitFooter();
}
private void EmitHeader() {
mOutput.WriteLine("using System;");
mOutput.WriteLine("using System.Linq;");
mOutput.WriteLine("using Cosmos.Assembler;");
mOutput.WriteLine("using Cosmos.Assembler.x86;");
mOutput.WriteLine();
mOutput.WriteLine("namespace {0}", Namespace);
mOutput.WriteLine("{");
mOutput.WriteLine("\tpublic class {0}: Cosmos.IL2CPU.Plugs.AssemblerMethod", Name);
mOutput.WriteLine("\t{");
mOutput.WriteLine("\t\tpublic override void AssembleNew(object aAssembler, object aMethodInfo)");
mOutput.WriteLine("\t\t{");
}
private void EmitFooter() {
EnsureHeaderWritten();
mOutput.WriteLine("\t\t}");
mOutput.WriteLine("\t}");
mOutput.WriteLine("}");
}
// +-[].=
protected Regex mRegex = new Regex(@"(\W)");
protected void ProcessLine(string aLine) {
aLine = aLine.Trim();
if (String.IsNullOrEmpty(aLine)) {
// Skip
} else if (aLine[0] == '#') {
ProcessComment(aLine.Substring(1));
} else if (aLine[0] == '!') {
ProcessLiteral(aLine.Substring(1));
} else {
if (aLine.EndsWith("++")) {
// TODO
} else if (aLine.EndsWith("--")) {
// TODO
} else {
var xParts = mRegex.Split(aLine);
xParts = xParts.Where(q => string.IsNullOrWhiteSpace(q) == false).ToArray();
if (xParts.Contains("=")) {
ProcessAssignment(xParts);
} else {
throw new Exception("Syntax error: '" + aLine + "'");
}
}
}
}
private void ProcessAssignment(string[] aParts) {
if (aParts.Length != 3) {
throw new Exception("Wrong Assignment");
}
string xLeft = aParts[0];
string xRight = aParts[2];
if (IsRegister(xLeft)) {
uint xValue;
if (UInt32.TryParse(xRight, out xValue)) {
mOutput.WriteLine("new Move{{DestinationReg = RegistersEnum.{0}, SourceValue = {1}}};", xLeft, xRight);
return;
}
}
throw new Exception("Wrong Assignment");
}
private void ProcessLiteral(string line) {
EnsureHeaderWritten();
mOutput.WriteLine("new LiteralAssemblerCode(\"{0}\");", line);
}
private void ProcessComment(string line) {
EnsureHeaderWritten();
mOutput.WriteLine("new Comment(\"{0}\");", line);
}
private bool IsRegister(string aWord) {
aWord = aWord.ToLower();
return
aWord == "eax" || aWord == "ax" || aWord == "ah" || aWord == "al" ||
aWord == "ebx" || aWord == "bx" || aWord == "bh" || aWord == "bl" ||
aWord == "ecx" || aWord == "cx" || aWord == "ch" || aWord == "cl" ||
aWord == "edx" || aWord == "dx" || aWord == "dh" || aWord == "dl" ||
aWord == "esp" ||
aWord == "ebp" ||
aWord == "esi" ||
aWord == "edi";
}
}
}