\r
#define shift_args c_shift_args\r
\r
+#define SV_FMT c_SV_FMT\r
+#define SV_ARG c_SV_ARG\r
+\r
+#define SV c_SV\r
+\r
+#define sv_print_dumb c_sv_print_dumb\r
+#define sv_from_cstr c_sv_from_cstr\r
+#define sv_lpop c_sv_lpop\r
+#define sv_lpop_until_predicate c_sv_lpop_until_predicate\r
+#define sv_rpop_until_predicate c_sv_rpop_until_predicate\r
+#define sv_lpop_until_char c_sv_lpop_until_char\r
+#define sv_rpop_until_char c_sv_rpop_until_char\r
+#define sv_lremove c_sv_lremove\r
+#define sv_rremove c_sv_rremove\r
+#define sv_lremove_until_char c_sv_lremove_until_char\r
+#define sv_rremove_until_char c_sv_rremove_until_char\r
+#define sv_lremove_until_char_after c_sv_lremove_until_char_after\r
+#define sv_rremove_until_char_after c_sv_rremove_until_char_after\r
+#define sv_ltrim c_sv_ltrim\r
+#define sv_rtrim c_sv_rtrim\r
+#define sv_trim c_sv_trim\r
+#define sv_to_cstr c_sv_to_cstr\r
+#define sv_to_int c_sv_to_int\r
+#define sv_to_uint64 c_sv_to_uint64\r
+#define sv_to_uint8_hex c_sv_to_uint8_hex\r
+#define sv_to_ptr c_sv_to_ptr\r
+#define sv_to_float c_sv_to_float\r
+#define sv_contains_char c_sv_contains_char\r
+#define sv_is_hex_numbers c_sv_is_hex_numbers\r
+#define sv_equals c_sv_equals\r
+\r
+\r
#endif // COMMONLIB_REMOVE_PREFIX\r
\r
// typedefs\r
#include <stdio.h>
+#include <ctype.h>
#define COMMONLIB_IMPLEMENTATION
#define COMMONLIB_REMOVE_PREFIX
}
typedef struct {
- const char *src;
- size_t src_len;
+ const char *filename;
+ int line;
+ int col;
+} Location;
+
+void print_loc(FILE *f, Location *loc) {
+ ASSERT(loc != NULL, "Bro you passed a NULL...");
+ fprintf(f, "%s:%d:%d", loc->filename, loc->line, loc->col);
+}
+
+typedef struct {
+ // NOTE: src gets data from a heap allocated string!!!
+ String_view src;
size_t cur;
size_t bol; // Beginning of Line
size_t line;
exit(1);
}
Lexer l = {
- .src = buf,
- .src_len = strlen(buf),
+ .src = sv_from_cstr(buf),
.cur = 0,
.bol = 0,
.line = 1,
}
bool eof(Lexer *l) {
- return l->cur >= l->src_len;
+ return l->cur >= l->src.count;
}
char current_char(Lexer *l) {
ASSERT(!eof(l), "Trying to get char after EOF");
- return l->src[l->cur];
+ return l->src.data[l->cur];
}
char consume_char(Lexer *l) {
return ch;
}
+void consume_ident(Lexer *l, String_view *ident_sv_out, Location *loc_out) {
+ // Identifiers can start with [a-z][A-Z]_ and contain [0-9] after the first char
+ ASSERT(isalpha(current_char(l)) || current_char(l) == '_', "Called consume_identifier() at the wrong character!");
+}
+
void left_trim(Lexer *l) {
while (!eof(l) && isspace(current_char(l))) {
// TODO: Care about window's \r\n....
}
bool next_token(Lexer *l, Token *t_out) {
+ (void)t_out;
left_trim(l);
if (eof(l)) return false;
char ch = current_char(l);
+ if (isalpha(ch) || ch == '_') {
+ String_view ident_sv = {0};
+ Location ident_loc = {0};
+ consume_ident(l, &ident_sv, &ident_loc);
+ }
+
switch (ch) {
+ case '"': {
+ } break;
+ default: {
+ error("Unhandled char '%c'", ch);
+ ASSERT(false, "UNREACHABLE!");
+ }
}
/*info("ch: '%c'", ch);*/