Example #1
0
File: codegen.go Project: vnev/ark
func (v *Codegen) genDefaultValue(typ parser.Type) llvm.Value {
	atyp := typ.ActualType()

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

	if tupleType, ok := atyp.(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 atyp.IsIntegerType() || atyp == parser.PRIMITIVE_bool {
		return llvm.ConstInt(v.typeToLLVMType(atyp), 0, false)
	}

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

	panic("type does not have default value: " + atyp.TypeName())
}
Example #2
0
File: codegen.go Project: vnev/ark
func createStructInitializer(typ parser.Type) *parser.CompositeLiteral {
	lit := &parser.CompositeLiteral{Type: typ}
	hasDefaultValues := false

	structType := typ.ActualType().(parser.StructType)

	for _, decl := range structType.Variables {
		vari := decl.Variable

		var value parser.Expr
		if _, ok := vari.Type.ActualType().(parser.StructType); ok {
			value = createStructInitializer(vari.Type)
		} else {
			value = decl.Assignment
		}

		if value != nil {
			hasDefaultValues = true
			lit.Values = append(lit.Values, value)
			lit.Fields = append(lit.Fields, vari.Name)
		}
	}

	if hasDefaultValues {
		return lit
	}
	return nil
}
Example #3
0
func createStructInitializer(typ parser.Type) *parser.StructLiteral {
	lit := &parser.StructLiteral{Type: typ, Values: make(map[string]parser.Expr)}
	hasDefaultValues := false

	structType := typ.ActualType().(parser.StructType)

	for _, decl := range structType.Variables {
		vari := decl.Variable

		var value parser.Expr
		if _, ok := vari.Type.ActualType().(parser.StructType); ok {
			value = createStructInitializer(vari.Type)
		} else {
			value = decl.Assignment
		}

		if value != nil {
			hasDefaultValues = true
			lit.Values[vari.Name] = value
		}
	}

	if hasDefaultValues {
		return lit
	}
	return nil
}
Example #4
0
func isTypeRecursive(typ parser.Type) (bool, []parser.Type) {
	typ = typ.ActualType()

	var check func(current parser.Type, path *[]parser.Type, traversed map[parser.Type]bool) bool
	check = func(current parser.Type, path *[]parser.Type, traversed map[parser.Type]bool) bool {
		switch current.(type) {
		case *parser.NamedType:
			if traversed[current] {
				return true
			}
			traversed[current] = true
		}

		switch current.(type) {
		case parser.StructType:
			st := current.(parser.StructType)
			for _, decl := range st.Variables {
				if check(decl.Variable.Type, path, traversed) {
					*path = append(*path, decl.Variable.Type)
					return true
				}
			}

		case parser.TupleType:
			tt := current.(parser.TupleType)
			for _, mem := range tt.Members {
				if check(mem, path, traversed) {
					*path = append(*path, mem)
					return true
				}
			}

		case parser.EnumType:
			et := current.(parser.EnumType)
			for _, mem := range et.Members {
				if check(mem.Type, path, traversed) {
					*path = append(*path, mem.Type)
					return true
				}
			}

		case *parser.NamedType:
			nt := current.(*parser.NamedType)
			if check(nt.Type, path, traversed) {
				*path = append(*path, nt.Type)
				return true
			}

			// TODO: Add array if we ever add embedded fixed size/static arrays
		}
		return false
	}

	var path []parser.Type
	return check(typ, &path, make(map[parser.Type]bool)), path
}