From ed3be39037ec1500602bb74139771116af5017ed Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Sun, 1 Feb 2026 17:45:15 +0100 Subject: [PATCH] Begin data_desc --- src/text_editor/data_desc.cpp | 184 ++++++++++++++++++++++++++++++++ src/text_editor/text_editor.cpp | 1 + 2 files changed, 185 insertions(+) create mode 100644 src/text_editor/data_desc.cpp diff --git a/src/text_editor/data_desc.cpp b/src/text_editor/data_desc.cpp new file mode 100644 index 0000000..cac0883 --- /dev/null +++ b/src/text_editor/data_desc.cpp @@ -0,0 +1,184 @@ +namespace DataDesc { +struct Lexer { + Allocator allocator; + char *at; + char *start; + char *end; + + char *file; + int line, column; +}; + +enum TokenKind { + TokenKind_EOF, + TokenKind_String, + TokenKind_Colon, + TokenKind_Comma, + TokenKind_OpenBrace, + TokenKind_CloseBrace, + TokenKind_Error, +}; + +struct Token { + TokenKind kind; + union { + struct {char *data; Int len;}; + String string; + }; + int line, column; + char *file; +}; + +Lexer MakeLexer(Allocator allocator, String string, char *file) { + Assert(string.data != NULL && string.data != 0); + Lexer result = {allocator, string.data, string.data, string.data + string.len}; + result.file = file; + return result; +} + +char At(Lexer *lex) { + if (lex->at < lex->end) { + return lex->at[0]; + } + return 0; +} + +void Advance(Lexer *lex) { + if (lex->at >= lex->end) { + return; + } + if (lex->at[0] == '\n') { + lex->line += 1; + lex->column = 0; + } + lex->column += 1; + lex->at += 1; +} + +void EatWhitespace(Lexer *lex) { + while (IsWhitespace(At(lex))) { + Advance(lex); + } +} + +void LexString(Lexer *lex, Token *t) { + t->kind = TokenKind_String; + char end_char = t->data[0]; + t->data += 1; + for (;;) { + char c = At(lex); + if (c == 0) { + break; + } + if (c == end_char) { + break; + } + if (c == '\\') { + Advance(lex); + } + Advance(lex); + } + Advance(lex); + t->len = (Int)(lex->at - t->data) - 1; +} + +bool IsOkForIdent(char cc) { + bool result = IsAlphanumeric(cc) || cc == '_' || cc == '/' || cc == '-' || cc == '.' || cc == '@'; + return result; +} + +Token Next(Lexer *lex) { + EatWhitespace(lex); + Token t = {}; + t.data = lex->at; + t.len = 1; + t.line = lex->line; + t.column = lex->column; + t.file = lex->file; + char c = At(lex); + Advance(lex); + + if (c == 0) { + t.kind = TokenKind_EOF; + } else if (c == '{') { + t.kind = TokenKind_OpenBrace; + } else if (c == '}') { + t.kind = TokenKind_CloseBrace; + } else if (c == ':') { + t.kind = TokenKind_Colon; + } else if (c == ',') { + t.kind = TokenKind_Comma; + } else if (c == '"') { + LexString(lex, &t); + } else if (c == '`') { + LexString(lex, &t); + } else if (IsOkForIdent(c)) { + t.kind = TokenKind_String; + for (;;) { + char cc = At(lex); + bool ok = IsOkForIdent(cc); + if (!ok) { + break; + } + Advance(lex); + } + t.len = (Int)(lex->at - t.data); + } else { + t.kind = TokenKind_Error; + t.string = Format(lex->allocator, "Got invalid character when parsing: '%c'", c); + return t; + } + + return t; +} + +void RunDataDescriptionTest() { + Scratch scratch; + String s = "{/usr/bin/python3, `Hidden`, Input:Clipboard}"; + Lexer lexer = MakeLexer(scratch, s, "test"); + { + Token tok = {}; + tok = Next(&lexer); + Assert(tok.kind == TokenKind_OpenBrace); + Assert(tok.len == 1); + Assert(tok.data[0] == '{'); + + tok = Next(&lexer); + Assert(tok.kind == TokenKind_String); + Assert(tok.string == "/usr/bin/python3"); + + tok = Next(&lexer); + Assert(tok.kind == TokenKind_Comma); + Assert(tok.string == ","); + + tok = Next(&lexer); + Assert(tok.kind == TokenKind_String); + Assert(tok.string == "Hidden"); + + tok = Next(&lexer); + Assert(tok.kind == TokenKind_Comma); + Assert(tok.string == ","); + + tok = Next(&lexer); + Assert(tok.kind == TokenKind_String); + Assert(tok.string == "Input"); + + tok = Next(&lexer); + Assert(tok.kind == TokenKind_Colon); + Assert(tok.string == ":"); + + tok = Next(&lexer); + Assert(tok.kind == TokenKind_String); + Assert(tok.string == "Clipboard"); + + tok = Next(&lexer); + Assert(tok.kind == TokenKind_CloseBrace); + Assert(tok.string == "}"); + + tok = Next(&lexer); + Assert(tok.kind == TokenKind_EOF); + } + + +} RegisterFunction(&TestFunctions, RunDataDescriptionTest); +} diff --git a/src/text_editor/text_editor.cpp b/src/text_editor/text_editor.cpp index 7990f33..2c3cf83 100644 --- a/src/text_editor/text_editor.cpp +++ b/src/text_editor/text_editor.cpp @@ -45,6 +45,7 @@ #include "text_editor.h" #include "globals.cpp" #include "coroutines.cpp" +#include "data_desc.cpp" #include "buffer.cpp" #include "view.cpp" #include "window.cpp"