Cosmos/source2/Compiler/Cosmos.XSharp/CSharpGenerator.cs
kudzu_cp 1860364041
2012-07-12 14:41:45 +00:00

109 lines
No EOL
3.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using XSharp.Nasm;
namespace Cosmos.Compiler.XSharp {
// This is a separate class from AsmGenerator and no common base because it is
// temporary and will go away soon.
public class CSharpGenerator {
protected TextReader mInput;
protected TextWriter mOutput;
protected TokenPatterns mPatterns = new TokenPatterns();
public bool EmitUserComments = false;
public bool EmitXSharpCodeComments = false;
protected int mLineNo = 0;
protected string mPathname = "";
public void Execute(string aNamespace, string aSrcPathname) {
mPathname = Path.GetFileName(aSrcPathname);
using (var xInput = new StreamReader(aSrcPathname)) {
using (var xOutput = new StreamWriter(Path.ChangeExtension(aSrcPathname, ".cs"))) {
Execute(aNamespace, Path.GetFileNameWithoutExtension(aSrcPathname), xInput, xOutput);
}
}
}
public void Execute(string aNamespace, string aClassname, TextReader aInput, TextWriter aOutput) {
mInput = aInput;
mOutput = aOutput;
mPatterns.EmitUserComments = EmitUserComments;
var xAsm = new Assembler();
mLineNo = 0;
EmitHeader(aNamespace, aClassname);
while (true) {
mLineNo++;
string xLine = aInput.ReadLine();
if (xLine == null) {
break;
}
var xAsm2 = ProcessLine(xLine);
xAsm.Data.AddRange(xAsm2.Data);
xAsm.Code.AddRange(xAsm2.Code);
}
foreach (var xLine in xAsm.Data) {
mOutput.WriteLine("\t\t\tmAssembler.DataMembers.Add(new DataMember() { RawAsm = \"" + xLine.Replace("\"", "\\\"") + "\" });");
}
foreach (var xLine in xAsm.Code) {
mOutput.WriteLine("\t\t\tnew LiteralAssemblerCode(\"" + xLine + "\");");
}
EmitFooter();
}
protected void EmitHeader(string aNamespace, string aClassname) {
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 " + aNamespace + " {");
mOutput.WriteLine("\tpublic class " + aClassname + " : Cosmos.Assembler.Code {");
mOutput.WriteLine();
mOutput.WriteLine("\t\tpublic " + aClassname + "(Assembler.Assembler aAssembler) : base(aAssembler) {}");
mOutput.WriteLine();
mOutput.WriteLine("\t\tpublic override void Assemble() {");
}
protected void EmitFooter() {
mOutput.WriteLine("\t\t}");
mOutput.WriteLine("\t}");
mOutput.WriteLine("}");
}
protected Assembler ProcessLine(string aLine) {
Assembler xAsm;
aLine = aLine.Trim();
if (String.IsNullOrEmpty(aLine)) {
xAsm = new Assembler();
xAsm += "";
return xAsm;
}
if (EmitXSharpCodeComments && !aLine.StartsWith("//")) {
string xLine = aLine.Replace("\"", "\\\"");
mOutput.WriteLine("\t\t\tnew Comment(\"X#: " + xLine + "\");");
}
xAsm = mPatterns.GetCode(aLine);
if (xAsm == null) {
var xMsg = new StringBuilder();
if (mPathname != "") {
xMsg.Append("File " + mPathname + ", ");
}
xMsg.Append("Line " + mLineNo + ", ");
xMsg.Append("Parsing error: " + aLine);
throw new Exception(xMsg.ToString());
}
return xAsm;
}
}
}