chore: 更新 .gitignore 文件
- 添加 docs 文件夹到忽略列表,以忽略 Doxygen 生成的文件 - 保持原有的忽略规则不变
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
CC = gcc
|
||||
CFLAGS = -g -Wall -I..
|
||||
LIBS = -Lccompiler -lcc -Lassembler/riscv32 -lasm -Llinker -llk -Lmcode -lmc -L../lib -lcore
|
||||
# CLFAGS += -fsanitize=address
|
||||
LIBS = -Lccompiler -lcc -Lassembler/riscv32 -lasm -Llinker -llk -Lmcode -lmc -L../lib -lcore
|
||||
CLFAGS += -fsanitize=address
|
||||
|
||||
all: smcc
|
||||
smcc: cc asm lib mc lk
|
||||
@@ -27,4 +27,4 @@ clean:
|
||||
make -C assembler/riscv32 clean
|
||||
make -C ccompiler clean
|
||||
make -C mcode clean
|
||||
make -C linker clean
|
||||
make -C linker clean
|
||||
|
||||
@@ -2,7 +2,6 @@ CC = gcc
|
||||
AR = ar
|
||||
CFLAGS = -g -Wall -I../../..
|
||||
|
||||
# 自动收集所有子模块源文件
|
||||
EXCLUDE = test*.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_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;
|
||||
u32_t text_base_address;
|
||||
u32_t data_base_address;
|
||||
vector_header(data, iptr_t);
|
||||
VECTOR_HEADER(data, iptr_t);
|
||||
mcode_rv32_t mcode;
|
||||
} rv32_prog_t;
|
||||
|
||||
|
||||
@@ -1,37 +1,76 @@
|
||||
/**
|
||||
* @file lexer.h
|
||||
* @brief C语言词法分析器核心数据结构与接口
|
||||
*/
|
||||
|
||||
#ifndef __SMCC_CC_LEXER_H__
|
||||
#define __SMCC_CC_LEXER_H__
|
||||
|
||||
#include <lib/core.h>
|
||||
#include "token.h"
|
||||
|
||||
#ifndef LEXER_MAX_TOKEN_SIZE
|
||||
#define LEXER_MAX_TOKEN_SIZE 63
|
||||
#endif
|
||||
#ifndef LEXER_BUFFER_SIZE
|
||||
#define LEXER_BUFFER_SIZE 4095
|
||||
#define LEXER_MAX_TOKEN_SIZE 63 ///< 单个token的最大长度限制
|
||||
#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);
|
||||
|
||||
/**
|
||||
* @brief 词法分析器核心结构体
|
||||
*
|
||||
* 封装词法分析所需的状态信息和缓冲区管理
|
||||
*/
|
||||
typedef struct cc_lexer {
|
||||
loc_t loc;
|
||||
|
||||
char* cur_ptr; // 当前扫描的字符,但是还没有开始扫描
|
||||
char* end_ptr; // 缓冲区最后一个字符的下一个位置
|
||||
char buffer[LEXER_BUFFER_SIZE+1];
|
||||
|
||||
lexer_sread_fn sread;
|
||||
void* stream;
|
||||
|
||||
strpool_t* strpool;
|
||||
loc_t loc; ///< 当前解析位置信息(文件名、行列号等)
|
||||
|
||||
char* cur_ptr; ///< 当前扫描指针(指向尚未处理的字符)
|
||||
char* end_ptr; ///< 缓冲区结束指针(指向最后一个有效字符的下一个位置)
|
||||
char buffer[LEXER_BUFFER_SIZE+1]; ///< 字符缓冲区(包含NUL终止符)
|
||||
|
||||
lexer_sread_fn sread; ///< 流读取函数指针
|
||||
void* stream; ///< 输入流对象指针
|
||||
strpool_t* strpool; ///< 字符串池(用于存储标识符等字符串)
|
||||
} 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,
|
||||
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);
|
||||
|
||||
// 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);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -84,10 +84,10 @@ typedef struct ast_node {
|
||||
union {
|
||||
void *children[6];
|
||||
struct {
|
||||
vector_header(children, struct ast_node *);
|
||||
VECTOR_HEADER(children, struct ast_node *);
|
||||
} root;
|
||||
struct {
|
||||
vector_header(children, struct ast_node *);
|
||||
VECTOR_HEADER(children, struct ast_node *);
|
||||
} block;
|
||||
struct {
|
||||
symtab_key_t key;
|
||||
@@ -95,7 +95,7 @@ typedef struct ast_node {
|
||||
tok_t tok;
|
||||
} syms;
|
||||
struct {
|
||||
vector_header(params, struct ast_node *);
|
||||
VECTOR_HEADER(params, struct ast_node *);
|
||||
} params;
|
||||
struct {
|
||||
struct ast_node * name;
|
||||
|
||||
@@ -38,21 +38,21 @@ typedef struct ir_node ir_node_t;
|
||||
|
||||
typedef struct ir_bblock {
|
||||
const char *label;
|
||||
vector_header(instrs, ir_node_t*);
|
||||
VECTOR_HEADER(instrs, ir_node_t*);
|
||||
// ir_arr_t used_by;
|
||||
} ir_bblock_t; // basic block
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
ir_type_t *type;
|
||||
vector_header(params, ir_node_t*);
|
||||
vector_header(bblocks, ir_bblock_t*);
|
||||
VECTOR_HEADER(params, ir_node_t*);
|
||||
VECTOR_HEADER(bblocks, ir_bblock_t*);
|
||||
} ir_func_t;
|
||||
|
||||
typedef struct {
|
||||
vector_header(global, ir_node_t*);
|
||||
vector_header(funcs, ir_func_t*);
|
||||
vector_header(extern_funcs, ir_func_t*);
|
||||
VECTOR_HEADER(global, ir_node_t*);
|
||||
VECTOR_HEADER(funcs, ir_func_t*);
|
||||
VECTOR_HEADER(extern_funcs, ir_func_t*);
|
||||
} ir_prog_t;
|
||||
|
||||
typedef enum ir_node_tag {
|
||||
@@ -72,7 +72,7 @@ typedef enum ir_node_tag {
|
||||
struct ir_node {
|
||||
const ir_type_t* type;
|
||||
const char* name;
|
||||
vector_header(used_by, ir_node_t*);
|
||||
VECTOR_HEADER(used_by, ir_node_t*);
|
||||
ir_node_tag_t tag;
|
||||
union {
|
||||
struct {
|
||||
@@ -141,7 +141,7 @@ struct ir_node {
|
||||
} jump;
|
||||
struct {
|
||||
ir_func_t* callee;
|
||||
vector_header(args, ir_node_t*);
|
||||
VECTOR_HEADER(args, ir_node_t*);
|
||||
} call;
|
||||
struct {
|
||||
ir_node_t* ret_val;
|
||||
|
||||
@@ -47,7 +47,7 @@ rv32_prog_t* link_rv32_prog(rv32_prog_t* progs[]) {
|
||||
if (paddr == NULL) {
|
||||
paddr = symtab_asm_get(&symtab, rinstr->target);
|
||||
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;
|
||||
} else {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
CC = gcc
|
||||
AR = ar
|
||||
CFLAGS = -g -Wall -I../..
|
||||
MODULES = riscv32
|
||||
MODULES = . riscv32
|
||||
|
||||
EXCLUDE = test*.c
|
||||
SRCS = $(filter-out $(EXCLUDE), $(wildcard $(addsuffix /*.c,$(MODULES))))
|
||||
@@ -14,4 +14,4 @@ libmc.a: $(OBJS)
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
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;
|
||||
|
||||
typedef struct mcode_rv32 {
|
||||
vector_header(rinstrs, rotated_instr_t);
|
||||
vector_header(code, u8_t);
|
||||
VECTOR_HEADER(rinstrs, rotated_instr_t);
|
||||
VECTOR_HEADER(code, u8_t);
|
||||
int target_size;
|
||||
} mcode_rv32_t;
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ int main(int argc, char** argv) {
|
||||
init_lib_core();
|
||||
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";
|
||||
if (argc >= 2) {
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user