refactor: 重构前端代码并添加日志功能

- 重命名和重构了多个文件,包括 lexer、parser 和 AST 相关代码
- 添加了日志功能,使用 LOG_* 宏替代原有的 error 和 warn 函数
- 优化了错误处理和内存分配方式
- 调整了代码结构,提高了模块化和可读性
This commit is contained in:
ZZY
2025-03-19 12:22:55 +08:00
parent 172d72b0a0
commit 05c637e594
76 changed files with 1479 additions and 310 deletions

142
lib/utils/ds/hashtable.c Normal file
View File

@ -0,0 +1,142 @@
#include "hashtable.h"
#define LOAD_FACTOR 0.75f
// 素数表用于桶扩容(最后一个元素为最大允许容量)
static const int PRIME_CAPACITIES[] = {
11, 23, 47, 97, 193, 389, 769, 1543, 3079,
6151, 12289, 24593, 49157, 98317, 196613, 393241,
786433, 1572869, 3145739, 6291469, 12582917, 25165843
};
// 私有函数声明
static u32_t calc_hash(const char* str, int len);
static void rehash(hash_table_t* ht);
hash_table_t* new_hash_table(int init_size, int max_cap) {
hash_table_t* ht = salloc_alloc(sizeof(hash_table_t));
hash_table_init(ht, init_size, max_cap);
return ht;
}
static inline get_real_size(int size) {
// 查找第一个不小于size的素数容量
int cap_idx = 0;
if (size < 0) {
return PRIME_CAPACITIES[SMCC_ARRLEN(PRIME_CAPACITIES)-1];
}
while (PRIME_CAPACITIES[cap_idx] < size && cap_idx < SMCC_ARRLEN(PRIME_CAPACITIES)-1) {
cap_idx++;
}
return PRIME_CAPACITIES[cap_idx];
}
void hash_table_init(hash_table_t* ht, int init_size, int max_cap) {
// 限制最大容量索引
ht->max_cap = get_real_size(max_cap);
// 应用实际容量
ht->cap = get_real_size(init_size);
ht->size = 0;
ht->buckets = NULL;
ht->buckets = salloc_realloc(ht->buckets, sizeof(hash_node_t*) * ht->cap);
}
void hash_table_insert(hash_table_t* ht, const char* str, int len) {
// 自动扩容检查
if (ht->size >= ht->cap * LOAD_FACTOR && ht->cap < ht->max_cap) {
rehash(ht);
}
if (ht->size >= ht->cap) {
LOG_TRACE("Hash table size exceeds maximum capacity. Consider increasing max_capacity.");
}
// 计算哈希值
u32_t hash = calc_hash(str, len);
int bucket_idx = hash % ht->cap;
// 检查重复
hash_node_t* node = ht->buckets[bucket_idx];
while (node) {
if (node->hash == hash &&
node->len == len &&
memcmp(node->str, str, len) == 0) {
return; // 已存在
}
node = node->next;
}
// 创建新节点
hash_node_t* new_node = salloc_alloc(sizeof(hash_node_t));
new_node->str = str;
new_node->len = len;
new_node->hash = hash;
new_node->next = ht->buckets[bucket_idx];
ht->buckets[bucket_idx] = new_node;
ht->size++;
}
hash_node_t* hash_table_find(hash_table_t* ht, const char* str, int len) {
u32_t hash = calc_hash(str, len);
int bucket_idx = hash % ht->cap;
hash_node_t* node = ht->buckets[bucket_idx];
while (node) {
if (node->hash == hash &&
node->len == len &&
memcmp(node->str, str, len) == 0) {
return node;
}
node = node->next;
}
return NULL;
}
static void rehash(hash_table_t* ht) {
int old_cap = ht->cap;
hash_node_t** old_buckets = ht->buckets;
// 查找下一个素数容量
int new_cap_idx = 0;
while (PRIME_CAPACITIES[new_cap_idx] <= old_cap &&
new_cap_idx < ht->max_cap) {
new_cap_idx++;
}
ht->cap = PRIME_CAPACITIES[new_cap_idx];
// 分配新桶数组
ht->buckets = salloc_alloc(sizeof(hash_node_t*) * ht->cap);
memset(ht->buckets, 0, sizeof(hash_node_t*) * ht->cap);
// 重新哈希所有节点
for (int i = 0; i < old_cap; i++) {
hash_node_t* node = old_buckets[i];
while (node) {
hash_node_t* next = node->next;
int new_bucket = node->hash % ht->cap;
node->next = ht->buckets[new_bucket];
ht->buckets[new_bucket] = node;
node = next;
}
}
salloc_free(old_buckets);
}
static u32_t calc_hash(const char* str, int len) {
// 使用与HASH_FNV_1A宏一致的算法
rt_strhash(str);
}
void hash_table_destroy(hash_table_t* ht) {
for (int i = 0; i < ht->cap; i++) {
hash_node_t* node = ht->buckets[i];
while (node) {
hash_node_t* next = node->next;
salloc_free(node);
node = next;
}
}
salloc_free(ht->buckets);
ht->buckets = NULL;
ht->size = ht->cap = 0;
}

27
lib/utils/ds/hashtable.h Normal file
View File

@ -0,0 +1,27 @@
#ifndef __SMCC_HASHTABLE_H__
#define __SMCC_HASHTABLE_H__
#include <lib/rt/rt.h>
typedef struct hash_node {
const char* str;
int len;
u32_t hash;
struct hash_node* next;
} hash_node_t;
typedef struct hash_table {
hash_node_t** buckets;
int size;
int cap;
int max_cap;
} hash_table_t;
hash_table_t* new_hash_table(int init_size, int max_cap);
void hash_table_init(hash_table_t* ht, int init_size, int max_cap);
void hash_table_destroy(hash_table_t* ht);
void hash_table_insert(hash_table_t* ht, const char* str, int len);
hash_node_t* hash_table_find(hash_table_t* ht, const char* str, int len);
#endif // __SMCC_HASHTABLE_H__

158
lib/utils/ds/kllist.h Normal file
View File

@ -0,0 +1,158 @@
/**
* kllist.h is a list implement by linux kernel list
* @link https://njusecourse.feishu.cn/wiki/I8vkw2zkwiEInUkujTJc7zzOnwf
* @link https://kernelnewlbies.org/FAQ/LinkedLists
* @link https://lwn.net/Articles/887097/
* @link https://liuluheng.github.io/wiki/public_html/Embedded-System/kernel/list-and-hlist.html
*/
#ifndef __KLLIST_H__
#define __KLLIST_H__
#ifndef NULL
#define NULL (0)
#define __NULL_KLIST_DEFINED__
#endif
#ifndef container_of
// Magic: https://radek.io/posts/magical-container_of-macro/
// StackOverflow: https://stackoverflow.com/q/15832301/1833118
#ifdef __GNUC__
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
#else
#define container_of(ptr, type, member) ({ \
const void *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
#endif
#endif
/**
* used by list
*/
struct list_head {
struct list_head *next, *prev;
};
/**
* list init
* @example
* 1. struct list_head your_list = LIST_HEAD_INIT(your_list);
* 2. struct list_head your_list; INIT_LIST_HEAD(&your_list);
* 3. LIST_HEAD(your_list); => struct your_list = { &(your_list), &(your_list) };
*/
#define LIST_HEAD_INIT(name) { &(name), &(name) }
static inline void INIT_LIST_HEAD(struct list_head *list) {
list->next = list;
list->prev = list;
}
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
/**
* list add
*/
static inline void __list_add(struct list_head *newl,
struct list_head *prev,
struct list_head *next) {
next->prev = newl;
newl->next = next;
newl->prev = prev;
prev->next = newl;
}
static inline void list_add(struct list_head *newl, struct list_head *head) {
__list_add(newl, head, head->next);
}
static inline void list_add_tail(struct list_head *newl, struct list_head *head) {
__list_add(newl, head->prev, head);
}
/**
* list delete
*/
static inline void __list_del(struct list_head * prev, struct list_head * next) {
next->prev = prev;
prev->next = next;
}
static inline void list_del(struct list_head *entry) {
__list_del(entry->prev, entry->next);
entry->next = NULL;
entry->prev = NULL;
}
/**
* list_is_first -- tests whether @list is the first entry in list @head
* @list: the entry to test
* @head: the head of the list
*/
static inline int list_is_first(const struct list_head *list, const struct list_head *head) {
return list->prev == head;
}
/**
* list_is_last - tests whether @list is the last entry in list @head
* @list: the entry to test
* @head: the head of the list
*/
static inline int list_is_last(const struct list_head *list, const struct list_head *head) {
return list->next == head;
}
/**
* list_is_head - tests whether @list is the list @head
* @list: the entry to test
* @head: the head of the list
*/
static inline int list_is_head(const struct list_head *list, const struct list_head *head) {
return list == head;
}
/**
* list_empty - tests whether a list is empty
* @head: the list to test.
*/
static inline int list_empty(const struct list_head *head) {
return head->next == head;
}
/**
* list_for_each - iterate over a list
* @pos: the &struct list_head to use as a loop cursor.
* @head: the head for your list.
*/
#define list_for_each(pos, head) \
for (pos = (head)->next; !list_is_head(pos, (head)); pos = pos->next)
/**
* list_for_each_prev - iterate over a list backwards
* @pos: the &struct list_head to use as a loop cursor.
* @head: the head for your list.
*/
#define list_for_each_prev(pos, head) \
for (pos = (head)->prev; !list_is_head(pos, (head)); pos = pos->prev)
/**
* list sort
* by linux kernel 6.3.1 /lib/list_sort.c
* it remain use sigle linked list to merge sort
* @link https://www.geeksforgeeks.org/merge-sort-for-linked-list/
*/
#ifdef HAVE_KLIST_SORT
typedef int (*list_cmp_func_t)(void *,
const struct list_head *, const struct list_head *);
static void list_sort(void *priv, struct list_head *head, list_cmp_func_t cmp);
#endif
#if defined(__NULL_KLIST_DEFINED__) && !defined(__NULL_KLIST_DEFINED_NOMOVE__)
#undef NULL
#endif
#endif

202
lib/utils/ds/vector-gdb.py Normal file
View File

@ -0,0 +1,202 @@
# # vector_gdb.py
# import gdb
# import re
# class VectorPrinter:
# """解析宏定义的 vector 结构体"""
# def __init__(self, val):
# self.val = val
# def check_vector_type(self):
# """验证是否为合法 vector 结构体"""
# try:
# # 检查是否包含 size/cap/data 字段
# return all(self.val.type.has_key(field)
# for field in ['size', 'cap', 'data'])
# except gdb.error:
# return False
# def get_array_view(self):
# """将 data 字段转换为数组视图"""
# if not self.check_vector_type():
# return None
# cap = int(self.val['cap'])
# data_ptr = self.val['data']
# if cap == 0 or data_ptr == 0:
# return []
# # 构造数组类型 (例如 int[cap])
# element_type = data_ptr.type.target()
# array_type = element_type.array(cap - 1) # C 数组声明语法
# return data_ptr.cast(array_type.pointer()).dereference()
# def to_string(self):
# if not self.check_vector_type():
# return "Not a vector type"
# size = self.val['size']
# cap = self.val['cap']
# data = self.get_array_view()
# return (f"vector(size={size}, cap={cap}, data={data})")
# class VectorInfoCommand(gdb.Command):
# """自定义命令:显示 vector 详细信息"""
# def __init__(self):
# super(VectorInfoCommand, self).__init__("vector_info",
# gdb.COMMAND_USER)
# def invoke(self, arg, from_tty):
# val = gdb.parse_and_eval(arg)
# printer = VectorPrinter(val)
# if not printer.check_vector_type():
# print(f"'{arg}' is not a vector structure")
# return
# size = int(val['size'])
# cap = int(val['cap'])
# data = printer.get_array_view()
# # 输出格式化信息
# print(f"Vector {arg}:")
# print(f"├─ Size: {size}")
# print(f"├─ Capacity: {cap}")
# print("└─ Data elements [0..{}]:".format(min(size, cap)-1))
# for i in range(min(size, cap)):
# try:
# print(f" [{i}]: {data[i]}")
# except gdb.MemoryError:
# print(f" [{i}]: <invalid memory>")
# def register_printers():
# """注册自动类型识别"""
# def vector_matcher(val):
# return VectorPrinter(val).check_vector_type()
# # 使用 lambda 包装以动态创建 printer
# gdb.pretty_printers.append(lambda val:
# VectorPrinter(val) if vector_matcher(val) else None)
# # 注册命令和打印机
# VectorInfoCommand()
# register_printers()
# vector_gdb.py
import gdb # type: ignore
from gdb.printing import PrettyPrinter # type: ignore
class VectorPrinter:
"""兼容新旧注册方式的最终方案"""
def __init__(self, val: gdb.Value):
self.val:gdb.Value = val
def check_type(self) -> bool:
"""类型检查(兼容匿名结构体)"""
try:
if self.val.type.code != gdb.TYPE_CODE_STRUCT:
return False
fields = self.val.type.fields()
if not fields:
return False
exp = ['size', 'cap', 'data']
for t in fields:
if t.name in exp:
exp.remove(t.name)
else:
return False
return True
except gdb.error:
return False
def to_string(self):
if not self.check_type():
return "Not a vector"
return "vector({} size={}, cap={})".format(
self.val.address,
self.val['size'],
self.val['cap'],
)
def display_hint(self):
return 'array'
def children(self):
"""生成数组元素(关键改进点)"""
if not self.check_type():
return []
size = int(self.val['size'])
cap = int(self.val['cap'])
data_ptr = self.val['data']
if cap == 0 or data_ptr == 0:
return []
# 使用 GDB 内置数组转换
array = data_ptr.dereference()
array = array.cast(data_ptr.type.target().array(cap - 1))
for i in range(size):
# state = "<used>" if i < size else "<unused>"
try:
value = array[i]
yield (f"[{i}] {value.type} {value.address}", value)
except gdb.MemoryError:
yield (f"[{i}]", "<invalid>")
# 注册方式一传统append方法您之前有效的方式self
def append_printer():
gdb.pretty_printers.append(
lambda val: VectorPrinter(val) if VectorPrinter(val).check_type() else None
)
# 注册方式二:新版注册方法(备用方案)
def register_new_printer():
class VectorPrinterLocator(PrettyPrinter):
def __init__(self):
super().__init__("vector_printer")
def __call__(self, val):
ret = VectorPrinter(val).check_type()
print(f"ret {ret}, type {val.type}, {[(i.name, i.type) for i in val.type.fields()]}")
return None
gdb.printing.register_pretty_printer(
gdb.current_objfile(),
VectorPrinterLocator()
)
# 双重注册保证兼容性
append_printer() # 保留您原来有效的方式
# register_new_printer() # 添加新版注册
class VectorInfoCommand(gdb.Command):
"""保持原有命令不变"""
def __init__(self):
super().__init__("vector_info", gdb.COMMAND_USER)
def invoke(self, arg, from_tty):
val = gdb.parse_and_eval(arg)
printer = VectorPrinter(val)
if not printer.check_type():
print("Invalid vector")
return
print("=== Vector Details ===")
print("Size:", val['size'])
print("Capacity:", val['cap'])
print("Elements:")
for name, value in printer.children():
print(f" {name}: {value}")
VectorInfoCommand()

51
lib/utils/ds/vector.h Normal file
View File

@ -0,0 +1,51 @@
// vector.h
#ifndef __SMCC_DS_VECTOR_H__
#define __SMCC_DS_VECTOR_H__
#include <lib/rt/rt.h>
#define vector_header(name, type) \
struct { \
rt_size_t size; \
rt_size_t cap; \
type *data; \
} name \
#define vector_init(vec) \
do { \
(vec).size = 0, \
(vec).cap = 0, \
(vec).data = NULL; \
} while(0)
#define vector_push(vec, value) \
do { \
if (vec.size >= vec.cap) { \
int cap = vec.cap ? vec.cap * 2 : 8; \
void* data = salloc_realloc(vec.data, cap * sizeof(*vec.data)); \
if (!data) { \
LOG_FATAL("vector_push: rt_realloc failed\n"); \
} \
(vec).cap = cap; \
(vec).data = data; \
} \
(vec).data[(vec).size++] = value; \
} while(0)
#define vector_pop(vec) \
((vec).data[--(vec).size])
#define vector_at(vec, idx) \
(((vec).data)[idx])
#define vector_idx(vec, ptr) \
((ptr) - (vec).data)
#define vector_free(vec) \
do { \
salloc_free((vec).data); \
(vec).data = NULL; \
(vec).size = (vec).cap = 0; \
} while(0)
#endif

0
lib/utils/gdb.py Normal file
View File

View File

View File

@ -0,0 +1,12 @@
#ifndef __SMCC_STRPOOL_H__
#define __SMCC_STRPOOL_H__
#include <lib/core.h>
#include "../ds/hash.h"
typedef struct strpool {
long_alloc_t *long_alloc;
} strpool_t;
void new_strpool();
#endif // __SMCC_STRPOOL_H__

View File

View File

19
lib/utils/tokbuf/token.c Normal file
View File

@ -0,0 +1,19 @@
// #include <lib/rt/rt.h>
// #include "token.h"
// #define ROUND_IDX(idx) ((idx) % tokbuf->cap)
// #define POW2(x) (1 << (x))
// void init_toks(tok_stream_t* tokbuf, int cap,
// tok_stream_close_func close, tok_stream_get_func gettok, void* stream)
// {
// tokbuf->cap_mask = POW2(cap) - 1;
// // tokbuf->buf =
// }
// int toks_next( tok_stream_t* toks, tok_t* out);
// int toks_peek( tok_stream_t* toks, tok_t* out, int lookahead);
// const tok_t* toks_peek_ref(tok_stream_t* toks, int lookahead);
// int toks_reset(tok_stream_t* toks);
// int toks_seek( tok_stream_t* toks, int pos);
// int toks_close(tok_stream_t* toks);

68
lib/utils/tokbuf/token.h Normal file
View File

@ -0,0 +1,68 @@
#ifndef __SMCC_TOKBUF_H__
#define __SMCC_TOKBUF_H__
#include <lib/rt/rt.h>
typedef struct loc {
const char *fname;
int line;
int col;
short len;
} loc_t;
typedef enum tok_type {
TK_BASIC_INVALID, // 错误占位
TK_BASIC_KEYWORD, // 关键字
TK_BASIC_OPERATOR, // 操作符
TK_BASIC_IDENTIFIER, // 标识符
TK_BASIC_LITERAL, // 字面量
TK_BASIC_PUNCTUATOR, // 标点符号
TK_BASIC_EOF // 结束标记
} tok_type_t;
typedef union ctype {
u8_t u8;
u16_t u16;
u32_t u32;
u64_t u64;
i8_t i8;
i16_t i16;
i32_t i32;
i64_t i64;
f32_t f32;
f64_t f64;
iptr_t iptr;
uptr_t uptr;
void* ptr;
} ctype_t;
typedef struct tok {
tok_type_t type;
int sub_type;
loc_t loc;
ctype_t val;
} tok_t;
// typedef void(*tok_stream_close_func)(void* stream);
// typedef void(*tok_stream_get_func)(void* stream, tok_t* token);
// typedef struct tok_stream {
// int cur;
// int end;
// int cap_mask;
// tok_t* buf;
// void* stream;
// tok_stream_close_func close;
// tok_stream_get_func gettok;
// } tok_stream_t;
// void init_toks(tok_stream_t* tokbuf, int cap,
// tok_stream_close_func close, tok_stream_get_func gettok, void* stream);
// int toks_next( tok_stream_t* toks, tok_t* out);
// int toks_peek( tok_stream_t* toks, tok_t* out, int lookahead);
// const tok_t* toks_peek_unsafe(tok_stream_t* toks, int lookahead);
// int toks_reset(tok_stream_t* toks);
// int toks_seek( tok_stream_t* toks, int pos);
// int toks_close(tok_stream_t* toks);
#endif // __SMCC_TOKEN_H__