aboutsummaryrefslogtreecommitdiff
path: root/lib/Lexer
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-16 10:04:27 +0000
committer_ov4 <ov4@ov4.org>2026-10-16 10:04:27 +0000
commit45c9d37eb27d204a6202b33cb37e890af0171357 (patch)
treedba23170b16053c5e1ec4bf78efc2a533cb94a4e /lib/Lexer
parent522742e9df7fc5ac596ce4aa53d41b31e4f6a030 (diff)
feat(control-flow): implement ordered CASE OF matching
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Diffstat (limited to 'lib/Lexer')
-rw-r--r--lib/Lexer/Lexer.cc46
1 files changed, 44 insertions, 2 deletions
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;
+}