refactor: 重构前端代码并添加日志功能
- 重命名和重构了多个文件,包括 lexer、parser 和 AST 相关代码 - 添加了日志功能,使用 LOG_* 宏替代原有的 error 和 warn 函数 - 优化了错误处理和内存分配方式 - 调整了代码结构,提高了模块化和可读性
This commit is contained in:
@ -1,20 +1,23 @@
|
||||
# 编译器设置
|
||||
CC = gcc
|
||||
AR = ar
|
||||
CFLAGS = -g -Wall
|
||||
CFLAGS = -g -Wall -I../..
|
||||
|
||||
IR_DIR = ./ir
|
||||
|
||||
# 源文件列表
|
||||
SRCS = \
|
||||
ir.c \
|
||||
ir_ast.c \
|
||||
ir_lib.c \
|
||||
ir_type.c
|
||||
middleend.c \
|
||||
$(IR_DIR)/ir.c \
|
||||
$(IR_DIR)/ir_ast.c \
|
||||
$(IR_DIR)/ir_lib.c \
|
||||
$(IR_DIR)/ir_type.c
|
||||
|
||||
# 生成目标文件列表
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
|
||||
# 最终目标
|
||||
TARGET = libir.a
|
||||
TARGET = libmiddleend.a
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
@ -27,4 +30,4 @@ $(TARGET): $(OBJS)
|
||||
clean:
|
||||
rm -f $(OBJS) $(TARGET)
|
||||
|
||||
.PHONY: all clean
|
||||
.PHONY: all clean
|
||||
|
@ -2,9 +2,7 @@
|
||||
#ifndef IR_CORE_H
|
||||
#define IR_CORE_H
|
||||
|
||||
#include "../../libcore/vector.h"
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <lib/utils/ds/vector.h>
|
||||
|
||||
// 错误码定义
|
||||
typedef enum {
|
||||
@ -26,12 +24,12 @@ typedef struct {
|
||||
union {
|
||||
struct {
|
||||
struct ir_type *base;
|
||||
size_t len;
|
||||
rt_size_t len;
|
||||
} arr;
|
||||
struct {
|
||||
struct ir_type *ret;
|
||||
struct ir_type **params;
|
||||
size_t param_cnt;
|
||||
rt_size_t param_cnt;
|
||||
} func;
|
||||
};
|
||||
} ir_type_t;
|
||||
@ -151,9 +149,4 @@ struct ir_node {
|
||||
} data;
|
||||
};
|
||||
|
||||
extern ir_prog_t prog;
|
||||
struct ASTNode;
|
||||
void gen_ir_from_ast(struct ASTNode* node);
|
||||
|
||||
|
||||
#endif // IR_CORE_H
|
@ -1,7 +1,8 @@
|
||||
#include "ir.h"
|
||||
#include "ir_lib.h"
|
||||
#include "ir_type.h"
|
||||
#include "../frontend/frontend.h"
|
||||
#include "../../frontend/frontend.h"
|
||||
#include "../../frontend/parser/ast.h"
|
||||
|
||||
// 上下文结构,记录生成过程中的状态
|
||||
typedef struct {
|
||||
@ -10,6 +11,7 @@ typedef struct {
|
||||
} IRGenContext;
|
||||
IRGenContext ctx;
|
||||
ir_prog_t prog;
|
||||
void _gen_ir_from_ast(ast_node_t* node);
|
||||
|
||||
static void emit_instr(ir_bblock_t* block, ir_node_t* node) {
|
||||
if (block == NULL) block = ctx.cur_block;
|
||||
@ -53,7 +55,7 @@ static ir_node_t* gen_ir_term(ast_node_t* node) {
|
||||
return call;
|
||||
}
|
||||
default: {
|
||||
assert(0);
|
||||
Panic("gen_ir_expr: unknown node type");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -164,10 +166,10 @@ static ir_node_t* gen_ir_expr(ast_node_t* node) {
|
||||
BINOP(IR_OP_GE); break;
|
||||
}
|
||||
case NT_AND_AND:// (expr) && (expr)
|
||||
error("unimpliment");
|
||||
LOG_ERROR("unimpliment");
|
||||
break;
|
||||
case NT_OR_OR:// (expr) || (expr)
|
||||
error("unimpliment");
|
||||
LOG_ERROR("unimpliment");
|
||||
break;
|
||||
case NT_NOT: {
|
||||
// ! (expr)
|
||||
@ -189,7 +191,7 @@ static ir_node_t* gen_ir_expr(ast_node_t* node) {
|
||||
// case NT_COND: // (expr) ? (expr) : (expr)
|
||||
default: {
|
||||
// TODO self error msg
|
||||
error("Unsupported IR generation for AST node type %d", node->type);
|
||||
LOG_ERROR("Unsupported IR generation for AST node type %d", node->type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -198,7 +200,7 @@ static ir_node_t* gen_ir_expr(ast_node_t* node) {
|
||||
}
|
||||
|
||||
static void gen_ir_func(ast_node_t* node, ir_func_t* func) {
|
||||
assert(node->type == NT_FUNC);
|
||||
Assert(node->type == NT_FUNC);
|
||||
ir_bblock_t *entry = new_ir_bblock("entry");
|
||||
vector_push(func->bblocks, entry);
|
||||
|
||||
@ -217,7 +219,7 @@ static void gen_ir_func(ast_node_t* node, ir_func_t* func) {
|
||||
decl->type = &type_i32;
|
||||
param->decl_val.data = decl;
|
||||
}
|
||||
gen_ir_from_ast(node->func.body);
|
||||
_gen_ir_from_ast(node->func.body);
|
||||
|
||||
ctx = prev_ctx;
|
||||
}
|
||||
@ -248,13 +250,13 @@ void gen_ir_jmp(ast_node_t* node) {
|
||||
// true block
|
||||
vector_push(ctx.cur_func->bblocks, trueb);
|
||||
ctx.cur_block = trueb;
|
||||
gen_ir_from_ast(node->if_stmt.if_stmt);
|
||||
_gen_ir_from_ast(node->if_stmt.if_stmt);
|
||||
|
||||
// else block
|
||||
if (node->if_stmt.else_stmt != NULL) {
|
||||
vector_push(ctx.cur_func->bblocks, falseb);
|
||||
ctx.cur_block = falseb;
|
||||
gen_ir_from_ast(node->if_stmt.else_stmt);
|
||||
_gen_ir_from_ast(node->if_stmt.else_stmt);
|
||||
ir_node_t* jmp;
|
||||
|
||||
ctx.cur_block = endb;
|
||||
@ -285,7 +287,7 @@ void gen_ir_jmp(ast_node_t* node) {
|
||||
// Body:
|
||||
ir_node_t* jmp;
|
||||
ctx.cur_block = bodyb;
|
||||
gen_ir_from_ast(node->while_stmt.body);
|
||||
_gen_ir_from_ast(node->while_stmt.body);
|
||||
NEW_IR_JMP(jmp, entryb);
|
||||
emit_instr(NULL, jmp);
|
||||
|
||||
@ -304,7 +306,7 @@ void gen_ir_jmp(ast_node_t* node) {
|
||||
|
||||
// Body:
|
||||
ctx.cur_block = bodyb;
|
||||
gen_ir_from_ast(node->do_while_stmt.body);
|
||||
_gen_ir_from_ast(node->do_while_stmt.body);
|
||||
ir_node_t* jmp;
|
||||
NEW_IR_JMP(jmp, entryb);
|
||||
emit_instr(NULL, jmp);
|
||||
@ -324,7 +326,7 @@ void gen_ir_jmp(ast_node_t* node) {
|
||||
ir_bblock_t* endb = bblocks[2];
|
||||
|
||||
if (node->for_stmt.init) {
|
||||
gen_ir_from_ast(node->for_stmt.init);
|
||||
_gen_ir_from_ast(node->for_stmt.init);
|
||||
}
|
||||
ir_node_t* entry;
|
||||
NEW_IR_JMP(entry, entryb);
|
||||
@ -342,7 +344,7 @@ void gen_ir_jmp(ast_node_t* node) {
|
||||
|
||||
// Body:
|
||||
ctx.cur_block = bodyb;
|
||||
gen_ir_from_ast(node->for_stmt.body);
|
||||
_gen_ir_from_ast(node->for_stmt.body);
|
||||
if (node->for_stmt.iter) {
|
||||
gen_ir_expr(node->for_stmt.iter);
|
||||
}
|
||||
@ -355,18 +357,21 @@ void gen_ir_jmp(ast_node_t* node) {
|
||||
break;
|
||||
}
|
||||
default:
|
||||
error("ir jmp can't hit here");
|
||||
LOG_ERROR("ir jmp can't hit here");
|
||||
}
|
||||
}
|
||||
|
||||
void gen_ir_from_ast(ast_node_t* node) {
|
||||
ir_prog_t* gen_ir_from_ast(ast_node_t* root) {
|
||||
Assert(root->type == NT_ROOT);
|
||||
for (int i = 0; i < root->root.children.size; i ++) {
|
||||
_gen_ir_from_ast(root->root.children.data[i]);
|
||||
}
|
||||
// _gen_ir_from_ast(root);
|
||||
return &prog;
|
||||
}
|
||||
|
||||
void _gen_ir_from_ast(ast_node_t* node) {
|
||||
switch (node->type) {
|
||||
case NT_ROOT: {
|
||||
for (int i = 0; i < node->root.children.size; i ++) {
|
||||
gen_ir_from_ast(node->root.children.data[i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NT_DECL_FUNC: {
|
||||
ir_func_t* func = new_ir_func(node->decl_func.name->syms.tok.val.str, &type_i32);
|
||||
if (node->decl_func.def == NULL) {
|
||||
@ -398,12 +403,12 @@ void gen_ir_from_ast(ast_node_t* node) {
|
||||
break;
|
||||
}
|
||||
case NT_STMT_BLOCK: {
|
||||
gen_ir_from_ast(node->block_stmt.block);
|
||||
_gen_ir_from_ast(node->block_stmt.block);
|
||||
break;
|
||||
}
|
||||
case NT_BLOCK: {
|
||||
for (int i = 0; i < node->block.children.size; i ++) {
|
||||
gen_ir_from_ast(node->block.children.data[i]);
|
||||
_gen_ir_from_ast(node->block.children.data[i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -420,7 +425,7 @@ void gen_ir_from_ast(ast_node_t* node) {
|
||||
ir->type = &type_i32;
|
||||
node->decl_val.data = ir;
|
||||
if (node->decl_val.expr_stmt != NULL) {
|
||||
gen_ir_from_ast(node->decl_val.expr_stmt);
|
||||
_gen_ir_from_ast(node->decl_val.expr_stmt);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -433,7 +438,7 @@ void gen_ir_from_ast(ast_node_t* node) {
|
||||
}
|
||||
default:
|
||||
// TODO: 错误处理
|
||||
error("unknown node type");
|
||||
LOG_ERROR("unknown node type");
|
||||
break;
|
||||
}
|
||||
}
|
7
ccompiler/middleend/ir/ir_ast.h
Normal file
7
ccompiler/middleend/ir/ir_ast.h
Normal file
@ -0,0 +1,7 @@
|
||||
#ifndef __IR_AST_H__
|
||||
#define __IR_AST_H__
|
||||
|
||||
#include "ir.h"
|
||||
ir_prog_t* gen_ir_from_ast(ast_node_t* node);
|
||||
|
||||
#endif //
|
76
ccompiler/middleend/ir/ir_dump.c
Normal file
76
ccompiler/middleend/ir/ir_dump.c
Normal file
@ -0,0 +1,76 @@
|
||||
#include "ir.h"
|
||||
#include "ir_lib.h"
|
||||
#include "ir_type.h"
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
typedef struct ir_dump {
|
||||
FILE* fp;
|
||||
} ir_dump_t;
|
||||
|
||||
|
||||
void dump_ir_node(ir_node_t* node, ir_dump_t* dump) {
|
||||
fprintf(dump->fp, "%%%p", node);
|
||||
switch (node->tag) {
|
||||
case IR_NODE_ALLOC: {
|
||||
node->type = NULL;
|
||||
// fprintf(dump->fp, "%p\n", );
|
||||
break;
|
||||
}
|
||||
case IR_NODE_BRANCH: {
|
||||
node->data.branch.cond = NULL;
|
||||
node->data.branch.true_bblock = NULL;
|
||||
node->data.branch.false_bblock = NULL;
|
||||
break;
|
||||
}
|
||||
case IR_NODE_CALL: {
|
||||
vector_init(node->data.call.args);
|
||||
node->data.call.callee = NULL;
|
||||
break;
|
||||
}
|
||||
case IR_NODE_CONST_INT: {
|
||||
node->data.const_int.val = 0;
|
||||
break;
|
||||
}
|
||||
case IR_NODE_JUMP: {
|
||||
node->data.jump.target_bblock = NULL;
|
||||
break;
|
||||
}
|
||||
case IR_NODE_LOAD: {
|
||||
node->data.load.target = NULL;
|
||||
break;
|
||||
}
|
||||
case IR_NODE_STORE: {
|
||||
node->data.store.target = NULL;
|
||||
node->data.store.value = NULL;
|
||||
break;
|
||||
}
|
||||
case IR_NODE_OP: {
|
||||
node->data.op.op = 0;
|
||||
node->data.op.lhs = NULL;
|
||||
node->data.op.rhs = NULL;
|
||||
break;
|
||||
}
|
||||
case IR_NODE_RET: {
|
||||
node->data.ret.ret_val = NULL;
|
||||
break;
|
||||
}
|
||||
case IR_NODE_GET_PTR: {
|
||||
}
|
||||
default: {
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dump_ir_bblock(ir_bblock_t* block) {
|
||||
|
||||
}
|
||||
|
||||
void dump_ir_func(ir_func_t* func) {
|
||||
|
||||
}
|
||||
|
||||
void dump_ir_prog(ir_prog_t* prog) {
|
||||
|
||||
}
|
@ -77,10 +77,6 @@ ir_node_t* new_ir_node(const char* name, ir_node_tag_t tag) {
|
||||
return node;
|
||||
}
|
||||
|
||||
void dump_ir_node(ir_node_t* node) {
|
||||
|
||||
}
|
||||
|
||||
void free_irnode() {
|
||||
|
||||
}
|
7
ccompiler/middleend/middleend.h
Normal file
7
ccompiler/middleend/middleend.h
Normal file
@ -0,0 +1,7 @@
|
||||
#ifndef __SMCC_MIDDLEEND_H__
|
||||
#define __SMCC_MIDDLEEND_H__
|
||||
|
||||
#include "ir/ir.h"
|
||||
#include "ir/ir_ast.h"
|
||||
|
||||
#endif // __SMCC_MIDDLEEND_H__
|
Reference in New Issue
Block a user