1 /// Copyright: Copyright (c) 2017-2019 Andrey Penechko. 2 /// License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0). 3 /// Authors: Andrey Penechko. 4 module vox.fe.ast.type.slice; 5 6 import vox.all; 7 8 @(AstType.type_slice) 9 struct SliceTypeNode { 10 mixin AstNodeData!(AstType.type_slice, AstFlags.isType, AstNodeState.name_register_self_done); 11 AstIndex type = CommonAstNodes.type_type; 12 TypeNode* typeNode() return { return cast(TypeNode*)&this; } 13 AstIndex base; 14 IrIndex irType; 15 IrIndex defaultVal; 16 17 enum sizealign = SizeAndAlignment(POINTER_SIZE * 2, POINTER_ALIGN_POW); 18 } 19 20 void print_slice(SliceTypeNode* node, ref AstPrintState state) 21 { 22 state.print("TYPE ", node.typeNode.printer(state.context)); 23 } 24 25 void post_clone_slice(SliceTypeNode* node, ref CloneState state) 26 { 27 state.fixAstIndex(node.base); 28 } 29 30 void name_register_nested_slice(SliceTypeNode* node, ref NameRegisterState state) { 31 node.state = AstNodeState.name_register_nested; 32 require_name_register(node.base, state); 33 node.state = AstNodeState.name_register_nested_done; 34 } 35 36 void name_resolve_slice(SliceTypeNode* node, ref NameResolveState state) { 37 node.state = AstNodeState.name_resolve; 38 require_name_resolve(node.base, state); 39 node.state = AstNodeState.name_resolve_done; 40 } 41 42 void type_check_slice(SliceTypeNode* node, ref TypeCheckState state) 43 { 44 CompilationContext* c = state.context; 45 node.state = AstNodeState.type_check; 46 require_type_check(node.base, state); 47 if (!node.base.isType(c)) 48 c.error(node.loc, "Slice base type is not a type, it is %s", node.base.astType(c)); 49 50 node.state = AstNodeState.type_check_done; 51 } 52 53 bool same_type_slice(SliceTypeNode* t1, SliceTypeNode* t2, CompilationContext* context) 54 { 55 return same_type(t1.base, t2.base, context); 56 } 57 58 IrIndex gen_init_value_slice(SliceTypeNode* node, CompilationContext* c) 59 { 60 if (node.defaultVal.isDefined) return node.defaultVal; 61 node.defaultVal = c.constants.addZeroConstant(gen_ir_type_slice(node, c)); 62 return node.defaultVal; 63 } 64 65 // slice is lowered into struct with two members 66 IrIndex gen_ir_type_slice(SliceTypeNode* t, CompilationContext* context) 67 out(res; res.isTypeStruct, "Not a struct type") 68 { 69 if (t.irType.isDefined) return t.irType; 70 71 t.irType = context.types.appendStruct(2); 72 IrTypeStruct* structType = &context.types.get!IrTypeStruct(t.irType); 73 IrIndex baseType = t.base.gen_ir_type(context, AllowHeaderOnly.yes); 74 // length 75 structType.members[0] = IrTypeStructMember(makeIrType(IrBasicType.i64), 0); 76 // ptr 77 structType.members[1] = IrTypeStructMember(context.types.appendPtr(baseType), POINTER_SIZE); 78 structType.sizealign = t.sizealign; 79 return t.irType; 80 } 81 82 TypeConvResKind type_conv_slice(SliceTypeNode* node, AstIndex typeBIndex, ref AstIndex expr, CompilationContext* c) 83 { 84 TypeNode* typeB = typeBIndex.get_type(c); 85 86 switch(typeB.astType) with(AstType) { 87 case type_ptr: 88 if (expr.astType(c) == AstType.literal_string) { 89 if (typeB.astType == AstType.type_ptr) { 90 TypeNode* ptrBaseType = typeB.as_ptr.base.get_type(c); 91 if (ptrBaseType.astType == AstType.type_basic && 92 ptrBaseType.as_basic.basicType == BasicType.t_u8) 93 { 94 return TypeConvResKind.string_literal_to_u8_ptr; 95 } 96 } 97 } 98 return TypeConvResKind.fail; 99 default: return TypeConvResKind.fail; 100 } 101 }