Permalink
Browse files

AdventureSample - implement FOR/NEXT

  • Loading branch information...
bobbymcr committed Apr 24, 2018
1 parent 36053cd commit 2601a7f116d02afdd51096784b11ff617625eab8
@@ -67,7 +67,16 @@ public void Assign(BasicExpression left, BasicExpression right)
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)
@@ -116,6 +125,9 @@ public void Many(string name, BasicExpression[] list)
case "Dim":
this.AddDim(list);
break;
case "Next":
this.AddNext(list[0]);
break;
case "Print":
this.AddPrint(list);
break;
@@ -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)
{
declarations.Add(this.generator.NamespaceImportDeclaration("System"));
@@ -845,6 +865,7 @@ private sealed class Lines
private readonly HashSet<int> references;
private readonly HashSet<int> subStarts;
private readonly HashSet<int> subEnds;
private readonly Loops loops;
public Lines(SyntaxGenerator generator)
{
@@ -853,6 +874,7 @@ public Lines(SyntaxGenerator generator)
this.references = new HashSet<int>();
this.subStarts = new HashSet<int>();
this.subEnds = new HashSet<int>();
this.loops = new Loops();
}
public void Add(int number, SyntaxNode node)
@@ -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)
{
return "L" + number;
@@ -974,6 +1034,32 @@ private Line Get(int number)
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 readonly int number;
@@ -1008,9 +1094,9 @@ public void Wrap(Func<IEnumerable<SyntaxNode>, SyntaxNode> wrap)
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());
}
@@ -34,6 +34,9 @@ 140 CLS
200 IF A=1 THEN 190
210 READ A
220 READ A$
230 FOR I=1 TO 10
240 PRINT I
250 NEXT I
1000 GOTO 20
2000 CLS
2001 DATA 1
@@ -60,6 +63,7 @@ internal sealed class MyProg
private string B1_s;
private float A_n;
private float B1_n;
private float I_n;
public MyProg(TextReader input, TextWriter output)
{
this.input = (input);
@@ -82,6 +86,7 @@ private void Init()
B1_s = ("""");
A_n = (0);
B1_n = (0);
I_n = (0);
}
private void PRINT(string expression)
@@ -220,6 +225,13 @@ private int Main()
A_n = (READ_n());
A_s = (READ_s());
I_n = (1);
while ((I_n) <= (10))
{
PRINT(("""") + (I_n));
I_n = ((I_n) + (1));
}
goto L20;
return 2;
}

0 comments on commit 2601a7f

Please sign in to comment.