From a6b023418396a5c2c6a38489f6abc5ba5645d139 Mon Sep 17 00:00:00 2001 From: IoIxD Date: Thu, 15 Jan 2026 22:13:52 -0700 Subject: [PATCH] more properer lexer --- Makefile | 2 +- src/lexer/lexer.c | 155 +++++++++++++++++++++++++++++++++++++++ src/lexer/lexer.h | 41 +++++++++++ src/main.c | 26 ++----- src/system/linux/linux.c | 4 +- 5 files changed, 207 insertions(+), 21 deletions(-) create mode 100644 src/lexer/lexer.c create mode 100644 src/lexer/lexer.h diff --git a/Makefile b/Makefile index 811f93f..bce7885 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -SOURCES := src/main.c +SOURCES := src/main.c src/util.c src/lexer/lexer.c CFLAGS := -g -O0 -nostdlib UNAME := $(shell uname) diff --git a/src/lexer/lexer.c b/src/lexer/lexer.c new file mode 100644 index 0000000..2387e17 --- /dev/null +++ b/src/lexer/lexer.c @@ -0,0 +1,155 @@ +#include "lexer.h" + +#include "../system/system.h" + +struct msh_lexer_t { + msh_lexer_item_list *item_list_head; + msh_lexer_item_list *item_list_cur; +}; + +msh_lexer *msh_lexer_new() { + msh_lexer *l = msh_allocate(sizeof(struct msh_lexer_t)); + l->item_list_head = msh_allocate(sizeof(struct msh_lexer_item_list_t)); + + l->item_list_head->item = 0; + l->item_list_head->next = 0; + + l->item_list_cur = l->item_list_head; + + return l; +}; + +void msh_lexer_push_item(msh_lexer *lexer, msh_lexer_item_type type, + unsigned char *buf, SIZE_TYPE strlen) { + int i; + msh_lexer_item *item = msh_callocate(sizeof(msh_lexer_item), 1); + + item->str = msh_allocate(strlen * sizeof(unsigned char)); + for (i = 0; i < strlen; i++) { + item->str[i] = buf[i]; + } + item->strlen = strlen; + item->type = type; + + lexer->item_list_cur->item = item; + lexer->item_list_cur->next = 0; + + lexer->item_list_cur->next = msh_callocate(sizeof(msh_lexer_item_list), 1); + lexer->item_list_cur = lexer->item_list_cur->next; +}; + +void msh_lexer_parse(msh_lexer *lexer, unsigned char *buf, SIZE_TYPE sz) { + int i = 0, n = 0, last = 0; + + unsigned char *cur_word_buf = msh_callocate(1024, sizeof(unsigned char)); + + for (i = 0; i < sz; i++) { + int do_clear = 0; + switch (buf[i]) { + /*case '#': + do_clear = 1; + break; + case '|': + if (i + 1 < sz) { + if (buf[i + 1] == '|') { + msh_lexer_push_item(lexer, MSH_LEXER_ITEM_TYPE_OP_OR, buf, 2); + last = i + 2; + } else { + msh_lexer_push_item(lexer, MSH_LEXER_ITEM_TYPE_OP_PIPE, buf, 1); + last = i + 1; + } + } + do_clear = 1; + break; + case '&': + if (i + 1 < sz) { + if (buf[i + 1] == '&') { + msh_lexer_push_item(lexer, MSH_LEXER_ITEM_TYPE_OP_AND, buf, 2); + last = i + 2; + } else { + msh_lexer_push_item(lexer, MSH_LEXER_ITEM_TYPE_OP_CONTROL, buf, 1); + last = i + 1; + } + } + do_clear = 1; + break; + case ';': + msh_lexer_push_item(lexer, MSH_LEXER_ITEM_TYPE_OP_SEMICOLON, buf, 1); + do_clear = 1; + break; + */ + case ' ': + case '\n': + case '\0': + cur_word_buf[n++] = '\0'; + msh_lexer_push_item(lexer, MSH_LEXER_ITEM_TYPE_WORD, cur_word_buf, n); + do_clear = 1; + break; + default: + cur_word_buf[n++] = buf[i]; + break; + } + if (do_clear) { + msh_deallocate(cur_word_buf); + cur_word_buf = msh_callocate(1024, sizeof(unsigned char)); + n = 0; + } + } +} + +void msh_lexer_execute(msh_lexer *lexer) { + msh_lexer_item_list *list = lexer->item_list_head; + unsigned char *cmd = 0; + + SIZE_TYPE cmd_size = 0; + SIZE_TYPE args_size = 0; + unsigned char **args = 0; + int is_first_arg = 0, n = 0; + + while (list != 0) { + if (!list->item) { + break; + } + if (cmd == 0) { + cmd = list->item->str; + cmd_size = list->item->strlen; + } else { + args_size += 1; + } + list = list->next; + } + list = lexer->item_list_head; + args = msh_allocate((args_size + 1) * sizeof(unsigned char *)); + while (list != 0) { + if (!list->item) { + break; + } + args[n++] = list->item->str; + list = list->next; + } + args[n++] = 0; + + msh_execute(cmd, args); + + msh_deallocate(args); + + msh_lexer_flush(lexer); +}; + +void msh_lexer_flush(msh_lexer *lexer) { + msh_lexer_item_list *list = lexer->item_list_head; + while (list->item != 0) { + msh_deallocate(list->item->str); + msh_deallocate(list->item); + list = list->next; + if (list == 0) { + break; + } + } + lexer->item_list_cur = lexer->item_list_head; +} + +void msh_lexer_free(msh_lexer *lexer) { + msh_deallocate(lexer->item_list_head); + msh_deallocate(lexer); +}; diff --git a/src/lexer/lexer.h b/src/lexer/lexer.h new file mode 100644 index 0000000..276e429 --- /dev/null +++ b/src/lexer/lexer.h @@ -0,0 +1,41 @@ +#ifndef __MSH_LEXER_H +#define __MSH_LEXER_H + +#include "../util.h" + +typedef enum msh_lexer_item_type_t { + MSH_LEXER_ITEM_TYPE_UNKNOWN = 0, + MSH_LEXER_ITEM_TYPE_WORD, + MSH_LEXER_ITEM_TYPE_COMMENT, /* # */ + MSH_LEXER_ITEM_TYPE_OP_OR, /* || */ + MSH_LEXER_ITEM_TYPE_OP_AND, /* && */ + MSH_LEXER_ITEM_TYPE_OP_PIPE, /* | */ + MSH_LEXER_ITEM_TYPE_OP_CONTROL, /* & */ + MSH_LEXER_ITEM_TYPE_OP_SEMICOLON, /* ; */ +} msh_lexer_item_type; + +typedef struct msh_lexer_item_t { + msh_lexer_item_type type; + unsigned char *str; + SIZE_TYPE strlen; +} msh_lexer_item; + +typedef struct msh_lexer_item_list_t { + msh_lexer_item *item; + struct msh_lexer_item_list_t *next; +} msh_lexer_item_list; + +typedef struct msh_lexer_t msh_lexer; + +msh_lexer *msh_lexer_new(); +void msh_lexer_parse(msh_lexer *lexer, unsigned char *buf, SIZE_TYPE sz); +void msh_lexer_push_item(msh_lexer *lexer, msh_lexer_item_type type, + unsigned char *buf, SIZE_TYPE strlen); + +void msh_lexer_flush(msh_lexer *lexer); + +void msh_lexer_execute(msh_lexer *lexer); + +void msh_lexer_free(msh_lexer *lexer); + +#endif diff --git a/src/main.c b/src/main.c index 268667b..cf6c43f 100644 --- a/src/main.c +++ b/src/main.c @@ -1,13 +1,15 @@ +#include "lexer/lexer.h" #include "system/system.h" unsigned char prefix[] = "%> "; /* Makefile-defined system entry point. */ MSH_ENTRY_POINT { + msh_lexer *lexer = msh_lexer_new(); + while (1) { int out; unsigned char *buf = msh_callocate(2048, sizeof(unsigned char)); - unsigned char **args = msh_callocate(2048 * 2, sizeof(unsigned char)); int i = 0, n = 0, last = 0; unsigned long long sz = 0; @@ -16,25 +18,13 @@ MSH_ENTRY_POINT { while ((out = msh_read_input(buf, &sz, 2048)), !out) { } - /* args */ - for (i = 0; i < sz; i++) { - if (buf[i] == ' ') { - *(buf + i) = '\0'; - if (i != sz - 1) { - args[n++] = buf + last; - last = i + 1; - if (n >= 2048) { - break; - } - } - } - } + msh_lexer_parse(lexer, buf, sz + 1); + msh_lexer_execute(lexer); - args[n++] = buf + last; - - msh_execute(buf, args); + // msh_execute(buf, args); msh_deallocate(buf); - msh_deallocate(args); } + + msh_lexer_free(lexer); } diff --git a/src/system/linux/linux.c b/src/system/linux/linux.c index c005007..79d1946 100644 --- a/src/system/linux/linux.c +++ b/src/system/linux/linux.c @@ -27,14 +27,14 @@ void msh_write(unsigned char *st, SIZE_TYPE size) { int msh_execute(unsigned char *cmd, unsigned char **args) { SIZE_TYPE fork = (SIZE_TYPE)SYSCALL(fork, 0); + // int fork = 0; if (fork == 0) { SYSCALL(execve, cmd, args, 0); - msh_deallocate(args); - SYSCALL(kill, fork, SIGKILL); return 0; } else { siginfo_t info; SYSCALL(waitid, P_ALL, 0, &info, WEXITED); + SYSCALL(kill, fork, SIGKILL); return info.si_code; } return 0;