Begin data_desc

This commit is contained in:
Krzosa Karol
2026-02-01 17:45:15 +01:00
parent 33d623268a
commit ed3be39037
2 changed files with 185 additions and 0 deletions

View File

@@ -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);
}

View File

@@ -45,6 +45,7 @@
#include "text_editor.h" #include "text_editor.h"
#include "globals.cpp" #include "globals.cpp"
#include "coroutines.cpp" #include "coroutines.cpp"
#include "data_desc.cpp"
#include "buffer.cpp" #include "buffer.cpp"
#include "view.cpp" #include "view.cpp"
#include "window.cpp" #include "window.cpp"