Permalink
Browse files

AdventureSample - support subroutines with multiple RETURNs

  • Loading branch information...
bobbymcr committed May 2, 2018
1 parent e5e2e04 commit 375ffdfecb00d034bf95f772352b16bb81bfc16b
@@ -1014,27 +1014,29 @@ public void AddReturn(int number)
public IEnumerable<SyntaxNode> Subroutines()
{
string subName = null;
List<SyntaxNode> statements = new List<SyntaxNode>();
IDictionary<int, int> subs = this.subLines.Compile();
int start = 0;
int end = 0;
foreach (KeyValuePair<int, Line> line in this.statements)
{
if ((subName == null) && this.subLines.IsStart(line.Key))
if ((start == 0) && subs.TryGetValue(line.Key, out end))
{
subName = "Sub_" + line.Key;
start = line.Key;
}
if (subName != null)
if (start != 0)
{
statements.AddRange(line.Value.Nodes(this.references));
if (this.subLines.IsEnd(line.Key))
if (end == line.Key)
{
var ret = this.generator.TypeExpression(SpecialType.System_Int32);
yield return this.generator.MethodDeclaration(
subName,
"Sub_" + start,
returnType: ret,
accessibility: Accessibility.Private,
statements: statements);
subName = null;
start = 0;
statements.Clear();
}
}
@@ -1043,23 +1045,20 @@ public IEnumerable<SyntaxNode> Subroutines()
public IEnumerable<SyntaxNode> Main()
{
bool readingSub = false;
IDictionary<int, int> subs = this.subLines.Compile();
int end = 0;
foreach (KeyValuePair<int, Line> line in this.statements)
{
if (readingSub)
if (end > 0)
{
if (this.subLines.IsEnd(line.Key))
if (end == line.Key)
{
readingSub = false;
end = 0;
}
}
else
{
if (this.subLines.IsStart(line.Key))
{
readingSub = true;
}
else
if (!subs.TryGetValue(line.Key, out end))
{
foreach (SyntaxNode node in line.Value.Nodes(this.references))
{
@@ -1212,11 +1211,31 @@ public SubLines()
public void AddStart(int n) => Add(this.starts, n);
public bool IsStart(int n) => Find(this.starts, n);
public void AddEnd(int n) => Add(this.ends, n);
public bool IsEnd(int n) => Find(this.ends, n);
public IDictionary<int, int> Compile()
{
Dictionary<int, int> subs = new Dictionary<int, int>();
int i = 0;
foreach (int end in this.ends)
{
int start = this.starts[i];
if (start <= end)
{
subs[start] = end;
if (i < this.starts.Count - 1)
{
++i;
}
}
else
{
subs[this.starts[i - 1]] = end;
}
}
return subs;
}
private static void Add(List<int> list, int n)
{
@@ -84,5 +84,53 @@ private int Main()
actual.Should().Match(Expected);
}
[Fact]
public void WithMultipleReturns()
{
const string Input =
@"10 GOSUB 30
20 GOTO 70
30 IF A=2 THEN RETURN
40 A=1
50 CLS
60 RETURN
70 PRINT";
const string Expected = @"*
private int Sub_30()
{
if ((((A_n.CompareTo(2)) == (0)) ? (-1) : (0)) != (0))
{
return 0;
}
A_n = (1);
CLS();
return 0;
}
private int Main()
{
this.Init();
switch (Sub_30())
{
case 1:
return 1;
case 2:
return 2;
}
goto L70;
L70:
;
PRINT("""");
return 2;
}
*";
string actual = Test.Translate("MyProg", Input);
actual.Should().Match(Expected);
}
}
}

0 comments on commit 375ffdf

Please sign in to comment.