test functions

This commit is contained in:
Arthur Barraux
2025-09-18 13:52:46 +02:00
parent 5818a8ecfc
commit ee2a34a3b1
21 changed files with 1252 additions and 1434 deletions
+24
View File
@@ -0,0 +1,24 @@
#ifndef BLISP_CONFIG_H_
#define BLISP_CONFIG_H_
#include "data.h"
ConfigValue *get_config_var(const char *name);
int get_config_int(const char *name, int default_val);
double get_config_float(const char *name, double default_val);
char *get_config_string(const char *name, const char *default_val);
bool get_config_bool(const char *name, bool default_val);
char **get_config_list(const char *name, int *count);
void free_config_value(ConfigValue *val);
bool config_var_exists(const char *name);
void set_config_int(const char *name, int value);
void set_config_float(const char *name, double value);
void set_config_string(const char *name, const char *value);
void set_config_bool(const char *name, bool value);
void print_all_config_vars(void);
#endif
-28
View File
@@ -1,28 +0,0 @@
#ifndef CONFIG_TOOLS_H_
#define CONFIG_TOOLS_H_
#include "data.h"
#include "parser.h"
#include <stdio.h>
void config_create(void);
void init_builtin_functions(void);
int handle_map_key(node_t **args, int arg_count);
int handle_define(node_t **args, int arg_count);
int handle_function(node_t **args, int arg_count);
int execute_function_call(node_t *call);
int config_parse_string(const char *input);
int config_parse_file(const char *filename);
const char *config_get_key_mapping(const char *key_combo);
node_t *find_variable(const char *name);
const char *config_get_string(const char *path, const char *default_value);
int config_get_int(const char *path, int default_value);
double config_get_double(const char *path, double default_value);
bool config_get_bool(const char *path, bool default_value);
void config_print_all(void);
#endif
+120 -126
View File
@@ -1,151 +1,145 @@
#ifndef DATA_H_PARSER
#define DATA_H_PARSER
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Token types for lexical analysis
// Forward declarations
typedef struct Value Value;
typedef struct Env Env;
// Value types
typedef enum {
VAL_NIL,
VAL_NUMBER,
VAL_STRING,
VAL_SYMBOL,
VAL_LIST,
VAL_FUNCTION,
VAL_KEYMAP
} ValueType;
typedef enum {
TOKEN_COMMA, // ,
TOKEN_PERCENT, // %
TOKEN_LPAREN, // (
TOKEN_RPAREN, // )
TOKEN_SYMBOL, // identifiers/function names
TOKEN_STRING, // "quoted strings"
TOKEN_NUMBER, // integers and floats
TOKEN_BOOLEAN, // true false
TOKEN_NEWLINE, // \n (statement separator)
TOKEN_EOF,
TOKEN_ERROR
} token_type_t;
CONFIG_INT,
CONFIG_FLOAT,
CONFIG_STRING,
CONFIG_BOOL,
CONFIG_LIST,
CONFIG_UNKNOWN
} ConfigType;
typedef struct {
token_type_t type;
char *value;
int line;
int column;
} token_t;
// AST node types
typedef enum {
NODE_SYMBOL,
NODE_STRING,
NODE_NUMBER,
NODE_BOOLEAN,
NODE_FUNCTION_REF, // %function-name
NODE_FUNCTION_CALL, // ,function-name()
NODE_LIST
} node_type_t;
typedef struct node {
node_type_t type;
ConfigType type;
union {
char *symbol;
char *string;
double number;
bool boolean;
char *function_ref;
int int_val;
double float_val;
char *string_val;
bool bool_val;
struct {
char *function_name;
struct node **args;
int arg_count;
} call;
struct {
struct node **children;
int child_count;
} list;
} data;
} node_t;
char **items;
int count;
} list_val;
} value;
} ConfigValue;
/**
* @typedef Functions
*
*/
typedef Value *(*Function)(char **params, int param_count, Value *body,
Env *closure);
// Value structure
struct Value {
ValueType type;
union {
double number;
char *string;
char *symbol;
struct {
Value *car;
Value *cdr;
} list;
Function *function;
struct {
char **keys;
Value **values;
int count;
int capacity;
} keymap;
} data;
};
// Environment for variable bindings
struct Env {
char **names;
Value **values;
int count;
int capacity;
Env *parent;
};
typedef enum {
TOK_LPAREN,
TOK_RPAREN,
TOK_QUOTE,
TOK_SYMBOL,
TOK_NUMBER,
TOK_STRING,
TOK_EOF
} TokenType;
typedef struct {
TokenType type;
char *value;
} Token;
// Lexer state
typedef struct {
const char *input;
int pos;
int line;
int column;
char current_char;
} lexer_t;
int length;
} Lexer;
// Configuration storage
typedef struct key_mapping {
char *key_combo;
char *function_name;
struct key_mapping *next;
} key_mapping_t;
/**
* @struct KeyBinding
* @brief Make the link between a Key Sequence and a command to execute
*/
typedef struct config_var {
char *name;
node_t *value;
struct config_var *next;
} config_var_t;
typedef struct {
char *key_sequence;
char *command;
} KeyBinding;
//@}
typedef struct {
KeyBinding *bindings;
int count;
int capacity;
} KeyBindingTable;
typedef struct config {
key_mapping_t *key_mappings;
config_var_t *variables;
} config_t;
Value *make_value(ValueType type);
Value *make_nil(void);
Value *make_number(double n);
Value *make_string(const char *s);
Value *make_symbol(const char *s);
Value *make_list(Value *car, Value *cdr);
Value *make_builtin(BuiltinFunc func);
Env *make_env(Env *parent);
void env_set(Env *env, const char *name, Value *value);
Value *env_get(Env *env, const char *name);
// Execution context for function calls
typedef struct exec_context {
struct {
char **names;
node_t **values;
int count;
} local_vars;
} exec_context_t;
#ifdef GLOBAL_ENV_
typedef void (*command_func_t)(void);
Env *global_env = NULL;
KeyBindingTable *active_keybindings = NULL;
typedef enum { FUNC_BUILTIN, FUNC_USER_DEFINED, FUNC_REGISTRY } function_type_t;
typedef struct unified_function {
char *name;
function_type_t type;
union {
// For built-in functions
struct {
int (*handler)(node_t **args, int arg_count);
bool eval_args; // Whether to evaluate arguments before calling
} builtin;
// For user-defined functions
struct {
char **parameters;
int param_count;
node_t *body;
} user_defined;
// For registry functions
struct {
command_func_t func;
} registry;
} data;
struct unified_function *next;
} unified_function_t;
void advance_char(lexer_t *lexer);
void skip_whitespace(lexer_t *lexer);
void skip_comment(lexer_t *lexer);
void add_arg_to_call(node_t *call, node_t *args);
void add_to_list(node_t *node, node_t *element);
#endif
#ifdef GLOBAL_CONFIG
unified_function_t *unified_functions = NULL;
int registry_count;
config_var_t variable_registry[256];
int var_registry_count;
config_t config;
#else
extern unified_function_t *unified_functions;
extern int registry_count;
extern config_var_t variable_registry[256];
extern int var_registry_count;
extern Env *global_env;
extern KeyBindingTable *active_keybindings;
extern config_t config;
#endif
#endif
-9
View File
@@ -1,9 +0,0 @@
#ifndef BLISP_DEFINE_H_
#define BLISP_DEFINE_H_
#define MAX_TOKEN_LENGTH 256
#define MAX_SYMBOL_LENGTH 128
#define MAX_STRING_LENGTH 512
#define MAX_ARGS 16
#endif
+21 -12
View File
@@ -3,22 +3,31 @@
#include "data.h"
int register_builtin_function(const char *name, int (*handler)(node_t **, int),
bool eval_args);
int register_user_function(const char *name, char **parameters, int param_count,
node_t *body);
int register_registry_function(const char *name, command_func_t func);
// Builtins
int register_function(const char *name, command_func_t func);
Value *builtin_add(Value *args);
Value *builtin_sub(Value *args);
Value *builtin_mul(Value *args);
Value *builtin_div(Value *args);
Value *builtin_eq(Value *args);
Value *builtin_list(Value *args);
Value *builtin_car(Value *args);
Value *builtin_cdr(Value *args);
unified_function_t *find_unified_function(const char *name);
// Evaluator
node_t *execute_unified_function(exec_context_t *ctx, const char *name,
node_t **args, int arg_count);
Value *eval_list(Value *list, Env *env);
Value *apply_function(Value *func, Value *args, Env *env);
Value *eval_expr(Value *expr, Env *env);
command_func_t find_function(const char *name);
int execute_command(const char *name);
// Key-mapping
node_t *execute_function_call_in_context(exec_context_t *ctx, node_t *call);
KeyBindingTable *extract_keybindings(Value *keymap);
char *normalize_key_sequence(const char *raw_input);
bool execute_keybinding(const char *key_sequence);
void set_active_keymap(const char *keymap_name);
void combine_keymaps(const char *global_keymap, const char *mode_keymap);
bool execute_editor_command(const char *command);
#endif
+13
View File
@@ -0,0 +1,13 @@
#ifndef BLISP_INIT_H_
#define BLISP_INIT_H_
#include "data.h"
void init_builtins(Env *env);
Value *lisp_eval(const char *input);
void lisp_init(void);
void repl(void);
void load_file(const char *filename);
#endif
+5 -3
View File
@@ -2,9 +2,11 @@
#define LEXER_H_
#include "data.h"
#include <ctype.h>
#include <string.h>
token_t next_token(lexer_t *lexer);
void skip_whitespace(Lexer *lex);
Token peek_token(Lexer *lex);
Token next_token(Lexer *lex);
#endif
-20
View File
@@ -1,20 +0,0 @@
#ifndef NODE_T_
#define NODE_T_
#include "data.h"
node_t *create_node(node_type_t type);
node_t *create_symbol_node(const char *symbol);
node_t *create_string_node(const char *string);
node_t *create_number_node(double number);
node_t *create_boolean_node(bool value);
node_t *create_list_node(void);
node_t *create_function_ref_node(const char *function_name);
node_t *create_function_call_node(const char *function_name);
void free_node(node_t *node);
node_t *copy_node(node_t *src);
node_t *evaluate_node(exec_context_t *ctx, node_t *node);
#endif
+2 -4
View File
@@ -3,9 +3,7 @@
#include "data.h"
node_t *parse_atom(lexer_t *lexer, token_t *token);
node_t *parse_function_call(lexer_t *lexer, const char *function_name);
node_t *parse_statement(lexer_t *lexer);
node_t *parse_expression(lexer_t *lexer, token_t *token);
Value *parse_list(Lexer *lex);
Value *parse_expr(Lexer *lex);
#endif
+14
View File
@@ -0,0 +1,14 @@
#ifndef BLISP_UTILS_H_
#define BLISP_UTILS_H_
#include "data.h"
bool is_nil(Value *v);
bool is_symbol(Value *v, const char *sym);
Value *car(Value *v);
Value *cdr(Value *v);
int list_length(Value *v);
void print_value(Value *v);
#endif