/* * Copyright (c) 2026, Chloe M. * Provided under the BSD-3 clause */ #include #include #include "cescal/lexer.h" #include "cescal/log.h" /* * Returns true if the given character is a whitespace * * @c: Character to check */ static inline bool lexer_is_ws(char c) { switch (c) { case '\t': case '\n': case ' ': case '\f': case '\r': return true; } return false; } /* * Consume a single character from the input source file and * optionally skip whitespace * * @state: Compiler state * @skip_ws: If true skip whitespace */ static char lexer_consume_single(struct cescal_state *state, bool skip_ws) { char c; if (state == NULL) { return '\0'; } while ((c = readbuf_read(&state->rb, state->in_fd)) != '\0') { if (lexer_is_ws(c)) { continue; } return c; } return '\0'; } int lexer_nom(struct cescal_state *state, struct token *res) { char c; if (state == NULL || res == NULL) { errno = EINVAL; return -1; } if ((c = lexer_consume_single(state, true)) == '\0') { return -1; } switch (c) { case '(': res->type = TT_LPAREN; res->c = c; return 0; case ')': res->type = TT_RPAREN; res->c = c; return 0; case ',': res->type = TT_COMMA; res->c = c; return 0; } cc_error("got unknown token '%c'\n", c); return -1; }