From b97134a15585fef42c50e3faa7b033991700eaa3 Mon Sep 17 00:00:00 2001 From: Ludovic 'Archivist' Lagouardette Date: Wed, 8 Sep 2021 11:56:13 +0200 Subject: [PATCH] While loops --- Functions/Add.cs | 14 ++++++++++++++ Parser.cs | 43 ++++++++++++++++++++++++++++++++++++++++--- Program.cs | 1 + SuperBASIC.csproj | 4 ++++ Test.basic | 25 +++++++++++-------------- 5 files changed, 70 insertions(+), 17 deletions(-) create mode 100644 Functions/Add.cs diff --git a/Functions/Add.cs b/Functions/Add.cs new file mode 100644 index 0000000..8a13eca --- /dev/null +++ b/Functions/Add.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace SuperBASIC.Functions +{ + class Add : IFunction + { + float IFunction.Apply(List arguments) + { + return arguments[0] + arguments[1]; + } + } +} diff --git a/Parser.cs b/Parser.cs index b83ad3f..0a560f4 100644 --- a/Parser.cs +++ b/Parser.cs @@ -230,9 +230,9 @@ namespace SuperBASIC { //Case 2: update the JZ c.bytecode[label.index + 2] = new BasicNumber(runtime, (float)c.bytecode.Count); - } - else - { + } + else + { int lineIndex = 0; foreach (int cnt in lineSpans.GetRange(0, idx + 1)) lineIndex += cnt; throw new ParseException($"Orphaned ENDIF\n\tat line {lineIndex}"); @@ -245,6 +245,43 @@ namespace SuperBASIC throw new ParseException($"Orphaned ENDIF despite THEN\n\tat line {lineIndex}"); } break; + case "WHILE": + // Role: manages the expression + // 1. Deal with expression + label.ctrl = Controls.While; + label.index = c.bytecode.Count; + labelStack.Push(label); + ParseExpression(c, components[1..], idx, lineSpans); + // 2. Adds the label to update the destination + label.ctrl = Controls.Wend; + label.index = c.bytecode.Count; + labelStack.Push(label); + // 3. Adds the jumper + c.bytecode.Add(new BasicNumber(runtime, library.nameResolution["JZ"])); + c.bytecode.Add(new BasicNumber(runtime)); + c.bytecode.Add(new BasicNumber(runtime, 0f)); + break; + case "WEND": + //Role: Destination if depending on what is skipped + var labelA = labelStack.Pop(); + if (labelA.ctrl == Controls.Wend) + { + + label = labelStack.Pop(); + if (label.ctrl == Controls.While) + { + c.bytecode.Add(new BasicNumber(runtime, library.nameResolution["GOTO"])); + c.bytecode.Add(new BasicNumber(runtime, (float)label.index)); + c.bytecode[labelA.index + 2] = new BasicNumber(runtime, (float)c.bytecode.Count); + } + } + else + { + int lineIndex = 0; + foreach (int cnt in lineSpans.GetRange(0, idx + 1)) lineIndex += cnt; + throw new ParseException($"Orphaned WEND\n\tat line {lineIndex}"); + } + break; default: ParseExpression(c, components, idx, lineSpans); break; diff --git a/Program.cs b/Program.cs index cda8602..09780aa 100644 --- a/Program.cs +++ b/Program.cs @@ -16,6 +16,7 @@ namespace SuperBASIC #endif lib.AddFunction(new Functions.Print(), 1, "PRINT"); lib.AddFunction(new Functions.Multiply(), 2, "MULTIPLY"); + lib.AddFunction(new Functions.Add(), 2, "ADD"); lib.AddFunction(new Functions.Compare(), 2, "COMPARE"); lib.AddFunction(new Functions.JumpZero(), 2, "JZ"); lib.AddFunction(new Functions.Goto(), 1, "GOTO"); diff --git a/SuperBASIC.csproj b/SuperBASIC.csproj index fdb69aa..e753f19 100644 --- a/SuperBASIC.csproj +++ b/SuperBASIC.csproj @@ -5,6 +5,10 @@ netcoreapp3.1 + + TRACE;MEMORY + + PreserveNewest diff --git a/Test.basic b/Test.basic index 1b16704..5c768cd 100644 --- a/Test.basic +++ b/Test.basic @@ -1,14 +1,11 @@ -EULER -MULTIPLY $ $ - -IF COMPARE $ 7.3890557 -THEN -PRINT 25 -GOTO end -ELSE -PRINT 10 -ENDIF -LABEL loop -PRINT 50 -GOTO loop -LABEL end \ No newline at end of file +MEMSTORE 1 0 +MEMSTORE 0 10 +WHILE MEMLOAD 0 +MEMLOAD 0 +ADD $ -1 +MEMSTORE 0 $ +MEMLOAD 1 +ADD $ 1 +MEMSTORE 1 $ +PRINT M1 +WEND \ No newline at end of file