diff --git a/Qrakhen.Qamp.Core/Benchmark.cs b/Qrakhen.Qamp.Core/Benchmark.cs index b7df3ed..10e4708 100644 --- a/Qrakhen.Qamp.Core/Benchmark.cs +++ b/Qrakhen.Qamp.Core/Benchmark.cs @@ -33,14 +33,14 @@ public static class Benchmark if (!_clocks.TryGetValue(key, out Stopwatch? sw)) { sw = _clocks[key] = new Stopwatch(); - Console.WriteLine($" ::: Registered new benchmark clock '{key}'"); + IO.Console.Write($" ::: Registered new benchmark clock '{key}'\n"); } if (!string.IsNullOrEmpty(message)) - Console.WriteLine($" ::: {key}:{line} > {message}"); + IO.Console.Write($" ::: {key}:{line} > {message}\n"); if (sw.IsRunning) - Console.WriteLine($" ::: {key}:{line} > already running with an elapsed time of {sw.Elapsed}. clock was reset."); + IO.Console.Write($" ::: {key}:{line} > already running with an elapsed time of {sw.Elapsed}. clock was reset.\n"); sw.Reset(); sw.Start(); diff --git a/Qrakhen.Qamp.Core/Console.cs b/Qrakhen.Qamp.Core/Console.cs index 0f4542b..46f90fa 100644 --- a/Qrakhen.Qamp.Core/Console.cs +++ b/Qrakhen.Qamp.Core/Console.cs @@ -2,11 +2,19 @@ public static class Console { + // TEMP + public static Action? StdOut; + // TEMP + public static void Write(object? any) { string[] split = $"{any ?? "null"}".Split('\n'); for (int i = 0; i < split.Length; i++) { - System.Console.Write((i == 0 ? " :> " : " ") + $"{split[i]}\n"); + string line = (i == 0 ? " :> " : " ") + $"{split[i]}\n"; + if (StdOut == null) + System.Console.Write(line); + else + StdOut(line); } } } \ No newline at end of file diff --git a/Qrakhen.Qamp.Core/Execution/Runner.cs b/Qrakhen.Qamp.Core/Execution/Runner.cs index d32cba7..a30f378 100644 --- a/Qrakhen.Qamp.Core/Execution/Runner.cs +++ b/Qrakhen.Qamp.Core/Execution/Runner.cs @@ -48,6 +48,7 @@ public class Runner : IDisposable Options = options; Calls = new StackLike(options.MaxCalls); Stack = new StackLike(options.InitialStackSize); + IO.Console.StdOut = options.StdOut; } public ExecutionResult Run(Stream stream) @@ -664,13 +665,17 @@ public enum ExecutionResult } public readonly struct Options( - int maxCalls = 0x100, - int stackSize = 0x200, - int initialStackSize = 0x80) + Action? stdOut = null, + Action? stdIn = null, + int maxCalls = 0x100, + int stackSize = 0x200, + int initialStackSize = 0x80) { + public readonly Action? StdOut = stdOut; + public readonly Action? StdIn = stdIn; public readonly int MaxCalls = maxCalls; public readonly int StackSize = stackSize; public readonly int InitialStackSize = initialStackSize; - public Options() : this(0x100, 0x200, 0x80) { } + public Options() : this(null, null, 0x100, 0x200, 0x80) { } } \ No newline at end of file diff --git a/Qrakhen.Qamp.Core/Logging/ILogger.cs b/Qrakhen.Qamp.Core/Logging/ILogger.cs index 0ef7295..19b8283 100644 --- a/Qrakhen.Qamp.Core/Logging/ILogger.cs +++ b/Qrakhen.Qamp.Core/Logging/ILogger.cs @@ -131,7 +131,7 @@ public class Logger : ILogger, ILogFormatter foreach (var value in values) { var lines = Format(value); for (int i = 0; i < lines.Length; i++) - Console.WriteLine($"{(i == 0 ? header.First : header.Extra)}{lines[i]}"); + IO.Console.Write($"{(i == 0 ? header.First : header.Extra)}{lines[i]}\n"); } Console.ForegroundColor = ConsoleColor.White; } diff --git a/Qrakhen.Qamp.Editor/Controls/LineRenderer.xaml.cs b/Qrakhen.Qamp.Editor/Controls/LineRenderer.xaml.cs index 9b3379d..f1af7cd 100644 --- a/Qrakhen.Qamp.Editor/Controls/LineRenderer.xaml.cs +++ b/Qrakhen.Qamp.Editor/Controls/LineRenderer.xaml.cs @@ -1,4 +1,5 @@ -using Qrakhen.Qamp.Memory; +using Qrakhen.Qamp.Editor.Primitives; +using Qrakhen.Qamp.Memory; using System; using System.ComponentModel; using System.Windows; @@ -38,11 +39,11 @@ public partial class LineRenderer : UserControl ); var x = Random.Shared.Next(0, LineBuffer.Tail); - var s = new BufferSpan(x, Random.Shared.Next(x, LineBuffer.Tail)); + var s = new BufferRegion(new BufferPosition(0, x), new BufferPosition(0, Random.Shared.Next(x, LineBuffer.Tail))); Selection = s; var highlighter = TextHelper.GetText( - new string(' ', Selection.Start) + new string('█', Selection.End - Selection.Start), + new string(' ', Selection.From.Column) + new string('█', Selection.To.Column - Selection.From.Column), FontSize, Highlighter, VisualTreeHelper.GetDpi(this).PixelsPerDip @@ -90,12 +91,12 @@ public partial class LineRenderer : UserControl public static readonly DependencyProperty SelectionProperty = DependencyProperty.Register( nameof(Selection), - typeof(BufferSpan), + typeof(BufferRegion), typeof(LineRenderer), - new FrameworkPropertyMetadata(BufferSpan.None, OnSelectionChanged)); + new FrameworkPropertyMetadata(BufferRegion.Void, OnSelectionChanged)); - public BufferSpan Selection { - get => (BufferSpan)GetValue(SelectionProperty); + public BufferRegion Selection { + get => (BufferRegion)GetValue(SelectionProperty); set => SetValue(SelectionProperty, value); } diff --git a/Qrakhen.Qamp.Editor/MainWindow.xaml b/Qrakhen.Qamp.Editor/MainWindow.xaml index 5802b54..518ee14 100644 --- a/Qrakhen.Qamp.Editor/MainWindow.xaml +++ b/Qrakhen.Qamp.Editor/MainWindow.xaml @@ -59,7 +59,7 @@ MinWidth="8" /> - + $ ... + Text="{Binding RunnerOutput}" + FontFamily="Consolas"> - + - + diff --git a/Qrakhen.Qamp.Editor/ViewModel/EditorFrameViewModel.cs b/Qrakhen.Qamp.Editor/ViewModel/EditorFrameViewModel.cs index 91b603b..81c5795 100644 --- a/Qrakhen.Qamp.Editor/ViewModel/EditorFrameViewModel.cs +++ b/Qrakhen.Qamp.Editor/ViewModel/EditorFrameViewModel.cs @@ -1,9 +1,11 @@ -using Qrakhen.Qamp.Editor.Commands; +using Microsoft.Win32; +using Qrakhen.Qamp.Editor.Commands; using Qrakhen.Qamp.Editor.Primitives; using Qrakhen.Qamp.Memory; using System; using System.Collections.ObjectModel; using System.IO; +using System.Text; using System.Windows.Documents; using System.Windows.Input; @@ -17,6 +19,12 @@ public class SelectableLineBuffer(LineBuffer buffer) public class EditorFrameViewModel : ObservableObject { + private Encoding _encoding; + public Encoding Encoding { + get => _encoding; + set => SetProperty(ref _encoding, value); + } + private FileInfo _fileInfo; public FileInfo FileInfo { get => _fileInfo; @@ -56,6 +64,8 @@ public class EditorFrameViewModel : ObservableObject public EditorFrameViewModel() { + Encoding = Encoding.ASCII; + MoveCaretCommand = new RelayCommand(ExecuteMoveCaret); MoveBlockCommand = new RelayCommand(ExecuteMoveBlock); InsertCommand = new RelayCommand(ExecuteInsert); @@ -202,4 +212,25 @@ public class EditorFrameViewModel : ObservableObject } #endregion + + public string Serialize(string? lineTerminator = null) + { + lineTerminator ??= Environment.NewLine; + string result = ""; + foreach (var line in Lines) { + result += $"{line.Buffer.ToString()}{lineTerminator}"; + } + return result; + } + + public void Deserialize(string source, Encoding? encoding = null, string? lineTerminator = null) + { + encoding ??= Encoding.ASCII; + lineTerminator ??= Environment.NewLine; + Lines.Clear(); + string[] lines = source.Split(lineTerminator); + foreach (var line in lines) { + Lines.Add(new SelectableLineBuffer(new LineBuffer(line, encoding))); + } + } } diff --git a/Qrakhen.Qamp.Editor/ViewModel/MainViewModel.cs b/Qrakhen.Qamp.Editor/ViewModel/MainViewModel.cs index 77c1cfb..5bb3c40 100644 --- a/Qrakhen.Qamp.Editor/ViewModel/MainViewModel.cs +++ b/Qrakhen.Qamp.Editor/ViewModel/MainViewModel.cs @@ -1,15 +1,24 @@ -using Qrakhen.Qamp.Editor.Commands; +using Qrakhen.Qamp.Core.Execution; +using Qrakhen.Qamp.Editor.Commands; using System; using System.Collections.Generic; +using System.IO; using System.Text; using System.Windows.Input; namespace Qrakhen.Qamp.Editor.ViewModel; -public class MainViewModel +public class MainViewModel : ObservableObject { public EditorFrameViewModel EditorFrame { get; set; } + private string _runnerOutput = ""; + public string RunnerOutput + { + get => _runnerOutput; + set => SetProperty(ref _runnerOutput, value); + } + public ICommand RunCommand { get; set; } public ICommand SaveCommand { get; set; } public ICommand LoadCommand { get; set; } @@ -25,7 +34,16 @@ public class MainViewModel private void ExecuteRun() { - + try { + string code = EditorFrame.Serialize(); + Runner runner = new Runner(new Options((m) => { RunnerOutput += m; })); + MemoryStream stream = new MemoryStream(); + stream.Write(EditorFrame.Encoding.GetBytes(code)); + runner.Run(stream); + OnPropertyChanged(nameof(RunnerOutput)); + } catch (Exception ex) { + RunnerOutput += $"\nERR: {ex.Message}\n"; + } } private bool CanRun()