bshell: generate and evaluate bytecode for shell input

This commit is contained in:
2026-05-17 15:35:22 +01:00
parent f629b05672
commit 2f200e8d1b
+82 -9
View File
@@ -1,37 +1,110 @@
#include "ast/ast.h"
#include "compile.h"
#include "debug.h"
#include "file.h" #include "file.h"
#include "line-ed/line-ed.h" #include "line-ed/line-ed.h"
#include "parse/lex.h"
#include "parse/parse.h"
#include "parse/token.h"
#include "runtime/runtime.h"
#include <stdio.h> #include <stdio.h>
static void print_token_queue(fx_queue *q)
{
fx_queue_entry *cur = fx_queue_first(q);
while (cur) {
struct lex_token *tok = fx_unbox(
struct lex_token,
cur,
tok_entry);
print_lex_token(tok);
cur = fx_queue_next(cur);
}
}
static void lex_only(struct lex_ctx *lex)
{
while (1) {
struct lex_token *tok = lex_ctx_peek(lex);
if (!tok) {
break;
}
lex_ctx_discard(lex);
}
}
static void lex_and_parse(struct parse_ctx *parse)
{
}
extern int compare_token_types(unsigned int a, unsigned int b);
int main(int argc, const char **argv) int main(int argc, const char **argv)
{ {
printf("B Shell " BSHELL_VERSION "\n"); printf("B Shell " BSHELL_VERSION "\n");
struct file *file = NULL;
struct line_ed *ed = NULL;
struct line_source *linesrc = NULL; struct line_source *linesrc = NULL;
enum bshell_status status = BSHELL_SUCCESS; enum bshell_status status = BSHELL_SUCCESS;
if (argc > 1) { if (argc > 1) {
struct file *file = NULL;
status = file_open(argv[1], &file); status = file_open(argv[1], &file);
linesrc = &file->f_base; linesrc = &file->f_base;
} else { } else {
struct line_ed *ed = line_ed_create(); #if BSHELL_INTERACTIVE == 1
ed = line_ed_create();
linesrc = line_ed_to_line_source(ed); linesrc = line_ed_to_line_source(ed);
#else
fprintf(stderr, "Interactive mode is not supported.\n");
return -1;
#endif
} }
fx_stringstream *linebuf = fx_stringstream_create(); struct lex_ctx lex = {0};
lex_ctx_init(&lex, LEX_PRINT_TOKENS, linesrc);
struct parse_ctx parse = {0};
parse_ctx_init(&parse, &lex);
#if 0
lex_only(&lex);
return 0;
#endif
bshell_scriptblock *block = bshell_scriptblock_create();
struct bshell_runtime *rt = bshell_runtime_create();
while (1) { while (1) {
enum bshell_status status struct ast_node *node = parse_ctx_read_node(&parse);
= line_source_readline(linesrc, linebuf); if (!node) {
if (status != BSHELL_SUCCESS) {
break; break;
} }
printf("%s", fx_stringstream_ptr(linebuf)); print_ast_node_recursive(node);
fx_stringstream_reset(linebuf); printf("----\n");
bshell_scriptblock_clear_text(block);
bshell_compile(node, block);
print_scriptblock(block, 0);
fx_value result = bshell_runtime_eval_global(rt, block);
print_value(&result);
}
parse_ctx_cleanup(&parse);
lex_ctx_cleanup(&lex);
#if BSHELL_INTERACTIVE == 1
if (ed) {
line_ed_destroy(ed);
}
#endif
if (file) {
file_close(file);
} }
return 0; return 0;