feat: L Language v0.1 编译器完整实现
5 阶段编译流水线: 词法分析 → 语法分析(Pratt) → 语义分析(类型推断) → LLVM IR → .exe 模块: - lexer: 手写状态机, 40 种 Token, // 和 /* */ 注释 - parser: Pratt 表达式解析(9 级优先级) + 递归下降语句/函数 - ast: 14 种节点类型 + 工厂函数 - sema: 作用域链符号表 + 类型推断 + 类型检查 - codegen: AST → LLVM-C API, print_i64/f64/bool 内建 - driver: 命令行 + 流水线串联 + 错误报告 - util: Arena bump allocator (8MB) 测试: 65 单元测试(词法41+语法15+语义9) + 5 集成测试 全部通过 语言特性: i64/f64/bool/void, let不可变变量, if/else, while, 递归函数
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
#ifndef AST_H
|
||||
#define AST_H
|
||||
|
||||
#include "l_lang.h"
|
||||
#include <stddef.h>
|
||||
|
||||
typedef enum {
|
||||
AST_PROGRAM,
|
||||
AST_FUNCTION,
|
||||
AST_PARAMETER,
|
||||
AST_BLOCK,
|
||||
AST_LET_STMT,
|
||||
AST_IF_STMT,
|
||||
AST_WHILE_STMT,
|
||||
AST_RETURN_STMT,
|
||||
AST_EXPR_STMT,
|
||||
AST_BINARY_EXPR,
|
||||
AST_UNARY_EXPR,
|
||||
AST_CALL_EXPR,
|
||||
AST_LITERAL_EXPR,
|
||||
AST_IDENT_EXPR,
|
||||
} AstKind;
|
||||
|
||||
typedef enum {
|
||||
OP_ADD, OP_SUB, OP_MUL, OP_DIV, OP_MOD,
|
||||
OP_EQ, OP_NE, OP_LT, OP_GT, OP_LE, OP_GE,
|
||||
OP_AND, OP_OR,
|
||||
OP_NEG, OP_NOT,
|
||||
} BinaryOp;
|
||||
|
||||
// 类型信息(语义分析阶段填充)
|
||||
typedef struct {
|
||||
TypeKind kind;
|
||||
} TypeInfo;
|
||||
|
||||
// AST 节点
|
||||
struct AstNode {
|
||||
AstKind kind;
|
||||
TypeInfo type; // 语义分析后填充,默认为 TYPE_UNKNOWN
|
||||
int line; // 源文件行号
|
||||
int col; // 源文件列号
|
||||
|
||||
// 节点特有数据(按 kind 解释)
|
||||
union {
|
||||
// AST_PROGRAM
|
||||
struct { struct AstNode** functions; size_t fn_count; } program;
|
||||
// AST_FUNCTION
|
||||
struct { const char* name; struct AstNode** params; size_t param_count;
|
||||
TypeKind return_type; struct AstNode* body; } function;
|
||||
// AST_PARAMETER
|
||||
struct { const char* name; TypeKind type; } parameter;
|
||||
// AST_BLOCK
|
||||
struct { struct AstNode** stmts; size_t stmt_count; } block;
|
||||
// AST_LET_STMT
|
||||
struct { const char* name; TypeKind annot_type; bool has_type_annot; struct AstNode* init; } let_stmt;
|
||||
// AST_IF_STMT
|
||||
struct { struct AstNode* cond; struct AstNode* then_block; struct AstNode* else_block; } if_stmt;
|
||||
// AST_WHILE_STMT
|
||||
struct { struct AstNode* cond; struct AstNode* body; } while_stmt;
|
||||
// AST_RETURN_STMT
|
||||
struct { struct AstNode* expr; } return_stmt;
|
||||
// AST_EXPR_STMT
|
||||
struct { struct AstNode* expr; } expr_stmt;
|
||||
// AST_BINARY_EXPR
|
||||
struct { BinaryOp op; struct AstNode* left; struct AstNode* right; } binary;
|
||||
// AST_UNARY_EXPR
|
||||
struct { BinaryOp op; struct AstNode* operand; } unary;
|
||||
// AST_CALL_EXPR
|
||||
struct { const char* name; struct AstNode** args; size_t arg_count; } call;
|
||||
// AST_LITERAL_EXPR
|
||||
struct { TypeKind lit_type; union { int64_t i64_val; double f64_val; bool bool_val; }; } literal;
|
||||
// AST_IDENT_EXPR
|
||||
struct { const char* name; } ident;
|
||||
} as;
|
||||
};
|
||||
|
||||
// 创建节点的辅助函数(内存来自 arena,通过 void* 传递避免循环依赖)
|
||||
AstNode* ast_make_program(void* alloc, AstNode** fns, size_t count, int line, int col);
|
||||
AstNode* ast_make_function(void* alloc, const char* name, AstNode** params, size_t pcount,
|
||||
TypeKind ret, AstNode* body, int line, int col);
|
||||
AstNode* ast_make_parameter(void* alloc, const char* name, TypeKind type, int line, int col);
|
||||
AstNode* ast_make_block(void* alloc, AstNode** stmts, size_t count, int line, int col);
|
||||
AstNode* ast_make_let(void* alloc, const char* name, TypeKind annot_type, bool has_type_annot, AstNode* init, int line, int col);
|
||||
AstNode* ast_make_if(void* alloc, AstNode* cond, AstNode* then_b, AstNode* else_b, int line, int col);
|
||||
AstNode* ast_make_while(void* alloc, AstNode* cond, AstNode* body, int line, int col);
|
||||
AstNode* ast_make_return(void* alloc, AstNode* expr, int line, int col);
|
||||
AstNode* ast_make_expr_stmt(void* alloc, AstNode* expr, int line, int col);
|
||||
AstNode* ast_make_binary(void* alloc, BinaryOp op, AstNode* left, AstNode* right, int line, int col);
|
||||
AstNode* ast_make_unary(void* alloc, BinaryOp op, AstNode* operand, int line, int col);
|
||||
AstNode* ast_make_call(void* alloc, const char* name, AstNode** args, size_t count, int line, int col);
|
||||
AstNode* ast_make_literal_i64(void* alloc, int64_t val, int line, int col);
|
||||
AstNode* ast_make_literal_f64(void* alloc, double val, int line, int col);
|
||||
AstNode* ast_make_literal_bool(void* alloc, bool val, int line, int col);
|
||||
AstNode* ast_make_ident(void* alloc, const char* name, int line, int col);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user