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,94 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
project(l_lang C)
|
||||
|
||||
set(CMAKE_C_STANDARD 17)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
|
||||
# === LLVM 配置 ===
|
||||
set(LLVM_PREFIX "D:/settings/Language/LLVM" CACHE PATH "LLVM installation prefix")
|
||||
|
||||
# 查找 LLVM(优先使用 CONFIG 模式,失败则手动配置)
|
||||
find_package(LLVM 19 QUIET CONFIG
|
||||
HINTS ${LLVM_PREFIX}/lib/cmake/llvm
|
||||
${LLVM_PREFIX}/cmake
|
||||
)
|
||||
|
||||
if(NOT LLVM_FOUND)
|
||||
message(STATUS "LLVM CONFIG not found — using manual LLVM paths")
|
||||
set(LLVM_FOUND TRUE)
|
||||
set(LLVM_INCLUDE_DIRS "${LLVM_PREFIX}/include")
|
||||
set(LLVM_LIBRARY_DIR "${LLVM_PREFIX}/lib")
|
||||
set(LLVM_LIBRARIES "${LLVM_PREFIX}/lib/LLVM-C.lib")
|
||||
# 标记使用手动模式
|
||||
set(LLVM_MANUAL_MODE ON)
|
||||
else()
|
||||
message(STATUS "LLVM found: ${LLVM_DIR}")
|
||||
message(STATUS "LLVM includes: ${LLVM_INCLUDE_DIRS}")
|
||||
message(STATUS "LLVM available libs: ${LLVM_AVAILABLE_LIBS}")
|
||||
set(LLVM_MANUAL_MODE OFF)
|
||||
endif()
|
||||
|
||||
# === 编译器库(不含 main.c,供测试复用)===
|
||||
file(GLOB_RECURSE L_LANG_LIB_SOURCES "src/*.c")
|
||||
list(REMOVE_ITEM L_LANG_LIB_SOURCES "${CMAKE_SOURCE_DIR}/src/driver/main.c")
|
||||
|
||||
add_library(l_lang_lib STATIC ${L_LANG_LIB_SOURCES})
|
||||
target_include_directories(l_lang_lib PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/include
|
||||
${LLVM_INCLUDE_DIRS}
|
||||
src/util src/lexer src/ast src/parser src/sema src/codegen src/driver
|
||||
)
|
||||
target_compile_options(l_lang_lib PRIVATE -Wall -Wextra -g)
|
||||
|
||||
# === 编译器可执行文件 ===
|
||||
add_executable(l_lang src/driver/main.c)
|
||||
target_link_libraries(l_lang PRIVATE l_lang_lib)
|
||||
target_include_directories(l_lang PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/include
|
||||
${LLVM_INCLUDE_DIRS}
|
||||
src/util src/lexer src/ast src/parser src/sema src/codegen src/driver
|
||||
)
|
||||
|
||||
# === 链接 LLVM(通过库)===
|
||||
if(LLVM_MANUAL_MODE)
|
||||
target_link_libraries(l_lang_lib PUBLIC ${LLVM_LIBRARIES})
|
||||
message(STATUS "Linking LLVM manually: ${LLVM_LIBRARIES}")
|
||||
else()
|
||||
target_link_libraries(l_lang_lib PUBLIC LLVM)
|
||||
endif()
|
||||
|
||||
# === LLVM 定义 ===
|
||||
if(NOT LLVM_MANUAL_MODE)
|
||||
target_compile_definitions(l_lang_lib PRIVATE ${LLVM_DEFINITIONS})
|
||||
endif()
|
||||
|
||||
# === 测试可执行文件(每个测试文件独立编译,各有自己的 main)===
|
||||
# Parser 测试
|
||||
add_executable(l_lang_test test/test_parser.c)
|
||||
target_link_libraries(l_lang_test PRIVATE l_lang_lib)
|
||||
target_include_directories(l_lang_test PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/include
|
||||
${LLVM_INCLUDE_DIRS}
|
||||
src/util src/lexer src/ast src/parser src/sema src/codegen src/driver
|
||||
test
|
||||
)
|
||||
|
||||
# Lexer 测试
|
||||
add_executable(l_lang_lexer_test test/test_lexer.c)
|
||||
target_link_libraries(l_lang_lexer_test PRIVATE l_lang_lib)
|
||||
target_include_directories(l_lang_lexer_test PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/include
|
||||
${LLVM_INCLUDE_DIRS}
|
||||
src/util src/lexer src/ast src/parser src/sema src/codegen src/driver
|
||||
test
|
||||
)
|
||||
|
||||
# Sema 测试
|
||||
add_executable(l_lang_sema_test test/test_sema.c)
|
||||
target_link_libraries(l_lang_sema_test PRIVATE l_lang_lib)
|
||||
target_include_directories(l_lang_sema_test PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/include
|
||||
${LLVM_INCLUDE_DIRS}
|
||||
src/util src/lexer src/ast src/parser src/sema src/codegen src/driver
|
||||
test
|
||||
)
|
||||
Reference in New Issue
Block a user