chore: 更新 .gitignore 文件
- 添加 docs 文件夹到忽略列表,以忽略 Doxygen 生成的文件 - 保持原有的忽略规则不变
This commit is contained in:
parent
c800b48ca2
commit
8d97fe896c
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,6 +1,9 @@
|
|||||||
.*
|
.*
|
||||||
!.gitignore
|
!.gitignore
|
||||||
|
|
||||||
|
# doxygen generated files
|
||||||
|
docs
|
||||||
|
|
||||||
# smcc compiler generated files
|
# smcc compiler generated files
|
||||||
*.bin
|
*.bin
|
||||||
.s
|
.s
|
||||||
|
14
Makefile
Normal file
14
Makefile
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
build-docs:
|
||||||
|
doxygen Doxyfile
|
||||||
|
|
||||||
|
docs: build-docs
|
||||||
|
python -m http.server -d docs/html
|
||||||
|
|
||||||
|
smcc-build:
|
||||||
|
make -C src
|
||||||
|
|
||||||
|
smcc-clean:
|
||||||
|
make -C src clean
|
||||||
|
|
||||||
|
smcc-test: smcc-build
|
||||||
|
make -C tests/simple
|
21
lib/core.h
21
lib/core.h
@ -1,9 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* @file core.h
|
||||||
|
* @brief 核心库初始化接口
|
||||||
|
*
|
||||||
|
* 定义SMCC库的核心初始化函数和基础服务配置
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef __SMCC_LIB_CORE_H__
|
#ifndef __SMCC_LIB_CORE_H__
|
||||||
#define __SMCC_LIB_CORE_H__
|
#define __SMCC_LIB_CORE_H__
|
||||||
|
|
||||||
#include "rt/rt.h"
|
#include "rt/rt.h"
|
||||||
|
|
||||||
// You MUST BE call this by the start
|
/**
|
||||||
|
* @brief 初始化核心库组件
|
||||||
|
*
|
||||||
|
* 此函数必须在调用任何其他库函数之前调用,可能负责:
|
||||||
|
* - TODO 初始化内存管理系统
|
||||||
|
* - TODO 注册基础信号处理器
|
||||||
|
* - TODO 配置默认日志系统
|
||||||
|
* - 设置运行时环境
|
||||||
|
*
|
||||||
|
* @note 必须作为程序启动后第一个调用的库函数
|
||||||
|
* @warning 重复调用不会导致未定义行为,你必须为此至少调用一次否则会导致未定义行为
|
||||||
|
* @see rt.h 中相关的运行时环境配置
|
||||||
|
*/
|
||||||
void init_lib_core();
|
void init_lib_core();
|
||||||
|
|
||||||
#endif // __SMCC_LIB_CORE_H__
|
#endif // __SMCC_LIB_CORE_H__
|
||||||
|
@ -1,33 +1,59 @@
|
|||||||
|
/**
|
||||||
|
* @file color.h
|
||||||
|
* @brief ANSI终端颜色控制码定义
|
||||||
|
*
|
||||||
|
* 提供跨平台的终端文本颜色和样式控制支持
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef __SMCC_TERMINAL_COLOR_H__
|
#ifndef __SMCC_TERMINAL_COLOR_H__
|
||||||
#define __SMCC_TERMINAL_COLOR_H__
|
#define __SMCC_TERMINAL_COLOR_H__
|
||||||
|
|
||||||
#define ANSI_FG_BLACK "\33[30m"
|
/// @name 前景色控制码
|
||||||
#define ANSI_FG_RED "\33[31m"
|
/// @{
|
||||||
#define ANSI_FG_GREEN "\33[32m"
|
#define ANSI_FG_BLACK "\33[30m" ///< 黑色前景
|
||||||
#define ANSI_FG_YELLOW "\33[33m"
|
#define ANSI_FG_RED "\33[31m" ///< 红色前景
|
||||||
#define ANSI_FG_BLUE "\33[34m"
|
#define ANSI_FG_GREEN "\33[32m" ///< 绿色前景
|
||||||
#define ANSI_FG_MAGENTA "\33[35m"
|
#define ANSI_FG_YELLOW "\33[33m" ///< 黄色前景
|
||||||
#define ANSI_FG_CYAN "\33[36m"
|
#define ANSI_FG_BLUE "\33[34m" ///< 蓝色前景
|
||||||
#define ANSI_FG_WHITE "\33[37m"
|
#define ANSI_FG_MAGENTA "\33[35m" ///< 品红色前景
|
||||||
|
#define ANSI_FG_CYAN "\33[36m" ///< 青色前景
|
||||||
|
#define ANSI_FG_WHITE "\33[37m" ///< 白色前景
|
||||||
|
/// @}
|
||||||
|
|
||||||
#define ANSI_BG_BLACK "\33[40m"
|
/// @name 背景色控制码
|
||||||
#define ANSI_BG_RED "\33[41m"
|
/// @{
|
||||||
#define ANSI_BG_GREEN "\33[42m"
|
#define ANSI_BG_BLACK "\33[40m" ///< 黑色背景
|
||||||
#define ANSI_BG_YELLOW "\33[43m"
|
#define ANSI_BG_RED "\33[41m" ///< 红色背景
|
||||||
#define ANSI_BG_BLUE "\33[44m"
|
#define ANSI_BG_GREEN "\33[42m" ///< 绿色背景
|
||||||
#define ANSI_BG_MAGENTA "\33[35m"
|
#define ANSI_BG_YELLOW "\33[43m" ///< 黄色背景
|
||||||
#define ANSI_BG_CYAN "\33[46m"
|
#define ANSI_BG_BLUE "\33[44m" ///< 蓝色背景
|
||||||
#define ANSI_BG_WHITE "\33[47m"
|
#define ANSI_BG_MAGENTA "\33[45m" ///< 品红色背景(注:原始代码此处应为45m)
|
||||||
|
#define ANSI_BG_CYAN "\33[46m" ///< 青色背景
|
||||||
|
#define ANSI_BG_WHITE "\33[47m" ///< 白色背景
|
||||||
|
/// @}
|
||||||
|
|
||||||
#define ANSI_UNDERLINED "\33[4m"
|
/// @name 文字样式控制码
|
||||||
#define ANSI_BOLD "\33[1m"
|
/// @{
|
||||||
#define ANSI_NONE "\33[0m"
|
#define ANSI_UNDERLINED "\33[4m" ///< 下划线样式
|
||||||
|
#define ANSI_BOLD "\33[1m" ///< 粗体样式
|
||||||
|
#define ANSI_NONE "\33[0m" ///< 重置所有样式
|
||||||
|
/// @}
|
||||||
|
|
||||||
// Maybe Some Terminal Doesn't Support Color
|
/**
|
||||||
|
* @def ANSI_FMT
|
||||||
|
* @brief 安全文本格式化宏
|
||||||
|
* @param str 目标字符串
|
||||||
|
* @param fmt ANSI格式序列(可组合多个样式)
|
||||||
|
*
|
||||||
|
* @note 当定义ANSI_FMT_DISABLE时自动禁用颜色输出
|
||||||
|
* @code
|
||||||
|
* printf(ANSI_FMT("Warning!", ANSI_FG_YELLOW ANSI_BOLD));
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
#ifndef ANSI_FMT_DISABLE
|
#ifndef ANSI_FMT_DISABLE
|
||||||
#define ANSI_FMT(str, fmt) fmt str ANSI_NONE
|
#define ANSI_FMT(str, fmt) fmt str ANSI_NONE ///< 启用样式包裹
|
||||||
#else
|
#else
|
||||||
#define ANSI_FMT(str, fmt) str
|
#define ANSI_FMT(str, fmt) str ///< 禁用样式输出
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif // __SMCC_TERMINAL_COLOR_H__
|
||||||
|
@ -20,7 +20,8 @@ static void default_handler(log_level_t level, const char* module, const char* f
|
|||||||
case LOG_LEVEL_TRACE: level_str = "TRACE"; break;
|
case LOG_LEVEL_TRACE: level_str = "TRACE"; break;
|
||||||
default: level_str = "NOTSET"; break;
|
default: level_str = "NOTSET"; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @note: 定义 __LOG_NO_COLOR__ 会取消颜色输出
|
||||||
#ifndef __LOG_NO_COLOR__
|
#ifndef __LOG_NO_COLOR__
|
||||||
const char* color_code = ANSI_NONE;
|
const char* color_code = ANSI_NONE;
|
||||||
switch (level) {
|
switch (level) {
|
||||||
@ -50,6 +51,12 @@ static logger_t root_logger = {
|
|||||||
.handler = default_handler,
|
.handler = default_handler,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void init_logger(logger_t* logger, const char* name) {
|
||||||
|
logger->name = name;
|
||||||
|
logger->handler = default_handler;
|
||||||
|
log_set_level(logger, LOG_LEVEL_ALL);
|
||||||
|
}
|
||||||
|
|
||||||
logger_t* log_get(const char* name) {
|
logger_t* log_get(const char* name) {
|
||||||
return &root_logger;
|
return &root_logger;
|
||||||
}
|
}
|
||||||
|
146
lib/rt/log/log.h
146
lib/rt/log/log.h
@ -1,21 +1,39 @@
|
|||||||
|
/**
|
||||||
|
* @file log.h
|
||||||
|
* @brief 日志系统核心模块(支持多级日志、断言和异常处理)
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef __SMCC_LOG_H__
|
#ifndef __SMCC_LOG_H__
|
||||||
#define __SMCC_LOG_H__
|
#define __SMCC_LOG_H__
|
||||||
|
|
||||||
#include "../std/rt_api_def.h"
|
#include "../std/rt_api_def.h"
|
||||||
#include "color.h"
|
#include "color.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 日志级别枚举
|
||||||
|
*
|
||||||
|
* 定义日志系统的输出级别和组合标志位
|
||||||
|
*/
|
||||||
typedef enum log_level {
|
typedef enum log_level {
|
||||||
LOG_LEVEL_NOTSET = 0,
|
LOG_LEVEL_NOTSET = 0, ///< 未设置级别(继承默认配置)
|
||||||
LOG_LEVEL_DEBUG = 1 << 0,
|
LOG_LEVEL_DEBUG = 1 << 0, ///< 调试信息(开发阶段详细信息)
|
||||||
LOG_LEVEL_INFO = 1 << 1,
|
LOG_LEVEL_INFO = 1 << 1, ///< 常规信息(系统运行状态)
|
||||||
LOG_LEVEL_WARN = 1 << 2,
|
LOG_LEVEL_WARN = 1 << 2, ///< 警告信息(潜在问题提示)
|
||||||
LOG_LEVEL_ERROR = 1 << 3,
|
LOG_LEVEL_ERROR = 1 << 3, ///< 错误信息(可恢复的错误)
|
||||||
LOG_LEVEL_FATAL = 1 << 4,
|
LOG_LEVEL_FATAL = 1 << 4, ///< 致命错误(导致程序终止的严重错误)
|
||||||
|
LOG_LEVEL_TRACE = 1 << 5, ///< 追踪(性能追踪或者栈帧追踪)
|
||||||
LOG_LEVEL_TRACE = 1 << 5,
|
LOG_LEVEL_ALL = 0xFF, ///< 全级别标志(组合所有日志级别)
|
||||||
LOG_LEVEL_ALL = 0xFF,
|
|
||||||
} log_level_t;
|
} log_level_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 日志处理回调函数类型
|
||||||
|
* @param level 日志级别
|
||||||
|
* @param module 模块名称(可为NULL)
|
||||||
|
* @param file 源文件名
|
||||||
|
* @param line 代码行号
|
||||||
|
* @param message 格式化后的日志消息
|
||||||
|
* @todo 待实现模块名称,输入的模块名称,都将被忽略
|
||||||
|
*/
|
||||||
typedef void (*log_handler)(
|
typedef void (*log_handler)(
|
||||||
log_level_t level,
|
log_level_t level,
|
||||||
const char* module,
|
const char* module,
|
||||||
@ -25,51 +43,119 @@ typedef void (*log_handler)(
|
|||||||
);
|
);
|
||||||
|
|
||||||
#ifndef LOGGER_MAX_BUF_SIZE
|
#ifndef LOGGER_MAX_BUF_SIZE
|
||||||
#define LOGGER_MAX_BUF_SIZE 256
|
#define LOGGER_MAX_BUF_SIZE 512 ///< 单条日志最大缓冲区尺寸
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 日志器实例结构体
|
||||||
|
*
|
||||||
|
* 每个日志器实例维护独立的配置和缓冲区
|
||||||
|
*/
|
||||||
typedef struct logger {
|
typedef struct logger {
|
||||||
const char* name;
|
const char* name; ///< 日志器名称(用于模块区分)
|
||||||
log_level_t level;
|
log_level_t level; ///< 当前设置的日志级别
|
||||||
log_handler handler;
|
log_handler handler; ///< 日志处理回调函数
|
||||||
char buf[LOGGER_MAX_BUF_SIZE];
|
char buf[LOGGER_MAX_BUF_SIZE]; ///< 格式化缓冲区
|
||||||
} logger_t;
|
} logger_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化日志实例 其余参数设置为默认值
|
||||||
|
* @param[in] logger 日志器实例指针
|
||||||
|
* @param[in] name 日志器名称(NULL表示获取默认日志器名称)
|
||||||
|
*/
|
||||||
|
void init_logger(logger_t* logger, const char* name);
|
||||||
|
|
||||||
|
// TODO log_set(); 暂未实现 日志注册
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取或创建日志器实例
|
||||||
|
* @param[in] name 日志器名称(NULL表示获取默认日志器)
|
||||||
|
* @return 日志器实例指针
|
||||||
|
* @warning 若没有找到相应日志器则会返回根日志器
|
||||||
|
*/
|
||||||
logger_t* log_get(const char* name);
|
logger_t* log_get(const char* name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 设置日志级别
|
||||||
|
* @param[in] logger 目标日志器实例
|
||||||
|
* @param[in] level 要设置的日志级别(可组合多个级别)
|
||||||
|
*/
|
||||||
void log_set_level(logger_t* logger, log_level_t level);
|
void log_set_level(logger_t* logger, log_level_t level);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 设置自定义日志处理器
|
||||||
|
* @param[in] logger 目标日志器实例
|
||||||
|
* @param[in] handler 自定义处理函数(NULL恢复默认处理)
|
||||||
|
*/
|
||||||
void log_set_handler(logger_t* logger, log_handler handler);
|
void log_set_handler(logger_t* logger, log_handler handler);
|
||||||
|
|
||||||
#ifndef LOG_MAX_MAROC_BUF_SIZE
|
#ifndef LOG_MAX_MAROC_BUF_SIZE
|
||||||
#define LOG_MAX_MAROC_BUF_SIZE LOGGER_MAX_BUF_SIZE
|
#define LOG_MAX_MAROC_BUF_SIZE LOGGER_MAX_BUF_SIZE ///< 宏展开缓冲区尺寸
|
||||||
#endif
|
#endif
|
||||||
#define _LOG(_level_, _msg_, ...) \
|
|
||||||
|
/**
|
||||||
|
* @def _LOG
|
||||||
|
* @brief 内部日志宏(供其他日志宏调用)
|
||||||
|
* @param _module_ 模块实例(NULL表示使用默认日志器)
|
||||||
|
* @param _level_ 日志级别
|
||||||
|
* @param _msg_ 格式字符串
|
||||||
|
* @param ... 可变参数列表
|
||||||
|
*/
|
||||||
|
#define _LOG(_module_, _level_, _msg_, ...) \
|
||||||
do { \
|
do { \
|
||||||
logger_t* _logger = log_get(NULL); \
|
logger_t* _logger; \
|
||||||
|
if (!_module_) { \
|
||||||
|
_logger = log_get(NULL); \
|
||||||
|
} \
|
||||||
|
else _logger = _module_; \
|
||||||
if (_logger && _logger->handler && (_logger->level & (_level_))) { \
|
if (_logger && _logger->handler && (_logger->level & (_level_))) { \
|
||||||
rt.snprintf(_logger->buf, sizeof(_logger->buf), (_msg_), ##__VA_ARGS__); \
|
rt.snprintf(_logger->buf, sizeof(_logger->buf), (_msg_), ##__VA_ARGS__); \
|
||||||
_logger->handler((_level_), _logger->name, __FILE__, __LINE__, _logger->buf); \
|
_logger->handler((_level_), _logger->name, __FILE__, __LINE__, _logger->buf); \
|
||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define LOG_NOTSET(...) _LOG(LOG_LEVEL_NOTSET, __VA_ARGS__)
|
/// @name 模块日志宏
|
||||||
#define LOG_DEBUG(...) _LOG(LOG_LEVEL_DEBUG, __VA_ARGS__)
|
/// @{
|
||||||
#define LOG_INFO(...) _LOG(LOG_LEVEL_INFO, __VA_ARGS__)
|
#define MLOG_NOTSET(module, ...) _LOG(module, LOG_LEVEL_NOTSET, __VA_ARGS__) ///< 未分类日志
|
||||||
#define LOG_WARN(...) _LOG(LOG_LEVEL_WARN, __VA_ARGS__)
|
#define MLOG_DEBUG( module, ...) _LOG(module, LOG_LEVEL_DEBUG, __VA_ARGS__) ///< 调试日志(需启用DEBUG级别)
|
||||||
#define LOG_ERROR(...) _LOG(LOG_LEVEL_ERROR, __VA_ARGS__)
|
#define MLOG_INFO( module, ...) _LOG(module, LOG_LEVEL_INFO, __VA_ARGS__) ///< 信息日志(常规运行日志)
|
||||||
#define LOG_FATAL(...) _LOG(LOG_LEVEL_FATAL, __VA_ARGS__)
|
#define MLOG_WARN( module, ...) _LOG(module, LOG_LEVEL_WARN, __VA_ARGS__) ///< 警告日志(潜在问题)
|
||||||
#define LOG_TRACE(...) _LOG(LOG_LEVEL_TRACE, __VA_ARGS__)
|
#define MLOG_ERROR( module, ...) _LOG(module, LOG_LEVEL_ERROR, __VA_ARGS__) ///< 错误日志(可恢复错误)
|
||||||
|
#define MLOG_FATAL( module, ...) _LOG(module, LOG_LEVEL_FATAL, __VA_ARGS__) ///< 致命错误日志(程序终止前)
|
||||||
|
#define MLOG_TRACE( module, ...) _LOG(module, LOG_LEVEL_TRACE, __VA_ARGS__) ///< 追踪日志(调用栈跟踪)
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
/// @name 快捷日志宏
|
||||||
|
/// @{
|
||||||
|
#define LOG_NOTSET(...) _LOG(NULL, LOG_LEVEL_NOTSET, __VA_ARGS__) ///< 未分类日志
|
||||||
|
#define LOG_DEBUG(...) _LOG(NULL, LOG_LEVEL_DEBUG, __VA_ARGS__) ///< 调试日志(需启用DEBUG级别)
|
||||||
|
#define LOG_INFO(...) _LOG(NULL, LOG_LEVEL_INFO, __VA_ARGS__) ///< 信息日志(常规运行日志)
|
||||||
|
#define LOG_WARN(...) _LOG(NULL, LOG_LEVEL_WARN, __VA_ARGS__) ///< 警告日志(潜在问题)
|
||||||
|
#define LOG_ERROR(...) _LOG(NULL, LOG_LEVEL_ERROR, __VA_ARGS__) ///< 错误日志(可恢复错误)
|
||||||
|
#define LOG_FATAL(...) _LOG(NULL, LOG_LEVEL_FATAL, __VA_ARGS__) ///< 致命错误日志(程序终止前)
|
||||||
|
#define LOG_TRACE(...) _LOG(NULL, LOG_LEVEL_TRACE, __VA_ARGS__) ///< 追踪日志(调用栈跟踪)
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def _Assert
|
||||||
|
* @brief 断言检查内部宏
|
||||||
|
* @param cond 检查条件表达式
|
||||||
|
* @param ... 错误信息参数(格式字符串+参数)
|
||||||
|
*/
|
||||||
#define _Assert(cond, ...) \
|
#define _Assert(cond, ...) \
|
||||||
do { \
|
do { \
|
||||||
if (!(cond)) { \
|
if (!(cond)) { \
|
||||||
LOG_FATAL(__VA_ARGS__); \
|
LOG_FATAL(__VA_ARGS__); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} 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
|
/// @name 断言工具宏
|
||||||
|
/// @{
|
||||||
|
#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 // __SMCC_LOG_H__
|
||||||
|
@ -1,36 +1,132 @@
|
|||||||
|
/**
|
||||||
|
* @file rt_alloc.h
|
||||||
|
* @brief 内存分配器接口
|
||||||
|
*
|
||||||
|
* 提供三种内存分配器实现:简单分配器、固定大小分配器和长块分配器
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef __SMCC_RT_ALLOC_H__
|
#ifndef __SMCC_RT_ALLOC_H__
|
||||||
#define __SMCC_RT_ALLOC_H__
|
#define __SMCC_RT_ALLOC_H__
|
||||||
|
|
||||||
#include "std/rt_api_def.h"
|
#include "std/rt_api_def.h"
|
||||||
// Simple or Static Allocator
|
|
||||||
|
|
||||||
|
/** @defgroup simple_allocator 简单分配器 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 分配指定大小的内存块
|
||||||
|
* @param size 请求分配的内存大小(字节)
|
||||||
|
* @return 成功返回内存指针,失败返回NULL
|
||||||
|
*/
|
||||||
void* salloc_alloc(int size);
|
void* salloc_alloc(int size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 重新分配内存块
|
||||||
|
* @param ptr 原内存指针
|
||||||
|
* @param size 新内存大小(字节)
|
||||||
|
* @return 成功返回新内存指针,失败返回NULL
|
||||||
|
*/
|
||||||
void* salloc_realloc(void* ptr, int size);
|
void* salloc_realloc(void* ptr, int size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 释放内存块
|
||||||
|
* @param ptr 要释放的内存指针
|
||||||
|
*/
|
||||||
void salloc_free(void* ptr);
|
void salloc_free(void* ptr);
|
||||||
|
|
||||||
|
/** @defgroup fixed_allocator 固定大小分配器 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @struct fixed_alloc_t
|
||||||
|
* @brief 固定大小内存分配器上下文
|
||||||
|
*/
|
||||||
typedef struct fixed_alloc {
|
typedef struct fixed_alloc {
|
||||||
|
/** @brief 内存页链表头指针 */
|
||||||
void* page_list;
|
void* page_list;
|
||||||
|
/** @brief 空闲块链表头指针 */
|
||||||
void* free_list;
|
void* free_list;
|
||||||
|
/** @brief 每个内存块的固定大小 */
|
||||||
int block_size;
|
int block_size;
|
||||||
|
/** @brief 每页包含的块数量 */
|
||||||
int blocks_per_page;
|
int blocks_per_page;
|
||||||
} fixed_alloc_t;
|
} fixed_alloc_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化固定大小分配器
|
||||||
|
* @param fa 分配器上下文指针
|
||||||
|
* @param fixed_size 每个内存块的固定大小
|
||||||
|
* @param init_size 初始预分配块数量
|
||||||
|
*/
|
||||||
void falloc_init(fixed_alloc_t* fa, int fixed_size, int init_size);
|
void falloc_init(fixed_alloc_t* fa, int fixed_size, int init_size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 分配固定大小内存块
|
||||||
|
* @param fa 分配器上下文指针
|
||||||
|
* @return 成功返回内存指针,失败返回NULL
|
||||||
|
*/
|
||||||
void* falloc_alloc(fixed_alloc_t* fa);
|
void* falloc_alloc(fixed_alloc_t* fa);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 释放内存块
|
||||||
|
* @param fa 分配器上下文指针
|
||||||
|
* @param ptr 要释放的内存指针
|
||||||
|
*/
|
||||||
void falloc_free(fixed_alloc_t* fa, void* ptr);
|
void falloc_free(fixed_alloc_t* fa, void* ptr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 销毁分配器并释放所有内存页
|
||||||
|
* @param fa 分配器上下文指针
|
||||||
|
*/
|
||||||
void falloc_destroy(fixed_alloc_t* fa);
|
void falloc_destroy(fixed_alloc_t* fa);
|
||||||
|
|
||||||
|
/** @defgroup long_allocator 长块分配器 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @struct long_block_t
|
||||||
|
* @brief 长块内存块头结构
|
||||||
|
*/
|
||||||
typedef struct long_block {
|
typedef struct long_block {
|
||||||
|
/** @brief 指向下一个内存块的指针 */
|
||||||
struct long_block* next;
|
struct long_block* next;
|
||||||
|
/** @brief 当前块使用状态标志 */
|
||||||
int used;
|
int used;
|
||||||
} long_block_t;
|
} long_block_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @struct long_alloc_t
|
||||||
|
* @brief 长块分配器上下文
|
||||||
|
*/
|
||||||
typedef struct long_alloc {
|
typedef struct long_alloc {
|
||||||
|
/** @brief 当前内存块指针 */
|
||||||
long_block_t* current;
|
long_block_t* current;
|
||||||
|
/** @brief 内存块的标准大小 */
|
||||||
int block_size;
|
int block_size;
|
||||||
} long_alloc_t;
|
} long_alloc_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化长块分配器
|
||||||
|
* @param la 分配器上下文指针
|
||||||
|
*/
|
||||||
void lalloc_init(long_alloc_t* la);
|
void lalloc_init(long_alloc_t* la);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 分配指定大小的内存块
|
||||||
|
* @param la 分配器上下文指针
|
||||||
|
* @param size 请求分配的内存大小
|
||||||
|
* @return 成功返回内存指针,失败返回NULL
|
||||||
|
*/
|
||||||
void* lalloc_alloc(long_alloc_t* la, int size);
|
void* lalloc_alloc(long_alloc_t* la, int size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 标记释放内存块(实际在块耗尽时统一释放)
|
||||||
|
* @param la 分配器上下文指针
|
||||||
|
* @param ptr 要释放的内存指针
|
||||||
|
*/
|
||||||
void lalloc_free(long_alloc_t* la, void* ptr);
|
void lalloc_free(long_alloc_t* la, void* ptr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 销毁分配器并释放所有内存块
|
||||||
|
* @param la 分配器上下文指针
|
||||||
|
*/
|
||||||
void lalloc_destroy(long_alloc_t* la);
|
void lalloc_destroy(long_alloc_t* la);
|
||||||
|
|
||||||
#endif
|
#endif // __SMCC_RT_ALLOC_H__
|
||||||
|
@ -25,11 +25,11 @@ void* rt_memcpy(void* restrict dest, const void* restrict src, rt_size_t n) {
|
|||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* rt_memset(void* s, int c, rt_size_t n) {
|
void* rt_memset(void* dest, int val, rt_size_t n) {
|
||||||
u8_t* p = s;
|
u8_t* p = dest;
|
||||||
for (rt_size_t i = 0; i < n; ++i)
|
for (rt_size_t i = 0; i < n; ++i)
|
||||||
p[i] = (u8_t)c;
|
p[i] = (u8_t)val;
|
||||||
return s;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
rt_size_t rt_strlen(const char* s) {
|
rt_size_t rt_strlen(const char* s) {
|
||||||
|
@ -1,15 +1,67 @@
|
|||||||
|
/**
|
||||||
|
* @file rt_string.h
|
||||||
|
* @brief 运行时字符串与内存操作
|
||||||
|
*
|
||||||
|
* 提供基本的内存操作和字符串处理函数实现
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef __SMCC_RT_STRING_H__
|
#ifndef __SMCC_RT_STRING_H__
|
||||||
#define __SMCC_RT_STRING_H__
|
#define __SMCC_RT_STRING_H__
|
||||||
|
|
||||||
#include "std/rt_api_def.h"
|
#include "std/rt_api_def.h"
|
||||||
|
|
||||||
|
/** @defgroup memory_operations 内存操作 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 内存区域比较
|
||||||
|
* @param s1 第一个内存区域指针
|
||||||
|
* @param s2 第二个内存区域指针
|
||||||
|
* @param n 比较的字节数
|
||||||
|
* @return 差异值(<0: s1<s2, 0: 相等, >0: s1>s2)
|
||||||
|
*/
|
||||||
int rt_memcmp(const void* s1, const void* s2, rt_size_t n);
|
int rt_memcmp(const void* s1, const void* s2, rt_size_t n);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 安全内存拷贝(要求内存区域不重叠)
|
||||||
|
* @param dest 目标内存地址(restrict修饰)
|
||||||
|
* @param src 源内存地址(restrict修饰)
|
||||||
|
* @param n 拷贝的字节数
|
||||||
|
* @return 目标内存地址
|
||||||
|
*/
|
||||||
|
void* rt_memcpy(void* restrict dest, const void* restrict src, rt_size_t n);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 内存区域填充
|
||||||
|
* @param s 目标内存地址
|
||||||
|
* @param c 填充字节值(转换为unsigned char)
|
||||||
|
* @param n 填充的字节数
|
||||||
|
* @return 原始内存地址
|
||||||
|
*/
|
||||||
|
void* rt_memset(void* dest, int val, rt_size_t n);
|
||||||
|
|
||||||
|
/** @defgroup string_operations 字符串操作 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 字符串比较
|
||||||
|
* @param s1 第一个字符串指针
|
||||||
|
* @param s2 第二个字符串指针
|
||||||
|
* @return 差异值(<0: s1<s2, 0: 相等, >0: s1>s2)
|
||||||
|
*/
|
||||||
int rt_strcmp(const char* s1, const char* s2);
|
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);
|
* @brief 计算字符串长度
|
||||||
|
* @param s 字符串指针
|
||||||
|
* @return 字符串长度(不含终止符)
|
||||||
|
*/
|
||||||
rt_size_t rt_strlen(const char* s);
|
rt_size_t rt_strlen(const char* s);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 计算字符串哈希值
|
||||||
|
* @param s 输入字符串
|
||||||
|
* @return 32位无符号哈希值
|
||||||
|
* @note 使用FNV-1a哈希算法实现
|
||||||
|
*/
|
||||||
u32_t rt_strhash(const char* s);
|
u32_t rt_strhash(const char* s);
|
||||||
|
|
||||||
#endif // __SMCC_RT_STRING_H__
|
#endif // __SMCC_RT_STRING_H__
|
||||||
|
@ -1,3 +1,10 @@
|
|||||||
|
/**
|
||||||
|
* @file rt_api_def.h
|
||||||
|
* @brief SMCC运行时库接口定义
|
||||||
|
*
|
||||||
|
* 定义运行时基础API函数指针类型及运行时接口结构体
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef __SMCC_RT_API_DEF_H__
|
#ifndef __SMCC_RT_API_DEF_H__
|
||||||
#define __SMCC_RT_API_DEF_H__
|
#define __SMCC_RT_API_DEF_H__
|
||||||
|
|
||||||
@ -5,48 +12,172 @@
|
|||||||
|
|
||||||
#ifndef __RT_SIZE_TYPE__
|
#ifndef __RT_SIZE_TYPE__
|
||||||
#define __RT_SIZE_TYPE__
|
#define __RT_SIZE_TYPE__
|
||||||
|
/**
|
||||||
|
* @typedef rt_size_t
|
||||||
|
* @brief 表示内存大小的类型定义
|
||||||
|
*/
|
||||||
typedef usz_t rt_size_t;
|
typedef usz_t rt_size_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef rt_malloc
|
||||||
|
* @brief 内存分配函数指针类型
|
||||||
|
* @param size 需要分配的内存大小
|
||||||
|
* @return 分配的内存指针,失败返回NULL
|
||||||
|
*/
|
||||||
typedef void* (*rt_malloc)(rt_size_t size);
|
typedef void* (*rt_malloc)(rt_size_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef rt_free
|
||||||
|
* @brief 内存释放函数指针类型
|
||||||
|
* @param ptr 需要释放的内存指针
|
||||||
|
*/
|
||||||
typedef void (*rt_free)(void* ptr);
|
typedef void (*rt_free)(void* ptr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef rt_exit
|
||||||
|
* @brief 程序退出函数指针类型
|
||||||
|
* @param code 退出状态码
|
||||||
|
*/
|
||||||
typedef void (*rt_exit)(int code);
|
typedef void (*rt_exit)(int code);
|
||||||
|
|
||||||
|
/** @defgroup file_io 文件I/O相关类型 */
|
||||||
|
|
||||||
#ifndef __RT_FILE_TYPE__
|
#ifndef __RT_FILE_TYPE__
|
||||||
#define __RT_FILE_TYPE__
|
#define __RT_FILE_TYPE__
|
||||||
|
/**
|
||||||
|
* @typedef rt_file_t
|
||||||
|
* @brief 文件句柄类型定义
|
||||||
|
*/
|
||||||
typedef void* rt_file_t;
|
typedef void* rt_file_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/** @brief 标准输入文件句柄 */
|
||||||
extern rt_file_t rt_stdin;
|
extern rt_file_t rt_stdin;
|
||||||
|
/** @brief 标准输出文件句柄 */
|
||||||
extern rt_file_t rt_stdout;
|
extern rt_file_t rt_stdout;
|
||||||
|
/** @brief 标准错误文件句柄 */
|
||||||
extern rt_file_t rt_stderr;
|
extern rt_file_t rt_stderr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef rt_fopen_t
|
||||||
|
* @brief 文件打开函数指针类型
|
||||||
|
* @param file_name 文件名
|
||||||
|
* @param mode 打开模式(同fopen)
|
||||||
|
* @return 文件句柄,失败返回NULL
|
||||||
|
*/
|
||||||
typedef rt_file_t (*rt_fopen_t)(const char* file_name, const char* mode);
|
typedef rt_file_t (*rt_fopen_t)(const char* file_name, const char* mode);
|
||||||
typedef int (*rt_fflush_t)(rt_file_t*file);
|
|
||||||
|
/**
|
||||||
|
* @typedef rt_fflush_t
|
||||||
|
* @brief 文件缓冲刷新函数指针类型
|
||||||
|
* @param file 文件句柄指针
|
||||||
|
* @return 成功返回0,失败返回非0值
|
||||||
|
*/
|
||||||
|
typedef int (*rt_fflush_t)(rt_file_t* file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef rt_fclose_t
|
||||||
|
* @brief 文件关闭函数指针类型
|
||||||
|
* @param file 文件句柄
|
||||||
|
* @return 成功返回0,失败返回EOF
|
||||||
|
*/
|
||||||
typedef int (*rt_fclose_t)(rt_file_t file);
|
typedef int (*rt_fclose_t)(rt_file_t file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef rt_fread_t
|
||||||
|
* @brief 文件读取函数指针类型
|
||||||
|
* @param dst_buf 目标缓冲区
|
||||||
|
* @param elem_size 单个元素大小
|
||||||
|
* @param count 元素数量
|
||||||
|
* @param file 文件句柄
|
||||||
|
* @return 实际读取的元素数量
|
||||||
|
*/
|
||||||
typedef int (*rt_fread_t)(void * dst_buf, rt_size_t elem_size, rt_size_t count, rt_file_t file);
|
typedef int (*rt_fread_t)(void * dst_buf, rt_size_t elem_size, rt_size_t count, rt_file_t file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef rt_fwrite_t
|
||||||
|
* @brief 文件写入函数指针类型
|
||||||
|
* @param buf 源缓冲区
|
||||||
|
* @param size 单个元素大小
|
||||||
|
* @param count 元素数量
|
||||||
|
* @param file 文件句柄
|
||||||
|
* @return 实际写入的元素数量
|
||||||
|
*/
|
||||||
typedef int (*rt_fwrite_t)(const void * buf, rt_size_t 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);
|
||||||
|
|
||||||
|
/** @defgroup utility 实用工具函数 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef rt_fprintf_t
|
||||||
|
* @brief 格式化输出函数指针类型
|
||||||
|
* @param file 文件句柄
|
||||||
|
* @param format 格式化字符串
|
||||||
|
* @param ... 可变参数
|
||||||
|
* @return 输出的字符数
|
||||||
|
*/
|
||||||
typedef int (*rt_fprintf_t)(void * file, const char *format, ...);
|
typedef int (*rt_fprintf_t)(void * file, const char *format, ...);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef rt_snprintf_t
|
||||||
|
* @brief 安全格式化字符串函数指针类型
|
||||||
|
* @param stream 目标缓冲区
|
||||||
|
* @param n 缓冲区大小
|
||||||
|
* @param format 格式化字符串
|
||||||
|
* @param ... 可变参数
|
||||||
|
* @return 写入的字符数(不含终止符)
|
||||||
|
*/
|
||||||
typedef int (*rt_snprintf_t)(char * stream, rt_size_t n, const char * format, ...);
|
typedef int (*rt_snprintf_t)(char * stream, rt_size_t n, const char * format, ...);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef rt_realloc_t
|
||||||
|
* @brief 内存重分配函数指针类型
|
||||||
|
* @param memory 原内存指针
|
||||||
|
* @param new_size 新内存大小
|
||||||
|
* @return 新内存指针,失败返回NULL
|
||||||
|
*/
|
||||||
typedef void* (*rt_realloc_t)(void *memory, rt_size_t new_size);
|
typedef void* (*rt_realloc_t)(void *memory, rt_size_t new_size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @struct smcc_rt_t
|
||||||
|
* @brief 运行时接口集合
|
||||||
|
*
|
||||||
|
* 包含内存管理、文件操作等核心运行时函数的指针集合
|
||||||
|
*/
|
||||||
typedef struct smcc_rt {
|
typedef struct smcc_rt {
|
||||||
|
/** @brief 内存分配函数指针 */
|
||||||
rt_malloc _malloc;
|
rt_malloc _malloc;
|
||||||
|
/** @brief 内存释放函数指针 */
|
||||||
rt_free _free;
|
rt_free _free;
|
||||||
|
/** @brief 程序退出函数指针 */
|
||||||
rt_exit exit;
|
rt_exit exit;
|
||||||
|
|
||||||
|
/** @brief 文件打开函数指针 */
|
||||||
rt_fopen_t fopen;
|
rt_fopen_t fopen;
|
||||||
|
/** @brief 文件缓冲刷新函数指针 */
|
||||||
rt_fflush_t fflush;
|
rt_fflush_t fflush;
|
||||||
|
/** @brief 文件关闭函数指针 */
|
||||||
rt_fclose_t fclose;
|
rt_fclose_t fclose;
|
||||||
|
/** @brief 文件读取函数指针 */
|
||||||
rt_fread_t fread;
|
rt_fread_t fread;
|
||||||
|
/** @brief 文件写入函数指针 */
|
||||||
rt_fwrite_t fwrite;
|
rt_fwrite_t fwrite;
|
||||||
|
|
||||||
// Optional useful runtime
|
/** @name 可选工具函数 */
|
||||||
|
///@{
|
||||||
|
/** @brief 格式化输出函数指针(可选) */
|
||||||
rt_fprintf_t fprintf;
|
rt_fprintf_t fprintf;
|
||||||
|
/** @brief 安全格式化字符串函数指针(可选) */
|
||||||
rt_snprintf_t snprintf;
|
rt_snprintf_t snprintf;
|
||||||
|
/** @brief 内存重分配函数指针(可选) */
|
||||||
rt_realloc_t _realloc;
|
rt_realloc_t _realloc;
|
||||||
|
///@}
|
||||||
} smcc_rt_t;
|
} smcc_rt_t;
|
||||||
|
|
||||||
|
/** @brief 全局运行时接口实例 */
|
||||||
extern const smcc_rt_t rt;
|
extern const smcc_rt_t rt;
|
||||||
|
|
||||||
|
/** @brief 空指针定义 */
|
||||||
#define NULL ((void *)0)
|
#define NULL ((void *)0)
|
||||||
|
|
||||||
#endif
|
#endif // __SMCC_RT_API_DEF_H__
|
||||||
|
@ -3,4 +3,4 @@
|
|||||||
|
|
||||||
void init_rt_std();
|
void init_rt_std();
|
||||||
|
|
||||||
#endif
|
#endif // __SMCC_RT_STD_H__
|
||||||
|
@ -1,29 +1,120 @@
|
|||||||
|
/**
|
||||||
|
* @file rt_type.h
|
||||||
|
* @brief 基础类型定义
|
||||||
|
*
|
||||||
|
* 定义跨平台基础数据类型别名,基于C99标准头文件<stdint.h>和<stddef.h>
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef __SMCC_RT_TYPE_H__
|
#ifndef __SMCC_RT_TYPE_H__
|
||||||
#define __SMCC_RT_TYPE_H__
|
#define __SMCC_RT_TYPE_H__
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/** @defgroup integer_types 整数类型 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef i8_t
|
||||||
|
* @brief 8位有符号整数
|
||||||
|
*/
|
||||||
typedef int8_t i8_t;
|
typedef int8_t i8_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef i16_t
|
||||||
|
* @brief 16位有符号整数
|
||||||
|
*/
|
||||||
typedef int16_t i16_t;
|
typedef int16_t i16_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef i32_t
|
||||||
|
* @brief 32位有符号整数
|
||||||
|
*/
|
||||||
typedef int32_t i32_t;
|
typedef int32_t i32_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef i64_t
|
||||||
|
* @brief 64位有符号整数
|
||||||
|
*/
|
||||||
typedef int64_t i64_t;
|
typedef int64_t i64_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef u8_t
|
||||||
|
* @brief 8位无符号整数
|
||||||
|
*/
|
||||||
typedef uint8_t u8_t;
|
typedef uint8_t u8_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef u16_t
|
||||||
|
* @brief 16位无符号整数
|
||||||
|
*/
|
||||||
typedef uint16_t u16_t;
|
typedef uint16_t u16_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef u32_t
|
||||||
|
* @brief 32位无符号整数
|
||||||
|
*/
|
||||||
typedef uint32_t u32_t;
|
typedef uint32_t u32_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef u64_t
|
||||||
|
* @brief 64位无符号整数
|
||||||
|
*/
|
||||||
typedef uint64_t u64_t;
|
typedef uint64_t u64_t;
|
||||||
|
|
||||||
|
/** @defgroup floating_point 浮点类型 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef f32_t
|
||||||
|
* @brief 32位单精度浮点数
|
||||||
|
*/
|
||||||
typedef float f32_t;
|
typedef float f32_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef f64_t
|
||||||
|
* @brief 64位双精度浮点数
|
||||||
|
*/
|
||||||
typedef double f64_t;
|
typedef double f64_t;
|
||||||
|
|
||||||
|
/** @defgroup pointer_types 指针类型 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef iptr_t
|
||||||
|
* @brief 带符号指针类型(intptr_t别名)
|
||||||
|
*/
|
||||||
typedef intptr_t iptr_t;
|
typedef intptr_t iptr_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef uptr_t
|
||||||
|
* @brief 无符号指针类型(uintptr_t别名)
|
||||||
|
*/
|
||||||
typedef uintptr_t uptr_t;
|
typedef uintptr_t uptr_t;
|
||||||
|
|
||||||
|
/** @defgroup size_types 大小类型 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef usz_t
|
||||||
|
* @brief 无符号大小类型(size_t别名)
|
||||||
|
*/
|
||||||
typedef size_t usz_t;
|
typedef size_t usz_t;
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * @typedef isz_t
|
||||||
|
// * @brief 带符号大小类型(ssize_t别名)
|
||||||
|
// */
|
||||||
// typedef ssize_t isz_t;
|
// typedef ssize_t isz_t;
|
||||||
|
|
||||||
|
// /** @defgroup word_types 字类型 */
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * @typedef uw_t
|
||||||
|
// * @brief 无符号机器字类型(32位)
|
||||||
|
// */
|
||||||
// typedef u32_t uw_t;
|
// typedef u32_t uw_t;
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * @typedef iw_t
|
||||||
|
// * @brief 带符号机器字类型(32位)
|
||||||
|
// */
|
||||||
// typedef i32_t iw_t;
|
// typedef i32_t iw_t;
|
||||||
|
|
||||||
#endif
|
#endif // __SMCC_RT_TYPE_H__
|
||||||
|
@ -52,7 +52,7 @@ static void adjust_capacity(hash_table_t* ht, int new_cap) {
|
|||||||
new_cap = next_power_of_two(new_cap);
|
new_cap = next_power_of_two(new_cap);
|
||||||
Assert(new_cap >= ht->entries.cap);
|
Assert(new_cap >= ht->entries.cap);
|
||||||
|
|
||||||
vector_header(old_entries, hash_entry_t);
|
VECTOR_HEADER(old_entries, hash_entry_t);
|
||||||
old_entries.data = ht->entries.data;
|
old_entries.data = ht->entries.data;
|
||||||
old_entries.cap = ht->entries.cap;
|
old_entries.cap = ht->entries.cap;
|
||||||
|
|
||||||
|
@ -1,3 +1,10 @@
|
|||||||
|
/**
|
||||||
|
* @file hashtable.h
|
||||||
|
* @brief 开放寻址法哈希表实现
|
||||||
|
*
|
||||||
|
* 提供基于向量容器的哈希表实现,支持动态扩容和墓碑机制
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef __SMCC_HASHTABLE_H__
|
#ifndef __SMCC_HASHTABLE_H__
|
||||||
#define __SMCC_HASHTABLE_H__
|
#define __SMCC_HASHTABLE_H__
|
||||||
|
|
||||||
@ -5,39 +12,113 @@
|
|||||||
#include <lib/rt/rt_alloc.h>
|
#include <lib/rt/rt_alloc.h>
|
||||||
#include "vector.h"
|
#include "vector.h"
|
||||||
|
|
||||||
// 哈希表条目状态标记
|
/**
|
||||||
|
* @enum ht_entry_state_t
|
||||||
|
* @brief 哈希表条目状态标识
|
||||||
|
*/
|
||||||
typedef enum hash_table_entry_state {
|
typedef enum hash_table_entry_state {
|
||||||
ENTRY_EMPTY,
|
ENTRY_EMPTY, /**< 空槽位(从未使用过) */
|
||||||
ENTRY_ACTIVE,
|
ENTRY_ACTIVE, /**< 有效条目(包含键值对) */
|
||||||
ENTRY_TOMBSTONE
|
ENTRY_TOMBSTONE /**< 墓碑标记(已删除条目) */
|
||||||
} ht_entry_state_t;
|
} ht_entry_state_t;
|
||||||
|
|
||||||
// 哈希表条目结构(不管理key/value内存)
|
/**
|
||||||
|
* @struct hash_entry_t
|
||||||
|
* @brief 哈希表条目结构
|
||||||
|
*
|
||||||
|
* @note key/value内存由调用者管理,哈希表不负责其生命周期
|
||||||
|
*/
|
||||||
typedef struct hash_entry {
|
typedef struct hash_entry {
|
||||||
const void* key; // 由调用者管理
|
const void* key; /**< 键指针(不可变) */
|
||||||
void* value; // 由调用者管理
|
void* value; /**< 值指针 */
|
||||||
u32_t hash; // 预计算哈希值
|
u32_t hash; /**< 预计算的哈希值(避免重复计算) */
|
||||||
ht_entry_state_t state; // 条目状态
|
ht_entry_state_t state; /**< 当前条目状态 */
|
||||||
} hash_entry_t;
|
} hash_entry_t;
|
||||||
|
|
||||||
// 哈希表主体结构
|
/**
|
||||||
|
* @struct hash_table_t
|
||||||
|
* @brief 哈希表主体结构
|
||||||
|
*
|
||||||
|
* 使用开放寻址法实现,采用墓碑标记处理删除操作
|
||||||
|
*/
|
||||||
typedef struct hash_table {
|
typedef struct hash_table {
|
||||||
vector_header(entries, hash_entry_t); // 使用vector管理条目
|
VECTOR_HEADER(entries, hash_entry_t); /**< 条目存储容器 */
|
||||||
u32_t count; // 有效条目数(不含墓碑)
|
u32_t count; /**< 有效条目数量(不含墓碑) */
|
||||||
u32_t tombstone_count; // 墓碑数量
|
u32_t tombstone_count; /**< 墓碑条目数量 */
|
||||||
|
/**
|
||||||
|
* @brief 哈希函数指针
|
||||||
|
* @param key 键指针
|
||||||
|
* @return 32位无符号哈希值
|
||||||
|
*/
|
||||||
u32_t (*hash_func)(const void* key);
|
u32_t (*hash_func)(const void* key);
|
||||||
|
/**
|
||||||
|
* @brief 键比较函数指针
|
||||||
|
* @param key1 第一个键指针
|
||||||
|
* @param key2 第二个键指针
|
||||||
|
* @return 相同返回0,不同返回非0
|
||||||
|
*/
|
||||||
int(*key_cmp)(const void* key1, const void* key2);
|
int(*key_cmp)(const void* key1, const void* key2);
|
||||||
} hash_table_t;
|
} hash_table_t;
|
||||||
|
|
||||||
// WARN you need set hash_func and key_cmp before use
|
/**
|
||||||
void init_hashtable(hash_table_t* ht) ;
|
* @brief 初始化哈希表结构
|
||||||
|
* @param ht 哈希表实例指针
|
||||||
|
*
|
||||||
|
* @warning 必须设置hash_func和key_cmp后才能使用
|
||||||
|
*/
|
||||||
|
void init_hashtable(hash_table_t* ht);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 插入/更新键值对
|
||||||
|
* @param ht 哈希表实例指针
|
||||||
|
* @param key 键指针
|
||||||
|
* @param value 值指针
|
||||||
|
* @return 被替换的旧值指针(无替换返回NULL)
|
||||||
|
*/
|
||||||
void* hashtable_set(hash_table_t* ht, const void* key, void* value);
|
void* hashtable_set(hash_table_t* ht, const void* key, void* value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 查找键对应值
|
||||||
|
* @param ht 哈希表实例指针
|
||||||
|
* @param key 查找键指针
|
||||||
|
* @return 找到返回值指针,未找到返回NULL
|
||||||
|
*/
|
||||||
void* hashtable_get(hash_table_t* ht, const void* key);
|
void* hashtable_get(hash_table_t* ht, const void* key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 删除键值对
|
||||||
|
* @param ht 哈希表实例指针
|
||||||
|
* @param key 要删除的键指针
|
||||||
|
* @return 被删除的值指针(不存在返回NULL)
|
||||||
|
*
|
||||||
|
* @note 实际采用墓碑标记方式删除
|
||||||
|
*/
|
||||||
void* hashtable_del(hash_table_t* ht, const void* key);
|
void* hashtable_del(hash_table_t* ht, const void* key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 销毁哈希表
|
||||||
|
* @param ht 哈希表实例指针
|
||||||
|
*
|
||||||
|
* @note 仅释放哈希表内部内存,不会释放key/value内存
|
||||||
|
*/
|
||||||
void hashtable_destory(hash_table_t* ht);
|
void hashtable_destory(hash_table_t* ht);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef hash_table_iter_func
|
||||||
|
* @brief 哈希表迭代回调函数类型
|
||||||
|
* @param key 当前键指针
|
||||||
|
* @param value 当前值指针
|
||||||
|
* @param context 用户上下文指针
|
||||||
|
* @return 返回非0停止迭代
|
||||||
|
*/
|
||||||
typedef int (*hash_table_iter_func)(const void* key, void* value, void* context);
|
typedef int (*hash_table_iter_func)(const void* key, void* value, void* context);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 遍历哈希表所有有效条目
|
||||||
|
* @param ht 哈希表实例指针
|
||||||
|
* @param iter_func 迭代回调函数
|
||||||
|
* @param context 用户上下文指针
|
||||||
|
*/
|
||||||
void hashtable_foreach(hash_table_t* ht, hash_table_iter_func iter_func, void* context);
|
void hashtable_foreach(hash_table_t* ht, hash_table_iter_func iter_func, void* context);
|
||||||
|
|
||||||
#endif // __SMCC_HASHTABLE_H__
|
#endif // __SMCC_HASHTABLE_H__
|
||||||
|
@ -1,17 +1,44 @@
|
|||||||
// vector.h
|
/**
|
||||||
|
* @file vector.h
|
||||||
|
* @brief 动态数组(Vector)实现
|
||||||
|
*
|
||||||
|
* 提供类型安全的动态数组容器实现,支持自动扩容和基本操作
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef __SMCC_DS_VECTOR_H__
|
#ifndef __SMCC_DS_VECTOR_H__
|
||||||
#define __SMCC_DS_VECTOR_H__
|
#define __SMCC_DS_VECTOR_H__
|
||||||
|
|
||||||
#include <lib/rt/rt.h>
|
#include <lib/rt/rt.h>
|
||||||
|
|
||||||
#define vector_header(name, type) \
|
/** @defgroup vector_struct 数据结构定义 */
|
||||||
struct { \
|
|
||||||
rt_size_t size; \
|
|
||||||
rt_size_t cap; \
|
|
||||||
type *data; \
|
|
||||||
} name \
|
|
||||||
|
|
||||||
// You can't malloc at init function becase some user just need a header
|
/**
|
||||||
|
* @def VECTOR_HEADER(name, type)
|
||||||
|
* @brief 声明向量结构体
|
||||||
|
* @param name 结构体变量名
|
||||||
|
* @param type 存储的数据类型
|
||||||
|
*
|
||||||
|
* 生成包含size/cap/data三个字段的结构体定义:
|
||||||
|
* - size: 当前元素数量
|
||||||
|
* - cap: 数组容量
|
||||||
|
* - data: 存储数组指针
|
||||||
|
*/
|
||||||
|
#define VECTOR_HEADER(name, type) \
|
||||||
|
struct { \
|
||||||
|
rt_size_t size; /**< 当前元素数量 */ \
|
||||||
|
rt_size_t cap; /**< 数组容量 */ \
|
||||||
|
type *data; /**< 数据存储指针 */ \
|
||||||
|
} name
|
||||||
|
|
||||||
|
/** @defgroup vector_operations 向量操作宏 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def vector_init(vec)
|
||||||
|
* @brief 初始化向量结构体
|
||||||
|
* @param vec 要初始化的向量结构体变量
|
||||||
|
*
|
||||||
|
* @note 此宏不会分配内存,仅做零初始化
|
||||||
|
*/
|
||||||
#define vector_init(vec) \
|
#define vector_init(vec) \
|
||||||
do { \
|
do { \
|
||||||
(vec).size = 0, \
|
(vec).size = 0, \
|
||||||
@ -19,6 +46,15 @@
|
|||||||
(vec).data = 0; \
|
(vec).data = 0; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def vector_push(vec, value)
|
||||||
|
* @brief 添加元素到向量末尾
|
||||||
|
* @param vec 目标向量结构体
|
||||||
|
* @param value 要添加的值(需匹配存储类型)
|
||||||
|
*
|
||||||
|
* @note 当容量不足时自动扩容为2倍(初始容量为8)
|
||||||
|
* @warning 内存分配失败时会触发LOG_FATAL
|
||||||
|
*/
|
||||||
#define vector_push(vec, value) \
|
#define vector_push(vec, value) \
|
||||||
do { \
|
do { \
|
||||||
if (vec.size >= vec.cap) { \
|
if (vec.size >= vec.cap) { \
|
||||||
@ -33,15 +69,43 @@
|
|||||||
(vec).data[(vec).size++] = value; \
|
(vec).data[(vec).size++] = value; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def vector_pop(vec)
|
||||||
|
* @brief 弹出最后一个元素
|
||||||
|
* @param vec 目标向量结构体
|
||||||
|
* @return 最后元素的引用
|
||||||
|
* @warning 需确保size > 0时使用
|
||||||
|
*/
|
||||||
#define vector_pop(vec) \
|
#define vector_pop(vec) \
|
||||||
((vec).data[--(vec).size])
|
((vec).data[--(vec).size])
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def vector_at(vec, idx)
|
||||||
|
* @brief 获取指定索引元素
|
||||||
|
* @param vec 目标向量结构体
|
||||||
|
* @param idx 元素索引(0 <= idx < size)
|
||||||
|
* @return 对应元素的引用
|
||||||
|
*/
|
||||||
#define vector_at(vec, idx) \
|
#define vector_at(vec, idx) \
|
||||||
(((vec).data)[idx])
|
(((vec).data)[idx])
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def vector_idx(vec, ptr)
|
||||||
|
* @brief 获取元素指针对应的索引
|
||||||
|
* @param vec 目标向量结构体
|
||||||
|
* @param ptr 元素指针(需在data数组范围内)
|
||||||
|
* @return 元素索引值
|
||||||
|
*/
|
||||||
#define vector_idx(vec, ptr) \
|
#define vector_idx(vec, ptr) \
|
||||||
((ptr) - (vec).data)
|
((ptr) - (vec).data)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def vector_free(vec)
|
||||||
|
* @brief 释放向量内存
|
||||||
|
* @param vec 目标向量结构体
|
||||||
|
*
|
||||||
|
* @note 释放后需重新初始化才能再次使用
|
||||||
|
*/
|
||||||
#define vector_free(vec) \
|
#define vector_free(vec) \
|
||||||
do { \
|
do { \
|
||||||
salloc_free((vec).data); \
|
salloc_free((vec).data); \
|
||||||
@ -49,4 +113,4 @@
|
|||||||
(vec).size = (vec).cap = 0; \
|
(vec).size = (vec).cap = 0; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#endif
|
#endif // __SMCC_DS_VECTOR_H__
|
||||||
|
@ -1,3 +1,10 @@
|
|||||||
|
/**
|
||||||
|
* @file strpool.h
|
||||||
|
* @brief 字符串池实现
|
||||||
|
*
|
||||||
|
* 提供字符串驻留(String Interning)功能,保证相同字符串的唯一性存储
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef __SMCC_STRPOOL_H__
|
#ifndef __SMCC_STRPOOL_H__
|
||||||
#define __SMCC_STRPOOL_H__
|
#define __SMCC_STRPOOL_H__
|
||||||
|
|
||||||
@ -5,13 +12,43 @@
|
|||||||
#include <lib/rt/rt_alloc.h>
|
#include <lib/rt/rt_alloc.h>
|
||||||
#include <lib/utils/ds/hashtable.h>
|
#include <lib/utils/ds/hashtable.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @struct strpool_t
|
||||||
|
* @brief 字符串池上下文
|
||||||
|
*
|
||||||
|
* 组合哈希表和专用内存分配器实现的高效字符串存储池
|
||||||
|
*/
|
||||||
typedef struct strpool {
|
typedef struct strpool {
|
||||||
hash_table_t ht; // 用于快速查找字符串
|
hash_table_t ht; /**< 哈希表用于快速查找已存储字符串 */
|
||||||
long_alloc_t stralloc; // 专门用于字符串存储的分配器
|
long_alloc_t stralloc; /**< 长块分配器优化小字符串内存管理 */
|
||||||
} strpool_t;
|
} strpool_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化字符串池
|
||||||
|
* @param pool 字符串池实例指针
|
||||||
|
*
|
||||||
|
* @warning 使用前需确保 hashtable 的 hash_func 和 key_cmp 已正确设置
|
||||||
|
*/
|
||||||
void init_strpool(strpool_t* pool);
|
void init_strpool(strpool_t* pool);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 驻留字符串到池中
|
||||||
|
* @param pool 字符串池实例指针
|
||||||
|
* @param str 要驻留的 C 字符串
|
||||||
|
* @return 池中唯一字符串的持久指针
|
||||||
|
*
|
||||||
|
* @note 返回值生命周期与字符串池一致
|
||||||
|
* @note 重复插入相同字符串会返回已有指针
|
||||||
|
*/
|
||||||
const char* strpool_intern(strpool_t* pool, const char* str);
|
const char* strpool_intern(strpool_t* pool, const char* str);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 销毁字符串池
|
||||||
|
* @param pool 字符串池实例指针
|
||||||
|
*
|
||||||
|
* @warning 销毁后已获取的字符串指针将失效
|
||||||
|
* @note 会自动释放所有驻留字符串内存
|
||||||
|
*/
|
||||||
void strpool_destroy(strpool_t* pool);
|
void strpool_destroy(strpool_t* pool);
|
||||||
|
|
||||||
#endif // __SMCC_STRPOOL_H__
|
#endif // __SMCC_STRPOOL_H__
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
CC = gcc
|
CC = gcc
|
||||||
CFLAGS = -g -Wall -I..
|
CFLAGS = -g -Wall -I..
|
||||||
LIBS = -Lccompiler -lcc -Lassembler/riscv32 -lasm -Llinker -llk -Lmcode -lmc -L../lib -lcore
|
LIBS = -Lccompiler -lcc -Lassembler/riscv32 -lasm -Llinker -llk -Lmcode -lmc -L../lib -lcore
|
||||||
# CLFAGS += -fsanitize=address
|
CLFAGS += -fsanitize=address
|
||||||
|
|
||||||
all: smcc
|
all: smcc
|
||||||
smcc: cc asm lib mc lk
|
smcc: cc asm lib mc lk
|
||||||
@ -27,4 +27,4 @@ clean:
|
|||||||
make -C assembler/riscv32 clean
|
make -C assembler/riscv32 clean
|
||||||
make -C ccompiler clean
|
make -C ccompiler clean
|
||||||
make -C mcode clean
|
make -C mcode clean
|
||||||
make -C linker clean
|
make -C linker clean
|
||||||
|
@ -2,7 +2,6 @@ CC = gcc
|
|||||||
AR = ar
|
AR = ar
|
||||||
CFLAGS = -g -Wall -I../../..
|
CFLAGS = -g -Wall -I../../..
|
||||||
|
|
||||||
# 自动收集所有子模块源文件
|
|
||||||
EXCLUDE = test*.c
|
EXCLUDE = test*.c
|
||||||
|
|
||||||
SRCS = $(filter-out $(EXCLUDE), $(wildcard *.c))
|
SRCS = $(filter-out $(EXCLUDE), $(wildcard *.c))
|
||||||
|
@ -13,3 +13,17 @@ void init_rv32_prog(rv32_prog_t* prog, strpool_t* strpool) {
|
|||||||
init_symtab_asm(&prog->symtab);
|
init_symtab_asm(&prog->symtab);
|
||||||
init_rv32_mcode(&prog->mcode, sizeof(symasm_entry_t));
|
init_rv32_mcode(&prog->mcode, sizeof(symasm_entry_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void asm_from_file(const char* file_name, rv32_prog_t* prog) {
|
||||||
|
init_rv32_prog(prog, NULL);
|
||||||
|
|
||||||
|
rt_file_t* fp = rt.fopen(file_name, "r");
|
||||||
|
if (fp == NULL) {
|
||||||
|
LOG_FATAL("Failed to open file %s", file_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
char buf[1024];
|
||||||
|
rt.fread(buf, 1, sizeof(buf), fp);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -9,7 +9,7 @@ typedef struct rv32_prog {
|
|||||||
symtab_asm_t symtab;
|
symtab_asm_t symtab;
|
||||||
u32_t text_base_address;
|
u32_t text_base_address;
|
||||||
u32_t data_base_address;
|
u32_t data_base_address;
|
||||||
vector_header(data, iptr_t);
|
VECTOR_HEADER(data, iptr_t);
|
||||||
mcode_rv32_t mcode;
|
mcode_rv32_t mcode;
|
||||||
} rv32_prog_t;
|
} rv32_prog_t;
|
||||||
|
|
||||||
|
@ -1,37 +1,76 @@
|
|||||||
|
/**
|
||||||
|
* @file lexer.h
|
||||||
|
* @brief C语言词法分析器核心数据结构与接口
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef __SMCC_CC_LEXER_H__
|
#ifndef __SMCC_CC_LEXER_H__
|
||||||
#define __SMCC_CC_LEXER_H__
|
#define __SMCC_CC_LEXER_H__
|
||||||
|
|
||||||
#include <lib/core.h>
|
#include <lib/core.h>
|
||||||
#include "token.h"
|
#include "token.h"
|
||||||
|
|
||||||
#ifndef LEXER_MAX_TOKEN_SIZE
|
#ifndef LEXER_MAX_TOKEN_SIZE
|
||||||
#define LEXER_MAX_TOKEN_SIZE 63
|
#define LEXER_MAX_TOKEN_SIZE 63 ///< 单个token的最大长度限制
|
||||||
#endif
|
|
||||||
#ifndef LEXER_BUFFER_SIZE
|
|
||||||
#define LEXER_BUFFER_SIZE 4095
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef LEXER_BUFFER_SIZE
|
||||||
|
#define LEXER_BUFFER_SIZE 4095 ///< 词法分析缓冲区大小
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 流读取函数原型
|
||||||
|
* @param dst_buf 目标缓冲区
|
||||||
|
* @param elem_size 元素大小
|
||||||
|
* @param count 元素数量
|
||||||
|
* @param stream 输入流指针
|
||||||
|
* @return 实际读取的元素数量
|
||||||
|
*/
|
||||||
typedef int (*lexer_sread_fn)(void *dst_buf, int elem_size, int count, void *stream);
|
typedef int (*lexer_sread_fn)(void *dst_buf, int elem_size, int count, void *stream);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 词法分析器核心结构体
|
||||||
|
*
|
||||||
|
* 封装词法分析所需的状态信息和缓冲区管理
|
||||||
|
*/
|
||||||
typedef struct cc_lexer {
|
typedef struct cc_lexer {
|
||||||
loc_t loc;
|
loc_t loc; ///< 当前解析位置信息(文件名、行列号等)
|
||||||
|
|
||||||
char* cur_ptr; // 当前扫描的字符,但是还没有开始扫描
|
char* cur_ptr; ///< 当前扫描指针(指向尚未处理的字符)
|
||||||
char* end_ptr; // 缓冲区最后一个字符的下一个位置
|
char* end_ptr; ///< 缓冲区结束指针(指向最后一个有效字符的下一个位置)
|
||||||
char buffer[LEXER_BUFFER_SIZE+1];
|
char buffer[LEXER_BUFFER_SIZE+1]; ///< 字符缓冲区(包含NUL终止符)
|
||||||
|
|
||||||
lexer_sread_fn sread;
|
lexer_sread_fn sread; ///< 流读取函数指针
|
||||||
void* stream;
|
void* stream; ///< 输入流对象指针
|
||||||
|
strpool_t* strpool; ///< 字符串池(用于存储标识符等字符串)
|
||||||
strpool_t* strpool;
|
|
||||||
} cc_lexer_t;
|
} cc_lexer_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化词法分析器
|
||||||
|
* @param[out] lexer 要初始化的词法分析器实例
|
||||||
|
* @param[in] file_name 当前解析的源文件名
|
||||||
|
* @param[in] stream 输入流对象指针
|
||||||
|
* @param[in] sread 自定义流读取函数
|
||||||
|
* @param[in] strpool 字符串池实例
|
||||||
|
*/
|
||||||
void init_lexer(cc_lexer_t* lexer, const char* file_name, void* stream,
|
void init_lexer(cc_lexer_t* lexer, const char* file_name, void* stream,
|
||||||
lexer_sread_fn sread, strpool_t* strpool);
|
lexer_sread_fn sread, strpool_t* strpool);
|
||||||
|
|
||||||
// pure token getter it will included empty token like TOKEN_BLANK
|
/**
|
||||||
|
* @brief 获取原始token
|
||||||
|
* @param[in] lexer 词法分析器实例
|
||||||
|
* @param[out] token 输出token存储位置
|
||||||
|
*
|
||||||
|
* 此函数会返回所有类型的token,包括空白符等无效token
|
||||||
|
*/
|
||||||
void get_token(cc_lexer_t* lexer, tok_t* token);
|
void get_token(cc_lexer_t* lexer, tok_t* token);
|
||||||
|
|
||||||
// get_token maybe got invalid (with parser as TOKEN_BLANK)
|
/**
|
||||||
|
* @brief 获取有效token
|
||||||
|
* @param[in] lexer 词法分析器实例
|
||||||
|
* @param[out] token 输出token存储位置
|
||||||
|
*
|
||||||
|
* 此函数会自动跳过空白符等无效token,返回对语法分析有意义的token
|
||||||
|
*/
|
||||||
void get_valid_token(cc_lexer_t* lexer, tok_t* token);
|
void get_valid_token(cc_lexer_t* lexer, tok_t* token);
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -84,10 +84,10 @@ typedef struct ast_node {
|
|||||||
union {
|
union {
|
||||||
void *children[6];
|
void *children[6];
|
||||||
struct {
|
struct {
|
||||||
vector_header(children, struct ast_node *);
|
VECTOR_HEADER(children, struct ast_node *);
|
||||||
} root;
|
} root;
|
||||||
struct {
|
struct {
|
||||||
vector_header(children, struct ast_node *);
|
VECTOR_HEADER(children, struct ast_node *);
|
||||||
} block;
|
} block;
|
||||||
struct {
|
struct {
|
||||||
symtab_key_t key;
|
symtab_key_t key;
|
||||||
@ -95,7 +95,7 @@ typedef struct ast_node {
|
|||||||
tok_t tok;
|
tok_t tok;
|
||||||
} syms;
|
} syms;
|
||||||
struct {
|
struct {
|
||||||
vector_header(params, struct ast_node *);
|
VECTOR_HEADER(params, struct ast_node *);
|
||||||
} params;
|
} params;
|
||||||
struct {
|
struct {
|
||||||
struct ast_node * name;
|
struct ast_node * name;
|
||||||
|
@ -38,21 +38,21 @@ typedef struct ir_node ir_node_t;
|
|||||||
|
|
||||||
typedef struct ir_bblock {
|
typedef struct ir_bblock {
|
||||||
const char *label;
|
const char *label;
|
||||||
vector_header(instrs, ir_node_t*);
|
VECTOR_HEADER(instrs, ir_node_t*);
|
||||||
// ir_arr_t used_by;
|
// ir_arr_t used_by;
|
||||||
} ir_bblock_t; // basic block
|
} ir_bblock_t; // basic block
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char *name;
|
const char *name;
|
||||||
ir_type_t *type;
|
ir_type_t *type;
|
||||||
vector_header(params, ir_node_t*);
|
VECTOR_HEADER(params, ir_node_t*);
|
||||||
vector_header(bblocks, ir_bblock_t*);
|
VECTOR_HEADER(bblocks, ir_bblock_t*);
|
||||||
} ir_func_t;
|
} ir_func_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
vector_header(global, ir_node_t*);
|
VECTOR_HEADER(global, ir_node_t*);
|
||||||
vector_header(funcs, ir_func_t*);
|
VECTOR_HEADER(funcs, ir_func_t*);
|
||||||
vector_header(extern_funcs, ir_func_t*);
|
VECTOR_HEADER(extern_funcs, ir_func_t*);
|
||||||
} ir_prog_t;
|
} ir_prog_t;
|
||||||
|
|
||||||
typedef enum ir_node_tag {
|
typedef enum ir_node_tag {
|
||||||
@ -72,7 +72,7 @@ typedef enum ir_node_tag {
|
|||||||
struct ir_node {
|
struct ir_node {
|
||||||
const ir_type_t* type;
|
const ir_type_t* type;
|
||||||
const char* name;
|
const char* name;
|
||||||
vector_header(used_by, ir_node_t*);
|
VECTOR_HEADER(used_by, ir_node_t*);
|
||||||
ir_node_tag_t tag;
|
ir_node_tag_t tag;
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
@ -141,7 +141,7 @@ struct ir_node {
|
|||||||
} jump;
|
} jump;
|
||||||
struct {
|
struct {
|
||||||
ir_func_t* callee;
|
ir_func_t* callee;
|
||||||
vector_header(args, ir_node_t*);
|
VECTOR_HEADER(args, ir_node_t*);
|
||||||
} call;
|
} call;
|
||||||
struct {
|
struct {
|
||||||
ir_node_t* ret_val;
|
ir_node_t* ret_val;
|
||||||
|
@ -47,7 +47,7 @@ rv32_prog_t* link_rv32_prog(rv32_prog_t* progs[]) {
|
|||||||
if (paddr == NULL) {
|
if (paddr == NULL) {
|
||||||
paddr = symtab_asm_get(&symtab, rinstr->target);
|
paddr = symtab_asm_get(&symtab, rinstr->target);
|
||||||
if (paddr == NULL) {
|
if (paddr == NULL) {
|
||||||
LOG_FATAL("linker: %s not found", ((symasm_entry_t*)rinstr)->name);
|
LOG_FATAL("linker: %s not found", ((symasm_entry_t*)rinstr->target)->name);
|
||||||
}
|
}
|
||||||
addr = *paddr;
|
addr = *paddr;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
CC = gcc
|
CC = gcc
|
||||||
AR = ar
|
AR = ar
|
||||||
CFLAGS = -g -Wall -I../..
|
CFLAGS = -g -Wall -I../..
|
||||||
MODULES = riscv32
|
MODULES = . riscv32
|
||||||
|
|
||||||
EXCLUDE = test*.c
|
EXCLUDE = test*.c
|
||||||
SRCS = $(filter-out $(EXCLUDE), $(wildcard $(addsuffix /*.c,$(MODULES))))
|
SRCS = $(filter-out $(EXCLUDE), $(wildcard $(addsuffix /*.c,$(MODULES))))
|
||||||
@ -14,4 +14,4 @@ libmc.a: $(OBJS)
|
|||||||
$(CC) $(CFLAGS) -c -o $@ $<
|
$(CC) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f libmc.a $(OBJS)
|
rm -f libmc.a $(OBJS)
|
||||||
|
48
src/mcode/reloc_symtab.c
Normal file
48
src/mcode/reloc_symtab.c
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#include "reloc_symtab.h"
|
||||||
|
|
||||||
|
// /* append label */
|
||||||
|
// static inline int
|
||||||
|
// rv32_append_label(mcode_rv32_t* prog, void* label, u32_t offset) {
|
||||||
|
// // prog->symtab
|
||||||
|
// symtab_asm_put(&prog->symtab, label, offset);
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// static u32_t hash_func(const symasm_entry_t* key) {
|
||||||
|
// return rt_strhash(key->name);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// static int cmp_func(const symasm_entry_t* k1, const symasm_entry_t* k2) {
|
||||||
|
// return rt_strcmp(k1->name, k2->name);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// void init_symtab_asm(symtab_asm_t* symtab) {
|
||||||
|
// init_hashtable(&symtab->symtab);
|
||||||
|
// symtab->symtab.hash_func = (u32_t(*)(const void*))hash_func;
|
||||||
|
// symtab->symtab.key_cmp = (int(*)(const void*, const void*))cmp_func;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// void symtab_asm_put(symtab_asm_t* symtab, symasm_entry_t* _entry, u32_t address) {
|
||||||
|
// // FIXME maybe memory leak
|
||||||
|
// u32_t* addr = salloc_alloc(sizeof(u32_t));
|
||||||
|
// if (addr == NULL) {
|
||||||
|
// LOG_FATAL("salloc_alloc failure");
|
||||||
|
// }
|
||||||
|
// symasm_entry_t* entry = salloc_alloc(sizeof(symasm_entry_t));
|
||||||
|
// if (entry == NULL) LOG_FATAL("malloc failure");
|
||||||
|
// *entry = *_entry;
|
||||||
|
// *addr = address;
|
||||||
|
// void* ret = hashtable_set(&symtab->symtab, entry, addr);
|
||||||
|
// if (ret != NULL) {
|
||||||
|
// LOG_ERROR("Symbol %s already exists", entry->name);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// u32_t* symtab_asm_get(symtab_asm_t* symtab, symasm_entry_t* entry) {
|
||||||
|
// u32_t* addr = hashtable_get(&symtab->symtab, entry);
|
||||||
|
// return addr;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// void symtab_asm_destroy(symtab_asm_t* symtab) {
|
||||||
|
// hashtable_destory(&symtab->symtab);
|
||||||
|
// }
|
27
src/mcode/reloc_symtab.h
Normal file
27
src/mcode/reloc_symtab.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#ifndef __SMCC_RELOC_SYMTAB_H__
|
||||||
|
#define __SMCC_RELOC_SYMTAB_H__
|
||||||
|
// Relocation Symbol Table
|
||||||
|
|
||||||
|
#include <lib/core.h>
|
||||||
|
#include <lib/utils/ds/hashtable.h>
|
||||||
|
|
||||||
|
typedef enum reloc_attr {
|
||||||
|
RELOC_ATTR_GLOBAL,
|
||||||
|
RELOC_ATTR_LOCAL,
|
||||||
|
} reloc_attr_t;
|
||||||
|
|
||||||
|
typedef struct reloc_entry {
|
||||||
|
const char* name;
|
||||||
|
reloc_attr_t attr;
|
||||||
|
} reloc_entry_t;
|
||||||
|
|
||||||
|
typedef struct reloc_symtab {
|
||||||
|
hash_table_t reloctab;
|
||||||
|
} reloc_symtab_t;
|
||||||
|
|
||||||
|
void init_symtab_asm(reloc_symtab_t* symtab);
|
||||||
|
void symtab_asm_put(reloc_symtab_t* symtab, reloc_entry_t* entry, u32_t address);
|
||||||
|
u32_t* symtab_asm_get(reloc_symtab_t* symtab, reloc_entry_t* entry);
|
||||||
|
void symtab_asm_destroy(reloc_symtab_t* symtab);
|
||||||
|
|
||||||
|
#endif
|
@ -12,8 +12,8 @@ typedef struct rotated_instr {
|
|||||||
} rotated_instr_t;
|
} rotated_instr_t;
|
||||||
|
|
||||||
typedef struct mcode_rv32 {
|
typedef struct mcode_rv32 {
|
||||||
vector_header(rinstrs, rotated_instr_t);
|
VECTOR_HEADER(rinstrs, rotated_instr_t);
|
||||||
vector_header(code, u8_t);
|
VECTOR_HEADER(code, u8_t);
|
||||||
int target_size;
|
int target_size;
|
||||||
} mcode_rv32_t;
|
} mcode_rv32_t;
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ int main(int argc, char** argv) {
|
|||||||
init_lib_core();
|
init_lib_core();
|
||||||
log_set_level(NULL, LOG_LEVEL_ERROR | LOG_LEVEL_WARN | LOG_LEVEL_FATAL);
|
log_set_level(NULL, LOG_LEVEL_ERROR | LOG_LEVEL_WARN | LOG_LEVEL_FATAL);
|
||||||
|
|
||||||
const char* infilename = "test.c";
|
const char* infilename = ".test.c";
|
||||||
const char* outfilename = "flat.bin";
|
const char* outfilename = "flat.bin";
|
||||||
if (argc >= 2) {
|
if (argc >= 2) {
|
||||||
infilename = argv[1];
|
infilename = argv[1];
|
||||||
|
52
src/test.c
52
src/test.c
@ -1,52 +0,0 @@
|
|||||||
// int main() {
|
|
||||||
// int a;
|
|
||||||
// int b;
|
|
||||||
// a = 1 + 2 * 3;
|
|
||||||
// b = 7;
|
|
||||||
// a = a - b + 1;
|
|
||||||
// return a;
|
|
||||||
// }
|
|
||||||
// // int main() {
|
|
||||||
// // int x = 10;
|
|
||||||
// // x = x + 1;
|
|
||||||
// // return x;
|
|
||||||
// // }
|
|
||||||
// int main(void) {
|
|
||||||
// int a;
|
|
||||||
// a = 1;
|
|
||||||
// if (a) {
|
|
||||||
// a = 1;
|
|
||||||
// } else {
|
|
||||||
// a = 2;
|
|
||||||
// }
|
|
||||||
// return a;
|
|
||||||
// }
|
|
||||||
// int add(int, int);
|
|
||||||
|
|
||||||
// int main(void) {
|
|
||||||
// return add(1, 2);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// int add(int a, int b) {
|
|
||||||
// return a + b;
|
|
||||||
// }
|
|
||||||
// int factorial(int num);
|
|
||||||
|
|
||||||
// int main() {
|
|
||||||
// int num = 5;
|
|
||||||
// int result = factorial(num);
|
|
||||||
// // printf("%d", result);
|
|
||||||
// return result;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// int factorial(int num) {
|
|
||||||
// if (num == 0) {
|
|
||||||
// return 1;
|
|
||||||
// } else {
|
|
||||||
// return num * factorial(num - 1);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
return 65536;
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user