bshell: generate and evaluate bytecode for shell input
This commit is contained in:
+82
-9
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user