bshell: re-organise build into three separate components

bshell: the front-end binary
bshell.runtime: contains the parser, compiler, and classes needed to run bshell scripts
bshell.core: contains the builtin commandlets and aliases
This commit is contained in:
2026-05-25 10:33:29 +01:00
parent 58c76a1f57
commit edfb3e24a3
165 changed files with 5173 additions and 4995 deletions
+28
View File
@@ -0,0 +1,28 @@
#include <bshell/ast.h>
#include <bshell/parse/token.h>
static enum bshell_status collect_children(
struct bshell_ast_node *node,
struct bshell_ast_iterator *it)
{
struct bshell_array_ast_node *array = (struct bshell_array_ast_node *)
node;
fx_queue_entry *cur = fx_queue_first(&array->n_items);
while (cur) {
struct bshell_ast_node *child = fx_unbox(
struct bshell_ast_node,
cur,
n_entry);
bshell_ast_iterator_enqueue(it, child);
cur = fx_queue_next(cur);
}
return BSHELL_SUCCESS;
}
struct bshell_ast_node_definition array_bshell_ast_node = {
.def_id = BSHELL_AST_ARRAY,
.def_node_size = sizeof(struct bshell_array_ast_node),
.def_collect_children = collect_children,
};
+277
View File
@@ -0,0 +1,277 @@
#include <assert.h>
#include <bshell/ast.h>
#include <bshell/status.h>
#include <stdlib.h>
#include <string.h>
extern struct bshell_ast_node_definition null_bshell_ast_node;
extern struct bshell_ast_node_definition int_bshell_ast_node;
extern struct bshell_ast_node_definition double_bshell_ast_node;
extern struct bshell_ast_node_definition word_bshell_ast_node;
extern struct bshell_ast_node_definition var_bshell_ast_node;
extern struct bshell_ast_node_definition string_bshell_ast_node;
extern struct bshell_ast_node_definition fstring_bshell_ast_node;
extern struct bshell_ast_node_definition cmdcall_bshell_ast_node;
extern struct bshell_ast_node_definition pipeline_bshell_ast_node;
extern struct bshell_ast_node_definition redirection_bshell_ast_node;
extern struct bshell_ast_node_definition block_bshell_ast_node;
extern struct bshell_ast_node_definition stmt_list_bshell_ast_node;
extern struct bshell_ast_node_definition func_bshell_ast_node;
extern struct bshell_ast_node_definition array_bshell_ast_node;
extern struct bshell_ast_node_definition hashtable_bshell_ast_node;
extern struct bshell_ast_node_definition hashtable_item_bshell_ast_node;
extern struct bshell_ast_node_definition if_bshell_ast_node;
extern struct bshell_ast_node_definition if_branch_bshell_ast_node;
extern struct bshell_ast_node_definition op_bshell_ast_node;
static const struct bshell_ast_node_definition *bshell_ast_node_definitions[]
= {
[BSHELL_AST_NULL] = &null_bshell_ast_node,
[BSHELL_AST_INT] = &int_bshell_ast_node,
[BSHELL_AST_DOUBLE] = &double_bshell_ast_node,
[BSHELL_AST_WORD] = &word_bshell_ast_node,
[BSHELL_AST_VAR] = &var_bshell_ast_node,
[BSHELL_AST_STRING] = &string_bshell_ast_node,
[BSHELL_AST_FSTRING] = &fstring_bshell_ast_node,
[BSHELL_AST_CMDCALL] = &cmdcall_bshell_ast_node,
[BSHELL_AST_PIPELINE] = &pipeline_bshell_ast_node,
[BSHELL_AST_REDIRECTION] = &redirection_bshell_ast_node,
[BSHELL_AST_BLOCK] = &block_bshell_ast_node,
[BSHELL_AST_STMT_LIST] = &stmt_list_bshell_ast_node,
[BSHELL_AST_FUNC] = &func_bshell_ast_node,
[BSHELL_AST_ARRAY] = &array_bshell_ast_node,
[BSHELL_AST_IF] = &if_bshell_ast_node,
[BSHELL_AST_IF_BRANCH] = &if_branch_bshell_ast_node,
[BSHELL_AST_HASHTABLE] = &hashtable_bshell_ast_node,
[BSHELL_AST_HASHTABLE_ITEM] = &hashtable_item_bshell_ast_node,
[BSHELL_AST_OP] = &op_bshell_ast_node,
};
static const size_t nr_bshell_ast_node_definitions
= sizeof bshell_ast_node_definitions
/ sizeof bshell_ast_node_definitions[0];
struct bshell_ast_node *bshell_ast_node_create(enum bshell_ast_node_type type)
{
assert(type < nr_bshell_ast_node_definitions);
const struct bshell_ast_node_definition *def
= bshell_ast_node_definitions[type];
struct bshell_ast_node *out = malloc(def->def_node_size);
if (!out) {
return NULL;
}
memset(out, 0x0, def->def_node_size);
out->n_type = type;
return out;
}
void bshell_ast_node_destroy(struct bshell_ast_node *node)
{
assert(node->n_type < nr_bshell_ast_node_definitions);
struct bshell_ast_iterator it = {0};
bshell_ast_iterator_enqueue(&it, node);
while (1) {
node = bshell_ast_iterator_peek(&it);
if (!node) {
break;
}
const struct bshell_ast_node_definition *def
= bshell_ast_node_definitions[node->n_type];
if (def->def_cleanup) {
def->def_cleanup(node);
}
bshell_ast_iterator_dequeue(&it);
free(node);
}
}
void bshell_ast_node_to_string(const struct bshell_ast_node *node, fx_bstr *out)
{
const struct bshell_ast_node_definition *def
= bshell_ast_node_definitions[node->n_type];
if (def->def_to_string) {
def->def_to_string(node, out);
}
}
#define ENUM_STR(x) \
case x: \
return #x
const char *bshell_ast_node_type_to_string(enum bshell_ast_node_type type)
{
switch (type) {
ENUM_STR(BSHELL_AST_NONE);
ENUM_STR(BSHELL_AST_NULL);
ENUM_STR(BSHELL_AST_STMT_LIST);
ENUM_STR(BSHELL_AST_INT);
ENUM_STR(BSHELL_AST_DOUBLE);
ENUM_STR(BSHELL_AST_WORD);
ENUM_STR(BSHELL_AST_STRING);
ENUM_STR(BSHELL_AST_FSTRING);
ENUM_STR(BSHELL_AST_VAR);
ENUM_STR(BSHELL_AST_VAR_SPLAT);
ENUM_STR(BSHELL_AST_FLAG);
ENUM_STR(BSHELL_AST_CMDCALL);
ENUM_STR(BSHELL_AST_PIPELINE);
ENUM_STR(BSHELL_AST_REDIRECTION);
ENUM_STR(BSHELL_AST_BLOCK);
ENUM_STR(BSHELL_AST_FUNC);
ENUM_STR(BSHELL_AST_IF);
ENUM_STR(BSHELL_AST_IF_BRANCH);
ENUM_STR(BSHELL_AST_OP);
ENUM_STR(BSHELL_AST_ARRAY);
ENUM_STR(BSHELL_AST_HASHTABLE);
ENUM_STR(BSHELL_AST_HASHTABLE_ITEM);
default:
return "<unknown>";
}
}
struct bshell_ast_node *bshell_ast_iterator_peek(struct bshell_ast_iterator *it)
{
fx_queue_entry *cur = fx_queue_first(&it->it_queue);
if (!cur) {
return NULL;
}
return fx_unbox(struct bshell_ast_node, cur, n_it.e_entry);
}
struct bshell_ast_node *bshell_ast_iterator_dequeue(
struct bshell_ast_iterator *it)
{
fx_queue_entry *cur = fx_queue_first(&it->it_queue);
if (!cur) {
return NULL;
}
struct bshell_ast_node *node = fx_unbox(
struct bshell_ast_node,
cur,
n_it.e_entry);
const struct bshell_ast_node_definition *def
= bshell_ast_node_definitions[node->n_type];
it->it_insert_after = cur;
if (def->def_collect_children) {
def->def_collect_children(node, it);
}
fx_queue_pop_front(&it->it_queue);
return fx_unbox(struct bshell_ast_node, cur, n_it.e_entry);
}
void bshell_ast_iterator_enqueue(
struct bshell_ast_iterator *it,
struct bshell_ast_node *node)
{
unsigned long new_depth = 0;
fx_queue_entry *cur = fx_queue_first(&it->it_queue);
if (cur) {
struct bshell_ast_node *cur_node = fx_unbox(
struct bshell_ast_node,
cur,
n_it.e_entry);
new_depth = cur_node->n_it.e_depth + 1;
}
node->n_it.e_depth = new_depth;
if (!it->it_insert_after) {
fx_queue_push_back(&it->it_queue, &node->n_it.e_entry);
return;
}
fx_queue_insert_after(
&it->it_queue,
&node->n_it.e_entry,
it->it_insert_after);
it->it_insert_after = &node->n_it.e_entry;
}
enum bshell_status bshell_ast_node_iterate(
struct bshell_ast_node *node,
struct bshell_ast_iterator *it,
bshell_ast_iterator_callback callback,
void *arg)
{
fx_queue_push_back(&it->it_queue, &node->n_it.e_entry);
node->n_it.e_depth = 0;
fx_queue_entry *entry = fx_queue_first(&it->it_queue);
while (entry) {
struct bshell_ast_iterator_entry *it_entry = fx_unbox(
struct bshell_ast_iterator_entry,
entry,
e_entry);
node = fx_unbox(struct bshell_ast_node, it_entry, n_it);
if (!node) {
/* this should never happen. */
return BSHELL_ERR_INTERNAL_FAILURE;
}
struct bshell_ast_iterate_result result = callback(
node,
BSHELL_AST_ITERATION_PRE,
it,
arg);
if (result.r_status != BSHELL_SUCCESS
|| result.r_flags & BSHELL_AST_ITERATE_STOP) {
return result.r_status;
}
const struct bshell_ast_node_definition *type
= bshell_ast_node_definitions[node->n_type];
if (type->def_collect_children
&& result.r_flags & BSHELL_AST_ITERATE_ADD_CHILDREN) {
it->it_insert_after = entry;
type->def_collect_children(node, it);
}
if (!(result.r_flags & BSHELL_AST_ITERATE_REPEAT)) {
entry = fx_queue_next(entry);
}
}
while (!fx_queue_empty(&it->it_queue)) {
fx_queue_entry *entry = fx_queue_last(&it->it_queue);
if (!entry) {
break;
}
node = fx_unbox(struct bshell_ast_node, entry, n_it);
if (!node) {
/* this should never happen. */
return BSHELL_ERR_INTERNAL_FAILURE;
}
struct bshell_ast_iterate_result result = callback(
node,
BSHELL_AST_ITERATION_POST,
it,
arg);
if (result.r_status != BSHELL_SUCCESS
|| result.r_flags & BSHELL_AST_ITERATE_STOP) {
return result.r_status;
}
if (!(result.r_flags & BSHELL_AST_ITERATE_REPEAT)) {
fx_queue_pop_back(&it->it_queue);
}
}
return BSHELL_SUCCESS;
}
+26
View File
@@ -0,0 +1,26 @@
#include <bshell/ast.h>
static enum bshell_status collect_children(
struct bshell_ast_node *node,
struct bshell_ast_iterator *it)
{
struct bshell_block_ast_node *block = (struct bshell_block_ast_node *)
node;
fx_queue_entry *cur = fx_queue_first(&block->n_statements);
while (cur) {
struct bshell_ast_node *child = fx_unbox(
struct bshell_ast_node,
cur,
n_entry);
bshell_ast_iterator_enqueue(it, child);
cur = fx_queue_next(cur);
}
return BSHELL_SUCCESS;
}
struct bshell_ast_node_definition block_bshell_ast_node = {
.def_id = BSHELL_AST_BLOCK,
.def_node_size = sizeof(struct bshell_block_ast_node),
.def_collect_children = collect_children,
};
+37
View File
@@ -0,0 +1,37 @@
#include <bshell/ast.h>
static enum bshell_status collect_children(
struct bshell_ast_node *node,
struct bshell_ast_iterator *it)
{
struct bshell_cmdcall_ast_node *cmdcall = (struct
bshell_cmdcall_ast_node *)
node;
fx_queue_entry *cur = fx_queue_first(&cmdcall->n_args);
while (cur) {
struct bshell_ast_node *child = fx_unbox(
struct bshell_ast_node,
cur,
n_entry);
bshell_ast_iterator_enqueue(it, child);
cur = fx_queue_next(cur);
}
cur = fx_queue_first(&cmdcall->n_redirect);
while (cur) {
struct bshell_ast_node *child = fx_unbox(
struct bshell_ast_node,
cur,
n_entry);
bshell_ast_iterator_enqueue(it, child);
cur = fx_queue_next(cur);
}
return BSHELL_SUCCESS;
}
struct bshell_ast_node_definition cmdcall_bshell_ast_node = {
.def_id = BSHELL_AST_CMDCALL,
.def_node_size = sizeof(struct bshell_cmdcall_ast_node),
.def_collect_children = collect_children,
};
+16
View File
@@ -0,0 +1,16 @@
#include <bshell/ast.h>
#include <bshell/parse/token.h>
#include <fx/stream.h>
static void to_string(const struct bshell_ast_node *node, fx_bstr *out)
{
struct bshell_double_ast_node *i = (struct bshell_double_ast_node *)
node;
fx_value_to_string(&i->n_value->tok_number, (fx_stream *)out, NULL);
}
struct bshell_ast_node_definition double_bshell_ast_node = {
.def_id = BSHELL_AST_DOUBLE,
.def_node_size = sizeof(struct bshell_double_ast_node),
.def_to_string = to_string,
};
+26
View File
@@ -0,0 +1,26 @@
#include <bshell/ast.h>
static enum bshell_status collect_children(
struct bshell_ast_node *node,
struct bshell_ast_iterator *it)
{
struct bshell_fstring_ast_node *fstring;
fstring = (struct bshell_fstring_ast_node *)node;
fx_queue_entry *cur = fx_queue_first(&fstring->n_elements);
while (cur) {
struct bshell_ast_node *child = fx_unbox(
struct bshell_ast_node,
cur,
n_entry);
bshell_ast_iterator_enqueue(it, child);
cur = fx_queue_next(cur);
}
return BSHELL_SUCCESS;
}
struct bshell_ast_node_definition fstring_bshell_ast_node = {
.def_id = BSHELL_AST_FSTRING,
.def_node_size = sizeof(struct bshell_fstring_ast_node),
.def_collect_children = collect_children,
};
+39
View File
@@ -0,0 +1,39 @@
#include <bshell/ast.h>
#include <bshell/parse/token.h>
static enum bshell_status collect_children(
struct bshell_ast_node *node,
struct bshell_ast_iterator *it)
{
struct bshell_func_ast_node *func = (struct bshell_func_ast_node *)node;
fx_queue_entry *cur = fx_queue_first(&func->n_params);
while (cur) {
struct bshell_ast_node *child = fx_unbox(
struct bshell_ast_node,
cur,
n_entry);
bshell_ast_iterator_enqueue(it, child);
cur = fx_queue_next(cur);
}
if (func->n_body) {
bshell_ast_iterator_enqueue(it, func->n_body);
}
return BSHELL_SUCCESS;
}
static void to_string(const struct bshell_ast_node *node, fx_bstr *out)
{
const struct bshell_func_ast_node *func = (const struct
bshell_func_ast_node *)node;
fx_bstr_write_fmt(out, NULL, "%s", func->n_name->tok_str);
}
struct bshell_ast_node_definition func_bshell_ast_node = {
.def_id = BSHELL_AST_FUNC,
.def_node_size = sizeof(struct bshell_func_ast_node),
.def_collect_children = collect_children,
.def_to_string = to_string,
};
+26
View File
@@ -0,0 +1,26 @@
#include <bshell/ast.h>
#include <bshell/parse/token.h>
static enum bshell_status collect_children(
struct bshell_ast_node *node,
struct bshell_ast_iterator *it)
{
struct bshell_hashtable_item_ast_node *item
= (struct bshell_hashtable_item_ast_node *)node;
if (item->n_key) {
bshell_ast_iterator_enqueue(it, item->n_key);
}
if (item->n_value) {
bshell_ast_iterator_enqueue(it, item->n_value);
}
return BSHELL_SUCCESS;
}
struct bshell_ast_node_definition hashtable_item_bshell_ast_node = {
.def_id = BSHELL_AST_HASHTABLE_ITEM,
.def_node_size = sizeof(struct bshell_hashtable_item_ast_node),
.def_collect_children = collect_children,
};
+24
View File
@@ -0,0 +1,24 @@
#include <bshell/ast.h>
static enum bshell_status collect_children(
struct bshell_ast_node *node,
struct bshell_ast_iterator *it)
{
struct bshell_hashtable_ast_node *hashtable
= (struct bshell_hashtable_ast_node *)node;
fx_queue_entry *cur = fx_queue_first(&hashtable->n_items);
while (cur) {
struct bshell_ast_node *child
= fx_unbox(struct bshell_ast_node, cur, n_entry);
bshell_ast_iterator_enqueue(it, child);
cur = fx_queue_next(cur);
}
return BSHELL_SUCCESS;
}
struct bshell_ast_node_definition hashtable_bshell_ast_node = {
.def_id = BSHELL_AST_HASHTABLE,
.def_node_size = sizeof(struct bshell_hashtable_ast_node),
.def_collect_children = collect_children,
};
+24
View File
@@ -0,0 +1,24 @@
#include <bshell/ast.h>
static enum bshell_status collect_children(
struct bshell_ast_node *node,
struct bshell_ast_iterator *it)
{
struct bshell_if_branch_ast_node *if_branch
= (struct bshell_if_branch_ast_node *)node;
if (if_branch->n_cond) {
bshell_ast_iterator_enqueue(it, if_branch->n_cond);
}
if (if_branch->n_body) {
bshell_ast_iterator_enqueue(it, if_branch->n_body);
}
return BSHELL_SUCCESS;
}
struct bshell_ast_node_definition if_branch_bshell_ast_node = {
.def_id = BSHELL_AST_IF_BRANCH,
.def_node_size = sizeof(struct bshell_if_branch_ast_node),
.def_collect_children = collect_children,
};
+23
View File
@@ -0,0 +1,23 @@
#include <bshell/ast.h>
static enum bshell_status collect_children(
struct bshell_ast_node *node,
struct bshell_ast_iterator *it)
{
struct bshell_if_ast_node *if_group = (struct bshell_if_ast_node *)node;
fx_queue_entry *cur = fx_queue_first(&if_group->n_branches);
while (cur) {
struct bshell_ast_node *child
= fx_unbox(struct bshell_ast_node, cur, n_entry);
bshell_ast_iterator_enqueue(it, child);
cur = fx_queue_next(cur);
}
return BSHELL_SUCCESS;
}
struct bshell_ast_node_definition if_bshell_ast_node = {
.def_id = BSHELL_AST_IF,
.def_node_size = sizeof(struct bshell_if_ast_node),
.def_collect_children = collect_children,
};
+15
View File
@@ -0,0 +1,15 @@
#include <bshell/ast.h>
#include <bshell/parse/token.h>
#include <fx/stream.h>
static void to_string(const struct bshell_ast_node *node, fx_bstr *out)
{
struct bshell_int_ast_node *i = (struct bshell_int_ast_node *)node;
fx_value_to_string(&i->n_value->tok_number, (fx_stream *)out, NULL);
}
struct bshell_ast_node_definition int_bshell_ast_node = {
.def_id = BSHELL_AST_INT,
.def_node_size = sizeof(struct bshell_int_ast_node),
.def_to_string = to_string,
};
+7
View File
@@ -0,0 +1,7 @@
#include <bshell/ast.h>
#include <bshell/parse/token.h>
struct bshell_ast_node_definition null_bshell_ast_node = {
.def_id = BSHELL_AST_NULL,
.def_node_size = sizeof(struct bshell_null_ast_node),
};
+38
View File
@@ -0,0 +1,38 @@
#include <bshell/ast.h>
#include <bshell/parse/token.h>
#include <bshell/runtime/operator.h>
static enum bshell_status collect_children(
struct bshell_ast_node *node,
struct bshell_ast_iterator *it)
{
struct bshell_op_ast_node *op = (struct bshell_op_ast_node *)node;
if (op->n_left) {
bshell_ast_iterator_enqueue(it, op->n_left);
}
if (op->n_right) {
bshell_ast_iterator_enqueue(it, op->n_right);
}
return BSHELL_SUCCESS;
}
static void to_string(const struct bshell_ast_node *node, fx_bstr *out)
{
const struct bshell_op_ast_node *op = (const struct bshell_op_ast_node
*)node;
fx_bstr_write_fmt(
out,
NULL,
"%s",
bshell_operator_id_to_string(op->n_op->op_id));
}
struct bshell_ast_node_definition op_bshell_ast_node = {
.def_id = BSHELL_AST_OP,
.def_node_size = sizeof(struct bshell_op_ast_node),
.def_collect_children = collect_children,
.def_to_string = to_string,
};
+26
View File
@@ -0,0 +1,26 @@
#include <bshell/ast.h>
static enum bshell_status collect_children(
struct bshell_ast_node *node,
struct bshell_ast_iterator *it)
{
struct bshell_pipeline_ast_node *pipeline;
pipeline = (struct bshell_pipeline_ast_node *)node;
fx_queue_entry *cur = fx_queue_first(&pipeline->n_stages);
while (cur) {
struct bshell_ast_node *child = fx_unbox(
struct bshell_ast_node,
cur,
n_entry);
bshell_ast_iterator_enqueue(it, child);
cur = fx_queue_next(cur);
}
return BSHELL_SUCCESS;
}
struct bshell_ast_node_definition pipeline_bshell_ast_node = {
.def_id = BSHELL_AST_PIPELINE,
.def_node_size = sizeof(struct bshell_pipeline_ast_node),
.def_collect_children = collect_children,
};
+49
View File
@@ -0,0 +1,49 @@
#include <bshell/ast.h>
static enum bshell_status collect_children(
struct bshell_ast_node *node,
struct bshell_ast_iterator *it)
{
struct bshell_redirection_ast_node *redirection
= (struct bshell_redirection_ast_node *)node;
if (redirection->n_out_path_expr) {
bshell_ast_iterator_enqueue(it, redirection->n_out_path_expr);
}
return BSHELL_SUCCESS;
}
static void to_string(const struct bshell_ast_node *node, fx_bstr *out)
{
struct bshell_redirection_ast_node *redirection
= (struct bshell_redirection_ast_node *)node;
fx_bstr_write_fmt(out, NULL, "&%u", redirection->n_in);
if (redirection->n_append) {
fx_bstr_write_fmt(out, NULL, " >>");
} else {
fx_bstr_write_fmt(out, NULL, " >");
}
if (redirection->n_out_is_fd) {
fx_bstr_write_fmt(out, NULL, " &");
} else {
fx_bstr_write_fmt(out, NULL, " ");
}
if (redirection->n_out_is_expr) {
fx_bstr_write_fmt(out, NULL, "<expr>");
} else if (redirection->n_out_path) {
fx_bstr_write_fmt(out, NULL, "'%s'", redirection->n_out_path);
} else {
fx_bstr_write_fmt(out, NULL, "%u", redirection->n_out);
}
}
struct bshell_ast_node_definition redirection_bshell_ast_node = {
.def_id = BSHELL_AST_REDIRECTION,
.def_node_size = sizeof(struct bshell_redirection_ast_node),
.def_collect_children = collect_children,
.def_to_string = to_string,
};
+24
View File
@@ -0,0 +1,24 @@
#include <bshell/ast.h>
static enum bshell_status collect_children(
struct bshell_ast_node *node,
struct bshell_ast_iterator *it)
{
struct bshell_stmt_list_ast_node *stmt_list
= (struct bshell_stmt_list_ast_node *)node;
fx_queue_entry *cur = fx_queue_first(&stmt_list->n_statements);
while (cur) {
struct bshell_ast_node *child
= fx_unbox(struct bshell_ast_node, cur, n_entry);
bshell_ast_iterator_enqueue(it, child);
cur = fx_queue_next(cur);
}
return BSHELL_SUCCESS;
}
struct bshell_ast_node_definition stmt_list_bshell_ast_node = {
.def_id = BSHELL_AST_STMT_LIST,
.def_node_size = sizeof(struct bshell_stmt_list_ast_node),
.def_collect_children = collect_children,
};
+16
View File
@@ -0,0 +1,16 @@
#include <bshell/ast.h>
#include <bshell/parse/token.h>
static void to_string(const struct bshell_ast_node *node, fx_bstr *out)
{
const struct bshell_string_ast_node *string = (const struct
bshell_string_ast_node *)
node;
fx_bstr_write_fmt(out, NULL, "%s", string->n_value->tok_str);
}
struct bshell_ast_node_definition string_bshell_ast_node = {
.def_id = BSHELL_AST_STRING,
.def_node_size = sizeof(struct bshell_string_ast_node),
.def_to_string = to_string,
};
+15
View File
@@ -0,0 +1,15 @@
#include <bshell/ast.h>
#include <bshell/parse/token.h>
static void to_string(const struct bshell_ast_node *node, fx_bstr *out)
{
const struct bshell_var_ast_node *var = (const struct
bshell_var_ast_node *)node;
fx_bstr_write_fmt(out, NULL, "%s", var->n_ident->tok_str);
}
struct bshell_ast_node_definition var_bshell_ast_node = {
.def_id = BSHELL_AST_VAR,
.def_node_size = sizeof(struct bshell_var_ast_node),
.def_to_string = to_string,
};
+15
View File
@@ -0,0 +1,15 @@
#include <bshell/ast.h>
#include <bshell/parse/token.h>
static void to_string(const struct bshell_ast_node *node, fx_bstr *out)
{
const struct bshell_word_ast_node *word = (const struct
bshell_word_ast_node *)node;
fx_bstr_write_fmt(out, NULL, "%s", word->n_value->tok_str);
}
struct bshell_ast_node_definition word_bshell_ast_node = {
.def_id = BSHELL_AST_WORD,
.def_node_size = sizeof(struct bshell_word_ast_node),
.def_to_string = to_string,
};