Files
bshell/bshell.runtime/parse/lex/string.c
T
wash edfb3e24a3 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
2026-05-25 10:33:29 +01:00

142 lines
3.0 KiB
C

#include "lex-internal.h"
static enum bshell_status string_symbol(struct bshell_lex_ctx *ctx)
{
const struct bshell_lex_token_definition *sym = NULL;
enum bshell_status status = read_symbol(ctx, &sym);
if (status != BSHELL_SUCCESS) {
return status;
}
handle_lex_state_transition(ctx, sym->id);
struct bshell_lex_token *tok = NULL;
switch (sym->id) {
case BSHELL_SYM_DQUOTE:
return BSHELL_SUCCESS;
case BSHELL_SYM_DOLLAR_LEFT_PAREN:
return push_symbol(ctx, sym->id);
case BSHELL_SYM_DOLLAR:
status = read_var(ctx, BSHELL_TOK_VAR, &tok);
if (status != BSHELL_SUCCESS) {
return status;
}
enqueue_token(ctx, tok);
return status;
case BSHELL_SYM_AT:
status = read_var(ctx, BSHELL_TOK_VAR_SPLAT, &tok);
if (status != BSHELL_SUCCESS) {
return status;
}
enqueue_token(ctx, tok);
return status;
case BSHELL_SYM_DOLLAR_LEFT_BRACE:
status = read_braced_var(ctx, BSHELL_TOK_VAR, &tok);
if (status != BSHELL_SUCCESS) {
return status;
}
enqueue_token(ctx, tok);
return status;
default:
break;
}
return BSHELL_ERR_BAD_SYNTAX;
}
static enum bshell_status string_content(struct bshell_lex_ctx *ctx)
{
fx_wchar c = FX_WCHAR_INVALID;
fx_string *temp = lex_state_get_tempstr(ctx);
set_token_start(ctx);
fx_string_clear(temp);
while (1) {
c = peek_char(ctx);
if (c == FX_WCHAR_INVALID) {
/* EOF without end of string */
ctx->lex_status = BSHELL_ERR_BAD_SYNTAX;
}
if (char_can_begin_symbol(ctx, c)) {
break;
}
fx_string_append_wc(temp, c);
set_token_end(ctx);
advance_char(ctx);
}
if (fx_string_get_size(temp, FX_STRLEN_NORMAL) == 0) {
return BSHELL_SUCCESS;
}
struct bshell_lex_token *tok = bshell_lex_token_create_with_string(
BSHELL_TOK_STRING,
fx_string_get_cstr(temp));
enqueue_token(ctx, tok);
return BSHELL_SUCCESS;
}
static enum bshell_status string_begin(struct bshell_lex_ctx *ctx)
{
struct bshell_lex_token *tok = bshell_lex_token_create(BSHELL_TOK_STR_START);
if (!tok) {
return BSHELL_ERR_NO_MEMORY;
}
enqueue_token(ctx, tok);
return BSHELL_SUCCESS;
}
static enum bshell_status string_end(struct bshell_lex_ctx *ctx)
{
struct bshell_lex_token *tok = bshell_lex_token_create(BSHELL_TOK_STR_END);
if (!tok) {
return BSHELL_ERR_NO_MEMORY;
}
enqueue_token(ctx, tok);
return BSHELL_SUCCESS;
}
static enum bshell_status string_pump_token(struct bshell_lex_ctx *ctx)
{
fx_wchar c = peek_char(ctx);
if (char_can_begin_symbol(ctx, c)) {
return string_symbol(ctx);
}
return string_content(ctx);
}
static const struct bshell_lex_state_link links[] = {
LINK_PUSH(BSHELL_SYM_DOLLAR_LEFT_PAREN, BSHELL_LEX_STATE_STATEMENT, 0),
LINK_POP(BSHELL_SYM_DQUOTE),
LINK_END,
};
static const unsigned int symbols[] = {
BSHELL_SYM_DOLLAR,
BSHELL_SYM_DOLLAR_LEFT_PAREN,
BSHELL_SYM_DOLLAR_LEFT_BRACE,
BSHELL_SYM_DQUOTE,
BSHELL_SYM_NONE,
};
const struct bshell_lex_state_type lex_string_state = {
.s_id = BSHELL_LEX_STATE_STRING,
.s_begin = string_begin,
.s_end = string_end,
.s_pump_token = string_pump_token,
.s_links = links,
.s_symbols = symbols,
};