refactor: 重构前端代码并添加日志功能
- 重命名和重构了多个文件,包括 lexer、parser 和 AST 相关代码 - 添加了日志功能,使用 LOG_* 宏替代原有的 error 和 warn 函数 - 优化了错误处理和内存分配方式 - 调整了代码结构,提高了模块化和可读性
This commit is contained in:
142
lib/utils/ds/hashtable.c
Normal file
142
lib/utils/ds/hashtable.c
Normal 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
27
lib/utils/ds/hashtable.h
Normal 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
158
lib/utils/ds/kllist.h
Normal 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
202
lib/utils/ds/vector-gdb.py
Normal 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
51
lib/utils/ds/vector.h
Normal 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
0
lib/utils/gdb.py
Normal file
0
lib/utils/strpool/strpool.c
Normal file
0
lib/utils/strpool/strpool.c
Normal file
12
lib/utils/strpool/strpool.h
Normal file
12
lib/utils/strpool/strpool.h
Normal 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__
|
0
lib/utils/symtab/symtab.c
Normal file
0
lib/utils/symtab/symtab.c
Normal file
0
lib/utils/symtab/symtab.h
Normal file
0
lib/utils/symtab/symtab.h
Normal file
19
lib/utils/tokbuf/token.c
Normal file
19
lib/utils/tokbuf/token.c
Normal 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
68
lib/utils/tokbuf/token.h
Normal 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__
|
Reference in New Issue
Block a user