From 34fc6119714b999bae5aaf08697453dca500f705 Mon Sep 17 00:00:00 2001 From: "Ian M." Date: Sat, 3 Oct 2026 06:25:43 +0000 Subject: frontend: Add lexer+parser groundwork Signed-off-by: Ian M. --- core/atas.c | 10 ++++++- core/lexer.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ core/parser.c | 55 +++++++++++++++++++++++++++++++++++++ head/atas/lexer.h | 22 +++++++++++++++ head/atas/parser.h | 20 ++++++++++++++ head/atas/token.h | 37 +++++++++++++++++++++++++ 6 files changed, 223 insertions(+), 1 deletion(-) create mode 100644 core/lexer.c create mode 100644 core/parser.c create mode 100644 head/atas/lexer.h create mode 100644 head/atas/parser.h create mode 100644 head/atas/token.h diff --git a/core/atas.c b/core/atas.c index 9585a26..623468f 100644 --- a/core/atas.c +++ b/core/atas.c @@ -5,7 +5,8 @@ #include #include -#include "atas/state.h" +#include +#include /* * Display help options @@ -39,6 +40,13 @@ atas_assemble(const char *in_file) return; } + error = atas_parse(&state); + if (error < 0) { + printf("failured occured in %s\n", in_file); + atas_state_destroy(&state); + return; + } + atas_state_destroy(&state); } diff --git a/core/lexer.c b/core/lexer.c new file mode 100644 index 0000000..019724c --- /dev/null +++ b/core/lexer.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2026, Apollo Telephone Laboratories. + * Provided under the BSD-3 clause. + */ + +#include +#include +#include + +/* + * Returns true if the given char is a whitespace + * + * @c: Character to compare against a set of whitespace + */ +static inline bool +lexer_is_ws(char c) +{ + switch (c) { + case '\n': + case '\f': + case '\t': + case '\r': + case ' ': + return true; + } + + return false; +} + +/* + * Scan a single byte from the input source file + * + * @state: Assembler state + * @skip_ws: If true, skip whitespaces + * + * Returns the scanned byte on success, returns '\0' + * on failure. + */ +static char +lexer_scan_byte(struct atas_state *state, bool skip_ws) +{ + char c; + + if (state == NULL) { + return '\0'; + } + + c = fgetc(state->in_file); + while (lexer_is_ws(c) && skip_ws) { + if ((c = fgetc(state->in_file)) == EOF) { + return '\0'; + } + } + + return c; +} + +int +atas_lexer_scan(struct atas_state *state, struct atas_token *token) +{ + char c; + + if (state == NULL || token == NULL) { + return -1; + } + + c = lexer_scan_byte(state, true); + if (c == '\0') { + return -1; + } + + switch (c) { + case ',': + token->type = TT_COMMA; + token->c = c; + return 0; + } + + return -1; +} diff --git a/core/parser.c b/core/parser.c new file mode 100644 index 0000000..6cf0a4e --- /dev/null +++ b/core/parser.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2026, Apollo Telephone Laboratories. + * Provided under the BSD-3 clause. + */ + +#include +#include +#include + +/* Symbolic token */ +#define SYMTOK(TOK) \ + "[" TOK "]" + +/* Literal token */ +#define LITTOK(TOK) \ + "'" TOK "'" + +/* + * Safe macro to index toktab + */ +#define TOK_STR(TT) \ + ((TT) >= TT_MAX) \ + ? "bad" \ + : toktab[(TT)] + +/* + * Lookup table to convert token constants into + * strings. + */ +static const char *toktab[] = { + [TT_NONE] = SYMTOK("NONE"), + [TT_COMMA] = LITTOK(",") +}; + +int +atas_parse(struct atas_state *state) +{ + int error; + struct atas_token tok; + + if (state == NULL) { + return -1; + } + + for (;;) { + error = atas_lexer_scan(state, &tok); + if (error < 0) { + break; + } + + printf("got token %s\n", TOK_STR(tok.type)); + } + + return 0; +} diff --git a/head/atas/lexer.h b/head/atas/lexer.h new file mode 100644 index 0000000..5944825 --- /dev/null +++ b/head/atas/lexer.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2026, Apollo Telephone Laboratories. + * Provided under the BSD-3 clause. + */ + +#ifndef ATAS_LEXER_H +#define ATAS_LEXER_H 1 + +#include +#include + +/* + * Scan for a single lexical element within a program + * + * @state: ATAS state + * @token: Token result is written here + * + * Returns zero on success + */ +int atas_lexer_scan(struct atas_state *state, struct atas_token *token); + +#endif /* !ATAS_LEXER_H */ diff --git a/head/atas/parser.h b/head/atas/parser.h new file mode 100644 index 0000000..7e410c8 --- /dev/null +++ b/head/atas/parser.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2026, Apollo Telephone Laboratories. + * Provided under the BSD-3 clause. + */ + +#ifndef ATAS_PARSER_H +#define ATAS_PARSER_H 1 + +#include + +/* + * Begin parsing the input source file + * + * @state: ATAS state machine + * + * Returns zero on success + */ +int atas_parse(struct atas_state *state); + +#endif /* !ATAS_PARSER_H */ diff --git a/head/atas/token.h b/head/atas/token.h new file mode 100644 index 0000000..1346eba --- /dev/null +++ b/head/atas/token.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2026, Apollo Telephone Laboratories. + * Provided under the BSD-3 clause. + */ + +#ifndef ATAS_TOKEN_H +#define ATAS_TOKEN_H 1 + +#include +#include +#include + +/* + * Token type + */ +typedef enum { + TT_NONE, /* [NONE] */ + TT_COMMA, /* ',' */ + TT_MAX +} atas_tt_t; + +/* + * Represents a single lexical element within a program + * + * @type: Token type + * @c: Character associated with token + * @v: Signed value associated with token + */ +struct atas_token { + atas_tt_t type; + union { + char c; + ssize_t v; + }; +}; + +#endif /* !ATAS_TOKEN_H */ -- cgit v1.2.3