diff options
| author | 2026-04-13 19:25:11 +0200 | |
|---|---|---|
| committer | 2026-04-13 19:30:01 +0200 | |
| commit | ddbd42e66cc71b470730037d76f4f267e98d8d40 (patch) | |
| tree | aae9ff541b3e0690e23e391bb2e5e8927d34bf38 /src/c_type.c | |
| parent | 36143af2748b6fcae02ca320baaac417d77ebe58 (diff) | |
C99 complex types MVP
Missing: static eval of complex values,
Silly inefficient implementation of equality comparisons between them
The whole thing is pretty inefficient without proper aggregate mem2reg
anyway
Diffstat (limited to 'src/c_type.c')
| -rw-r--r-- | src/c_type.c | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/src/c_type.c b/src/c_type.c index ef4770d..c34d7df 100644 --- a/src/c_type.c +++ b/src/c_type.c @@ -224,7 +224,7 @@ completetype(internstr name, int id, TypeData *td) assert(tagtypetags[id] == name && "bad redefn"); else tagtypetags[id] = name; - return mktype(td->t, .flag = td->flag, .dat = interntd(td)); + return mktype(td->t, .dat = interntd(td)); } Type @@ -312,9 +312,24 @@ cvtarith(Type a, Type b) if (!isarith(a) || !isarith(b)) return none; if (a.t == TYENUM) a = typechild(a); if (b.t == TYENUM) b = typechild(b); + if (iscomplex(a)) { + if (iscomplex(b)) { + /* when both are complex, choose type with greatest rank */ + /* enumeration order of type tags reflects arithmetic type rank */ + return a.t > b.t ? a : b; + } + /* complex float + double -> complex double */ + if (a.t - TYCOMPLEXF + TYFLOAT < b.t) + a.t = b.t + TYCOMPLEXF - TYFLOAT; + return a; + } else if (iscomplex(b)) { + /* double + complex float -> complex double */ + if (b.t - TYCOMPLEXF + TYFLOAT < a.t) + b.t = a.t + TYCOMPLEXF - TYFLOAT; + return b; + } if (isflt(a) || isflt(b)) { /* when one type is float, choose type with greatest rank */ - /* enumeration order of type tags reflects arithmetic type rank */ return a.t > b.t ? a : b; } a.t = intpromote(a.t); @@ -340,4 +355,23 @@ cvtarith(Type a, Type b) } } +/* transform 'complex T' -> struct 'complex T' { T real, imag; } */ +Type +complex2struct(Type t) +{ + assert(iscomplex(t)); + static Type cache[3]; + if (cache[t.t-TYCOMPLEXF].t) return cache[t.t-TYCOMPLEXF]; + static const char *names[] = { + "complex$float", "complex$double", "complex$longdouble" + }; + Type base = mktype(t.t - TYCOMPLEXF + TYFLOAT); + return cache[t.t-TYCOMPLEXF] = mktagtype(intern(names[t.t-TYCOMPLEXF]), &(TypeData){ + TYSTRUCT, .fld = (NamedField [2]){ + {intern("real"), {.t = base, .off = 0}}, + {intern("imag"), {.t = base, .off = typesize(base)}}, + }, .nmemb = 2, .align = typealign(base), .siz = typesize(base) * 2 + }); +} + /* vim:set ts=3 sw=3 expandtab: */ |