IR: gen string literal

This commit is contained in:
Andrew Kelley 2016-11-10 00:41:17 -05:00
parent 9d19b8d66e
commit a5c9da0de2
3 changed files with 85 additions and 16 deletions

View File

@ -1593,6 +1593,7 @@ struct IrInstructionFieldPtr {
IrInstruction *container_ptr;
Buf *field_name;
bool is_const;
};
struct IrInstructionStructFieldPtr {
@ -1600,6 +1601,7 @@ struct IrInstructionStructFieldPtr {
IrInstruction *struct_ptr;
TypeStructField *field;
bool is_const;
};
struct IrInstructionReadField {
@ -1614,12 +1616,14 @@ struct IrInstructionElemPtr {
IrInstruction *array_ptr;
IrInstruction *elem_index;
bool is_const;
};
struct IrInstructionVarPtr {
IrInstruction base;
VariableTableEntry *var;
bool is_const;
};
struct IrInstructionCall {
@ -1716,6 +1720,7 @@ enum LValPurpose {
LValPurposeNone,
LValPurposeAssign,
LValPurposeAddressOf,
LValPurposeConstAddressOf,
};
#endif

View File

@ -367,6 +367,55 @@ static IrInstruction *ir_build_const_bool(IrBuilder *irb, AstNode *source_node,
return &const_instruction->base;
}
static IrInstruction *ir_build_const_str_lit(IrBuilder *irb, AstNode *source_node, Buf *str) {
IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);
TypeTableEntry *u8_type = irb->codegen->builtin_types.entry_u8;
TypeTableEntry *type_entry = get_array_type(irb->codegen, u8_type, buf_len(str));
const_instruction->base.type_entry = type_entry;
ConstExprValue *const_val = &const_instruction->base.static_value;
const_val->ok = true;
const_val->data.x_array.fields = allocate<ConstExprValue*>(buf_len(str));
ConstExprValue *all_chars = allocate<ConstExprValue>(buf_len(str));
for (size_t i = 0; i < buf_len(str); i += 1) {
ConstExprValue *this_char = &all_chars[i];
this_char->ok = true;
bignum_init_unsigned(&this_char->data.x_bignum, buf_ptr(str)[i]);
const_val->data.x_array.fields[i] = this_char;
}
return &const_instruction->base;
}
static IrInstruction *ir_build_const_c_str_lit(IrBuilder *irb, AstNode *source_node, Buf *str) {
IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);
TypeTableEntry *u8_type = irb->codegen->builtin_types.entry_u8;
TypeTableEntry *type_entry = get_pointer_to_type(irb->codegen, u8_type, true);
const_instruction->base.type_entry = type_entry;
ConstExprValue *const_val = &const_instruction->base.static_value;
const_val->ok = true;
size_t len_with_null = buf_len(str) + 1;
const_val->data.x_ptr.ptr = allocate<ConstExprValue*>(len_with_null);
const_val->data.x_ptr.len = len_with_null;
const_val->data.x_ptr.is_c_str = true;
ConstExprValue *all_chars = allocate<ConstExprValue>(len_with_null);
for (size_t i = 0; i < buf_len(str); i += 1) {
ConstExprValue *this_char = &all_chars[i];
this_char->ok = true;
bignum_init_unsigned(&this_char->data.x_bignum, buf_ptr(str)[i]);
const_val->data.x_ptr.ptr[i] = this_char;
}
ConstExprValue *null_char = &all_chars[len_with_null - 1];
null_char->ok = true;
bignum_init_unsigned(&null_char->data.x_bignum, 0);
const_val->data.x_ptr.ptr[len_with_null - 1] = null_char;
return &const_instruction->base;
}
static IrInstruction *ir_build_bin_op(IrBuilder *irb, AstNode *source_node, IrBinOp op_id,
IrInstruction *op1, IrInstruction *op2)
{
@ -398,9 +447,7 @@ static IrInstruction *ir_build_var_ptr(IrBuilder *irb, AstNode *source_node, Var
return &instruction->base;
}
static IrInstruction *ir_build_var_ptr_from(IrBuilder *irb, IrInstruction *old_instruction,
VariableTableEntry *var)
{
static IrInstruction *ir_build_var_ptr_from(IrBuilder *irb, IrInstruction *old_instruction, VariableTableEntry *var) {
IrInstruction *new_instruction = ir_build_var_ptr(irb, old_instruction->source_node, var);
ir_link_new_instruction(new_instruction, old_instruction);
return new_instruction;
@ -1589,6 +1636,16 @@ static IrInstruction *ir_gen_bool_literal(IrBuilder *irb, AstNode *node) {
return ir_build_const_bool(irb, node, node->data.bool_literal.value);
}
static IrInstruction *ir_gen_string_literal(IrBuilder *irb, AstNode *node) {
assert(node->type == NodeTypeStringLiteral);
if (node->data.string_literal.c) {
return ir_build_const_c_str_lit(irb, node, node->data.string_literal.buf);
} else {
return ir_build_const_str_lit(irb, node, node->data.string_literal.buf);
}
}
static IrInstruction *ir_gen_array_type(IrBuilder *irb, AstNode *node) {
assert(node->type == NodeTypeArrayType);
@ -1662,6 +1719,8 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockCont
return ir_gen_bool_literal(irb, node);
case NodeTypeArrayType:
return ir_gen_array_type(irb, node);
case NodeTypeStringLiteral:
return ir_gen_string_literal(irb, node);
case NodeTypeUnwrapErrorExpr:
case NodeTypeDefer:
case NodeTypeSliceExpr:
@ -1672,7 +1731,6 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockCont
case NodeTypeContinue:
case NodeTypeLabel:
case NodeTypeSwitchExpr:
case NodeTypeStringLiteral:
case NodeTypeCharLiteral:
case NodeTypeNullLiteral:
case NodeTypeUndefinedLiteral:
@ -3331,11 +3389,14 @@ static TypeTableEntry *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstruct
if (var->type->id == TypeTableEntryIdInvalid)
return var->type;
zig_panic("TODO if var is a global, this code is wrong");
TypeTableEntry *ptr_type = get_pointer_to_type(ira->codegen, var->type, false);
// TODO once the anlayze code is fully ported over to IR we won't need this SIZE_MAX thing.
// TODO once the analyze code is fully ported over to IR we won't need this SIZE_MAX thing.
if (var->mem_slot_index != SIZE_MAX) {
ConstExprValue *mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index];
if (mem_slot->ok) {
zig_panic("TODO do we really want to set up this fake pointer to do constant evaluation?");
ConstExprValue *out_val = ir_build_const_from(ira, &var_ptr_instruction->base,
mem_slot->depends_on_compile_var);
@ -6995,16 +7056,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {
// return g->builtin_types.entry_void;
//}
//
//static TypeTableEntry *analyze_string_literal_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
// TypeTableEntry *expected_type, AstNode *node)
//{
// if (node->data.string_literal.c) {
// return resolve_expr_const_val_as_c_string_lit(g, node, node->data.string_literal.buf);
// } else {
// return resolve_expr_const_val_as_string_lit(g, node, node->data.string_literal.buf);
// }
//}
//
//static TypeTableEntry *analyze_block_expr(CodeGen *g, ImportTableEntry *import, BlockContext *parent_context,
// TypeTableEntry *expected_type, AstNode *node)
//{

View File

@ -84,9 +84,22 @@ static void ir_print_const_value(IrPrint *irp, TypeTableEntry *type_entry, Const
fprintf(irp->f, "(scope:%zu:%zu)", node->line + 1, node->column + 1);
break;
}
case TypeTableEntryIdArray:
{
uint64_t len = type_entry->data.array.len;
fprintf(irp->f, "%s{", buf_ptr(&type_entry->name));
for (uint64_t i = 0; i < len; i += 1) {
if (i != 0)
fprintf(irp->f, ",");
ConstExprValue *child_value = const_val->data.x_array.fields[i];
TypeTableEntry *child_type = type_entry->data.array.child_type;
ir_print_const_value(irp, child_type, child_value);
}
fprintf(irp->f, "}");
break;
}
case TypeTableEntryIdVar:
case TypeTableEntryIdFloat:
case TypeTableEntryIdArray:
case TypeTableEntryIdStruct:
case TypeTableEntryIdUndefLit:
case TypeTableEntryIdNullLit: