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

33
lib/rt/log/color.h Normal file
View File

@ -0,0 +1,33 @@
#ifndef __SMCC_TERMINAL_COLOR_H__
#define __SMCC_TERMINAL_COLOR_H__
#define ANSI_FG_BLACK "\33[30m"
#define ANSI_FG_RED "\33[31m"
#define ANSI_FG_GREEN "\33[32m"
#define ANSI_FG_YELLOW "\33[33m"
#define ANSI_FG_BLUE "\33[34m"
#define ANSI_FG_MAGENTA "\33[35m"
#define ANSI_FG_CYAN "\33[36m"
#define ANSI_FG_WHITE "\33[37m"
#define ANSI_BG_BLACK "\33[40m"
#define ANSI_BG_RED "\33[41m"
#define ANSI_BG_GREEN "\33[42m"
#define ANSI_BG_YELLOW "\33[43m"
#define ANSI_BG_BLUE "\33[44m"
#define ANSI_BG_MAGENTA "\33[35m"
#define ANSI_BG_CYAN "\33[46m"
#define ANSI_BG_WHITE "\33[47m"
#define ANSI_UNDERLINED "\33[4m"
#define ANSI_BOLD "\33[1m"
#define ANSI_NONE "\33[0m"
// Maybe Some Terminal Doesn't Support Color
#ifndef ANSI_FMT_DISABLE
#define ANSI_FMT(str, fmt) fmt str ANSI_NONE
#else
#define ANSI_FMT(str, fmt) str
#endif
#endif

65
lib/rt/log/log.c Normal file
View File

@ -0,0 +1,65 @@
#include "log.h"
typedef void (*log_handler)(
log_level_t level,
const char* module,
const char* file,
int line,
const char* message
);
static void default_handler(log_level_t level, const char* module, const char* file, int line, const char* message) {
if (!rt_stderr) return;
const char* level_str;
switch (level) {
case LOG_LEVEL_DEBUG: level_str = "DEBUG"; break;
case LOG_LEVEL_INFO: level_str = "INFO "; break;
case LOG_LEVEL_WARN: level_str = "WARN "; break;
case LOG_LEVEL_ERROR: level_str = "ERROR"; break;
case LOG_LEVEL_FATAL: level_str = "FATAL"; break;
case LOG_LEVEL_TRACE: level_str = "TRACE"; break;
default: level_str = "NOTSET"; break;
}
#ifndef __LOG_NO_COLOR__
const char* color_code = ANSI_NONE;
switch (level) {
case LOG_LEVEL_DEBUG: color_code = ANSI_FG_CYAN; break;
case LOG_LEVEL_INFO: color_code = ANSI_FG_GREEN; break;
case LOG_LEVEL_TRACE: color_code = ANSI_FG_BLUE; break;
case LOG_LEVEL_WARN: color_code = ANSI_FG_YELLOW; break;
case LOG_LEVEL_ERROR: color_code = ANSI_FG_RED; break;
case LOG_LEVEL_FATAL: color_code = ANSI_FG_RED ANSI_UNDERLINED; break; // 增强对比度
default: color_code = ANSI_NONE;
}
rt.fprintf(rt_stderr, ANSI_BOLD "%s[%s] - %s - %s:%d | %s" ANSI_NONE "\n", color_code,
level_str, module, file, line, message);
#else
rt.fprintf(rt_stderr, "[%s] %s:%d | %s: %s\n",
level_str, file, line, module, message);
#endif
if (level & LOG_LEVEL_FATAL) {
rt.exit(-LOG_LEVEL_FATAL);
}
}
static logger_t root_logger = {
.name = "root",
.level = LOG_LEVEL_ALL,
.handler = default_handler,
};
logger_t* log_get(const char* name) {
return &root_logger;
}
void log_set_level(logger_t* logger, log_level_t level) {
if (logger) logger->level = level;
else root_logger.level = level;
}
void log_set_handler(logger_t* logger, log_handler handler) {
if (logger) logger->handler = handler;
else root_logger.handler = handler;
}

75
lib/rt/log/log.h Normal file
View File

@ -0,0 +1,75 @@
#ifndef __SMCC_LOG_H__
#define __SMCC_LOG_H__
#include "../std/rt_api_def.h"
#include "color.h"
typedef enum log_level {
LOG_LEVEL_NOTSET = 0,
LOG_LEVEL_DEBUG = 1 << 0,
LOG_LEVEL_INFO = 1 << 1,
LOG_LEVEL_WARN = 1 << 2,
LOG_LEVEL_ERROR = 1 << 3,
LOG_LEVEL_FATAL = 1 << 4,
LOG_LEVEL_TRACE = 1 << 5,
LOG_LEVEL_ALL = 0xFF,
} log_level_t;
typedef void (*log_handler)(
log_level_t level,
const char* module,
const char* file,
int line,
const char* message
);
#ifndef LOGGER_MAX_BUF_SIZE
#define LOGGER_MAX_BUF_SIZE 256
#endif
typedef struct logger {
const char* name;
log_level_t level;
log_handler handler;
char buf[LOGGER_MAX_BUF_SIZE];
} logger_t;
logger_t* log_get(const char* name);
void log_set_level(logger_t* logger, log_level_t level);
void log_set_handler(logger_t* logger, log_handler handler);
#ifndef LOG_MAX_MAROC_BUF_SIZE
#define LOG_MAX_MAROC_BUF_SIZE LOGGER_MAX_BUF_SIZE
#endif
#define _LOG(_level_, _msg_, ...) \
do { \
logger_t* _logger = log_get(NULL); \
if (_logger && _logger->handler && (_logger->level & (_level_))) { \
rt.snprintf(_logger->buf, sizeof(_logger->buf), (_msg_), ##__VA_ARGS__); \
_logger->handler((_level_), _logger->name, __FILE__, __LINE__, _logger->buf); \
} \
} while(0)
#define LOG_NOTSET(...) _LOG(LOG_LEVEL_NOTSET, __VA_ARGS__)
#define LOG_DEBUG(...) _LOG(LOG_LEVEL_DEBUG, __VA_ARGS__)
#define LOG_INFO(...) _LOG(LOG_LEVEL_INFO, __VA_ARGS__)
#define LOG_WARN(...) _LOG(LOG_LEVEL_WARN, __VA_ARGS__)
#define LOG_ERROR(...) _LOG(LOG_LEVEL_ERROR, __VA_ARGS__)
#define LOG_FATAL(...) _LOG(LOG_LEVEL_FATAL, __VA_ARGS__)
#define LOG_TRACE(...) _LOG(LOG_LEVEL_TRACE, __VA_ARGS__)
#define _Assert(cond, ...) \
do { \
if (!(cond)) { \
LOG_FATAL(__VA_ARGS__); \
} \
} while (0)
#define AssertFmt(cond, format, ...) _Assert(cond, "Assertion Failure: " format, ## __VA_ARGS__)
#define PanicFmt(format, ...) _Assert(0, "Panic: " format, ## __VA_ARGS__)
#define Assert(cond) AssertFmt(cond, "cond is `" SMCC_STR(cond) "`")
#define Panic(...) PanicFmt(__VA_ARGS__)
#define TODO() PanicFmt("TODO please implement me")
#endif

10
lib/rt/rt.c Normal file
View File

@ -0,0 +1,10 @@
#include "rt.h"
void init_rt() {
// TODO Choice OS
#ifndef __SMCC_NO_OS_STD__
#include "std/rt_std.h"
init_rt_std();
#endif
return;
}

18
lib/rt/rt.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef __SMCC_RT_H__
#define __SMCC_RT_H__
#include "std/rt_api_def.h"
#include "std/rt_type.h"
#include "log/log.h"
#include "rt_alloc.h"
#include "rt_string.h"
void init_rt();
// define
#define _SMCC_STR(str) #str
#define SMCC_STR(str) _SMCC_STR(str)
#define SMCC_ARRLEN(arr) (sizeof(arr) / sizeof(arr[0]))
#endif // __SMCC_RT_H__

135
lib/rt/rt_alloc.c Normal file
View File

@ -0,0 +1,135 @@
#include "rt_alloc.h"
#define ALLOCATOR_PAGE_SIZE (4096)
/* Simple / Static Allocator */
void* salloc_alloc(int size) {
// TODO do some trace
return rt._malloc(size);
}
void* salloc_realloc(void* ptr, int size) {
return rt._realloc(ptr, size);
}
void salloc_free(void* ptr) {
// TODO do some trace
rt._free(ptr);
}
/* Fixed Allocator */
#define PAGE_ALIGN(size) (((size) + ALLOCATOR_PAGE_SIZE -1) & ~(ALLOCATOR_PAGE_SIZE-1))
void falloc_init(fixed_alloc_t* fa, int fixed_size, int init_blocks) {
fa->free_list = NULL;
fa->page_list = NULL;
// 确保块大小至少能存放指针(用于空闲链表)
const int min_size = sizeof(void*);
fa->block_size = (fixed_size < min_size) ? min_size :
(fixed_size + 15) & ~15; // 16字节对齐
// 计算每页块数(优化缓存利用率)
const int page_size = ALLOCATOR_PAGE_SIZE - sizeof(void*);
fa->blocks_per_page = page_size / fa->block_size;
// TODO copy paste 需要使用函数抽象 申请过程
// 预分配初始页
void* page = salloc_alloc(PAGE_ALIGN(fa->block_size * init_blocks));
unsigned char* p = (unsigned char*)page;
for (int i = 0; i < init_blocks; ++i) {
void** block = (void**)p;
*block = fa->free_list;
fa->free_list = block;
p += fa->block_size;
}
*(void**)page = fa->page_list;
fa->page_list = page;
}
void* falloc_alloc(fixed_alloc_t* fa) {
if (!fa->free_list) {
// 分配新页(带页头保存链表指针)
void* page = salloc_alloc(ALLOCATOR_PAGE_SIZE);
unsigned char* p = (unsigned char*)page + sizeof(void*);
// 链接新页块到空闲链表
for (int i = 0; i < fa->blocks_per_page; ++i) {
void** block = (void**)p;
*block = fa->free_list;
fa->free_list = block;
p += fa->block_size;
}
*(void**)page = fa->page_list;
fa->page_list = page;
}
void* block = fa->free_list;
fa->free_list = *(void**)block;
return (void*)((unsigned char*)block + sizeof(void*)); // 跳过链表指针
}
void falloc_free(fixed_alloc_t* fa, void* ptr) {
if (!fa || !ptr) return;
void** block = (void**)((u8_t*)ptr - sizeof(void*));
*block = fa->free_list;
fa->free_list = block;
}
void falloc_destroy(fixed_alloc_t* fa) {
if (!fa) return;
// 逆向释放所有内存页(保持地址连续性)
void* current_page = fa->page_list;
while (current_page) {
void* next_page = *(void**)current_page; // 页头保存了链表指针
salloc_free(current_page);
current_page = next_page;
}
// 防御性清零(防止悬垂指针)
fa->free_list = NULL;
fa->blocks_per_page = 0;
fa->block_size = 0;
fa->page_list = NULL;
}
/* Long Allocator */
void lalloc_init(long_alloc_t* la) {
la->current = NULL;
la->block_size = ALLOCATOR_PAGE_SIZE; // 初始块大小
}
void* lalloc_alloc(long_alloc_t* la, int size) {
size = (size + 15) & ~15; // 16字节对齐
if (!la->current || (la->current->used + size) > la->block_size) {
int new_size = la->block_size;
if (new_size < size + sizeof(long_block_t))
new_size = size + sizeof(long_block_t);
long_block_t* new_block = (long_block_t*)salloc_alloc(new_size);
new_block->next = la->current;
new_block->used = sizeof(long_block_t);
la->current = new_block;
la->block_size = new_size;
}
void* ptr = (unsigned char*)la->current + la->current->used;
la->current->used += size;
return ptr;
}
void lalloc_destroy(long_alloc_t* la) {
while (la->current) {
long_block_t* prev = la->current->next;
salloc_free(la->current);
la->current = prev;
}
}

36
lib/rt/rt_alloc.h Normal file
View File

@ -0,0 +1,36 @@
#ifndef __SMCC_RT_ALLOC_H__
#define __SMCC_RT_ALLOC_H__
#include "std/rt_api_def.h"
// Simple or Static Allocator
void* salloc_alloc(int size);
void* salloc_realloc(void* ptr, int size);
void salloc_free(void* ptr);
typedef struct fixed_alloc {
void* page_list;
void* free_list;
int block_size;
int blocks_per_page;
} fixed_alloc_t;
void falloc_init(fixed_alloc_t* fa, int fixed_size, int init_size);
void* falloc_alloc(fixed_alloc_t* fa);
void falloc_free(fixed_alloc_t* fa, void* ptr);
void falloc_destroy(fixed_alloc_t* fa);
typedef struct long_block {
struct long_block* next;
int used;
} long_block_t;
typedef struct long_alloc {
long_block_t* current;
int block_size;
} long_alloc_t;
void lalloc_init(long_alloc_t* la);
void* lalloc_alloc(long_alloc_t* la, int size);
void lalloc_free(long_alloc_t* la, void* ptr);
void lalloc_destroy(long_alloc_t* la);
#endif

49
lib/rt/rt_string.c Normal file
View File

@ -0,0 +1,49 @@
#include "rt_string.h"
int rt_memcmp(const void* s1, const void* s2, rt_size_t n) {
const unsigned char *p1 = s1, *p2 = s2;
for (rt_size_t i = 0; i < n; ++i) {
if (p1[i] != p2[i])
return p1[i] - p2[i];
}
return 0;
}
int rt_strcmp(const char* s1, const char* s2) {
while (*s1 && *s2 && (*s1 == *s2)) {
s1++;
s2++;
}
return *(const unsigned char*)s1 - *(const unsigned char*)s2;
}
void* rt_memcpy(void* restrict dest, const void* restrict src, rt_size_t n) {
u8_t* d = dest;
const u8_t* s = src;
for (rt_size_t i = 0; i < n; ++i)
d[i] = s[i];
return dest;
}
void* rt_memset(void* s, int c, rt_size_t n) {
u8_t* p = s;
for (rt_size_t i = 0; i < n; ++i)
p[i] = (u8_t)c;
return s;
}
rt_size_t rt_strlen(const char* s) {
const char* p = s;
while (*p) p++;
return p - s;
}
/* strhash - 字符串哈希(用于符号表) */
u32_t rt_strhash(const char* s) {
u32_t hash = 2166136261u; // FNV-1a偏移基础值
while (*s) {
hash ^= *s++;
hash *= 16777619u;
}
return hash;
}

15
lib/rt/rt_string.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef __SMCC_RT_STRING_H__
#define __SMCC_RT_STRING_H__
#include "std/rt_api_def.h"
int rt_memcmp(const void* s1, const void* s2, rt_size_t n);
int rt_strcmp(const char* s1, const char* s2);
void* rt_memcpy(void* restrict dest, const void* restrict src, rt_size_t n);
void* rt_memset(void* s, int c, rt_size_t n);
rt_size_t rt_strlen(const char* s);
u32_t rt_strhash(const char* s);
#endif // __SMCC_RT_STRING_H__

64
lib/rt/std/rt_api_def.h Normal file
View File

@ -0,0 +1,64 @@
#ifndef __SMCC_RT_API_DEF_H__
#define __SMCC_RT_API_DEF_H__
#include "rt_type.h"
#ifndef __RT_SIZE_TYPE__
#define __RT_SIZE_TYPE__
typedef usz_t rt_size_t;
#endif
typedef void* (*rt_malloc)(rt_size_t size);
typedef void (*rt_free)(void* ptr);
typedef void (*rt_exit)(int code);
#ifndef __RT_FILE_TYPE__
#define __RT_FILE_TYPE__
typedef void* rt_file_t;
#endif
extern rt_file_t rt_stdin;
extern rt_file_t rt_stdout;
extern rt_file_t rt_stderr;
typedef rt_file_t (*rt_fopen_t)(const char* file_name, const char* mode);
typedef int (*rt_fflush_t)(rt_file_t*file);
typedef int (*rt_fclose_t)(rt_file_t file);
typedef int (*rt_freads_t)(void * dst_buf, rt_size_t dst_size, rt_size_t elem_size, rt_size_t count, rt_file_t file);
typedef int (*rt_fwrite_t)(const void * buf, rt_size_t size, rt_size_t count, rt_file_t file);
typedef int (*rt_fprintf_t)(void * file, const char *format, ...);
typedef int (*rt_snprintf_t)(char * stream, rt_size_t n, const char * format, ...);
typedef void* (*rt_realloc_t)(void *memory, rt_size_t new_size);
typedef struct smcc_rt {
rt_malloc _malloc;
rt_free _free;
rt_exit exit;
rt_fopen_t fopen;
rt_fflush_t fflush;
rt_fclose_t fclose;
rt_freads_t freads;
rt_fwrite_t fwrite;
// Optional useful runtime
rt_fprintf_t fprintf;
rt_snprintf_t snprintf;
rt_realloc_t _realloc;
} smcc_rt_t;
extern const smcc_rt_t rt;
// #ifndef NULL
// #ifdef __cplusplus
// #ifndef _WIN64
// #define NULL 0
// #else
// #define NULL 0LL
// #endif /* W64 */
// #else
// #define NULL ((void *)0)
// #endif
// #endif
#define NULL ((void *)0)
#endif

32
lib/rt/std/rt_std.c Normal file
View File

@ -0,0 +1,32 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "rt_api_def.h"
const smcc_rt_t rt = {
._malloc = (rt_malloc)malloc,
._free = (rt_free)free,
.exit = (rt_exit)exit,
.fopen = (rt_fopen_t)fopen,
.fflush = (rt_fflush_t)fflush,
.fclose = (rt_fclose_t)fclose,
.freads = (rt_freads_t)fread_s,
.fwrite = (rt_fwrite_t)fwrite,
._realloc = (rt_realloc_t)realloc,
.fprintf = (rt_fprintf_t)fprintf,
.snprintf = (rt_snprintf_t)snprintf,
};
rt_file_t rt_stdin;
rt_file_t rt_stdout;
rt_file_t rt_stderr;
void init_rt_std() {
rt_stdin = stdin;
rt_stdout = stdout;
rt_stderr = stderr;
}

6
lib/rt/std/rt_std.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef __SMCC_RT_STD_H__
#define __SMCC_RT_STD_H__
void init_rt_std();
#endif

28
lib/rt/std/rt_type.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef __SMCC_RT_TYPE_H__
#define __SMCC_RT_TYPE_H__
#include <stdint.h>
typedef int8_t i8_t;
typedef int16_t i16_t;
typedef int32_t i32_t;
typedef int64_t i64_t;
typedef uint8_t u8_t;
typedef uint16_t u16_t;
typedef uint32_t u32_t;
typedef uint64_t u64_t;
typedef float f32_t;
typedef double f64_t;
typedef intptr_t iptr_t;
typedef uintptr_t uptr_t;
typedef size_t usz_t;
typedef ssize_t isz_t;
// typedef u32_t uw_t;
// typedef i32_t iw_t;
#endif