added some classic sqript spice, fixed a few bugs

This commit is contained in:
Qrakhen 2025-11-09 10:44:49 +01:00
parent 3013a338ed
commit 298a2ffa67
6 changed files with 75 additions and 57 deletions

View File

@ -30,7 +30,7 @@ public class ConsoleRenderer
if (token.Type.IsBoolean()) if (token.Type.IsBoolean())
color = ConsoleColor.Blue; color = ConsoleColor.Blue;
if (token.Type.IsString()) if (token.Type.IsString())
color = ConsoleColor.Magenta; color = ConsoleColor.Cyan;
if (token.Type.IsNumber()) if (token.Type.IsNumber())
color = ConsoleColor.DarkCyan; color = ConsoleColor.DarkCyan;
if (token.Type.IsOperator()) if (token.Type.IsOperator())

View File

@ -148,12 +148,17 @@ public class Digester : ISteppable<Token>
{ {
_logger.Method(); _logger.Method();
ParseExpression(); ParseExpression();
Consume(T.Semicolon, "Expected ';' after statement"); if (Builder.Type == FunctionType.Code && Check(T.Eof))
Emit(Op.Pop); // in an expression statement, we definitely do not want to remain the value on stack, Emit(Op.Print); // if we got presented with only an expression on top-level code and no ; at the end,
// as it would fuck over the entire stack for the rest of the execution. // we assume the user wants to see the value.
// not pushing it, e.g. with a flag to the Expression() call, would be a good todo idea. else {
// Consume(T.Semicolon, "Expected ';' after statement");
// a tad bit older me: it's a terrible idea as return a = b; wouldn't work anymore Emit(Op.Pop); // in an expression statement, we definitely do not want to remain the value on stack,
// as it would fuck over the entire stack for the rest of the execution.
// not pushing it, e.g. with a flag to the Expression() call, would be a good todo idea.
//
// a tad bit older me: it's a terrible idea as return a = b; wouldn't work anymore
}
} }
internal void ParseExpression() => WeightedDigest(Weight.Assign); internal void ParseExpression() => WeightedDigest(Weight.Assign);

View File

@ -1,26 +1,18 @@
namespace Qrakhen.Qamp.Core.Tokenization; namespace Qrakhen.Qamp.Core.Tokenization;
using Qrakhen.Qamp.Core.Collections;
using static TokenType; using static TokenType;
public class Dialect public class Dialect
{ {
private char[][] _sequences; // suuuper slow but meh, who cares
private Register<string, TokenType> _register = new();
public Dialect()
{
_sequences = new char[0x80][];
}
public void Define(TokenType type, string sequence) public void Define(TokenType type, string sequence)
=> Define(type, sequence.ToCharArray()); => _register[sequence] = type;
public void Define(TokenType type, char[] sequence) public TokenType Get(string sequence)
{ => _register[sequence];
_sequences[(int)type] = sequence;
}
public char[] Get(TokenType type)
=> _sequences[(int)type];
} }
public class DefaultDialect : Dialect public class DefaultDialect : Dialect
@ -88,7 +80,7 @@ public class DefaultDialect : Dialect
Define(Ref, "ref"); Define(Ref, "ref");
Define(Function, "function"); Define(Function, "function");
Define(Class, "class"); Define(Class, "class");
Define(Base, "base"); Define(Base, "base");
Define(TypeOf, "typeof"); Define(TypeOf, "typeof");
Define(Print, "print"); Define(Print, "print");
Define(Import, "import"); Define(Import, "import");

View File

@ -23,13 +23,16 @@ internal static partial class ReaderPatterns
Keywords["false"] = False; Keywords["false"] = False;
Keywords["true"] = True; Keywords["true"] = True;
Keywords["null"] = Null; Keywords["null"] = Null;
Keywords["void"] = Null;
Keywords["and"] = And; Keywords["and"] = And;
Keywords["else"] = Else; Keywords["else"] = Else;
Keywords["for"] = For; Keywords["for"] = For;
Keywords["if"] = If; Keywords["if"] = If;
Keywords["or"] = Or; Keywords["or"] = Or;
Keywords["this"] = This; Keywords["this"] = This;
Keywords[".~"] = This;
Keywords["var"] = Var; Keywords["var"] = Var;
Keywords["*~"] = Var;
Keywords["while"] = While; Keywords["while"] = While;
Keywords["do"] = Do; Keywords["do"] = Do;
Keywords["ref"] = Ref; Keywords["ref"] = Ref;
@ -38,10 +41,14 @@ internal static partial class ReaderPatterns
Keywords["fq"] = Function; Keywords["fq"] = Function;
Keywords["funq"] = Function; Keywords["funq"] = Function;
Keywords["return"] = Return; Keywords["return"] = Return;
Keywords["<:"] = Return;
Keywords["class"] = Class; Keywords["class"] = Class;
Keywords["base"] = Base; Keywords["base"] = Base;
Keywords["^~"] = Base;
Keywords["typeof"] = TypeOf; Keywords["typeof"] = TypeOf;
Keywords["?:"] = TypeOf;
Keywords["print"] = Print; Keywords["print"] = Print;
Keywords["::"] = Var;
Keywords["globals"] = PrintGlobals; Keywords["globals"] = PrintGlobals;
Keywords["stack"] = PrintStack; Keywords["stack"] = PrintStack;
Keywords["expr"] = PrintExpr; Keywords["expr"] = PrintExpr;
@ -255,56 +262,70 @@ public class Reader : IReader<Token>, IDisposable
'}' => MakeToken(ContextClose, buffer), '}' => MakeToken(ContextClose, buffer),
'(' => MakeToken(GroupOpen, buffer), '(' => MakeToken(GroupOpen, buffer),
')' => MakeToken(GroupClose, buffer), ')' => MakeToken(GroupClose, buffer),
'.' => MakeToken(Dot, buffer), '.' => Check('~') ?
MakeToken(This, buffer + Next()) :
MakeToken(Dot, buffer),
',' => MakeToken(Comma, buffer), ',' => MakeToken(Comma, buffer),
';' => MakeToken(Semicolon, buffer), ';' => MakeToken(Semicolon, buffer),
':' => MakeToken(Colon, buffer), ':' => Check(':') ?
MakeToken(Print, buffer + Next()) :
MakeToken(Colon, buffer),
'&' => Check('&') ? '&' => Check('&') ?
MakeToken(And, buffer + Next()) : MakeToken(And, buffer + Next()) :
MakeToken(BitwiseAnd, buffer), MakeToken(BitwiseAnd, buffer),
'^' => MakeToken(BitwiseXor, buffer), '^' => Check('~') ?
MakeToken(Base, buffer + Next()) :
MakeToken(BitwiseXor, buffer),
'%' => Check('=') ? '%' => Check('=') ?
MakeToken(ModuloEqual, buffer + Next()) : MakeToken(ModuloEqual, buffer + Next()) :
MakeToken(Modulo, buffer), MakeToken(Modulo, buffer),
'|' => Check('|') ? '|' => Check('|') ?
MakeToken(Or, buffer + Next()) : MakeToken(Or, buffer + Next()) :
MakeToken(BitwiseOr, buffer), MakeToken(BitwiseOr, buffer),
'!' => Check('=') ? '!' => Check('=') ?
MakeToken(BangEqual, buffer + Next()) : MakeToken(BangEqual, buffer + Next()) :
MakeToken(Bang, buffer), MakeToken(Bang, buffer),
'+' => Check('+') ? '+' => Check('+') ?
MakeToken(Increment, buffer + Next()) : MakeToken(Increment, buffer + Next()) :
Check('=') ? Check('=') ?
MakeToken(PlusEqual, buffer + Next()) : MakeToken(PlusEqual, buffer + Next()) :
MakeToken(Plus, buffer), MakeToken(Plus, buffer),
'-' => Check('-') ? '-' => Check('-') ?
MakeToken(Decrement, buffer + Next()) : MakeToken(Decrement, buffer + Next()) :
Check('=') ? Check('=') ?
MakeToken(MinusEqual, buffer + Next()) : MakeToken(MinusEqual, buffer + Next()) :
MakeToken(Minus, buffer), MakeToken(Minus, buffer),
'/' => Check('=') ? '/' => Check('=') ?
MakeToken(SlashEqual, buffer + Next()) : MakeToken(SlashEqual, buffer + Next()) :
MakeToken(Slash, buffer), MakeToken(Slash, buffer),
'*' => Check('=') ? '*' => Check('=') ?
MakeToken(StarEqual, buffer + Next()) : MakeToken(StarEqual, buffer + Next()) :
MakeToken(Star, buffer), Check('~') ?
MakeToken(Var, buffer + Next()) :
MakeToken(Star, buffer),
'=' => Check('=') ? '=' => Check('=') ?
MakeToken(EqualEqual, buffer + Next()) : MakeToken(EqualEqual, buffer + Next()) :
MakeToken(Equal, buffer), MakeToken(Equal, buffer),
'<' => Check('<') ? '<' => Check('~') ?
MakeToken(BitwiseLeft, buffer + Next()) : MakeToken(Equal, buffer + Next()) :
Check('=') ? Check(':') ?
MakeToken(LessEqual, buffer + Next()) : MakeToken(Return, buffer + Next()) :
MakeToken(Less, buffer), Check('<') ?
MakeToken(BitwiseLeft, buffer + Next()) :
Check('=') ?
MakeToken(LessEqual, buffer + Next()) :
MakeToken(Less, buffer),
'>' => Check('>') ? '>' => Check('>') ?
MakeToken(BitwiseRight, buffer + Next()) : MakeToken(BitwiseRight, buffer + Next()) :
Check('=') ? Check('=') ?
MakeToken(GreaterEqual, buffer + Next()) : MakeToken(GreaterEqual, buffer + Next()) :
MakeToken(Greater, buffer), MakeToken(Greater, buffer),
'~' => MakeToken(BitwiseNot, buffer), '~' => MakeToken(BitwiseNot, buffer),
'?' => Check('?') ? '?' => Check('?') ?
MakeToken(DoubleQuestion, buffer + Next()) : MakeToken(DoubleQuestion, buffer + Next()) :
MakeToken(Question, buffer), Check(':') ?
MakeToken(TypeOf, buffer + Next()) :
MakeToken(Question, buffer),
_ => MakeToken(Error, buffer) //throw new ReaderException($"Could not identify operator <{buffer}>", this) _ => MakeToken(Error, buffer) //throw new ReaderException($"Could not identify operator <{buffer}>", this)
}; };
} }

View File

@ -114,7 +114,7 @@ public static class TokenTypeExtensions
=> type is Identifier; => type is Identifier;
public static bool IsControl(this TokenType type) public static bool IsControl(this TokenType type)
=> type is If or Else or For or While or Do or Return or And or Or; => type is If or Var or Class or Else or For or While or Do or Return or And or Or or TypeOf or Print;
public static bool IsBoolean(this TokenType type) public static bool IsBoolean(this TokenType type)
=> type is True or False; => type is True or False;

View File

@ -4,5 +4,5 @@ public class Array(IEnumerable<Value> data) : Obj(ValueType.Array)
{ {
public List<Value> Data = [..data]; public List<Value> Data = [..data];
public override string ToString() => $"Array<{Data.Count}>"; public override string ToString() => $"Array [{Data.Count}]";
} }