diff --git a/Trs80.Level1Basic.Extensions.Test/StringExtensionsTest.cs b/Trs80.Level1Basic.Extensions.Test/StringExtensionsTest.cs new file mode 100644 index 0000000..935a6f2 --- /dev/null +++ b/Trs80.Level1Basic.Extensions.Test/StringExtensionsTest.cs @@ -0,0 +1,155 @@ +using FluentAssertions; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Trs80.Level1Basic.Common.Extensions; + +namespace Trs80.Level1Basic.Extensions.Test +{ + [TestClass] + public class StringExtensionsTest + { + private const string testString = "four Score-and_seven_YeArs AGO"; + private const string testOneWordString = "fOUr"; + private const string testUpperOneLetterString = "F"; + private const string testLowerOneLetterString = "f"; + + [TestMethod] + public void Can_Convert_String_To_Pascal_Case() + { + string? result = testString.ToPascalCase(); + result.Should().Be("FourScoreAndSevenYearsAgo"); + } + + [TestMethod] + public void Can_Convert_String_To_Camel_Case() + { + string? result = testString.ToCamelCase(); + result.Should().Be("fourScoreAndSevenYearsAgo"); + } + + [TestMethod] + public void Can_Convert_String_To_Snake_Case() + { + string? result = testString.ToSnakeCase(); + result.Should().Be("four_score_and_seven_years_ago"); + } + + [TestMethod] + public void Can_Convert_String_To_Caps_Case() + { + string? result = testString.ToCapsCase(); + result.Should().Be("FOUR_SCORE_AND_SEVEN_YEARS_AGO"); + } + + [TestMethod] + public void Can_Convert_String_To_Kebab_Case() + { + string? result = testString.ToKebabCase(); + result.Should().Be("four-score-and-seven-years-ago"); + } + + [TestMethod] + public void Can_Convert_One_Word_String_To_Pascal_Case() + { + string? result = testOneWordString.ToPascalCase(); + result.Should().Be("Four"); + } + + [TestMethod] + public void Can_Convert_One_Word_String_To_Camel_Case() + { + string? result = testOneWordString.ToCamelCase(); + result.Should().Be("four"); + } + + [TestMethod] + public void Can_Convert_One_Word_String_To_Snake_Case() + { + string? result = testOneWordString.ToSnakeCase(); + result.Should().Be("four"); + } + + [TestMethod] + public void Can_Convert_One_Word_String_To_Caps_Case() + { + string? result = testOneWordString.ToCapsCase(); + result.Should().Be("FOUR"); + } + + [TestMethod] + public void Can_Convert_One_Word_String_To_Kebab_Case() + { + string? result = testOneWordString.ToKebabCase(); + result.Should().Be("four"); + } + + [TestMethod] + public void Can_Convert_One_Letter_Upper_String_To_Pascal_Case() + { + string? result = testUpperOneLetterString.ToPascalCase(); + result.Should().Be("F"); + } + + [TestMethod] + public void Can_Convert_One_Letter_Upper_String_To_Camel_Case() + { + string? result = testUpperOneLetterString.ToCamelCase(); + result.Should().Be("f"); + } + + [TestMethod] + public void Can_Convert_One_Letter_Upper_String_To_Snake_Case() + { + string? result = testUpperOneLetterString.ToSnakeCase(); + result.Should().Be("f"); + } + + [TestMethod] + public void Can_Convert_One_Letter_Upper_String_To_Caps_Case() + { + string? result = testUpperOneLetterString.ToCapsCase(); + result.Should().Be("F"); + } + + [TestMethod] + public void Can_Convert_One_Letter_Upper_String_To_Kebab_Case() + { + string? result = testUpperOneLetterString.ToKebabCase(); + result.Should().Be("f"); + } + + [TestMethod] + public void Can_Convert_One_Letter_Lower_String_To_Pascal_Case() + { + string? result = testLowerOneLetterString.ToPascalCase(); + result.Should().Be("F"); + } + + [TestMethod] + public void Can_Convert_One_Letter_Lower_String_To_Camel_Case() + { + string? result = testLowerOneLetterString.ToCamelCase(); + result.Should().Be("f"); + } + + [TestMethod] + public void Can_Convert_One_Letter_Lower_String_To_Snake_Case() + { + string? result = testLowerOneLetterString.ToSnakeCase(); + result.Should().Be("f"); + } + + [TestMethod] + public void Can_Convert_One_Letter_Lower_String_To_Caps_Case() + { + string? result = testLowerOneLetterString.ToCapsCase(); + result.Should().Be("F"); + } + + [TestMethod] + public void Can_Convert_One_Letter_Lower_String_To_Kebab_Case() + { + string? result = testLowerOneLetterString.ToKebabCase(); + result.Should().Be("f"); + } + } +} \ No newline at end of file diff --git a/Trs80.Level1Basic.Extensions.Test/Trs80.Level1Basic.Extensions.Test.csproj b/Trs80.Level1Basic.Extensions.Test/Trs80.Level1Basic.Extensions.Test.csproj new file mode 100644 index 0000000..2767e2d --- /dev/null +++ b/Trs80.Level1Basic.Extensions.Test/Trs80.Level1Basic.Extensions.Test.csproj @@ -0,0 +1,25 @@ + + + + net6.0 + enable + + false + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + diff --git a/Trs80.Level1Basic.Extensions/Extensions/StringExtensions.cs b/Trs80.Level1Basic.Extensions/Extensions/StringExtensions.cs index 2410036..aab86ca 100644 --- a/Trs80.Level1Basic.Extensions/Extensions/StringExtensions.cs +++ b/Trs80.Level1Basic.Extensions/Extensions/StringExtensions.cs @@ -1,6 +1,8 @@ using System; +using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; +using System.Text; namespace Trs80.Level1Basic.Common.Extensions; @@ -9,21 +11,83 @@ public static class StringExtensions { public static string ToPascalCase(this string text) { - if (string.IsNullOrEmpty(text)) return text; - if (text.Length == 1) return text.ToUpper(); + string result = HandleBaseCases(text, true); + if (!string.IsNullOrEmpty(result)) return result; - string[] words = text.Split(new[] { '-', '_' }, StringSplitOptions.RemoveEmptyEntries); + string[] words = SplitWords(text); if (words.Length > 1) return string.Concat(words.Select(word => word[..1].ToUpper() + word[1..].ToLower())); - return words[0][..1].ToUpper() + words[0][1..]; + return words[0][..1].ToUpper() + words[0][1..].ToLower(); + } + + private static string[] SplitWords(string text) + { + string[] words = text.Split(new[] { '-', '_', ' ' }, StringSplitOptions.RemoveEmptyEntries); + return words; } public static string ToCamelCase(this string text) { - string result = ToPascalCase(text); + string result = HandleBaseCases(text, false); + if (!string.IsNullOrEmpty(result)) return result; + + result = ToPascalCase(text); return result[..1].ToLower() + result[1..]; } + + public static string ToSnakeCase(this string text) + { + string result = HandleBaseCases(text, false); + if (!string.IsNullOrEmpty(result)) return result; + + string[] words = SplitWords(text); + + return CasedStringWithSeparator(words, false, '_'); + } + + public static string ToCapsCase(this string text) + { + string result = HandleBaseCases(text, true); + if (!string.IsNullOrEmpty(result)) return result; + + string[] words = SplitWords(text); + + return CasedStringWithSeparator(words, true, '_'); + } + + public static string ToKebabCase(this string text) + { + string result = HandleBaseCases(text, false); + if (!string.IsNullOrEmpty(result)) return result; + + string[] words = SplitWords(text); + + return CasedStringWithSeparator(words, false, '-'); + } + + private static string HandleBaseCases(this string text, bool isUpper) + { + if (string.IsNullOrEmpty(text)) return text; + return text.Length == 1 ? text.ConvertCase(isUpper) : string.Empty; + } + private static string ConvertCase(this string word, bool isUpper) + { + return isUpper ? word.ToUpper() : word.ToLower(); + } + + private static string CasedStringWithSeparator(IReadOnlyList words, bool isUpper, char separator) + { + if (words.Count == 1) return words[0].ConvertCase(isUpper); + + StringBuilder sb = new(); + + for (int i = 0; i < words.Count - 1; i++) + sb.Append(words[i].ConvertCase(isUpper) + separator); + + sb.Append(words[^1].ConvertCase(isUpper)); + return sb.ToString(); + } } \ No newline at end of file diff --git a/Trs80.Level1Basic.GenerateAst/Program.cs b/Trs80.Level1Basic.GenerateAst/Program.cs index 2ad00db..c1c6e30 100644 --- a/Trs80.Level1Basic.GenerateAst/Program.cs +++ b/Trs80.Level1Basic.GenerateAst/Program.cs @@ -153,7 +153,7 @@ private static void DefineVisitorInterface(string outputDir, string baseName, Li string returnType = baseName.Contains("Statement") ? "void" : "dynamic"; string typeName = type.Split(":")[0].Trim(); - writer.WriteLine($" {returnType} Visit{typeName}{baseName}({typeName} root);"); + writer.WriteLine($" {returnType} Visit{typeName}{baseName}({typeName} {baseName.ToCamelCase()});"); } writer.WriteLine("}"); WriteEnd(writer); diff --git a/Trs80.Level1Basic.GenerateAst/Properties/launchSettings.json b/Trs80.Level1Basic.GenerateAst/Properties/launchSettings.json index ffe60cb..05fbb12 100644 --- a/Trs80.Level1Basic.GenerateAst/Properties/launchSettings.json +++ b/Trs80.Level1Basic.GenerateAst/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "GenerateAst": { "commandName": "Project", - "commandLineArgs": "..\\..\\..\\..\\Trs80.Level1Basic.Interpreter\\Parser" + "commandLineArgs": "..\\..\\..\\..\\Trs80.Level1Basic.VirtualMachine\\Parser" } } } \ No newline at end of file diff --git a/Trs80.Level1Basic.VirtualMachine/Interpreter/Interpreter.cs b/Trs80.Level1Basic.VirtualMachine/Interpreter/Interpreter.cs index 21eab13..8114dca 100644 --- a/Trs80.Level1Basic.VirtualMachine/Interpreter/Interpreter.cs +++ b/Trs80.Level1Basic.VirtualMachine/Interpreter/Interpreter.cs @@ -64,26 +64,26 @@ public void Execute(Statement statement) } } - public dynamic VisitBasicArrayExpression(BasicArray root) + public dynamic VisitBasicArrayExpression(BasicArray expression) { - dynamic index = Evaluate(root.Index); - return _machine.GetArrayValue(root.Name.Lexeme, index); + dynamic index = Evaluate(expression.Index); + return _machine.GetArrayValue(expression.Name.Lexeme, index); } - public dynamic VisitAssignExpression(Assign assign) + public dynamic VisitAssignExpression(Assign expression) { - dynamic value = Evaluate(assign.Value); - return AssignVariable(assign, value); + dynamic value = Evaluate(expression.Value); + return AssignVariable(expression, value); } - public dynamic VisitBinaryExpression(Binary binary) + public dynamic VisitBinaryExpression(Binary expression) { - dynamic left = Evaluate(binary.Left); - dynamic right = Evaluate(binary.Right); + dynamic left = Evaluate(expression.Left); + dynamic right = Evaluate(expression.Right); - CheckForProperOperands(binary.OperatorType, left, right); + CheckForProperOperands(expression.OperatorType, left, right); - return binary.OperatorType.Type switch + return expression.OperatorType.Type switch { TokenType.Plus => (left is bool && right is bool) ? left || right : left + right, TokenType.Minus => left - right, @@ -99,12 +99,12 @@ public dynamic VisitBinaryExpression(Binary binary) }; } - public dynamic VisitCallExpression(Call call) + public dynamic VisitCallExpression(Call expression) { - var arguments = call.Arguments.Select(argument => Evaluate(argument)).ToList(); + var arguments = expression.Arguments.Select(argument => Evaluate(argument)).ToList(); FunctionDefinition function = _machine - .GetFunctionDefinition(call.Name.Lexeme).First(f => f.Arity == arguments.Count); + .GetFunctionDefinition(expression.Name.Lexeme).First(f => f.Arity == arguments.Count); return function.Call(this, arguments); } @@ -142,9 +142,9 @@ private static bool AreEqual(dynamic left, dynamic right) return left != null && (bool)left.Equals(right); } - public dynamic VisitGroupingExpression(Grouping root) + public dynamic VisitGroupingExpression(Grouping expression) { - return Evaluate(root.Expression); + return Evaluate(expression.Expression); } private dynamic Evaluate(Expression expression) @@ -152,28 +152,28 @@ private dynamic Evaluate(Expression expression) return expression.Accept(this); } - public dynamic VisitLiteralExpression(Literal literal) + public dynamic VisitLiteralExpression(Literal expression) { - if (literal.Value is not int) return literal.Value; + if (expression.Value is not int) return expression.Value; - if (literal.Value > short.MaxValue || literal.Value < short.MinValue) + if (expression.Value > short.MaxValue || expression.Value < short.MinValue) // ReSharper disable once PossibleInvalidCastException - return (float)literal.Value; + return (float)expression.Value; - return literal.Value; + return expression.Value; } - public dynamic VisitUnaryExpression(Unary unary) + public dynamic VisitUnaryExpression(Unary expression) { - dynamic right = Evaluate(unary.Right); + dynamic right = Evaluate(expression.Right); - CheckForNumericOperand(unary.OperatorType, right); + CheckForNumericOperand(expression.OperatorType, right); return -1 * right; } - public dynamic VisitIdentifierExpression(Identifier identifier) + public dynamic VisitIdentifierExpression(Identifier expression) { - return _machine.GetVariable(identifier.Name.Lexeme); + return _machine.GetVariable(expression.Name.Lexeme); } private void WriteExpression(Expression expression) @@ -226,9 +226,9 @@ private void WriteFloatValue(dynamic value) _sb.Append(value.ToString("######")); } - public void VisitNextStatement(Next root) + public void VisitNextStatement(Next statement) { - ForCheckCondition checkCondition = GetCheckCondition(root); + ForCheckCondition checkCondition = GetCheckCondition(statement); dynamic nextIndexerValue = IncrementIndexer(checkCondition); if (EndOfLoop(checkCondition, nextIndexerValue)) return; Loop(checkCondition); @@ -315,18 +315,18 @@ private ForCheckCondition GetCheckCondition(Next next) return checkCondition; } - public void VisitOnStatement(On on) + public void VisitOnStatement(On statement) { - int selector = (int)Math.Floor((float)Evaluate(on.Selector)) - 1; - var locations = on.Locations.Select(location => Evaluate(location)).ToList(); + int selector = (int)Math.Floor((float)Evaluate(statement.Selector)) - 1; + var locations = statement.Locations.Select(location => Evaluate(location)).ToList(); if (selector >= locations.Count || selector < 0) return; - if (on.IsGosub) + if (statement.IsGosub) { - _machine.ProgramStack.Push(on.Next); + _machine.ProgramStack.Push(statement.Next); Expression location = new Literal(locations[selector]); - Statement jumpToStatement = GetJumpToStatement(on, location, "GOSUB"); + Statement jumpToStatement = GetJumpToStatement(statement, location, "GOSUB"); _machine.RunProgram(jumpToStatement, this); _machine.SetNextStatement(_machine.ProgramStack.Pop()); @@ -336,25 +336,25 @@ public void VisitOnStatement(On on) Statement nextStatement = GetStatementByLineNumber(locations[selector]); if (nextStatement is null) - throw new RuntimeStatementException(on.LineNumber, on.SourceLine, + throw new RuntimeStatementException(statement.LineNumber, statement.SourceLine, $"Can't 'GOTO' line {locations[selector]}."); _machine.SetNextStatement(nextStatement); } - public void VisitPrintStatement(Print printStatement) + public void VisitPrintStatement(Print statement) { _sb = new StringBuilder(); - if (printStatement.AtPosition != null) PrintAt(printStatement.AtPosition); + if (statement.AtPosition != null) PrintAt(statement.AtPosition); - if (printStatement.Expressions is { Count: > 0 }) - foreach (Expression expression in printStatement.Expressions) + if (statement.Expressions is { Count: > 0 }) + foreach (Expression expression in statement.Expressions) WriteExpression(expression); string text = _sb.ToString(); _console.Write(text); - if (!printStatement.WriteNewline) return; + if (!statement.WriteNewline) return; _console.WriteLine(); CursorX = 0; @@ -373,17 +373,17 @@ private void PrintAt(Expression position) CursorY = row; } - public void VisitReplaceStatement(Replace root) + public void VisitReplaceStatement(Replace statement) { - if (string.IsNullOrEmpty(root.Line.SourceLine)) - DeleteStatement(root.Line.LineNumber); + if (string.IsNullOrEmpty(statement.Line.SourceLine)) + DeleteStatement(statement.Line.LineNumber); else - _machine.Program.ReplaceLine(root.Line); + _machine.Program.ReplaceLine(statement.Line); } - public void VisitReadStatement(Read root) + public void VisitReadStatement(Read statement) { - foreach (Expression variable in root.Variables) + foreach (Expression variable in statement.Variables) AssignVariable(variable, _machine.Data.GetNext()); } @@ -430,9 +430,9 @@ public void VisitStatementExpressionStatement(StatementExpression statement) Evaluate(statement.Expression); } - public void VisitStopStatement(Stop root) + public void VisitStopStatement(Stop statement) { - _console.WriteLine($"BREAK AT {root.LineNumber}"); + _console.WriteLine($"BREAK AT {statement.LineNumber}"); _machine.HaltRun(); } @@ -441,17 +441,17 @@ public void VisitRestoreStatement(Restore _) _machine.Data.MoveFirst(); } - public void VisitReturnStatement(Return returnStatement) + public void VisitReturnStatement(Return statement) { _machine.SetNextStatement(null); } - public void VisitRunStatement(Run runStatement) + public void VisitRunStatement(Run statement) { _machine.InitializeProgram(); GetCursorPosition(); - int lineNumber = GetStartingLineNumber(runStatement.StartAtLineNumber); + int lineNumber = GetStartingLineNumber(statement.StartAtLineNumber); if (lineNumber < 0) lineNumber = GetFirstLineNumber(); if (lineNumber < 0) return; @@ -459,7 +459,7 @@ public void VisitRunStatement(Run runStatement) _machine.LoadData(this); Statement firstStatement = GetStatementByLineNumber(lineNumber); if (firstStatement is null) - throw new RuntimeStatementException(-1, runStatement.SourceLine, $"Can't start execution at {lineNumber}"); + throw new RuntimeStatementException(-1, statement.SourceLine, $"Can't start execution at {lineNumber}"); RunProgram(firstStatement, true); } @@ -500,13 +500,13 @@ public void RunProgram(Statement statement, bool initialize) _console.WriteLine("READY"); } - public void VisitListStatement(List listStatement) + public void VisitListStatement(List statement) { - int lineNumber = GetStartingLineNumber(listStatement.StartAtLineNumber); + int lineNumber = GetStartingLineNumber(statement.StartAtLineNumber); _machine.ListProgram(lineNumber); } - public void VisitRemStatement(Rem remStatement) + public void VisitRemStatement(Rem statement) { // do nothing } @@ -543,10 +543,10 @@ private static string OpenFileDialog() } - public void VisitLoadStatement(Load loadStatement) + public void VisitLoadStatement(Load statement) { _machine.NewProgram(); - string path = Evaluate(loadStatement.Path); + string path = Evaluate(statement.Path); if (string.IsNullOrEmpty(path)) path = OpenFileDialog(); @@ -556,9 +556,9 @@ public void VisitLoadStatement(Load loadStatement) _console.WriteLine($"Loaded \"{path}\"."); } - public void VisitMergeStatement(Merge mergeStatement) + public void VisitMergeStatement(Merge statement) { - string path = Evaluate(mergeStatement.Path); + string path = Evaluate(statement.Path); if (string.IsNullOrEmpty(path)) path = OpenFileDialog(); @@ -568,9 +568,9 @@ public void VisitMergeStatement(Merge mergeStatement) _console.WriteLine($"Merged \"{path}\"."); } - public void VisitSaveStatement(Save saveStatement) + public void VisitSaveStatement(Save statement) { - string path = Evaluate(saveStatement.Path); + string path = Evaluate(statement.Path); if (string.IsNullOrEmpty(path)) path = SaveFileDialog(); @@ -579,32 +579,32 @@ public void VisitSaveStatement(Save saveStatement) _machine.SaveProgram(path); _console.WriteLine($"Saved \"{path}\"."); } - public void VisitEndStatement(End endStatement) + public void VisitEndStatement(End statement) { _machine.HaltRun(); } - public void VisitForStatement(For forStatement) + public void VisitForStatement(For statement) { - dynamic startValue = Evaluate(forStatement.StartValue); - AssignVariable(forStatement.Variable, startValue); + dynamic startValue = Evaluate(statement.StartValue); + AssignVariable(statement.Variable, startValue); - dynamic endValue = Evaluate(forStatement.EndValue); - dynamic stepValue = Evaluate(forStatement.StepValue); + dynamic endValue = Evaluate(statement.EndValue); + dynamic stepValue = Evaluate(statement.StepValue); _machine.ForChecks.Push(new ForCheckCondition { - Variable = forStatement.Variable, + Variable = statement.Variable, Start = (int)startValue, End = (int)endValue, Step = (int)stepValue, - Next = forStatement.Next + Next = statement.Next }); } - public void VisitGotoStatement(Goto gotoStatement) + public void VisitGotoStatement(Goto statement) { - Statement jumpToStatement = GetJumpToStatement(gotoStatement, gotoStatement.Location, "GOTO"); + Statement jumpToStatement = GetJumpToStatement(statement, statement.Location, "GOTO"); _machine.SetNextStatement(jumpToStatement); } @@ -621,22 +621,22 @@ private Statement GetJumpToStatement(Statement statement, Expression location, s return jumpToStatement; } - public void VisitGosubStatement(Gosub gosubStatement) + public void VisitGosubStatement(Gosub statement) { - if (gosubStatement.Next != null) - _machine.ProgramStack.Push(gosubStatement.Next); + if (statement.Next != null) + _machine.ProgramStack.Push(statement.Next); else _machine.ProgramStack.Push(CurrentStatement.Next); - Statement jumpToStatement = GetJumpToStatement(gosubStatement, gosubStatement.Location, "GOSUB"); + Statement jumpToStatement = GetJumpToStatement(statement, statement.Location, "GOSUB"); _machine.RunProgram(jumpToStatement, this); _machine.SetNextStatement(_machine.ProgramStack.Pop()); } - public void VisitIfStatement(If ifStatement) + public void VisitIfStatement(If statement) { - dynamic value = Evaluate(ifStatement.Condition); + dynamic value = Evaluate(statement.Condition); dynamic check; if (value is int intVal) @@ -646,7 +646,7 @@ public void VisitIfStatement(If ifStatement) if (!check) return; - switch (ifStatement.ThenStatement) + switch (statement.ThenStatement) { case Goto gotoStatement: VisitGotoStatement(gotoStatement); @@ -655,7 +655,7 @@ public void VisitIfStatement(If ifStatement) VisitGosubStatement(gosubStatement); break; default: - VisitThenStatement(ifStatement); + VisitThenStatement(statement); break; } } @@ -671,11 +671,11 @@ private void VisitThenStatement(If ifStatement) } } - public void VisitInputStatement(Input inputStatement) + public void VisitInputStatement(Input statement) { _sb = new StringBuilder(); - foreach (Expression expression in inputStatement.Expressions) - ProcessInputExpression(expression, inputStatement.WriteNewline); + foreach (Expression expression in statement.Expressions) + ProcessInputExpression(expression, statement.WriteNewline); } private void ProcessInputExpression(Expression expression, bool writeNewline) @@ -735,34 +735,34 @@ private Statement GetStatementByLineNumber(int lineNumber) return _machine.GetStatementByLineNumber(lineNumber); } - public void VisitLetStatement(Let root) + public void VisitLetStatement(Let statement) { dynamic value = null; - if (root.Initializer != null) - value = Evaluate(root.Initializer); + if (statement.Initializer != null) + value = Evaluate(statement.Initializer); - AssignVariable(root.Variable, value); + AssignVariable(statement.Variable, value); } - public void VisitNewStatement(New root) + public void VisitNewStatement(New statement) { NewProgram(); } - public void VisitClsStatement(Cls root) + public void VisitClsStatement(Cls statement) { _console.Clear(); Thread.Sleep(500); } - public void VisitContStatement(Cont root) + public void VisitContStatement(Cont statement) { RunProgram(_machine.GetNextStatement(), false); } - public void VisitDataStatement(Data data) + public void VisitDataStatement(Data statement) { - foreach (Expression element in data.DataElements) + foreach (Expression element in statement.DataElements) _machine.Data.Add(Evaluate(element)); } @@ -772,9 +772,9 @@ private void DeleteStatement(int lineNumber) if (programLine != null) _machine.Program.RemoveLine(programLine); } - public void VisitDeleteStatement(Delete root) + public void VisitDeleteStatement(Delete statement) { - DeleteStatement(root.LineToDelete); + DeleteStatement(statement.LineToDelete); } private void NewProgram() diff --git a/Trs80.Level1Basic.VirtualMachine/Parser/Expressions/IExpressionVisitor.cs b/Trs80.Level1Basic.VirtualMachine/Parser/Expressions/IExpressionVisitor.cs index c1dc56e..c3b6f39 100644 --- a/Trs80.Level1Basic.VirtualMachine/Parser/Expressions/IExpressionVisitor.cs +++ b/Trs80.Level1Basic.VirtualMachine/Parser/Expressions/IExpressionVisitor.cs @@ -7,12 +7,12 @@ namespace Trs80.Level1Basic.VirtualMachine.Parser.Expressions; public interface IExpressionVisitor { - dynamic VisitBasicArrayExpression(BasicArray root); - dynamic VisitAssignExpression(Assign root); - dynamic VisitBinaryExpression(Binary root); - dynamic VisitCallExpression(Call root); - dynamic VisitGroupingExpression(Grouping root); - dynamic VisitLiteralExpression(Literal root); - dynamic VisitUnaryExpression(Unary root); - dynamic VisitIdentifierExpression(Identifier root); + dynamic VisitBasicArrayExpression(BasicArray expression); + dynamic VisitAssignExpression(Assign expression); + dynamic VisitBinaryExpression(Binary expression); + dynamic VisitCallExpression(Call expression); + dynamic VisitGroupingExpression(Grouping expression); + dynamic VisitLiteralExpression(Literal expression); + dynamic VisitUnaryExpression(Unary expression); + dynamic VisitIdentifierExpression(Identifier expression); } diff --git a/Trs80.Level1Basic.VirtualMachine/Parser/Statements/IStatementVisitor.cs b/Trs80.Level1Basic.VirtualMachine/Parser/Statements/IStatementVisitor.cs index 4ddc6ff..85a55f5 100644 --- a/Trs80.Level1Basic.VirtualMachine/Parser/Statements/IStatementVisitor.cs +++ b/Trs80.Level1Basic.VirtualMachine/Parser/Statements/IStatementVisitor.cs @@ -7,31 +7,31 @@ namespace Trs80.Level1Basic.VirtualMachine.Parser.Statements; public interface IStatementVisitor { - void VisitClsStatement(Cls root); - void VisitContStatement(Cont root); - void VisitDataStatement(Data root); - void VisitDeleteStatement(Delete root); - void VisitEndStatement(End root); - void VisitForStatement(For root); - void VisitGotoStatement(Goto root); - void VisitGosubStatement(Gosub root); - void VisitIfStatement(If root); - void VisitInputStatement(Input root); - void VisitLetStatement(Let root); - void VisitListStatement(List root); - void VisitLoadStatement(Load root); - void VisitMergeStatement(Merge root); - void VisitNewStatement(New root); - void VisitNextStatement(Next root); - void VisitOnStatement(On root); - void VisitPrintStatement(Print root); - void VisitReplaceStatement(Replace root); - void VisitReadStatement(Read root); - void VisitRemStatement(Rem root); - void VisitRestoreStatement(Restore root); - void VisitReturnStatement(Return root); - void VisitRunStatement(Run root); - void VisitSaveStatement(Save root); - void VisitStatementExpressionStatement(StatementExpression root); - void VisitStopStatement(Stop root); + void VisitClsStatement(Cls statement); + void VisitContStatement(Cont statement); + void VisitDataStatement(Data statement); + void VisitDeleteStatement(Delete statement); + void VisitEndStatement(End statement); + void VisitForStatement(For statement); + void VisitGotoStatement(Goto statement); + void VisitGosubStatement(Gosub statement); + void VisitIfStatement(If statement); + void VisitInputStatement(Input statement); + void VisitLetStatement(Let statement); + void VisitListStatement(List statement); + void VisitLoadStatement(Load statement); + void VisitMergeStatement(Merge statement); + void VisitNewStatement(New statement); + void VisitNextStatement(Next statement); + void VisitOnStatement(On statement); + void VisitPrintStatement(Print statement); + void VisitReplaceStatement(Replace statement); + void VisitReadStatement(Read statement); + void VisitRemStatement(Rem statement); + void VisitRestoreStatement(Restore statement); + void VisitReturnStatement(Return statement); + void VisitRunStatement(Run statement); + void VisitSaveStatement(Save statement); + void VisitStatementExpressionStatement(StatementExpression statement); + void VisitStopStatement(Stop statement); } diff --git a/Trs80.Level1Basic.sln b/Trs80.Level1Basic.sln index a837ba2..59a5946 100644 --- a/Trs80.Level1Basic.sln +++ b/Trs80.Level1Basic.sln @@ -26,7 +26,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Application", "Application" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Workflow", "Workflow", "{527AA9D1-704A-4AA4-9012-8C47380E7B08}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "VirtualMachine", "VirtualMachine", "{EC14AF9B-5F4B-4EFC-AE2F-0F5EF3AD0F55}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Level I BASIC", "Level I BASIC", "{EC14AF9B-5F4B-4EFC-AE2F-0F5EF3AD0F55}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Trs80.Level1Basic.Console", "Trs80.Level1Basic.Console\Trs80.Level1Basic.Console.csproj", "{46D5282B-47E8-4597-90C9-C37443C4E34D}" EndProject @@ -48,6 +48,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Trs80.Level1Basic.TestUtili EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Trs80.Level1Basic.VirtualMachine", "Trs80.Level1Basic.VirtualMachine\Trs80.Level1Basic.VirtualMachine.csproj", "{827C9838-033A-4044-B091-E0C6FE509DDC}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Trs80.Level1Basic.Extensions.Test", "Trs80.Level1Basic.Extensions.Test\Trs80.Level1Basic.Extensions.Test.csproj", "{464C903C-6EE4-4629-9031-5D877E0B96E6}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -102,6 +104,10 @@ Global {827C9838-033A-4044-B091-E0C6FE509DDC}.Debug|Any CPU.Build.0 = Debug|Any CPU {827C9838-033A-4044-B091-E0C6FE509DDC}.Release|Any CPU.ActiveCfg = Release|Any CPU {827C9838-033A-4044-B091-E0C6FE509DDC}.Release|Any CPU.Build.0 = Release|Any CPU + {464C903C-6EE4-4629-9031-5D877E0B96E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {464C903C-6EE4-4629-9031-5D877E0B96E6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {464C903C-6EE4-4629-9031-5D877E0B96E6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {464C903C-6EE4-4629-9031-5D877E0B96E6}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -120,6 +126,7 @@ Global {CCDDE474-9B7C-4300-9962-9C56996F91B0} = {CD571827-E0DE-4EEA-BCCE-3475124C8BB2} {C0766798-3B89-476D-A53B-2B18ACA2529E} = {CD571827-E0DE-4EEA-BCCE-3475124C8BB2} {827C9838-033A-4044-B091-E0C6FE509DDC} = {EC14AF9B-5F4B-4EFC-AE2F-0F5EF3AD0F55} + {464C903C-6EE4-4629-9031-5D877E0B96E6} = {CD571827-E0DE-4EEA-BCCE-3475124C8BB2} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {5EB0E852-7B78-46A4-934D-25D7E53322B7}