multi: completely remove fx.term dependency when interactive support is disabled

This commit is contained in:
2026-05-30 21:08:39 +01:00
parent ca33228e0e
commit 338c0356ca
9 changed files with 223 additions and 119 deletions
+11 -4
View File
@@ -7,11 +7,18 @@ if (NOT DEFINED bshell_interactive)
set(bshell_interactive 1)
endif ()
if (NOT DEFINED bshell_verbose)
set(bshell_verbose 0)
endif ()
set(required_fx_assemblies fx.runtime fx.collections)
if (bshell_interactive)
set(required_fx_assemblies ${required_fx_assemblies} fx.term)
endif ()
find_package(Python COMPONENTS Interpreter REQUIRED)
find_package(FX REQUIRED COMPONENTS
fx.runtime
fx.collections
fx.term)
find_package(FX REQUIRED COMPONENTS ${required_fx_assemblies})
execute_process(
COMMAND ${Python_EXECUTABLE}
+1 -1
View File
@@ -13,7 +13,7 @@ endforeach (d)
add_library(bshell.core SHARED ${sources})
target_link_libraries(bshell.core bshell.runtime FX::Runtime FX::Collections FX::Term)
target_link_libraries(bshell.core bshell.runtime FX::Runtime FX::Collections)
target_include_directories(bshell.core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_compile_definitions(bshell.core PUBLIC
BSHELL_VERSION="${bshell_version}")
+9 -2
View File
@@ -15,7 +15,14 @@ endforeach (d)
add_library(bshell.runtime SHARED ${sources})
target_link_libraries(bshell.runtime FX::Runtime FX::Collections FX::Term)
target_link_libraries(bshell.runtime FX::Runtime FX::Collections)
if (bshell_interactive)
target_link_libraries(bshell.runtime FX::Term)
endif ()
target_include_directories(bshell.runtime PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_compile_definitions(bshell.runtime PUBLIC
BSHELL_VERSION="${bshell_version}")
BSHELL_VERSION="${bshell_version}"
BSHELL_INTERACTIVE=${bshell_interactive}
BSHELL_VERBOSE=${bshell_verbose})
+6
View File
@@ -5,9 +5,15 @@
static void format_value_fallback(const fx_value *value, fx_stream *dest)
{
#if BSHELL_INTERACTIVE == 1
fx_printf("[yellow]");
#endif
fx_value_to_string(value, dest, NULL);
#if BSHELL_INTERACTIVE == 1
fx_printf("[reset]\n");
#endif
}
enum bshell_status format_value_default(const fx_value *value, fx_stream *dest)
+26 -4
View File
@@ -137,10 +137,14 @@ enum bshell_status bshell_table_ctx_prepare_columns_from_format(
ctx->ctx_columns = columns;
ctx->ctx_columns_count = fmt->fmt_column_count;
ctx->ctx_tty_width = 0;
#if BSHELL_INTERACTIVE == 1
fx_tty_get_dimensions(fx_stdtty, &ctx->ctx_tty_width, NULL);
#endif
if (!ctx->ctx_tty_width) {
ctx->ctx_tty_width = 150;
ctx->ctx_tty_width = 80;
}
ctx->ctx_variable_columns_count = 0;
@@ -208,10 +212,14 @@ enum bshell_status bshell_table_ctx_prepare_columns_from_object(
ctx->ctx_columns = columns;
ctx->ctx_columns_count = column_count;
ctx->ctx_tty_width = 0;
#if BSHELL_INTERACTIVE == 1
fx_tty_get_dimensions(fx_stdtty, &ctx->ctx_tty_width, NULL);
#endif
if (!ctx->ctx_tty_width) {
ctx->ctx_tty_width = 150;
ctx->ctx_tty_width = 80;
}
ctx->ctx_variable_columns_count = 0;
@@ -232,9 +240,23 @@ enum bshell_status bshell_table_ctx_prepare_columns_from_object(
return BSHELL_SUCCESS;
}
static void set_table_header_tty_colour(void)
{
#if BSHELL_INTERACTIVE == 1
fx_printf("[bold,bright_green]");
#endif
}
static void reset_tty_colour(void)
{
#if BSHELL_INTERACTIVE == 1
fx_printf("[reset]");
#endif
}
enum bshell_status bshell_table_ctx_print_headers(struct bshell_table_ctx *ctx)
{
fx_printf("[bold,bright_green]");
set_table_header_tty_colour();
bool repeat = false;
struct bshell_table_ctx_column *c = NULL;
@@ -293,7 +315,7 @@ enum bshell_status bshell_table_ctx_print_headers(struct bshell_table_ctx *ctx)
}
}
fx_printf("[reset]");
reset_tty_colour();
fx_stream_write_char(ctx->ctx_out, '\n');
return BSHELL_SUCCESS;
}
+9 -4
View File
@@ -116,12 +116,17 @@ static enum bshell_status resolve_call_target(
}
const char *cmd_name_cstr = fx_string_get_cstr(cmd_name_s);
fx_printf(
"[bold,bright_red]%s: The term '%s' is not recognised as a "
"name of a cmdlet, "
"function, script file, or executable program.[reset]\n",
#if BSHELL_INTERACTIVE == 1
fx_printf("[bold,bright_red]");
#endif
printf("%s: The term '%s' is not recognised as a name of a cmdlet, "
"function, script file, or executable program.\n",
cmd_name_cstr,
cmd_name_cstr);
#if BSHELL_INTERACTIVE == 1
fx_printf("[reset]");
#endif
printf("\n");
return BSHELL_ERR_NO_ENTRY;
}
+7 -2
View File
@@ -24,7 +24,12 @@ add_executable(bshell ${bshell_sources})
target_link_libraries(bshell
bshell.core bshell.runtime
FX::Runtime FX::Collections FX::Term)
FX::Runtime FX::Collections)
if (bshell_interactive)
target_link_libraries(bshell FX::Term)
endif ()
target_compile_definitions(bshell PUBLIC
BSHELL_VERSION="${bshell_version}"
BSHELL_INTERACTIVE=${bshell_interactive})
BSHELL_INTERACTIVE=${bshell_interactive}
BSHELL_VERBOSE=${bshell_verbose})
+131 -96
View File
@@ -8,6 +8,32 @@
#include <fx/term/print.h>
#include <stdio.h>
#if BSHELL_INTERACTIVE == 1
#define RED "[red]"
#define YELLOW "[yellow]"
#define GREEN "[green]"
#define BLUE "[blue]"
#define CYAN "[cyan]"
#define MAGENTA "[magenta]"
#define DARK_GREY "[dark_grey]"
#define RESET "[reset]"
#define LEFT_BRACKET "[["
#define debug_printf(...) fx_printf(__VA_ARGS__)
#else
#define RED ""
#define YELLOW ""
#define GREEN ""
#define BLUE ""
#define CYAN ""
#define MAGENTA ""
#define DARK_GREY ""
#define RESET ""
#define LEFT_BRACKET "["
#define debug_printf(...) printf(__VA_ARGS__)
#endif
extern void print_lex_token(struct bshell_lex_token *tok)
{
printf("[%lu:%lu - %lu:%lu] ",
@@ -18,38 +44,38 @@ extern void print_lex_token(struct bshell_lex_token *tok)
switch (tok->tok_type) {
case BSHELL_TOK_KEYWORD:
fx_puts("[magenta]");
debug_printf(MAGENTA);
break;
case BSHELL_TOK_SYMBOL:
fx_puts("[blue]");
debug_printf(BLUE);
break;
case BSHELL_TOK_INT:
case BSHELL_TOK_DOUBLE:
case BSHELL_TOK_VAR:
case BSHELL_TOK_VAR_SPLAT:
fx_puts("[yellow]");
debug_printf(YELLOW);
break;
case BSHELL_TOK_OPERATOR:
fx_puts("[red]");
debug_printf(RED);
break;
case BSHELL_TOK_WORD:
case BSHELL_TOK_WORD_START:
case BSHELL_TOK_WORD_END:
fx_puts("[cyan]");
debug_printf(CYAN);
break;
case BSHELL_TOK_STRING:
case BSHELL_TOK_STR_START:
case BSHELL_TOK_STR_END:
fx_puts("[green]");
debug_printf(GREEN);
break;
case BSHELL_TOK_LINEFEED:
fx_puts("[dark_grey]");
debug_printf(DARK_GREY);
break;
default:
break;
}
fx_puts(bshell_token_type_to_string(tok->tok_type));
fputs(bshell_token_type_to_string(tok->tok_type), stdout);
switch (tok->tok_type) {
case BSHELL_TOK_WORD:
@@ -79,13 +105,13 @@ extern void print_lex_token(struct bshell_lex_token *tok)
break;
}
fx_puts("[reset]\n");
debug_printf(RESET "\n");
}
void print_ast_node(struct bshell_ast_node *node)
{
for (unsigned long i = 0; i < node->n_it.e_depth; i++) {
fx_puts(" ");
fputs(" ", stdout);
}
switch (node->n_type) {
@@ -94,7 +120,7 @@ void print_ast_node(struct bshell_ast_node *node)
case BSHELL_AST_BLOCK:
case BSHELL_AST_FUNC:
case BSHELL_AST_STMT_LIST:
fx_puts("[magenta]");
debug_printf(MAGENTA);
break;
case BSHELL_AST_REDIRECTION:
case BSHELL_AST_PIPELINE:
@@ -102,29 +128,29 @@ void print_ast_node(struct bshell_ast_node *node)
case BSHELL_AST_ARRAY:
case BSHELL_AST_HASHTABLE:
case BSHELL_AST_HASHTABLE_ITEM:
fx_puts("[blue]");
debug_printf(BLUE);
break;
case BSHELL_AST_CMDCALL:
case BSHELL_AST_NULL:
fx_puts("[red]");
debug_printf(RED);
break;
case BSHELL_AST_INT:
case BSHELL_AST_DOUBLE:
case BSHELL_AST_VAR:
fx_puts("[yellow]");
debug_printf(YELLOW);
break;
case BSHELL_AST_WORD:
fx_puts("[cyan]");
debug_printf(CYAN);
break;
case BSHELL_AST_STRING:
case BSHELL_AST_FSTRING:
fx_puts("[green]");
debug_printf(GREEN);
break;
default:
break;
}
fx_printf("%s", bshell_ast_node_type_to_string(node->n_type));
debug_printf("%s", bshell_ast_node_type_to_string(node->n_type));
char s[128] = {0};
fx_bstr str;
@@ -132,10 +158,10 @@ void print_ast_node(struct bshell_ast_node *node)
bshell_ast_node_to_string(node, &str);
if (fx_bstr_get_size(&str)) {
fx_printf("(%s)", fx_bstr_end(&str));
debug_printf("(%s)", fx_bstr_end(&str));
}
fx_printf("[reset]\n");
debug_printf(RESET "\n");
}
void print_ast_node_recursive(struct bshell_ast_node *node)
@@ -212,22 +238,24 @@ void print_instruction(
bshell_instruction_decode(instr, &opcode, &arg);
fx_printf("%08x [blue]", instr);
debug_printf("%08x " BLUE, instr);
switch (opcode) {
case BSHELL_OPCODE_LDC_INT:
fx_printf("ldc.int [yellow]#0x%02x", arg);
debug_printf("ldc.int " YELLOW "#0x%02x", arg);
break;
case BSHELL_OPCODE_LDC_FP:
pool_value = bshell_scriptblock_get_pool_value(
container,
arg,
FX_TYPE_DOUBLE);
fx_printf("ldc.fp [cyan]@0x%02x ", arg);
debug_printf("ldc.fp " CYAN "@0x%02x ", arg);
if (pool_value) {
fx_value_get_double(pool_value, &d);
fx_printf("[reset][[[yellow]%g[reset]]", d);
debug_printf(
RESET LEFT_BRACKET YELLOW "%g" RESET "]",
d);
} else {
fx_printf("[red]<INVALID>[reset]");
debug_printf(RED "<INVALID>" RESET);
}
break;
@@ -242,30 +270,33 @@ void print_instruction(
arg,
FX_TYPE_CSTR);
}
fx_printf("ldc.str [cyan]@0x%02x ", arg);
debug_printf("ldc.str " CYAN "@0x%02x ", arg);
if (pool_value) {
fx_value_get_cstr(pool_value, &s);
fx_printf("[reset][[[green]%s[reset]]", s);
debug_printf(
RESET LEFT_BRACKET GREEN "%s" RESET "]",
s);
} else {
fx_printf("[red]<INVALID>[reset]");
debug_printf(RED "<INVALID>" RESET);
}
break;
case BSHELL_OPCODE_LDGLOBAL:
fx_printf("ldglobal [cyan]@0x%02x", arg);
debug_printf("ldglobal " CYAN "@0x%02x", arg);
break;
case BSHELL_OPCODE_LDBLOCK:
pool_value = bshell_scriptblock_get_pool_value(
container,
arg,
BSHELL_TYPE_SCRIPTBLOCK);
fx_printf("ldblock [cyan]@0x%02x ", arg);
debug_printf("ldblock " CYAN "@0x%02x ", arg);
if (pool_value) {
fx_printf("[reset][[[magenta]vvv[reset]]\n");
debug_printf(
RESET LEFT_BRACKET MAGENTA "vvv" RESET "]\n");
fx_value_get_object(pool_value, &obj);
print_scriptblock(obj, depth + 1);
} else {
fx_printf("[red]<INVALID>[reset]");
debug_printf(RED "<INVALID>" RESET);
}
break;
@@ -280,32 +311,34 @@ void print_instruction(
arg,
FX_TYPE_CSTR);
}
fx_printf("ldlocal [cyan]@0x%02x ", arg);
debug_printf("ldlocal " CYAN "@0x%02x ", arg);
if (pool_value) {
fx_value_get_cstr(pool_value, &s);
fx_printf("[reset][[[green]%s[reset]]", s);
debug_printf(
RESET LEFT_BRACKET GREEN "%s" RESET "]",
s);
} else {
fx_printf("[red]<INVALID>");
debug_printf(RED "<INVALID>");
}
break;
case BSHELL_OPCODE_LDENV:
fx_printf("ldenv [cyan]@0x%02x", arg);
debug_printf("ldenv " CYAN "@0x%02x", arg);
break;
case BSHELL_OPCODE_LDSTATIC:
fx_printf("ldstatic [cyan]@0x%02x", arg);
debug_printf("ldstatic " CYAN "@0x%02x", arg);
break;
case BSHELL_OPCODE_LDARG:
fx_printf("ldarg [cyan]@0x%02x", arg);
debug_printf("ldarg " CYAN "@0x%02x", arg);
break;
case BSHELL_OPCODE_LDPROP:
fx_printf("ldprop");
debug_printf("ldprop");
break;
case BSHELL_OPCODE_LDELEM:
fx_printf("ldelem [cyan]@0x%02x", arg);
debug_printf("ldelem " CYAN "@0x%02x", arg);
break;
case BSHELL_OPCODE_LDELEM_C:
fx_printf("ldelem.c [cyan]@0x%02x", arg);
debug_printf("ldelem.c " CYAN "@0x%02x", arg);
break;
case BSHELL_OPCODE_STLOCAL:
pool_value = bshell_scriptblock_get_pool_value(
@@ -318,173 +351,175 @@ void print_instruction(
arg,
FX_TYPE_CSTR);
}
fx_printf("stlocal [cyan]@0x%02x ", arg);
debug_printf("stlocal " CYAN "@0x%02x ", arg);
if (pool_value) {
fx_value_get_cstr(pool_value, &s);
fx_printf("[reset][[[green]%s[reset]]", s);
debug_printf(
RESET LEFT_BRACKET GREEN "%s" RESET "]",
s);
} else {
fx_printf("<INVALID>");
debug_printf("<INVALID>");
}
break;
case BSHELL_OPCODE_STPROP:
fx_printf("stprop [cyan]@0x%02x", arg);
debug_printf("stprop " CYAN "@0x%02x", arg);
break;
case BSHELL_OPCODE_STELEM:
fx_printf("stelem [cyan]@0x%02x", arg);
debug_printf("stelem " CYAN "@0x%02x", arg);
break;
case BSHELL_OPCODE_LDCMD:
fx_printf("ldcmd [yellow]#0x%02x", arg);
debug_printf("ldcmd " YELLOW "#0x%02x", arg);
break;
case BSHELL_OPCODE_PEXEC:
fx_printf("pexec [yellow]#0x%02x", arg);
debug_printf("pexec " YELLOW "#0x%02x", arg);
break;
case BSHELL_OPCODE_CALL:
fx_printf("call");
debug_printf("call");
break;
case BSHELL_OPCODE_MK_STR:
fx_printf("mk.str [yellow]#0x%02x", arg);
debug_printf("mk.str " YELLOW "#0x%02x", arg);
break;
case BSHELL_OPCODE_MK_ARRAY:
fx_printf("mk.array [yellow]#0x%02x", arg);
debug_printf("mk.array " YELLOW "#0x%02x", arg);
break;
case BSHELL_OPCODE_MK_HTAB:
fx_printf("mk.htab [yellow]#0x%02x", arg);
debug_printf("mk.htab " YELLOW "#0x%02x", arg);
break;
case BSHELL_OPCODE_POP:
fx_printf("pop");
debug_printf("pop");
break;
case BSHELL_OPCODE_ADD:
fx_printf("add");
debug_printf("add");
break;
case BSHELL_OPCODE_SUB:
fx_printf("sub");
debug_printf("sub");
break;
case BSHELL_OPCODE_MUL:
fx_printf("mul");
debug_printf("mul");
break;
case BSHELL_OPCODE_DIV:
fx_printf("div");
debug_printf("div");
break;
case BSHELL_OPCODE_ADD_IP:
fx_printf("add.ip");
debug_printf("add.ip");
break;
case BSHELL_OPCODE_MOD:
fx_printf("mod");
debug_printf("mod");
break;
case BSHELL_OPCODE_INC:
fx_printf("inc");
debug_printf("inc");
break;
case BSHELL_OPCODE_DEC:
fx_printf("dec");
debug_printf("dec");
break;
case BSHELL_OPCODE_SHL:
fx_printf("shl");
debug_printf("shl");
break;
case BSHELL_OPCODE_SHR:
fx_printf("shr");
debug_printf("shr");
break;
case BSHELL_OPCODE_BAND:
fx_printf("band");
debug_printf("band");
break;
case BSHELL_OPCODE_BOR:
fx_printf("bor");
debug_printf("bor");
break;
case BSHELL_OPCODE_BXOR:
fx_printf("bxor");
debug_printf("bxor");
break;
case BSHELL_OPCODE_BNOT:
fx_printf("bnot");
debug_printf("bnot");
break;
case BSHELL_OPCODE_CMP_NULL:
fx_printf("cmp.null");
debug_printf("cmp.null");
break;
case BSHELL_OPCODE_CMP_EQ:
fx_printf("cmp.eq");
debug_printf("cmp.eq");
break;
case BSHELL_OPCODE_CMP_NE:
fx_printf("cmp.ne");
debug_printf("cmp.ne");
break;
case BSHELL_OPCODE_CMP_LT:
fx_printf("cmp.lt");
debug_printf("cmp.lt");
break;
case BSHELL_OPCODE_CMP_GT:
fx_printf("cmp.gt");
debug_printf("cmp.gt");
break;
case BSHELL_OPCODE_CMP_LE:
fx_printf("cmp.le");
debug_printf("cmp.le");
break;
case BSHELL_OPCODE_CMP_GE:
fx_printf("cmp.ge");
debug_printf("cmp.ge");
break;
case BSHELL_OPCODE_LAND:
fx_printf("land");
debug_printf("land");
break;
case BSHELL_OPCODE_LOR:
fx_printf("lor");
debug_printf("lor");
break;
case BSHELL_OPCODE_LXOR:
fx_printf("lxor");
debug_printf("lxor");
break;
case BSHELL_OPCODE_LNOT:
fx_printf("lnot");
debug_printf("lnot");
break;
case BSHELL_OPCODE_BR:
fx_printf(
"br [yellow]#0x%04x [=%04llx]",
debug_printf(
"br " YELLOW "#0x%04x [=%04llx]",
arg,
(long long)arg + (long long)offset);
break;
case BSHELL_OPCODE_BR_TRUE:
fx_printf(
"br.true [yellow]#0x%04x [=%04llx]",
debug_printf(
"br.true " YELLOW "#0x%04x [=%04llx]",
arg,
(long long)arg + (long long)offset);
break;
case BSHELL_OPCODE_RANGE:
fx_printf("range");
debug_printf("range");
break;
case BSHELL_OPCODE_MATCH:
fx_printf("match");
debug_printf("match");
break;
case BSHELL_OPCODE_REPLACE:
fx_printf("replace");
debug_printf("replace");
break;
case BSHELL_OPCODE_LIKE:
fx_printf("like");
debug_printf("like");
break;
case BSHELL_OPCODE_IN:
fx_printf("in");
debug_printf("in");
break;
case BSHELL_OPCODE_FMT:
fx_printf("fmt");
debug_printf("fmt");
break;
case BSHELL_OPCODE_CONTAINS:
fx_printf("contains");
debug_printf("contains");
break;
case BSHELL_OPCODE_SPLIT:
fx_printf("split");
debug_printf("split");
break;
case BSHELL_OPCODE_JOIN:
fx_printf("join");
debug_printf("join");
break;
case BSHELL_OPCODE_IS:
fx_printf("is");
debug_printf("is");
break;
case BSHELL_OPCODE_AS:
fx_printf("as");
debug_printf("as");
break;
default:
fx_printf("INVALID\n");
debug_printf("INVALID\n");
break;
}
fx_printf("[reset]\n");
debug_printf(RESET "\n");
}
void print_value(fx_value *val)
{
fx_printf("[yellow]");
debug_printf(YELLOW);
fx_value_to_string(val, fx_stdout, NULL);
fx_printf("[reset]\n");
debug_printf(RESET "\n");
}
+21 -4
View File
@@ -43,19 +43,19 @@ static void lex_and_parse(struct bshell_parse_ctx *parse)
{
}
#if BSHELL_VERBOSE == 1
static void lex_token_scanned(
struct bshell_lex_ctx *ctx,
struct bshell_lex_token *tok)
{
print_lex_token(tok);
}
#endif
extern int compare_token_types(unsigned int a, unsigned int b);
int main(int argc, const char **argv)
{
printf("B Shell " BSHELL_VERSION "\n");
bshell_assembly_get();
bshell_runtime_assembly_get();
bshell_core_assembly_get();
@@ -68,10 +68,12 @@ int main(int argc, const char **argv)
struct bshell_line_source *linesrc = NULL;
enum bshell_status status = BSHELL_SUCCESS;
bool interactive = true;
if (argc > 1) {
status = bshell_file_open(argv[1], &file);
linesrc = &file->f_base;
interactive = false;
} else {
#if BSHELL_INTERACTIVE == 1
ed = line_ed_create();
@@ -83,8 +85,10 @@ int main(int argc, const char **argv)
}
struct bshell_lex_ctx lex = {0};
bshell_lex_ctx_init(&lex, LEX_PRINT_TOKENS, linesrc);
bshell_lex_ctx_init(&lex, 0, linesrc);
#if BSHELL_VERBOSE == 1
lex.lex_token_scanned = lex_token_scanned;
#endif
struct bshell_parse_ctx parse = {0};
bshell_parse_ctx_init(&parse, &lex);
@@ -93,6 +97,10 @@ int main(int argc, const char **argv)
return 0;
#endif
if (interactive) {
printf("B Shell " BSHELL_VERSION "\n");
}
bshell_scriptblock *block = bshell_scriptblock_create();
struct bshell_runtime *rt = bshell_runtime_create();
@@ -103,15 +111,19 @@ int main(int argc, const char **argv)
break;
}
#if BSHELL_VERBOSE == 1
print_ast_node_recursive(node);
printf("----\n");
#endif
bshell_scriptblock_clear_text(block);
switch (node->n_type) {
case BSHELL_AST_FUNC: {
bshell_function *func = NULL;
bshell_compile_function(node, &func);
#if BSHELL_VERBOSE == 1
print_function(func);
#endif
bshell_runtime_define_function(rt, func);
bshell_function_unref(func);
break;
@@ -119,12 +131,17 @@ int main(int argc, const char **argv)
default: {
bshell_compile(node, block);
#if BSHELL_VERBOSE == 1
print_scriptblock(block, 0);
#endif
fx_value result = bshell_runtime_eval_global(rt, block);
if (result.v_type != NULL) {
if (interactive && result.v_type != NULL) {
format_value_default(&result, fx_stdout);
}
fx_value_unset(&result);
break;
}
}