Files
bshell/bshell.runtime/parse/lex/lex-internal.h
T
2026-05-30 19:50:38 +01:00

205 lines
7.5 KiB
C

#ifndef PARSE_LEX_INTERNAL_H_
#define PARSE_LEX_INTERNAL_H_
#include <bshell/parse/lex.h>
#include <bshell/parse/token.h>
#include <bshell/status.h>
struct bshell_lex_ctx;
enum state_flags {
/* statement: don't convert matching words to keywords */
STATEMENT_F_DISABLE_KEYWORDS = 0x01u,
/* arithmetic: don't switch back to statement mode even when
* encountering a token that would otherwise require it. */
ARITHMETIC_F_DISABLE_STATEMENTS = 0x01u,
};
enum read_flags {
READ_APPEND_HYPHEN = 0x01u,
READ_NO_SET_TOKEN_START = 0x02u,
READ_NO_NUMBER_RECOGNITION = 0x04u,
};
enum link_flags {
LINK_ALLOW_RECURSION = 0x01u,
};
#define LINK_PUSH(tok, target, flags) \
((struct bshell_lex_state_link) { \
.l_token = (tok), \
.l_type = BSHELL_LEX_STATE_LINK_PUSH, \
.l_target = (target), \
.l_target_flags = (flags), \
})
#define LINK_PUSH_WITH_TERM(tok, target, flags, ...) \
((struct bshell_lex_state_link) { \
.l_token = (tok), \
.l_type = BSHELL_LEX_STATE_LINK_PUSH, \
.l_target = (target), \
.l_target_flags = (flags), \
.l_terminators = {__VA_ARGS__, BSHELL_TOK_NONE}, \
})
#define LINK_CHANGE(tok, target) \
((struct bshell_lex_state_link) { \
.l_token = (tok), \
.l_type = BSHELL_LEX_STATE_LINK_CHANGE, \
.l_target = (target), \
})
#define LINK_POP(tok) \
((struct bshell_lex_state_link) { \
.l_token = (tok), \
.l_type = BSHELL_LEX_STATE_LINK_POP, \
})
#define LINK_POP2(tok, flags) \
((struct bshell_lex_state_link) { \
.l_token = (tok), \
.l_type = BSHELL_LEX_STATE_LINK_POP, \
.l_flags = (flags), \
})
#define LINK_NONE(tok) \
((struct bshell_lex_state_link) { \
.l_token = (tok), \
.l_type = BSHELL_LEX_STATE_LINK_NONE, \
})
#define LINK_END ((struct bshell_lex_state_link) {})
struct bshell_lex_state_link {
unsigned int l_token;
enum {
BSHELL_LEX_STATE_LINK_NONE,
BSHELL_LEX_STATE_LINK_PUSH,
BSHELL_LEX_STATE_LINK_CHANGE,
BSHELL_LEX_STATE_LINK_POP,
} l_type;
enum link_flags l_flags;
enum bshell_lex_state_id l_target;
enum state_flags l_target_flags;
unsigned int l_terminators[BSHELL_LEX_STATE_MAX_TERMINATORS];
};
typedef enum bshell_status (*lex_state_pump_token)(struct bshell_lex_ctx *);
typedef enum bshell_status (*lex_state_begin)(struct bshell_lex_ctx *);
typedef enum bshell_status (*lex_state_end)(struct bshell_lex_ctx *);
struct bshell_lex_state_type {
enum bshell_lex_state_id s_id;
lex_state_pump_token s_pump_token;
lex_state_begin s_begin;
lex_state_end s_end;
const unsigned int *s_keywords;
const unsigned int *s_operators;
const unsigned int *s_symbols;
const struct bshell_lex_state_link *s_links;
};
extern enum bshell_status pump_token_statement(struct bshell_lex_ctx *ctx);
extern enum bshell_status pump_token_expression(struct bshell_lex_ctx *ctx);
extern enum bshell_status pump_token_command(struct bshell_lex_ctx *ctx);
extern enum bshell_status pump_token_arithmetic(struct bshell_lex_ctx *ctx);
extern enum bshell_status pump_token_string(struct bshell_lex_ctx *ctx);
extern void set_token_start(struct bshell_lex_ctx *ctx);
extern void set_token_end(struct bshell_lex_ctx *ctx);
extern struct bshell_lex_state *lex_state_push(
struct bshell_lex_ctx *ctx,
enum bshell_lex_state_id state_type,
enum state_flags flags);
extern void lex_state_pop(struct bshell_lex_ctx *ctx, bool no_preserve_root);
extern struct bshell_lex_state *lex_state_get(struct bshell_lex_ctx *ctx);
extern void lex_state_change(
struct bshell_lex_ctx *ctx,
enum bshell_lex_state_id type);
extern fx_string *lex_state_get_tempstr(struct bshell_lex_ctx *ctx);
extern void lex_state_add_terminator(
struct bshell_lex_state *state,
unsigned int tok);
extern bool lex_state_terminates_at_token(
struct bshell_lex_ctx *ctx,
unsigned int tok);
extern fx_wchar peek_char(struct bshell_lex_ctx *ctx);
extern fx_wchar peek_char_noread(struct bshell_lex_ctx *ctx);
extern fx_wchar peek2_char(struct bshell_lex_ctx *ctx);
extern fx_wchar peek2_char_noread(struct bshell_lex_ctx *ctx);
extern void advance_char(struct bshell_lex_ctx *ctx);
extern void advance_char_noread(struct bshell_lex_ctx *ctx);
extern bool string_is_valid_number(
const char *s,
fx_value *out,
enum bshell_lex_token_type *out_type);
extern bool convert_word_to_number(struct bshell_lex_token *tok);
extern bool convert_word_to_keyword(struct bshell_lex_token *tok);
extern bool convert_word_to_operator(
struct bshell_lex_ctx *ctx,
struct bshell_lex_token *tok);
extern void enqueue_token(
struct bshell_lex_ctx *ctx,
struct bshell_lex_token *tok);
extern void enqueue_token_with_coordinates(
struct bshell_lex_ctx *ctx,
struct bshell_lex_token *tok,
const struct bshell_char_cell *start,
const struct bshell_char_cell *end);
extern enum bshell_status read_word(
struct bshell_lex_ctx *ctx,
enum read_flags flags,
struct bshell_lex_token **out);
extern enum bshell_status read_symbol(
struct bshell_lex_ctx *ctx,
const struct bshell_lex_token_definition **out);
extern enum bshell_status read_literal_string(
struct bshell_lex_ctx *ctx,
struct bshell_lex_token **out);
extern enum bshell_status read_line_comment(struct bshell_lex_ctx *lex);
extern enum bshell_status read_var(
struct bshell_lex_ctx *ctx,
enum bshell_lex_token_type type,
struct bshell_lex_token **out);
extern enum bshell_status read_braced_var(
struct bshell_lex_ctx *ctx,
enum bshell_lex_token_type type,
struct bshell_lex_token **out);
extern enum bshell_status push_symbol(
struct bshell_lex_ctx *ctx,
enum bshell_lex_symbol sym);
extern bool char_can_begin_symbol(struct bshell_lex_ctx *ctx, char c);
extern bool char_can_begin_symbol_in_state(
struct bshell_lex_ctx *ctx,
char c,
enum bshell_lex_state_id state_type);
extern bool char_has_flags(
struct bshell_lex_ctx *ctx,
char c,
enum bshell_lex_token_flags flags);
extern bool keyword_has_flags(
struct bshell_lex_ctx *ctx,
enum bshell_lex_keyword kw,
enum bshell_lex_token_flags flags);
extern enum bshell_lex_token_flags keyword_get_flags(
struct bshell_lex_ctx *ctx,
enum bshell_lex_keyword kw);
extern bool symbol_has_flags(
struct bshell_lex_ctx *ctx,
enum bshell_lex_symbol sym,
enum bshell_lex_token_flags flags);
extern enum bshell_lex_token_flags symbol_get_flags(
struct bshell_lex_ctx *ctx,
enum bshell_lex_symbol sym);
extern enum bshell_lex_operator get_bshell_operator_with_string(
struct bshell_lex_ctx *ctx,
const char *s);
extern void handle_lex_state_transition(
struct bshell_lex_ctx *ctx,
unsigned int token);
#endif