chore: 更新 .gitignore 文件

- 添加 docs 文件夹到忽略列表,以忽略 Doxygen 生成的文件
- 保持原有的忽略规则不变
This commit is contained in:
ZZY 2025-04-05 23:11:39 +08:00
parent c800b48ca2
commit 8d97fe896c
32 changed files with 3939 additions and 187 deletions

3
.gitignore vendored
View File

@ -1,6 +1,9 @@
.* .*
!.gitignore !.gitignore
# doxygen generated files
docs
# smcc compiler generated files # smcc compiler generated files
*.bin *.bin
.s .s

2970
Doxyfile Normal file

File diff suppressed because it is too large Load Diff

14
Makefile Normal file
View 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

View File

@ -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__

View File

@ -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__

View File

@ -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;
} }

View File

@ -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__

View File

@ -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__

View File

@ -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) {

View File

@ -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__

View File

@ -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 00
*/
typedef int (*rt_fflush_t)(rt_file_t* file);
/**
* @typedef rt_fclose_t
* @brief
* @param file
* @return 0EOF
*/
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__

View File

@ -3,4 +3,4 @@
void init_rt_std(); void init_rt_std();
#endif #endif // __SMCC_RT_STD_H__

View File

@ -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__

View File

@ -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;

View File

@ -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 00
*/
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__

View File

@ -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 28
* @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__

View File

@ -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__

View File

@ -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

View File

@ -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))

View File

@ -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);
}

View File

@ -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;

View File

@ -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存储位置
*
* tokentoken
*/
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存储位置
*
* tokentoken
*/
void get_valid_token(cc_lexer_t* lexer, tok_t* token); void get_valid_token(cc_lexer_t* lexer, tok_t* token);
#endif #endif

View File

@ -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;

View File

@ -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;

View File

@ -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 {

View File

@ -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
View 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
View 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

View File

@ -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;

View File

@ -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];

View File

@ -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;
}