-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathStackLevelInfo.cs
More file actions
69 lines (60 loc) · 2.85 KB
/
StackLevelInfo.cs
File metadata and controls
69 lines (60 loc) · 2.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices.Marshalling;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace NewPaloAltoTB;
internal enum StackEntryKind {
None,
For,
Gosub
}
/// <summary>
/// Provides a stack on which to save nested control structure data (gosub-return addresses and for loops).
/// </summary>
internal class StackLevelInfo {
//SymbolTable LocalSymbols; //symbols defined at current level
//SymbolTable LocalScope; //level of last new scope (sub/function)
internal ProgramLocation EntryPoint; //1st statement of loop body, or statement after gosub
internal ProgramLocation? EndPoint; //1st stmt after next or other loop terminator; unused by gosub
internal StackEntryKind Kind = StackEntryKind.None;
internal LValue? ForLValue;
internal Value ForInitial;
internal Value ForLimit;
internal Value ForIncrement;
internal ProgramLocation? FindForLoopEndPoint() {
if (EndPoint == null) {
var Parser = CodeParser.Shared;
var Interpreter = CodeInterpreter.Shared;
//tricky here, for a richer language: scan over code to find "next forvariable"
//we'll make it simpler using some clean nesting rules - for..next must be 1:1 with next after for, with
//any nested loops begun and ended inside loop body - no crazy spaghetti, and next must name correct var
var (linesave, positionsave) = (Parser.Line, Parser.LinePosition);
foreach (var (linenum, src) in Interpreter.ProgramSource.Where(e => e.linenum >= EntryPoint.LineNumber &&
e.src.Contains("next",StringComparison.InvariantCultureIgnoreCase))) {
//skip until find a line matching next\s+forvariable; make sure it is not a comment or print literal
while (!Parser.EoL()) {
(Parser.Line, Parser.LinePosition) = (src, 0);
var match = Parser.ScanRegex("\\s*next\\s+" + ForLValue!.LVar.VName + "(\\;|$)");
if (match != null) {
EndPoint = new ProgramLocation(EntryPoint.FileName, linenum, Parser.LinePosition, Parser.Line);
break;
}
else {
Parser.SkipToEolOrNextStatementOnLine(); //skip past next non-quoted ';'
}
}
if (EndPoint != null) {
break;
}
}
(Parser.Line, Parser.LinePosition) = (linesave, positionsave);
}
return EndPoint;
}
internal StackLevelInfo(string file, int lineNum, int colNum, string? srcLine) {
EntryPoint = new(file, lineNum, colNum, srcLine);
}
}