diff --git a/src/Chip8.OctoAsm/Chip8.OctoAsm.csproj b/src/Chip8.OctoAsm/Chip8.OctoAsm.csproj new file mode 100644 index 0000000..1ded6a1 --- /dev/null +++ b/src/Chip8.OctoAsm/Chip8.OctoAsm.csproj @@ -0,0 +1,16 @@ + + + + net6.0 + disable + enable + Chip8.OctoAsm + Chip8.OctoAsm + 10 + + + + + + + diff --git a/src/Chip8.OctoAsm/OctoDiagnostic.cs b/src/Chip8.OctoAsm/OctoDiagnostic.cs new file mode 100644 index 0000000..9cc8951 --- /dev/null +++ b/src/Chip8.OctoAsm/OctoDiagnostic.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; + +namespace Chip8.OctoAsm; + +public enum OctoSeverity +{ + Error, + Warning, +} + +public readonly struct OctoDiagnostic +{ + public OctoDiagnostic(OctoSeverity severity, string message, SourcePosition position) + { + this.severity = severity; + this.message = message; + this.position = position; + } + + public OctoSeverity severity { get; } + public string message { get; } + public SourcePosition position { get; } + + public int line => position.line; + public int column => position.column; + + public override string ToString() => + severity.ToString().ToLowerInvariant() + " at " + position + ": " + message; +} + +public sealed class OctoCompileException : Exception +{ + public OctoCompileException(OctoDiagnostic diagnostic) + : this(new[] { diagnostic }) + { + } + + public OctoCompileException(IReadOnlyList diagnostics) + : base(describe(diagnostics)) + { + this.diagnostics = diagnostics; + } + + public IReadOnlyList diagnostics { get; } + + public OctoDiagnostic diagnostic => diagnostics[0]; + + static string describe(IReadOnlyList diagnostics) + { + if (diagnostics.Count == 1) + { + return diagnostics[0].ToString(); + } + return diagnostics.Count + " Octo compile errors; first: " + diagnostics[0]; + } +} diff --git a/src/Chip8.OctoAsm/OctoToken.cs b/src/Chip8.OctoAsm/OctoToken.cs new file mode 100644 index 0000000..990eb13 --- /dev/null +++ b/src/Chip8.OctoAsm/OctoToken.cs @@ -0,0 +1,51 @@ +namespace Chip8.OctoAsm; + +public enum OctoTokenKind +{ + Word, + Number, + OpenBrace, + CloseBrace, + OpenParen, + CloseParen, + EndOfFile, +} + +public readonly struct SourcePosition +{ + public SourcePosition(int line, int column) + { + this.line = line; + this.column = column; + } + + public int line { get; } + public int column { get; } + + public override string ToString() => "line " + line + ", col " + column; +} + +public readonly struct OctoToken +{ + public OctoToken(OctoTokenKind kind, string text, int value, SourcePosition position) + { + this.kind = kind; + this.text = text; + this.value = value; + this.position = position; + } + + public OctoTokenKind kind { get; } + public string text { get; } + public int value { get; } + public SourcePosition position { get; } + + public bool isWord(string word) => kind == OctoTokenKind.Word && text == word; + + public override string ToString() => kind switch + { + OctoTokenKind.EndOfFile => "", + OctoTokenKind.Number => "number(" + value + ")", + _ => "'" + text + "'", + }; +}