diff --git a/Qrakhen.Qamp.Core/Compilation/ExpressionParser.cs b/Qrakhen.Qamp.Core/Compilation/ExpressionParser.cs index c984cb2..64c3547 100644 --- a/Qrakhen.Qamp.Core/Compilation/ExpressionParser.cs +++ b/Qrakhen.Qamp.Core/Compilation/ExpressionParser.cs @@ -299,6 +299,9 @@ public static class ExpressionParser case TokenType.BitwiseNot: digester.Emit(OpCode.BitwiseNot); break; + case TokenType.AddressOf: + digester.Emit(OpCode.Addr); + break; } } @@ -357,6 +360,7 @@ public static class ExpressionParser _rules[TokenType.Or] = new Rule(null, Or, Weight.Or); _rules[TokenType.Print] = new Rule(null, null, Weight.None); _rules[TokenType.TypeOf] = new Rule(TypeOf, null, Weight.None); + _rules[TokenType.AddressOf] = new Rule(Modifier, null, Weight.Term); _rules[TokenType.Export] = new Rule(null, null, Weight.None); _rules[TokenType.Import] = new Rule(null, null, Weight.None); _rules[TokenType.Return] = new Rule(null, null, Weight.None); diff --git a/Qrakhen.Qamp.Core/Execution/OpCode.cs b/Qrakhen.Qamp.Core/Execution/OpCode.cs index 6412fb6..811e764 100644 --- a/Qrakhen.Qamp.Core/Execution/OpCode.cs +++ b/Qrakhen.Qamp.Core/Execution/OpCode.cs @@ -15,6 +15,7 @@ public enum OpCode Val = 0x10, Ref = 0x11, + Addr = 0x12, SetGlobal = 0x20, GetGlobal = 0x21, diff --git a/Qrakhen.Qamp.Core/Execution/Runner.cs b/Qrakhen.Qamp.Core/Execution/Runner.cs index 69b8d91..5bc2d68 100644 --- a/Qrakhen.Qamp.Core/Execution/Runner.cs +++ b/Qrakhen.Qamp.Core/Execution/Runner.cs @@ -118,6 +118,14 @@ public class Runner : IDisposable Push(Value.False); break; + case Op.Addr: { + Value value = Pop(); + if (!value.IsObj) + return Error($"can not get address of a value on stack"); + Push(new Value(value.Ptr.Address)); + break; + } + case Op.GetGlobal: { string? name = call.Instruction.GetStringConstant(call.Instruction.NextDynamic())?.Value; if (string.IsNullOrEmpty(name)) diff --git a/Qrakhen.Qamp.Core/Tokenization/Reader.cs b/Qrakhen.Qamp.Core/Tokenization/Reader.cs index 8c2b99a..6c32a5e 100644 --- a/Qrakhen.Qamp.Core/Tokenization/Reader.cs +++ b/Qrakhen.Qamp.Core/Tokenization/Reader.cs @@ -285,7 +285,7 @@ public class Reader : IReader, IDisposable '&' => Check('&') ? MakeToken(And, buffer + Next()) : Check(':') ? - MakeToken(Address, buffer + Next()) : + MakeToken(AddressOf, buffer + Next()) : MakeToken(BitwiseAnd, buffer), '^' => Check('~') ? MakeToken(Base, buffer + Next()) : @@ -318,9 +318,9 @@ public class Reader : IReader, IDisposable MakeToken(Var, buffer + Next()) : MakeToken(Star, buffer), '=' => Check('=') ? - MakeToken(EqualEqual, buffer + Next()) : - MakeToken(Equal, buffer), - '<' => Peek(1) switch { + MakeToken(EqualEqual, buffer + Next()) : + MakeToken(Equal, buffer), + '<' => Peek(0) switch { '~' => MakeToken(Equal, buffer + Next()), ':' => MakeToken(Return, buffer + Next()), '+' => MakeToken(PlusEqual, buffer + Next()), diff --git a/Qrakhen.Qamp.Core/Tokenization/TokenType.cs b/Qrakhen.Qamp.Core/Tokenization/TokenType.cs index 7554e21..85d0937 100644 --- a/Qrakhen.Qamp.Core/Tokenization/TokenType.cs +++ b/Qrakhen.Qamp.Core/Tokenization/TokenType.cs @@ -47,7 +47,7 @@ public enum TokenType BitwiseNot = Operator | 9, BitwiseLeft = Operator | 10, BitwiseRight = Operator | 11, - Address = Operator | 12, // returns the address of a ptr/object as a value + AddressOf = Operator | 12, // returns the address of a ptr/object as a value Assignment = 1 << 9, Equal = Assignment | 1,