summaryrefslogtreecommitdiff
path: root/core/lexer.c
diff options
context:
space:
mode:
authorIan M. <ian@aptel.org>2026-10-03 06:25:43 +0000
committerIan M. <ian@aptel.org>2026-10-03 06:25:43 +0000
commit34fc6119714b999bae5aaf08697453dca500f705 (patch)
tree0c03967204996f943d903b47f7b201ad73d6e817 /core/lexer.c
parent8e838a73368d5f26fee796d6ddb065e21449e989 (diff)
frontend: Add lexer+parser groundwork
Signed-off-by: Ian M. <ian@aptel.org>
Diffstat (limited to 'core/lexer.c')
-rw-r--r--core/lexer.c80
1 files changed, 80 insertions, 0 deletions
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 <atas/lexer.h>
+#include <stdio.h>
+#include <stdbool.h>
+
+/*
+ * 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;
+}