From 45c9d37eb27d204a6202b33cb37e890af0171357 Mon Sep 17 00:00:00 2001 From: _ov4 Date: Fri, 16 Oct 2026 10:04:27 +0000 Subject: feat(control-flow): implement ordered CASE OF matching Co-Authored-By: Claude Fable 5.1 --- lib/Lexer/Lexer.cc | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) (limited to 'lib/Lexer/Lexer.cc') diff --git a/lib/Lexer/Lexer.cc b/lib/Lexer/Lexer.cc index 31bafe1..fcc9a40 100644 --- a/lib/Lexer/Lexer.cc +++ b/lib/Lexer/Lexer.cc @@ -7,12 +7,14 @@ using namespace cps; -int Lexer::gettok() { +int Lexer::readToken() { while (isspace(LastChar)) { if (LastChar == '\n') CurrentLine++; LastChar = Input.get(); } + TokenLine = CurrentLine; + if (LastChar == '"') { StringVal.clear(); LastChar = Input.get(); @@ -86,6 +88,10 @@ int Lexer::gettok() { if (IdentifierStr == "INPUT") return tok_input; if (IdentifierStr == "OUTPUT") return tok_output; + if (IdentifierStr == "CASE") return tok_case; + if (IdentifierStr == "ENDCASE") return tok_endcase; + if (IdentifierStr == "OTHERWISE") return tok_otherwise; + if (IdentifierStr == "IF") return tok_if; if (IdentifierStr == "THEN") return tok_then; if (IdentifierStr == "ELSE") return tok_else; @@ -225,7 +231,7 @@ int Lexer::gettok() { } while (LastChar != EOF && LastChar != '\n' && LastChar != '\r'); if (LastChar != EOF) - return gettok(); + return readToken(); } else { LastChar = NextChar; return '/'; @@ -239,3 +245,39 @@ int Lexer::gettok() { LastChar = Input.get(); return ThisChar; } + +Lexer::TokenData Lexer::captureToken(int Kind) const { + return {Kind, TokenLine, IdentifierStr, StringVal, NumVal, RealVal, CharVal}; +} + +void Lexer::restoreToken(const TokenData &Token) { + TokenLine = Token.Line; + IdentifierStr = Token.Identifier; + StringVal = Token.String; + NumVal = Token.Integer; + RealVal = Token.Real; + CharVal = Token.Character; +} + +int Lexer::gettok() { + if (Lookahead.empty()) return readToken(); + auto Token = std::move(Lookahead.front()); + Lookahead.pop_front(); + restoreToken(Token); + return Token.Kind; +} + +int Lexer::peekToken(unsigned Offset) { + auto Current = captureToken(0); + while (Lookahead.size() <= Offset) { + int Kind = readToken(); + Lookahead.push_back(captureToken(Kind)); + } + restoreToken(Current); + return Lookahead[Offset].Kind; +} + +int Lexer::peekLine(unsigned Offset) { + peekToken(Offset); + return Lookahead[Offset].Line; +} -- cgit v1.3.1-4-g156e