more properer lexer

This commit is contained in:
IoIxD 2026-01-15 22:13:52 -07:00
commit a6b0234183
5 changed files with 207 additions and 21 deletions

View file

@ -1,4 +1,4 @@
SOURCES := src/main.c SOURCES := src/main.c src/util.c src/lexer/lexer.c
CFLAGS := -g -O0 -nostdlib CFLAGS := -g -O0 -nostdlib
UNAME := $(shell uname) UNAME := $(shell uname)

155
src/lexer/lexer.c Normal file
View file

@ -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);
};

41
src/lexer/lexer.h Normal file
View file

@ -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

View file

@ -1,13 +1,15 @@
#include "lexer/lexer.h"
#include "system/system.h" #include "system/system.h"
unsigned char prefix[] = "%> "; unsigned char prefix[] = "%> ";
/* Makefile-defined system entry point. */ /* Makefile-defined system entry point. */
MSH_ENTRY_POINT { MSH_ENTRY_POINT {
msh_lexer *lexer = msh_lexer_new();
while (1) { while (1) {
int out; int out;
unsigned char *buf = msh_callocate(2048, sizeof(unsigned char)); 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; int i = 0, n = 0, last = 0;
unsigned long long sz = 0; unsigned long long sz = 0;
@ -16,25 +18,13 @@ MSH_ENTRY_POINT {
while ((out = msh_read_input(buf, &sz, 2048)), !out) { while ((out = msh_read_input(buf, &sz, 2048)), !out) {
} }
/* args */ msh_lexer_parse(lexer, buf, sz + 1);
for (i = 0; i < sz; i++) { msh_lexer_execute(lexer);
if (buf[i] == ' ') {
*(buf + i) = '\0';
if (i != sz - 1) {
args[n++] = buf + last;
last = i + 1;
if (n >= 2048) {
break;
}
}
}
}
args[n++] = buf + last; // msh_execute(buf, args);
msh_execute(buf, args);
msh_deallocate(buf); msh_deallocate(buf);
msh_deallocate(args);
} }
msh_lexer_free(lexer);
} }

View file

@ -27,14 +27,14 @@ void msh_write(unsigned char *st, SIZE_TYPE size) {
int msh_execute(unsigned char *cmd, unsigned char **args) { int msh_execute(unsigned char *cmd, unsigned char **args) {
SIZE_TYPE fork = (SIZE_TYPE)SYSCALL(fork, 0); SIZE_TYPE fork = (SIZE_TYPE)SYSCALL(fork, 0);
// int fork = 0;
if (fork == 0) { if (fork == 0) {
SYSCALL(execve, cmd, args, 0); SYSCALL(execve, cmd, args, 0);
msh_deallocate(args);
SYSCALL(kill, fork, SIGKILL);
return 0; return 0;
} else { } else {
siginfo_t info; siginfo_t info;
SYSCALL(waitid, P_ALL, 0, &info, WEXITED); SYSCALL(waitid, P_ALL, 0, &info, WEXITED);
SYSCALL(kill, fork, SIGKILL);
return info.si_code; return info.si_code;
} }
return 0; return 0;