Skip to content

Commit

Permalink
AdventureSample - implement FOR/NEXT
Browse files Browse the repository at this point in the history
  • Loading branch information
bobbymcr committed Apr 24, 2018
1 parent 36053cd commit 2601a7f
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 3 deletions.
92 changes: 89 additions & 3 deletions projects/AdventureSample/src/GWBas2CS/BasicVisitor.cs
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -67,7 +67,16 @@ public void Assign(BasicExpression left, BasicExpression right)


public void For(BasicExpression v, BasicExpression start, BasicExpression end, BasicExpression step) public void For(BasicExpression v, BasicExpression start, BasicExpression end, BasicExpression step)
{ {
throw new NotImplementedException(); ExpressionNode expr = new ExpressionNode(this.generator, this.vars, this.methods);
v.Accept(expr);
var vx = expr.Value;
start.Accept(expr);
var sx = expr.Value;
end.Accept(expr);
var ex = expr.Value;
step.Accept(expr);
var sp = expr.Value;
this.lines.For(this.lineNumber, vx, sx, ex, sp);
} }


public void Go(string name, int dest) public void Go(string name, int dest)
Expand Down Expand Up @@ -116,6 +125,9 @@ public void Many(string name, BasicExpression[] list)
case "Dim": case "Dim":
this.AddDim(list); this.AddDim(list);
break; break;
case "Next":
this.AddNext(list[0]);
break;
case "Print": case "Print":
this.AddPrint(list); this.AddPrint(list);
break; break;
Expand Down Expand Up @@ -156,6 +168,14 @@ public void Void(string name)
} }
} }


private void AddNext(BasicExpression v)
{
ExpressionNode expr = new ExpressionNode(this.generator, this.vars, this.methods);
v.Accept(expr);
var vx = expr.Value;
this.lines.Next(this.lineNumber, vx);
}

private void Usings(IList<SyntaxNode> declarations) private void Usings(IList<SyntaxNode> declarations)
{ {
declarations.Add(this.generator.NamespaceImportDeclaration("System")); declarations.Add(this.generator.NamespaceImportDeclaration("System"));
Expand Down Expand Up @@ -845,6 +865,7 @@ private sealed class Lines
private readonly HashSet<int> references; private readonly HashSet<int> references;
private readonly HashSet<int> subStarts; private readonly HashSet<int> subStarts;
private readonly HashSet<int> subEnds; private readonly HashSet<int> subEnds;
private readonly Loops loops;


public Lines(SyntaxGenerator generator) public Lines(SyntaxGenerator generator)
{ {
Expand All @@ -853,6 +874,7 @@ public Lines(SyntaxGenerator generator)
this.references = new HashSet<int>(); this.references = new HashSet<int>();
this.subStarts = new HashSet<int>(); this.subStarts = new HashSet<int>();
this.subEnds = new HashSet<int>(); this.subEnds = new HashSet<int>();
this.loops = new Loops();
} }


public void Add(int number, SyntaxNode node) public void Add(int number, SyntaxNode node)
Expand Down Expand Up @@ -957,6 +979,44 @@ public IEnumerable<SyntaxNode> Main()
} }
} }


public void For(int number, SyntaxNode vx, SyntaxNode sx, SyntaxNode ex, SyntaxNode sp)
{
this.loops.Push(number, vx, sx, ex, sp);
}

public void Next(int end, SyntaxNode vx)
{
Tuple<int, SyntaxNode, SyntaxNode, SyntaxNode, SyntaxNode> t = this.loops.Pop(vx);
int start = t.Item1;
List<SyntaxNode> body = new List<SyntaxNode>();
foreach (int n in this.statements.Keys.ToArray())
{
if (n >= end)
{
break;
}
else if (n >= start)
{
body.AddRange(this.statements[n].Nodes());
this.statements.Remove(n);
}
}

var sx = t.Item3;
var ex = t.Item4;
var sp = t.Item5;

var inc = this.generator.AddExpression(vx, sp);
body.Add(this.generator.AssignmentStatement(vx, inc));

var init = this.generator.AssignmentStatement(vx, sx);
this.Add(start, init);

var cond = this.generator.LessThanOrEqualExpression(vx, ex);
var loop = this.generator.WhileStatement(cond, body);
this.Add(end, loop);
}

private static string Label(int number) private static string Label(int number)
{ {
return "L" + number; return "L" + number;
Expand All @@ -974,6 +1034,32 @@ private Line Get(int number)
return line; return line;
} }


private sealed class Loops
{
private readonly Stack<Tuple<int, SyntaxNode, SyntaxNode, SyntaxNode, SyntaxNode>> loops;

public Loops()
{
this.loops = new Stack<Tuple<int, SyntaxNode, SyntaxNode, SyntaxNode, SyntaxNode>>();
}

public void Push(int number, SyntaxNode vx, SyntaxNode sx, SyntaxNode ex, SyntaxNode sp)
{
this.loops.Push(Tuple.Create(number, vx, sx, ex, sp));
}

public Tuple<int, SyntaxNode, SyntaxNode, SyntaxNode, SyntaxNode> Pop(SyntaxNode vx)
{
var t = this.loops.Pop();
if (!t.Item2.IsEquivalentTo(vx))
{
throw new InvalidProgramException("NEXT (" + vx + ") does not match FOR (" + t.Item2 + ").");
}

return t;
}
}

private sealed class Line private sealed class Line
{ {
private readonly int number; private readonly int number;
Expand Down Expand Up @@ -1008,9 +1094,9 @@ public void Wrap(Func<IEnumerable<SyntaxNode>, SyntaxNode> wrap)
this.nodes.Add(wrapped); this.nodes.Add(wrapped);
} }


public IEnumerable<SyntaxNode> Nodes(ISet<int> references) public IEnumerable<SyntaxNode> Nodes(ISet<int> references = null)
{ {
if (references.Contains(this.number)) if ((references != null) && references.Contains(this.number))
{ {
yield return SyntaxFactory.LabeledStatement(Label(this.number), SyntaxFactory.EmptyStatement()); yield return SyntaxFactory.LabeledStatement(Label(this.number), SyntaxFactory.EmptyStatement());
} }
Expand Down
12 changes: 12 additions & 0 deletions projects/AdventureSample/test/GWBas2CS.Test/ExampleProgram.cs
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ 190 INPUT A
200 IF A=1 THEN 190 200 IF A=1 THEN 190
210 READ A 210 READ A
220 READ A$ 220 READ A$
230 FOR I=1 TO 10
240 PRINT I
250 NEXT I
1000 GOTO 20 1000 GOTO 20
2000 CLS 2000 CLS
2001 DATA 1 2001 DATA 1
Expand All @@ -60,6 +63,7 @@ internal sealed class MyProg
private string B1_s; private string B1_s;
private float A_n; private float A_n;
private float B1_n; private float B1_n;
private float I_n;
public MyProg(TextReader input, TextWriter output) public MyProg(TextReader input, TextWriter output)
{ {
this.input = (input); this.input = (input);
Expand All @@ -82,6 +86,7 @@ private void Init()
B1_s = (""""); B1_s = ("""");
A_n = (0); A_n = (0);
B1_n = (0); B1_n = (0);
I_n = (0);
} }
private void PRINT(string expression) private void PRINT(string expression)
Expand Down Expand Up @@ -220,6 +225,13 @@ private int Main()
A_n = (READ_n()); A_n = (READ_n());
A_s = (READ_s()); A_s = (READ_s());
I_n = (1);
while ((I_n) <= (10))
{
PRINT(("""") + (I_n));
I_n = ((I_n) + (1));
}
goto L20; goto L20;
return 2; return 2;
} }
Expand Down

0 comments on commit 2601a7f

Please sign in to comment.