Example #1
0
// parentEnum is nil if not in enum
func (v *TypeCheck) CheckTupleLiteral(s *SemanticAnalyzer, lit *ast.TupleLiteral) {
	tupleType, ok := lit.GetType().BaseType.ActualType().(ast.TupleType)
	if !ok {
		panic("Type of tuple literal was not `TupleType`")
	}
	memberTypes := tupleType.Members

	if len(lit.Members) != len(memberTypes) {
		s.Err(lit, "Invalid amount of entries in tuple")
	}

	var gcon *ast.GenericContext
	if lit.ParentEnumLiteral != nil {
		gcon = ast.NewGenericContext(lit.ParentEnumLiteral.GetType().BaseType.ActualType().(ast.EnumType).GenericParameters, lit.ParentEnumLiteral.Type.GenericArguments)
	} else {
		gcon = ast.NewGenericContext(nil, nil)
	}

	for idx, mem := range lit.Members {
		expectType(s, mem, gcon.Get(memberTypes[idx]), &mem)
	}
}
Example #2
0
// if outer is not nil, this function does not add the current function gcon as outer, as it assumes it is already there
func (v *Codegen) typeRefToLLVMTypeWithOuter(typ *ast.TypeReference, outer *ast.GenericContext) llvm.Type {
	var gcon *ast.GenericContext
	if len(typ.GenericArguments) > 0 {
		gcon = ast.NewGenericContextFromTypeReference(typ)
	} else {
		gcon = ast.NewGenericContext(nil, nil)
	}

	if outer != nil {
		gcon.Outer = outer
	} else if v.inFunction() {
		gcon.Outer = v.currentFunction().gcon
	}

	return v.typeRefToLLVMTypeWithGenericContext(typ, gcon)
}
Example #3
0
func (v *TypeCheck) CheckCompositeLiteral(s *SemanticAnalyzer, lit *ast.CompositeLiteral) {
	gcon := ast.NewGenericContext([]*ast.SubstitutionType{}, []*ast.TypeReference{})
	if len(lit.Type.GenericArguments) > 0 {
		gcon = ast.NewGenericContextFromTypeReference(lit.Type)
	}

	switch typ := lit.Type.BaseType.ActualType().(type) {
	case ast.ArrayType:
		memType := typ.MemberType
		for i, mem := range lit.Values {
			expectType(s, mem, memType, &mem)

			if lit.Fields[i] != "" {
				s.Err(mem, "Unexpected field in array literal: `%s`", lit.Fields[i])
			}
		}

	case ast.StructType:
		for i, mem := range lit.Values {
			name := lit.Fields[i]

			if name == "" {
				s.Err(mem, "Missing field in struct literal")
				continue
			}

			sMem := typ.GetMember(name)
			if sMem == nil {
				s.Err(lit, "No member named `%s` on struct of type `%s`", name, typ.String())
			}

			sMemType := gcon.Replace(sMem.Type)
			expectType(s, mem, sMemType, &mem)
		}

	default:
		panic("composite literal has neither struct nor array type")
	}
}