Example #1
0
func (v *RecursiveDefinitionCheck) Visit(s *SemanticAnalyzer, n parser.Node) {
	var typ parser.Type

	if typeDecl, ok := n.(*parser.TypeDecl); ok {
		actualType := typeDecl.NamedType.ActualType()
		switch actualType.(type) {
		case *parser.EnumType:
			typ = actualType.(*parser.EnumType)

		case *parser.StructType:
			typ = actualType.(*parser.StructType)

			// TODO: Check tuple types once we add named types for everything

		default:
			return
		}
	}

	if ok, path := isTypeRecursive(typ); ok {
		s.Err(n, "Encountered recursive type definition")

		log.Errorln("semantic", "Path taken:")
		for _, typ := range path {
			log.Error("semantic", typ.TypeName())
			log.Error("semantic", " <- ")
		}
		log.Error("semantic", "%s\n\n", typ.TypeName())
	}

}
Example #2
0
func (v *Codegen) genDefaultValue(typ parser.Type) llvm.Value {
	typ = typ.ActualType()

	// Generate default struct values
	if structType, ok := typ.(*parser.StructType); ok {
		lit := createStructInitializer(structType)
		if lit != nil {
			return v.genStructLiteral(lit)
		} else {
			return llvm.Undef(v.typeToLLVMType(structType))
		}
	}

	if tupleType, ok := typ.(*parser.TupleType); ok {
		values := make([]llvm.Value, len(tupleType.Members))
		for idx, member := range tupleType.Members {
			values[idx] = v.genDefaultValue(member)
		}
		return llvm.ConstStruct(values, false)
	}

	if typ.IsIntegerType() || typ == parser.PRIMITIVE_bool {
		return llvm.ConstInt(v.typeToLLVMType(typ), 0, false)
	}

	if typ.IsFloatingType() {
		return llvm.ConstFloat(v.typeToLLVMType(typ), 0)
	}

	panic("type does not have default value: " + typ.TypeName())
}
Example #3
0
func (v *RecursiveDefinitionCheck) Visit(s *SemanticAnalyzer, n parser.Node) {
	var typ parser.Type

	if typeDecl, ok := n.(*parser.TypeDecl); ok {
		typ = typeDecl.NamedType
	} else {
		return
	}

	if ok, path := isTypeRecursive(typ); ok {
		s.Err(n, "Encountered recursive type definition")

		log.Errorln("semantic", "Path taken:")
		for _, typ := range path {
			log.Error("semantic", typ.TypeName())
			log.Error("semantic", " <- ")
		}
		log.Error("semantic", "%s\n\n", typ.TypeName())
	}

}
Example #4
0
File: type.go Project: vnev/ark
func (v *Codegen) typeToLLVMType(typ parser.Type) llvm.Type {
	switch typ := typ.(type) {
	case parser.PrimitiveType:
		return v.primitiveTypeToLLVMType(typ)
	case parser.FunctionType:
		return v.functionTypeToLLVMType(typ, true)
	case parser.StructType:
		return v.structTypeToLLVMType(typ)
	case parser.PointerType:
		return llvm.PointerType(v.typeToLLVMType(typ.Addressee), 0)
	case parser.ArrayType:
		return v.arrayTypeToLLVMType(typ)
	case parser.TupleType:
		return v.tupleTypeToLLVMType(typ)
	case parser.EnumType:
		return v.enumTypeToLLVMType(typ)
	case *parser.NamedType:
		nt := typ
		switch nt.Type.(type) {
		case parser.StructType, parser.EnumType:
			v.addNamedType(nt)
			lt := v.namedTypeLookup[nt.MangledName(parser.MANGLE_ARK_UNSTABLE)]
			return lt

		default:
			return v.typeToLLVMType(nt.Type)
		}
	case parser.MutableReferenceType:
		return llvm.PointerType(v.typeToLLVMType(typ.Referrer), 0)
	case parser.ConstantReferenceType:
		return llvm.PointerType(v.typeToLLVMType(typ.Referrer), 0)
	default:
		log.Debugln("codegen", "Type was %s (%s)", typ.TypeName(), reflect.TypeOf(typ))
		panic("Unimplemented type category in LLVM codegen")
	}
}