fix formatting everywhere and make operation resolving faster
This commit is contained in:
parent
fad93a7973
commit
a39096014c
|
|
@ -121,16 +121,14 @@ do {
|
||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
runner.Run(stream);
|
runner.Run(stream);
|
||||||
stream.Dispose();
|
stream.Dispose();
|
||||||
}
|
} catch (QampException e) {
|
||||||
catch (QampException e) {
|
|
||||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||||
Console.WriteLine($" !> {e.Message}");
|
Console.WriteLine($" !> {e.Message}");
|
||||||
if (e.StackTrace != null) {
|
if (e.StackTrace != null) {
|
||||||
Console.Write($" ! ");
|
Console.Write($" ! ");
|
||||||
Console.WriteLine(string.Join("\n ! ", e.StackTrace.Split('\n')));
|
Console.WriteLine(string.Join("\n ! ", e.StackTrace.Split('\n')));
|
||||||
}
|
}
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
Console.ForegroundColor = ConsoleColor.DarkRed;
|
Console.ForegroundColor = ConsoleColor.DarkRed;
|
||||||
Console.WriteLine($" !? {e.Message}");
|
Console.WriteLine($" !? {e.Message}");
|
||||||
if (e.StackTrace != null) {
|
if (e.StackTrace != null) {
|
||||||
|
|
@ -138,7 +136,7 @@ do {
|
||||||
Console.WriteLine(string.Join("\n ! ", e.StackTrace.Split('\n')));
|
Console.WriteLine(string.Join("\n ! ", e.StackTrace.Split('\n')));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while(code != ConsoleCode.Exit);
|
} while (code != ConsoleCode.Exit);
|
||||||
|
|
||||||
public class Command
|
public class Command
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -31,8 +31,7 @@ public static class Benchmark
|
||||||
|
|
||||||
string key = MakeKey(id, member, file);
|
string key = MakeKey(id, member, file);
|
||||||
|
|
||||||
if (!_clocks.TryGetValue(key, out Stopwatch? sw))
|
if (!_clocks.TryGetValue(key, out Stopwatch? sw)) {
|
||||||
{
|
|
||||||
sw = _clocks[key] = new Stopwatch();
|
sw = _clocks[key] = new Stopwatch();
|
||||||
Console.WriteLine($" ::: Registered new benchmark clock '{key}'");
|
Console.WriteLine($" ::: Registered new benchmark clock '{key}'");
|
||||||
}
|
}
|
||||||
|
|
@ -60,8 +59,7 @@ public static class Benchmark
|
||||||
|
|
||||||
string key = MakeKey(id, member, file);
|
string key = MakeKey(id, member, file);
|
||||||
|
|
||||||
if (!_clocks.TryGetValue(key, out Stopwatch sw))
|
if (!_clocks.TryGetValue(key, out Stopwatch sw)) {
|
||||||
{
|
|
||||||
#if LOG
|
#if LOG
|
||||||
_logger.Debug($"No clock found for '{key}', start one first using Benchmark.Start()");
|
_logger.Debug($"No clock found for '{key}', start one first using Benchmark.Start()");
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,7 @@ public class SegmentBuilder() : IBuilder<Segment>, IDebug<string>
|
||||||
public string Debug(DebugLevel level = DebugLevel.None)
|
public string Debug(DebugLevel level = DebugLevel.None)
|
||||||
{
|
{
|
||||||
string str = Debugger.GetContextString(this);
|
string str = Debugger.GetContextString(this);
|
||||||
for (int i = 0; i < Instructions.Count; i++)
|
for (int i = 0; i < Instructions.Count; i++) {
|
||||||
{
|
|
||||||
var instruction = Instructions[i];
|
var instruction = Instructions[i];
|
||||||
/*if ((instruction.Code & 0x80) == 1) {
|
/*if ((instruction.Code & 0x80) == 1) {
|
||||||
// dynamic
|
// dynamic
|
||||||
|
|
|
||||||
|
|
@ -129,10 +129,14 @@ public class Digester : ISteppable<Token>
|
||||||
#if LOG
|
#if LOG
|
||||||
_logger.Method();
|
_logger.Method();
|
||||||
#endif
|
#endif
|
||||||
if (Match(T.Class)) DeclareClass();
|
if (Match(T.Class))
|
||||||
else if (Match(T.Function)) DeclareFunction();
|
DeclareClass();
|
||||||
else if (Match(T.Var)) DeclareVariable();
|
else if (Match(T.Function))
|
||||||
else Statement();
|
DeclareFunction();
|
||||||
|
else if (Match(T.Var))
|
||||||
|
DeclareVariable();
|
||||||
|
else
|
||||||
|
Statement();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Statement()
|
internal void Statement()
|
||||||
|
|
@ -140,21 +144,36 @@ public class Digester : ISteppable<Token>
|
||||||
#if LOG
|
#if LOG
|
||||||
_logger.Method();
|
_logger.Method();
|
||||||
#endif
|
#endif
|
||||||
if (Match(T.If)) If();
|
if (Match(T.If))
|
||||||
else if (Match(T.Else)) Else();
|
If();
|
||||||
else if (Match(T.While)) While();
|
else if (Match(T.Else))
|
||||||
else if (Match(T.Do)) Do();
|
Else();
|
||||||
else if (Match(T.For)) For();
|
else if (Match(T.While))
|
||||||
else if (Match(T.Return)) Return();
|
While();
|
||||||
else if (Match(T.TypeOf)) TypeOf();
|
else if (Match(T.Do))
|
||||||
else if (Match(T.Print)) Print();
|
Do();
|
||||||
else if (Match(T.PrintStack)) PrintStack();
|
else if (Match(T.For))
|
||||||
else if (Match(T.PrintGlobals)) PrintGlobals();
|
For();
|
||||||
else if (Match(T.PrintExpr)) PrintExpr();
|
else if (Match(T.Return))
|
||||||
else if (Match(T.Export)) Export();
|
Return();
|
||||||
else if (Match(T.Import)) Import();
|
else if (Match(T.TypeOf))
|
||||||
else if (Match(T.ContextOpen)) Context();
|
TypeOf();
|
||||||
else Expression();
|
else if (Match(T.Print))
|
||||||
|
Print();
|
||||||
|
else if (Match(T.PrintStack))
|
||||||
|
PrintStack();
|
||||||
|
else if (Match(T.PrintGlobals))
|
||||||
|
PrintGlobals();
|
||||||
|
else if (Match(T.PrintExpr))
|
||||||
|
PrintExpr();
|
||||||
|
else if (Match(T.Export))
|
||||||
|
Export();
|
||||||
|
else if (Match(T.Import))
|
||||||
|
Import();
|
||||||
|
else if (Match(T.ContextOpen))
|
||||||
|
Context();
|
||||||
|
else
|
||||||
|
Expression();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Expression()
|
internal void Expression()
|
||||||
|
|
@ -240,8 +259,7 @@ public class Digester : ISteppable<Token>
|
||||||
IsDerived = false
|
IsDerived = false
|
||||||
};
|
};
|
||||||
|
|
||||||
if (Match(T.Colon))
|
if (Match(T.Colon)) {
|
||||||
{
|
|
||||||
Consume(T.Identifier, "Expected base class name.", false);
|
Consume(T.Identifier, "Expected base class name.", false);
|
||||||
ExpressionParser.Variable(this, false);
|
ExpressionParser.Variable(this, false);
|
||||||
if (name == Previous.Value!)
|
if (name == Previous.Value!)
|
||||||
|
|
@ -718,8 +736,7 @@ public class Digester : ISteppable<Token>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal void Patch(byte[] bytes, long position)
|
internal void Patch(byte[] bytes, long position)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < bytes.Length; i++)
|
for (int i = 0; i < bytes.Length; i++) {
|
||||||
{
|
|
||||||
Function.Segment.Instructions[position + i] = bytes[i];
|
Function.Segment.Instructions[position + i] = bytes[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -856,7 +873,7 @@ public class Digester : ISteppable<Token>
|
||||||
|
|
||||||
private void ReportError(Token token, string errorMessage)
|
private void ReportError(Token token, string errorMessage)
|
||||||
{
|
{
|
||||||
#if LOG
|
#if LOG
|
||||||
_logger.Method();
|
_logger.Method();
|
||||||
#endif
|
#endif
|
||||||
ErrorPosition = token.Position;
|
ErrorPosition = token.Position;
|
||||||
|
|
|
||||||
|
|
@ -28,25 +28,62 @@ public static class ExpressionParser
|
||||||
digester.WeightedDigest(rule.Weight + 1);
|
digester.WeightedDigest(rule.Weight + 1);
|
||||||
|
|
||||||
switch (operatorType) {
|
switch (operatorType) {
|
||||||
case TokenType.BangEqual: digester.Emit(OpCode.Equal, OpCode.Not); break;
|
case TokenType.BangEqual:
|
||||||
case TokenType.EqualEqual: digester.Emit(OpCode.Equal); break;
|
digester.Emit(OpCode.Equal, OpCode.Not);
|
||||||
case TokenType.Greater: digester.Emit(OpCode.Greater); break;
|
break;
|
||||||
case TokenType.GreaterEqual: digester.Emit(OpCode.Less, OpCode.Not); break;
|
case TokenType.EqualEqual:
|
||||||
case TokenType.Less: digester.Emit(OpCode.Less); break;
|
digester.Emit(OpCode.Equal);
|
||||||
case TokenType.LessEqual: digester.Emit(OpCode.Greater, OpCode.Not); break;
|
break;
|
||||||
case TokenType.Plus: digester.Emit(OpCode.Add); break;
|
case TokenType.Greater:
|
||||||
case TokenType.Minus: digester.Emit(OpCode.Subtract); break;
|
digester.Emit(OpCode.Greater);
|
||||||
case TokenType.Star: digester.Emit(OpCode.Multiply); break;
|
break;
|
||||||
case TokenType.Slash: digester.Emit(OpCode.Divide); break;
|
case TokenType.GreaterEqual:
|
||||||
case TokenType.BitwiseAnd: digester.Emit(OpCode.BitwiseAnd); break;
|
digester.Emit(OpCode.Less, OpCode.Not);
|
||||||
case TokenType.BitwiseOr: digester.Emit(OpCode.BitwiseOr); break;
|
break;
|
||||||
case TokenType.BitwiseXor: digester.Emit(OpCode.BitwiseXor); break;
|
case TokenType.Less:
|
||||||
case TokenType.BitwiseNot: digester.Emit(OpCode.BitwiseNot); break;
|
digester.Emit(OpCode.Less);
|
||||||
case TokenType.BitwiseLeft: digester.Emit(OpCode.BitwiseLeft); break;
|
break;
|
||||||
case TokenType.BitwiseRight: digester.Emit(OpCode.BitwiseRight); break;
|
case TokenType.LessEqual:
|
||||||
case TokenType.Increment: digester.Emit(OpCode.Increment); break;
|
digester.Emit(OpCode.Greater, OpCode.Not);
|
||||||
case TokenType.Decrement: digester.Emit(OpCode.Decrement); break;
|
break;
|
||||||
default: return;
|
case TokenType.Plus:
|
||||||
|
digester.Emit(OpCode.Add);
|
||||||
|
break;
|
||||||
|
case TokenType.Minus:
|
||||||
|
digester.Emit(OpCode.Subtract);
|
||||||
|
break;
|
||||||
|
case TokenType.Star:
|
||||||
|
digester.Emit(OpCode.Multiply);
|
||||||
|
break;
|
||||||
|
case TokenType.Slash:
|
||||||
|
digester.Emit(OpCode.Divide);
|
||||||
|
break;
|
||||||
|
case TokenType.BitwiseAnd:
|
||||||
|
digester.Emit(OpCode.BitwiseAnd);
|
||||||
|
break;
|
||||||
|
case TokenType.BitwiseOr:
|
||||||
|
digester.Emit(OpCode.BitwiseOr);
|
||||||
|
break;
|
||||||
|
case TokenType.BitwiseXor:
|
||||||
|
digester.Emit(OpCode.BitwiseXor);
|
||||||
|
break;
|
||||||
|
case TokenType.BitwiseNot:
|
||||||
|
digester.Emit(OpCode.BitwiseNot);
|
||||||
|
break;
|
||||||
|
case TokenType.BitwiseLeft:
|
||||||
|
digester.Emit(OpCode.BitwiseLeft);
|
||||||
|
break;
|
||||||
|
case TokenType.BitwiseRight:
|
||||||
|
digester.Emit(OpCode.BitwiseRight);
|
||||||
|
break;
|
||||||
|
case TokenType.Increment:
|
||||||
|
digester.Emit(OpCode.Increment);
|
||||||
|
break;
|
||||||
|
case TokenType.Decrement:
|
||||||
|
digester.Emit(OpCode.Decrement);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -203,14 +240,12 @@ public static class ExpressionParser
|
||||||
digester.ErrorAtPrevious("We're currently not in a class. 'base' only works inside of a class context.");
|
digester.ErrorAtPrevious("We're currently not in a class. 'base' only works inside of a class context.");
|
||||||
else if (digester.ClassBuilder.Outer == null)
|
else if (digester.ClassBuilder.Outer == null)
|
||||||
digester.ErrorAtPrevious($"{digester.ClassBuilder.Name} is not inherited from any class, so the 'base' keyword points to nothing.");
|
digester.ErrorAtPrevious($"{digester.ClassBuilder.Name} is not inherited from any class, so the 'base' keyword points to nothing.");
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
digester.Consume(TokenType.Dot, "Expected '.' after 'base' keyword.");
|
digester.Consume(TokenType.Dot, "Expected '.' after 'base' keyword.");
|
||||||
digester.Consume(TokenType.Identifier, "Expected an identifier after 'base' keyword.");
|
digester.Consume(TokenType.Identifier, "Expected an identifier after 'base' keyword.");
|
||||||
long name = digester.IdentifierConstant(digester.Previous.Value);
|
long name = digester.IdentifierConstant(digester.Previous.Value);
|
||||||
Variable(digester, "this", false);
|
Variable(digester, "this", false);
|
||||||
if (digester.Match(TokenType.GroupOpen))
|
if (digester.Match(TokenType.GroupOpen)) {
|
||||||
{
|
|
||||||
byte arguments = digester.Arguments();
|
byte arguments = digester.Arguments();
|
||||||
Variable(digester, "base", false);
|
Variable(digester, "base", false);
|
||||||
digester.Emit(OpCode.InvokeBase);
|
digester.Emit(OpCode.InvokeBase);
|
||||||
|
|
@ -235,9 +270,15 @@ public static class ExpressionParser
|
||||||
Token token = digester.Previous;
|
Token token = digester.Previous;
|
||||||
digester.WeightedDigest(Weight.Modifier);
|
digester.WeightedDigest(Weight.Modifier);
|
||||||
switch (token.Type) {
|
switch (token.Type) {
|
||||||
case TokenType.Bang: digester.Emit(OpCode.Not); break;
|
case TokenType.Bang:
|
||||||
case TokenType.Minus: digester.Emit(OpCode.Negate); break;
|
digester.Emit(OpCode.Not);
|
||||||
case TokenType.BitwiseNot: digester.Emit(OpCode.BitwiseNot); break;
|
break;
|
||||||
|
case TokenType.Minus:
|
||||||
|
digester.Emit(OpCode.Negate);
|
||||||
|
break;
|
||||||
|
case TokenType.BitwiseNot:
|
||||||
|
digester.Emit(OpCode.BitwiseNot);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ public class Runner : IDisposable
|
||||||
#if LOG
|
#if LOG
|
||||||
_logger.Warn($"Something went wrong, stack cursor is at {Stack.Position}. Resetting Stack.");
|
_logger.Warn($"Something went wrong, stack cursor is at {Stack.Position}. Resetting Stack.");
|
||||||
#endif
|
#endif
|
||||||
Stack.Decimate(0);
|
Stack = new StackLike<Value>(Options.InitialStackSize);
|
||||||
}
|
}
|
||||||
using Reader reader = new Reader(stream);
|
using Reader reader = new Reader(stream);
|
||||||
Compilation.Digester digester = new(reader);
|
Compilation.Digester digester = new(reader);
|
||||||
|
|
@ -99,11 +99,21 @@ public class Runner : IDisposable
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (opCode) {
|
switch (opCode) {
|
||||||
case Op.Null: Push(Value.Void); break;
|
case Op.Null:
|
||||||
case Op.Constant: Push(call.Instruction.NextConstant()); break;
|
Push(Value.Void);
|
||||||
case Op.Pop: Pop(); break;
|
break;
|
||||||
case Op.True: Push(Value.True); break;
|
case Op.Constant:
|
||||||
case Op.False: Push(Value.False); break;
|
Push(call.Instruction.NextConstant());
|
||||||
|
break;
|
||||||
|
case Op.Pop:
|
||||||
|
Pop();
|
||||||
|
break;
|
||||||
|
case Op.True:
|
||||||
|
Push(Value.True);
|
||||||
|
break;
|
||||||
|
case Op.False:
|
||||||
|
Push(Value.False);
|
||||||
|
break;
|
||||||
|
|
||||||
case Op.GetGlobal: {
|
case Op.GetGlobal: {
|
||||||
string? name = call.Instruction.GetStringConstant(call.Instruction.NextDynamic())?.Value;
|
string? name = call.Instruction.GetStringConstant(call.Instruction.NextDynamic())?.Value;
|
||||||
|
|
@ -421,7 +431,7 @@ public class Runner : IDisposable
|
||||||
private Outer CaptureOuter(Pointer<Value> target)
|
private Outer CaptureOuter(Pointer<Value> target)
|
||||||
{
|
{
|
||||||
Outer? outer = null;
|
Outer? outer = null;
|
||||||
for (int i = Outers.Count; i-->0;) {
|
for (int i = Outers.Count; i-- > 0;) {
|
||||||
outer = Outers[i];
|
outer = Outers[i];
|
||||||
if (outer.Target.Cursor <= target.Cursor)
|
if (outer.Target.Cursor <= target.Cursor)
|
||||||
break;
|
break;
|
||||||
|
|
@ -435,7 +445,7 @@ public class Runner : IDisposable
|
||||||
|
|
||||||
private void CloseOuters(Pointer<Value> last)
|
private void CloseOuters(Pointer<Value> last)
|
||||||
{
|
{
|
||||||
for (int i = Outers.Count;i-->0;) {
|
for (int i = Outers.Count; i-- > 0;) {
|
||||||
Outer outer = Outers[i];
|
Outer outer = Outers[i];
|
||||||
if (outer.IsClosed)
|
if (outer.IsClosed)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ public static class ValueOperation
|
||||||
#if LOG
|
#if LOG
|
||||||
_logger.Method($"{operation.Left} {operation.OpCode} {operation.Right}");
|
_logger.Method($"{operation.Left} {operation.OpCode} {operation.Right}");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// p sure switch is faster here (as opposed to dict lookup)
|
// p sure switch is faster here (as opposed to dict lookup)
|
||||||
return operation.OpCode switch {
|
return operation.OpCode switch {
|
||||||
OpCode.Equal => Equal(operation),
|
OpCode.Equal => Equal(operation),
|
||||||
|
|
@ -94,9 +93,6 @@ public static class ValueOperation
|
||||||
public static Value Not(Operation operation)
|
public static Value Not(Operation operation)
|
||||||
{
|
{
|
||||||
Value value = operation.Left;
|
Value value = operation.Left;
|
||||||
#if LOG
|
|
||||||
_logger.Method($"{value}");
|
|
||||||
#endif
|
|
||||||
Assert.NotVoid(value);
|
Assert.NotVoid(value);
|
||||||
ulong inner = value.Unsigned;
|
ulong inner = value.Unsigned;
|
||||||
return new Value(inner == 0);
|
return new Value(inner == 0);
|
||||||
|
|
|
||||||
|
|
@ -111,8 +111,7 @@ public class Logger : ILogger, ILogFormatter
|
||||||
result.Add("null");
|
result.Add("null");
|
||||||
else if (value is string str)
|
else if (value is string str)
|
||||||
result.AddRange(str.Split('\n'));
|
result.AddRange(str.Split('\n'));
|
||||||
else if (value is Exception e)
|
else if (value is Exception e) {
|
||||||
{
|
|
||||||
result.Add(e.Message);
|
result.Add(e.Message);
|
||||||
if (!string.IsNullOrEmpty(e.StackTrace))
|
if (!string.IsNullOrEmpty(e.StackTrace))
|
||||||
result.AddRange(e.StackTrace.Split('\n'));
|
result.AddRange(e.StackTrace.Split('\n'));
|
||||||
|
|
@ -129,8 +128,7 @@ public class Logger : ILogger, ILogFormatter
|
||||||
|
|
||||||
var header = headers[level];
|
var header = headers[level];
|
||||||
Console.ForegroundColor = colors[level];
|
Console.ForegroundColor = colors[level];
|
||||||
foreach (var value in values)
|
foreach (var value in values) {
|
||||||
{
|
|
||||||
var lines = Format(value);
|
var lines = Format(value);
|
||||||
for (int i = 0; i < lines.Length; i++)
|
for (int i = 0; i < lines.Length; i++)
|
||||||
Console.WriteLine($"{(i == 0 ? header.First : header.Extra)}{lines[i]}");
|
Console.WriteLine($"{(i == 0 ? header.First : header.Extra)}{lines[i]}");
|
||||||
|
|
@ -151,13 +149,12 @@ public class Logger : ILogger, ILogFormatter
|
||||||
if (Level < LogLevel.Trace)
|
if (Level < LogLevel.Trace)
|
||||||
return; // save some ticks here
|
return; // save some ticks here
|
||||||
|
|
||||||
if (caller == null)
|
if (caller == null) {
|
||||||
{
|
|
||||||
var st = new StackTrace();
|
var st = new StackTrace();
|
||||||
var previous = st.GetFrame(1)?.GetMethod();
|
var previous = st.GetFrame(1)?.GetMethod();
|
||||||
if (previous != null)
|
if (previous != null)
|
||||||
caller = $"{previous.DeclaringType?.Name}.{previous.Name}";
|
caller = $"{previous.DeclaringType?.Name}.{previous.Name}";
|
||||||
}
|
}
|
||||||
Log(LogLevel.Trace, [ $"[{caller}] {value}" ]);
|
Log(LogLevel.Trace, [$"[{caller}] {value}"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,7 @@ public class Tokens : IDebug<string>
|
||||||
public string Debug(DebugLevel level = DebugLevel.None)
|
public string Debug(DebugLevel level = DebugLevel.None)
|
||||||
{
|
{
|
||||||
string str = Debugger.GetContextString(this);
|
string str = Debugger.GetContextString(this);
|
||||||
foreach (var token in _tokens)
|
foreach (var token in _tokens) {
|
||||||
{
|
|
||||||
str += $"\n {token}";
|
str += $"\n {token}";
|
||||||
}
|
}
|
||||||
return str;
|
return str;
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ public class NativeExtension(
|
||||||
static NativeExtension()
|
static NativeExtension()
|
||||||
{
|
{
|
||||||
Register(ValueType.String, "Length", (v, p) => new Value((long)v.Ptr.As<Objects.String>()!.Value!.Length), []);
|
Register(ValueType.String, "Length", (v, p) => new Value((long)v.Ptr.As<Objects.String>()!.Value!.Length), []);
|
||||||
Register(ValueType.String, "IndexOf", (v, p) => new Value((long)v.Ptr.As<Objects.String>()!.Value!.IndexOf(p[0].Ptr.As<Objects.String>()!.Value!)), [ "needle" ]);
|
Register(ValueType.String, "IndexOf", (v, p) => new Value((long)v.Ptr.As<Objects.String>()!.Value!.IndexOf(p[0].Ptr.As<Objects.String>()!.Value!)), ["needle"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,7 @@ public class Outer(Pointer<Value> target) : Obj(T.Outer)
|
||||||
/// Dynamic getter & setter that returns or writes to either the target value directly,
|
/// Dynamic getter & setter that returns or writes to either the target value directly,
|
||||||
/// or the stored value if this <see cref="Outer"/> has been closed.
|
/// or the stored value if this <see cref="Outer"/> has been closed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Value Value
|
public Value Value {
|
||||||
{
|
|
||||||
get => IsClosed ? _stored : Target!.Get();
|
get => IsClosed ? _stored : Target!.Get();
|
||||||
set {
|
set {
|
||||||
if (IsClosed)
|
if (IsClosed)
|
||||||
|
|
|
||||||
|
|
@ -143,8 +143,7 @@ public partial class EditorFrame : UserControl
|
||||||
AutoScroll(offset);
|
AutoScroll(offset);
|
||||||
else
|
else
|
||||||
HideCaret();
|
HideCaret();
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
MoveCaret(position);
|
MoveCaret(position);
|
||||||
|
|
||||||
if (!CurrentSelection.IsVoid) {
|
if (!CurrentSelection.IsVoid) {
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,13 @@ public struct BufferRegion(BufferPosition from, BufferPosition to)
|
||||||
|
|
||||||
public bool IsVoid => (From - To).IsInitial;
|
public bool IsVoid => (From - To).IsInitial;
|
||||||
|
|
||||||
public BufferPosition From = from;
|
public readonly BufferPosition From = from;
|
||||||
public BufferPosition To = to;
|
public BufferPosition To = to;
|
||||||
|
|
||||||
|
public static BufferRegion operator +(BufferRegion left, BufferPosition right)
|
||||||
|
=> new(left.From, left.To + right);
|
||||||
|
|
||||||
|
public static BufferRegion operator -(BufferRegion left, BufferPosition right)
|
||||||
|
=> new(left.From, left.To - right);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -3,6 +3,7 @@ using Qrakhen.Qamp.Editor.Primitives;
|
||||||
using Qrakhen.Qamp.Memory;
|
using Qrakhen.Qamp.Memory;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
|
using System.IO;
|
||||||
using System.Windows.Documents;
|
using System.Windows.Documents;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
|
|
||||||
|
|
@ -16,6 +17,12 @@ public class SelectableLineBuffer(LineBuffer buffer)
|
||||||
|
|
||||||
public class EditorFrameViewModel : ObservableObject
|
public class EditorFrameViewModel : ObservableObject
|
||||||
{
|
{
|
||||||
|
private FileInfo _fileInfo;
|
||||||
|
public FileInfo FileInfo {
|
||||||
|
get => _fileInfo;
|
||||||
|
set => SetProperty(ref _fileInfo, value);
|
||||||
|
}
|
||||||
|
|
||||||
private BufferPosition _cursorPosition;
|
private BufferPosition _cursorPosition;
|
||||||
public BufferPosition CursorPosition {
|
public BufferPosition CursorPosition {
|
||||||
get => _cursorPosition;
|
get => _cursorPosition;
|
||||||
|
|
@ -56,8 +63,6 @@ public class EditorFrameViewModel : ObservableObject
|
||||||
ClipBoardCommand = new RelayCommand(() => { });
|
ClipBoardCommand = new RelayCommand(() => { });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void SetCursor(int line, int column) => SetCursor(new BufferPosition(line, column));
|
public void SetCursor(int line, int column) => SetCursor(new BufferPosition(line, column));
|
||||||
public void SetCursor(BufferPosition position)
|
public void SetCursor(BufferPosition position)
|
||||||
{
|
{
|
||||||
|
|
@ -111,6 +116,20 @@ public class EditorFrameViewModel : ObservableObject
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Select(BufferPosition relativePosition, bool jump = false)
|
||||||
|
{
|
||||||
|
if (CurrentSelection.IsVoid) {
|
||||||
|
CurrentSelection = new BufferRegion(CursorPosition, CursorPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrentSelection += relativePosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Deselect()
|
||||||
|
{
|
||||||
|
CurrentSelection = BufferRegion.Void;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
asdasdy
|
asdasdy
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue