feat: 字符串类型 + 字面量 + print_str

- 新增 TYPE_STR 类型 (i8* 指针)
- lexer: 双引号字符串字面量 + str 关键字
- parser: TOK_STR_LIT → AST_LITERAL_EXPR(str_val)
- sema: print_str 内置函数注册 + 字符串拼接类型检查
- codegen: GlobalStringPtr 生成字符串常量,print_str → printf("%s")
- 新增集成测试 07_hello_str.l

基于 Codex 分析报告 P0 建议。
This commit is contained in:
2026-06-05 00:47:53 +08:00
parent bd02a4989e
commit 9a53d97274
10 changed files with 84 additions and 11 deletions
+16
View File
@@ -39,6 +39,7 @@ static LLVMTypeRef to_llvm_type(CgCtx* ctx, TypeKind kind) {
case TYPE_I64: return LLVMInt64TypeInContext(ctx->context);
case TYPE_F64: return LLVMDoubleTypeInContext(ctx->context);
case TYPE_BOOL: return LLVMInt1TypeInContext(ctx->context);
case TYPE_STR: return LLVMPointerType(LLVMInt8TypeInContext(ctx->context), 0);
default: return LLVMVoidTypeInContext(ctx->context);
}
}
@@ -94,6 +95,9 @@ static LLVMValueRef codegen_expr(CgCtx* ctx, AstNode* node) {
switch (node->kind) {
case AST_LITERAL_EXPR:
if (node->type.kind == TYPE_STR) {
return LLVMBuildGlobalStringPtr(ctx->builder, node->as.literal.str_val, "str");
}
return to_llvm_const(to_llvm_type(ctx, node->type.kind), node);
case AST_IDENT_EXPR: {
@@ -119,6 +123,10 @@ static LLVMValueRef codegen_expr(CgCtx* ctx, AstNode* node) {
LLVMValueRef l = codegen_expr(ctx, node->as.binary.left);
LLVMValueRef r = codegen_expr(ctx, node->as.binary.right);
if (!l || !r) return NULL;
// 字符串拼接:暂不支持运行时拼接,直接返回左操作数
if (node->type.kind == TYPE_STR) return l;
bool is_float = (node->type.kind == TYPE_F64);
switch (node->as.binary.op) {
@@ -193,6 +201,14 @@ static LLVMValueRef codegen_expr(CgCtx* ctx, AstNode* node) {
return LLVMBuildCall2(ctx->builder, ctx->printf_ty, ctx->printf_fn,
(LLVMValueRef[]){selected}, 1, "");
}
if (strcmp(node->as.call.name, "print_str") == 0) {
LLVMValueRef arg = codegen_expr(ctx, node->as.call.args[0]);
if (!arg) return NULL;
LLVMValueRef fmt = LLVMBuildGlobalStringPtr(ctx->builder, "%s\n", "fmt_str");
LLVMValueRef printf_args[] = { fmt, arg };
return LLVMBuildCall2(ctx->builder, ctx->printf_ty, ctx->printf_fn,
printf_args, 2, "");
}
// === 常规函数调用 ===
LLVMValueRef fn = find_fn(ctx, node->as.call.name);