Permalink
Browse files

AdventureSample - rename BasicProgram, SourceCodeStream

  • Loading branch information...
bobbymcr committed Apr 21, 2018
1 parent 77acb26 commit 518a4bc06c67426c49367bd240f350ddc11bf08a
@@ -4,265 +4,25 @@
namespace GWBas2CS
{
using System;
using System.Collections.Generic;
using GWParse.Expressions;
using GWParse.Statements;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Editing;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using GWParse.Lines;
internal sealed class BasicProgram : ILineVisitor, IStatementVisitor
public static class BasicProgram
{
private readonly string name;
private readonly SyntaxGenerator generator;
private readonly List<SyntaxNode> intrinsics;
private readonly Lines lines;
private int lineNumber;
public BasicProgram(string name)
{
this.name = name;
this.generator = SyntaxGenerator.GetGenerator(new AdhocWorkspace(), LanguageNames.CSharp);
this.lines = new Lines();
this.intrinsics = new List<SyntaxNode>();
}
public override string ToString()
{
var usingDirectives = this.generator.NamespaceImportDeclaration("System");
List<SyntaxNode> classMembers = new List<SyntaxNode>();
var runCoreMember = this.generator.MemberAccessExpression(this.generator.ThisExpression(), "Main");
var callRunCore = this.generator.InvocationExpression(runCoreMember);
List<SyntaxNode> runStatements = new List<SyntaxNode>();
var whileLoop = this.generator.WhileStatement(callRunCore, null);
runStatements.Add(whileLoop);
var runMethod = this.generator.MethodDeclaration("Run", accessibility: Accessibility.Public, statements: runStatements);
classMembers.Add(runMethod);
var lastStatement = this.generator.ReturnStatement(this.generator.LiteralExpression(false));
this.lines.Add(65535, lastStatement);
var boolType = this.generator.TypeExpression(SpecialType.System_Boolean);
var mainMethod = this.generator.MethodDeclaration("Main", accessibility: Accessibility.Private, returnType: boolType, statements: this.lines.Statements());
classMembers.AddRange(this.intrinsics);
classMembers.Add(mainMethod);
var classDecl = this.generator.ClassDeclaration(this.name, accessibility: Accessibility.Internal, modifiers: DeclarationModifiers.Sealed, members: classMembers);
return this.generator.CompilationUnit(usingDirectives, classDecl).NormalizeWhitespace().ToString();
}
public void Line(int number, BasicStatement[] list)
{
this.lineNumber = number;
foreach (BasicStatement stmt in list)
{
stmt.Accept(this);
}
}
public void Assign(BasicExpression left, BasicExpression right)
{
throw new NotImplementedException();
}
public void For(BasicExpression v, BasicExpression start, BasicExpression end, BasicExpression step)
{
throw new NotImplementedException();
}
public void Go(string name, int dest)
{
switch (name)
{
case "Goto":
this.AddGoto(dest);
break;
default:
throw new NotImplementedException("Go:" + name);
}
}
public void IfThen(BasicExpression cond, BasicStatement ifTrue)
{
throw new NotImplementedException();
}
public void Input(string prompt, BasicExpression v)
{
throw new NotImplementedException();
}
public void Many(string name, BasicExpression[] list)
{
switch (name)
{
case "Print":
this.AddPrint(list[0]);
break;
default:
throw new NotImplementedException("Many:" + name);
}
}
public void Remark(string text)
{
this.lines.AddComment(this.lineNumber, SyntaxFactory.Comment("// " + text));
}
public void Void(string name)
{
throw new NotImplementedException();
}
public void AddGoto(int destination)
public static async Task TranslateAsync(string name, Stream input, Stream output)
{
this.lines.AddGoto(this.lineNumber, destination);
}
private void AddPrint(BasicExpression expr)
{
ExpressionNode node = new ExpressionNode(this.generator);
expr.Accept(node);
var callPrint = this.generator.InvocationExpression(SyntaxFactory.IdentifierName("PRINT"), node.Value);
this.lines.Add(this.lineNumber, callPrint);
var callConsoleWriteLine = this.generator.MemberAccessExpression(this.generator.IdentifierName("Console"), "WriteLine");
SyntaxNode[] printStatements = new SyntaxNode[] { this.generator.InvocationExpression(callConsoleWriteLine, this.generator.IdentifierName("expression")) };
SyntaxNode[] parameters = new SyntaxNode[] { this.generator.ParameterDeclaration("expression", type: this.generator.TypeExpression(SpecialType.System_String)) };
var printMethod = this.generator.MethodDeclaration("PRINT", accessibility: Accessibility.Private, modifiers: DeclarationModifiers.Static, parameters: parameters, statements: printStatements);
this.intrinsics.Add(printMethod);
}
private sealed class ExpressionNode : IExpressionVisitor
{
private readonly SyntaxGenerator generator;
public ExpressionNode(SyntaxGenerator generator)
{
this.generator = generator;
}
public SyntaxNode Value { get; private set; }
public void Array(BasicType type, string name, BasicExpression[] subs)
{
throw new NotImplementedException();
}
public void Literal(BasicType type, object o)
{
this.Value = this.generator.LiteralExpression(o);
}
public void Operator(string name, BasicExpression[] operands)
{
throw new NotImplementedException();
}
public void Variable(BasicType type, string name)
{
throw new NotImplementedException();
}
}
private sealed class Lines
{
private readonly List<Line> statements;
private readonly HashSet<int> references;
public Lines()
{
this.statements = new List<Line>();
this.references = new HashSet<int>();
}
public void Add(int line, SyntaxNode node)
{
this.statements.Add(new Line(line, node, null));
}
public void AddComment(int line, SyntaxTrivia comment)
{
this.statements.Add(new Line(line, null, comment));
}
public void AddGoto(int line, int destination)
{
var label = SyntaxFactory.IdentifierName(Label(destination));
var gotoStatement = SyntaxFactory.GotoStatement(SyntaxKind.GotoStatement, label);
this.Add(line, gotoStatement);
this.references.Add(destination);
}
public IEnumerable<SyntaxNode> Statements()
{
SyntaxTrivia? previous = null;
foreach (Line line in this.statements)
{
SyntaxTrivia? next = line.Comment;
if (next == null)
{
foreach (SyntaxNode node in line.Nodes(this.references, previous))
{
yield return node;
}
}
previous = next;
}
}
private static string Label(int number)
BasicVisitor program = new BasicVisitor(name);
foreach (BasicLine line in await BasicStream.ReadAsync(input))
{
return "L" + number;
line.Accept(program);
}
private sealed class Line
{
private readonly int number;
private readonly SyntaxNode node;
private readonly SyntaxTrivia? comment;
public Line(int number, SyntaxNode node, SyntaxTrivia? comment)
{
this.number = number;
this.node = node;
this.comment = comment;
}
public SyntaxTrivia? Comment => this.comment;
string outputCode = program.ToString();
public IEnumerable<SyntaxNode> Nodes(ISet<int> references, SyntaxTrivia? previous)
{
SyntaxNode first = null;
SyntaxNode second = null;
if (references.Contains(this.number))
{
first = SyntaxFactory.LabeledStatement(Label(this.number), SyntaxFactory.EmptyStatement());
second = this.node;
}
else
{
first = this.node;
}
if (previous.HasValue)
{
first = first.WithLeadingTrivia(previous.Value);
}
yield return first;
if (second != null)
{
yield return second;
}
}
}
byte[] rawOutput = Encoding.UTF8.GetBytes(outputCode.ToString());
await output.WriteAsync(rawOutput, 0, rawOutput.Length);
}
}
}
Oops, something went wrong.

0 comments on commit 518a4bc

Please sign in to comment.