private static void MakeLoopEnd(TokenizerOutput program, TLine line, Stack <LoopData> loopStack) { if (loopStack.Count < 1) { throw new TokenizerException(line, "Misplaced NEXT"); } LoopData data = loopStack.Pop(); var next = (KwNext)line.Statement; if (data.LoopVariable.Name != next.Variable.Name) { throw new TokenizerException(line, "NEXT Error : Unknown variable " + next.Variable.Name); } // step 1: change the variable var add = new NumBinaryOperator(data.LoopVariable, data.StepVariable, "+"); var assign = new NumBinaryOperator(data.LoopVariable, add, "="); program.Program.Add(line.Clone(assign)); // step 2: goto to the begining var gt = new KwrGoto(data.StartLine, true); program.Program.Add(line.Clone(gt)); // change the top jump condition ((KwrJumpIfTrue)program.Program[data.StartLine].Statement).JumpPos = program.Program.Count; }
private static LoopData MakeLoopBegin(TokenizerOutput program, TLine line) { var kwFor = (KwFor)line.Statement; var ret = new LoopData { StartLine = (program.Program.Count + 2) }; // step 1: var = initial NumVariable forVar = kwFor.Variable; program.Program.Add(line.Clone(new NumBinaryOperator(forVar, kwFor.Initial, "="))); ret.LoopVariable = forVar; // step 2: make step variable var stepVar = new NumVariable("$" + ret.StartLine + forVar.Name + "_StepVariable"); NumStatement stepValue = kwFor.Step ?? new NumConstant("1"); program.Program.Add(line.Clone(new NumBinaryOperator(stepVar, stepValue, "="))); ret.StepVariable = stepVar; // step 3: loop var condition = new NumBoolBinaryOperator(forVar, kwFor.End, ">"); var jmp = new KwrJumpIfTrue(condition, -1); program.Program.Add(line.Clone(jmp)); return(ret); }
private static void MakeBranch(TokenizerOutput program, TLine line, Stack <LoopData> loopStack) { var kwif = (KwIf)line.Statement; var newIf = new KwrJumpIfNotTrue(kwif.Condition, -1); program.Program.Add(line.Clone(newIf)); // placeholder foreach (Statement s in kwif.Statements) { TokenizeStatement(program, line.Clone(s), loopStack); } if (kwif.ElseStatements == null) { newIf.JumpPos = program.Program.Count; } else { var gt = new KwrGoto(-1, true); program.Program.Add(line.Clone(gt)); newIf.JumpPos = program.Program.Count; foreach (Statement s in kwif.ElseStatements) { TokenizeStatement(program, line.Clone(s), loopStack); } gt.JumpPos = program.Program.Count; } }
private static void TokenizeStatement(TokenizerOutput program, TLine line, Stack <LoopData> loopStack) { if (line.Statement is KwGoto) { program.Program.Add(line.Clone(new KwrGoto(((KwGoto)line.Statement).Value.Value, false))); } else if (line.Statement is KwGosub) { program.Program.Add(line.Clone(new KwrGosub(((KwGosub)line.Statement).Value.Value, false))); } else if (line.Statement is KwData) { KwData data = (KwData)line.Statement; if (program.Data == null) { program.Data = new List <string>(); } ((List <string>)program.Data).AddRange(data.Data); program.Program.Add(line.Clone(new KwRem(line.OriginalLine.OriginalLine))); } else if (line.Statement is KwIf) { MakeBranch(program, line, loopStack); } else if (line.Statement is KwFor) { LoopData d = MakeLoopBegin(program, line); loopStack.Push(d); } else if (line.Statement is KwNext) { MakeLoopEnd(program, line, loopStack); } else if (line.Statement is KwOn) { MakeOnStatement(program, line); } else if (line.Statement is KwPrint) { MakePrintStatement(program, line); } else if (line.Statement is KwDim) { KwDim dim = (KwDim)line.Statement; foreach (VariableArray arr in dim.ArrayList) { program.Program.Add(line.Clone(new KwrDim(arr))); } } else { program.Program.Add(line); } }
private static void MakeOnStatement(TokenizerOutput program, TLine line) { var kw = (KwOn)line.Statement; for (int j = 0; j < kw.JumpList.Count; ++j) { var cnd = new NumBoolBinaryOperator(kw.Statement, new NumConstant((j + 1).ToString()), "=="); var ifc = new KwrJumpIfNotTrue(cnd, -1); program.Program.Add(line.Clone(ifc)); int jumpPos = kw.JumpList[j].Value; KwrJump jmp = kw.Kind == KwOn.OnKind.Goto ? new KwrGoto(jumpPos, false) : (KwrJump) new KwrGosub(jumpPos, false); program.Program.Add(line.Clone(jmp)); ifc.JumpPos = program.Program.Count; } }
private static void MakePrintStatement(TokenizerOutput program, TLine line) { var print = (KwPrint)line.Statement; if (print.PrintList == null) { program.Program.Add(line.Clone(new KwrPrint(new StringConstant(""), true))); return; } foreach (KwPrint.Group group in print.PrintList) { bool newLine = String.IsNullOrEmpty(group.EndChar); program.Program.Add(line.Clone(new KwrPrint(group.Statement, newLine))); if (!newLine && group.EndChar == ",") { program.Program.Add(line.Clone(new KwrPrint(new StringConstant("\t"), false))); } } }