type DComplex {.exportc: "complex double".} = tuple[r, i: float64]
proc ccos (x: DComplex): DComplex {.importc: "ccos", header: "<complex.h>".}
let a = ccos ((r:1.0,i:1.0))
The above code does not work as the generated C call for ccos has argument of type tcomplexXXXXXXXXX and not complex double. I also tried replacing exportc with importc, and then with both pragmas thrown in. Nothing worked. Any help will be appreciated. Thanks.
Here is how you can do it. Note that while the use of {.emit.} is discouraged (because it may not work for all backends), it is difficult to avoid in this case, as you can't use {.importc.} to access normal arithmetic.
type DoubleComplex {.importc: "double complex", header: "<complex.h>",
final, pure.} = object
{.push importc, header: "<complex.h>".}
proc ccos(z: DoubleComplex): DoubleComplex
proc csin(z: DoubleComplex): DoubleComplex
proc csqrt(z: DoubleComplex): DoubleComplex
proc conj(z: DoubleComplex): DoubleComplex
proc creal(z: DoubleComplex): float64
proc cimag(z: DoubleComplex): float64
{.pop.}
proc `+`(z, z2: DoubleComplex): DoubleComplex =
{.emit: "`result` = `z` + `z2`;\n".}
proc `-`(z, z2: DoubleComplex): DoubleComplex =
{.emit: "`result` = `z` - `z2`;\n".}
proc `-`(z: DoubleComplex): DoubleComplex =
{.emit: "`result` = - `z`;\n".}
proc `*`(z, z2: DoubleComplex): DoubleComplex =
{.emit: "`result` = `z` * `z2`;\n".}
proc `/`(z, z2: DoubleComplex): DoubleComplex =
{.emit: "`result` = `z` / `z2`;\n".}
proc complex(re, im: float64): DoubleComplex =
{.emit: "`result` = `re` + `im` * I;\n".}
proc complex(re: float64): DoubleComplex =
complex(re, 0.0)
proc `$`(z: DoubleComplex): string =
$creal(z) & "+" & $cimag(z) & "i"
when isMainModule:
let z = complex(3.0)
let z2 = z + complex(1.0)
echo z2, " ", csqrt(z2)
Thanks Araq and Jehan. I now realize why I should not use tuple (sort of). Jehan's example should be enough to get me going.
@Araq: it would be good to hear more about your views of C99 (and C11).