Skip to content

Commit

Permalink
SLEEP statement, LIST bug fix, and PLOT sample.
Browse files Browse the repository at this point in the history
  • Loading branch information
treytomes committed Dec 31, 2021
1 parent 7443109 commit 0a0db31
Show file tree
Hide file tree
Showing 15 changed files with 251 additions and 82 deletions.
34 changes: 20 additions & 14 deletions src/ECMABasic.Core/ComplexTokenReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@ namespace ECMABasic.Core
/// </remarks>
public class ComplexTokenReader
{
/// <summary>
/// The index into _tokens.
/// </summary>
private int _tokenIndex;
private readonly List<Token> _tokens;

private ComplexTokenReader(SimpleTokenReader reader)
Expand All @@ -33,7 +29,12 @@ private ComplexTokenReader(SimpleTokenReader reader)
reader.Dispose();
}

public bool IsAtEnd => _tokenIndex >= _tokens.Count;
/// <summary>
/// The index into _tokens.
/// </summary>
public int TokenIndex { get; private set; }

public bool IsAtEnd => TokenIndex >= _tokens.Count;

public static ComplexTokenReader FromFile(string filename)
{
Expand Down Expand Up @@ -158,7 +159,7 @@ public static ComplexTokenReader FromText(string text)
/// <exception cref="UnexpectedTokenException">Throws an exception if the token type doesn't match what was expected.</exception>
public Token Next(TokenType type, bool throwOnError = true, string pattern = null)
{
var startPosition = _tokenIndex;
var startPosition = TokenIndex;
var token = Next();
if ((token == null) || (token.Type != type) || ((pattern != null) && !Regex.IsMatch(token.Text, @"^" + pattern + @"$", RegexOptions.Singleline)))
{
Expand All @@ -168,7 +169,7 @@ public Token Next(TokenType type, bool throwOnError = true, string pattern = nul
}
else
{
_tokenIndex = startPosition;
TokenIndex = startPosition;
return null;
}
}
Expand Down Expand Up @@ -274,7 +275,7 @@ public Token Next()

private Token ReadRestOfString(Token start)
{
var startIndex = _tokenIndex;
var startIndex = TokenIndex;
List<Token> stringTokens = new() { start };

while (true)
Expand All @@ -283,7 +284,7 @@ private Token ReadRestOfString(Token start)
if ((token == null) || (token.Type == TokenType.EndOfLine))
{
// Rewind.
_tokenIndex = startIndex;
TokenIndex = startIndex;
return null;
}

Expand All @@ -307,8 +308,8 @@ private Token Read()
return null;
}

var token = _tokens[_tokenIndex];
_tokenIndex++;
var token = _tokens[TokenIndex];
TokenIndex++;
return token;
}

Expand All @@ -318,16 +319,21 @@ public Token Peek()
{
return null;
}
return _tokens[_tokenIndex];
return _tokens[TokenIndex];
}

public void Seek(int index)
{
TokenIndex = index;
}

public void Rewind()
{
if (_tokenIndex == 0)
if (TokenIndex == 0)
{
return;
}
_tokenIndex--;
TokenIndex--;
}
}
}
11 changes: 10 additions & 1 deletion src/ECMABasic.Core/EnvironmentBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,15 @@ public abstract class EnvironmentBase : IEnvironment

private readonly IBasicConfiguration _config;

public EnvironmentBase(IBasicConfiguration config = null)
public EnvironmentBase(Interpreter interpreter = null, IBasicConfiguration config = null)
{
Interpreter = interpreter ?? new Interpreter();
_config = config ?? MinimalBasicConfiguration.Instance;
Program = new Program();
}

public Interpreter Interpreter { get; }

/// <summary>
/// The line number currently being executed.
/// </summary>
Expand Down Expand Up @@ -114,5 +117,11 @@ public ICallStackContext PopCallStack()
}

public abstract void CheckForStopRequest();

public bool LoadFile(string filename)
{
Program.Clear();
return Interpreter.InterpretProgramFromFile(this, filename);
}
}
}
11 changes: 11 additions & 0 deletions src/ECMABasic.Core/IEnvironment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
/// </summary>
public interface IEnvironment : IErrorReporter
{
/// <summary>
/// The active interpreter.
/// </summary>
public Interpreter Interpreter { get; }

/// <summary>
/// The full program, ready to execute.
/// </summary>
Expand Down Expand Up @@ -95,5 +100,11 @@ public interface IEnvironment : IErrorReporter
/// Used by the Program evaluator to see if a stop has been requested.
/// </summary>
public void CheckForStopRequest();

/// <summary>
/// Load and interpret a file.
/// </summary>
/// <param name="filename">The file to load.</param>
public bool LoadFile(string filename);
}
}
35 changes: 21 additions & 14 deletions src/ECMABasic.Core/Interpreter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,9 @@ public class Interpreter

protected ComplexTokenReader _reader;
private readonly IBasicConfiguration _config;
protected readonly IEnvironment _env;

public Interpreter(IEnvironment env, IBasicConfiguration config = null)
public Interpreter(IBasicConfiguration config = null)
{
_env = env;
_config = config ?? MinimalBasicConfiguration.Instance;

_lineStatements = new List<StatementParser>()
Expand Down Expand Up @@ -49,8 +47,8 @@ public Interpreter(IEnvironment env, IBasicConfiguration config = null)
/// <returns>Was the input interpreted successfully?</returns>
public static bool FromText(string text, IEnvironment env, IBasicConfiguration config = null)
{
var interpreter = new Interpreter(env, config);
return interpreter.InterpretProgramFromText(text);
var interpreter = new Interpreter(config);
return interpreter.InterpretProgramFromText(env, text);
}

/// <summary>
Expand All @@ -61,8 +59,17 @@ public static bool FromText(string text, IEnvironment env, IBasicConfiguration c
/// <returns>Was the input interpreted successfully?</returns>
public static bool FromFile(string path, IEnvironment env, IBasicConfiguration config = null)
{
var interpreter = new Interpreter(env, config);
return interpreter.InterpretProgramFromFile(path);
var interpreter = new Interpreter(config);
return interpreter.InterpretProgramFromFile(env, path);
}

/// <summary>
/// Allow interpretation of additional statements.
/// </summary>
/// <param name="additionalStatements">The statements to add to the interpreter.</param>
public void InjectStatements(IEnumerable<StatementParser> additionalStatements)
{
_lineStatements.AddRange(additionalStatements);
}

/// <summary>
Expand All @@ -71,10 +78,10 @@ public static bool FromFile(string path, IEnvironment env, IBasicConfiguration c
/// <param name="path">The path to the file to interpret.</param>
/// <param name="reporter">A receiver for error messages.</param>
/// <returns>Was the input interpreted successfully?</returns>
public bool InterpretProgramFromFile(string path)
public bool InterpretProgramFromFile(IEnvironment env, string path)
{
_reader = ComplexTokenReader.FromFile(path);
return InterpretProgram();
return InterpretProgram(env);
}

/// <summary>
Expand All @@ -83,13 +90,13 @@ public bool InterpretProgramFromFile(string path)
/// <param name="text">The text to interpret.</param>
/// <param name="reporter">A receiver for error messages.</param>
/// <returns>Was the input interpreted successfully?</returns>
public bool InterpretProgramFromText(string text)
public bool InterpretProgramFromText(IEnvironment env, string text)
{
_reader = ComplexTokenReader.FromText(text);
return InterpretProgram();
return InterpretProgram(env);
}

private bool InterpretProgram()
private bool InterpretProgram(IEnvironment env)
{
try
{
Expand All @@ -102,7 +109,7 @@ private bool InterpretProgram()
}
else
{
_env.Program.Insert(line);
env.Program.Insert(line);
}
}

Expand All @@ -115,7 +122,7 @@ private bool InterpretProgram()
}
catch (SyntaxException e)
{
_env.ReportError(e.Message);
env.ReportError(e.Message);
return false;
}
}
Expand Down
18 changes: 18 additions & 0 deletions src/ECMABasic.Core/NumericExpressionParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ private IExpression ParseSums()
{
var space = _reader.Next(TokenType.Space, false);

var preSymbolIndex = _reader.TokenIndex;
var symbol = _reader.Next(TokenType.Symbol, false, @"\+|\-");
if (symbol == null)
{
Expand All @@ -143,6 +144,11 @@ private IExpression ParseSums()
_reader.Next(TokenType.Space, false);

var right = ParseProducts();
if (right == null)
{
_reader.Seek(preSymbolIndex);
return expr;
}

expr = symbol.Text switch
{
Expand All @@ -165,6 +171,7 @@ private IExpression ParseProducts()
{
var space = _reader.Next(TokenType.Space, false);

var preSymbolIndex = _reader.TokenIndex;
var symbol = _reader.Next(TokenType.Symbol, false, @"\*|\/");
if (symbol == null)
{
Expand All @@ -178,6 +185,11 @@ private IExpression ParseProducts()
_reader.Next(TokenType.Space, false);

var right = ParseUnary();
if (right == null)
{
_reader.Seek(preSymbolIndex);
return expr;
}

expr = symbol.Text switch
{
Expand Down Expand Up @@ -220,6 +232,7 @@ private IExpression ParseInvolution()
{
var space = _reader.Next(TokenType.Space, false);

var preSymbolIndex = _reader.TokenIndex;
var symbol = _reader.Next(TokenType.Symbol, false, @"\^");
if (symbol == null)
{
Expand All @@ -233,6 +246,11 @@ private IExpression ParseInvolution()
_reader.Next(TokenType.Space, false);

var right = ParseAtomic(true);
if (right == null)
{
_reader.Seek(preSymbolIndex);
return expr;
}

expr = new InvolutionExpression(expr, right);
}
Expand Down
9 changes: 2 additions & 7 deletions src/ECMABasic.Core/Parsers/PrintStatementParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,18 +76,13 @@ private static IPrintItemSeparator ProcessPrintSeparator(ComplexTokenReader read

private static IPrintItem ProcessPrintItem(ComplexTokenReader reader, int? lineNumber = null)
{
//if (lineNumber == 680)
//{
// var a = 0;
//}

IPrintItem expr = ParseExpression(reader, lineNumber, false);
var expr = ProcessTabExpression(reader, lineNumber);
if (expr != null)
{
return expr;
}

expr = ProcessTabExpression(reader, lineNumber);
expr = ParseExpression(reader, lineNumber, false);
if (expr != null)
{
return expr;
Expand Down
9 changes: 7 additions & 2 deletions src/ECMABasic55/ConsoleEnvironment.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
using ECMABasic.Core;
using ECMABasic.Core.Configuration;
using ECMABasic.Core.Exceptions;
using ECMABasic.Core.Statements;
using System;

namespace ECMABasic55
{
class ConsoleEnvironment : EnvironmentBase
public class ConsoleEnvironment : EnvironmentBase
{
public ConsoleEnvironment(Interpreter interpreter = null, IBasicConfiguration config = null)
: base(interpreter, config)
{
}

public override int TerminalRow
{
get
Expand Down
8 changes: 8 additions & 0 deletions src/ECMABasic55/PLOT.BAS
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
10 LET P=3.14159265359
20 LET A=0
30 LET R=((COS(A*(P/180))+1)*16)+8
50 SLEEP 100
40 PRINT TAB(R);"*"
80 LET A=A+16
90 GOTO 30
100 END
Loading

0 comments on commit 0a0db31

Please sign in to comment.