type.om (3793B)
1 struct type { 2 kind: int; 3 st: *decl; 4 val: *type; 5 arg: *type; 6 } 7 8 enum { 9 TY_NIL, 10 TY_VOID, 11 TY_INT, 12 TY_BYTE, 13 TY_PTR, 14 TY_ARG, 15 TY_FUNC, 16 TY_STRUCT, 17 TY_UNION, 18 } 19 20 func type_sizeof(c: *compiler, t: *type): int { 21 var kind: int; 22 23 kind = t.kind; 24 if (kind == TY_NIL) { 25 return 8; 26 } else if (kind == TY_INT) { 27 return 8; 28 } else if (kind == TY_BYTE) { 29 return 8; 30 } else if (kind == TY_PTR) { 31 return 8; 32 } else if (kind == TY_FUNC) { 33 return 8; 34 } else if (kind == TY_STRUCT) { 35 layout_struct(c, t.st); 36 return t.st.struct_size; 37 } else if (kind == TY_UNION) { 38 layout_union(c, t.st); 39 return t.st.struct_size; 40 } else { 41 cdie(c, "sizeof: invalid type"); 42 return 0; 43 } 44 } 45 46 // Unify two types 47 func unify(c: *compiler, a: *type, b: *type) { 48 var kind: int; 49 50 if (a == b) { 51 return; 52 } 53 54 if a && b && ((a.kind == TY_NIL && (b.kind == TY_PTR || b.kind == TY_FUNC)) || ((a.kind == TY_PTR || a.kind == TY_FUNC) && b.kind == TY_NIL)) { 55 return; 56 } 57 58 if ((a && !b) || (b && !a) || a.kind != b.kind) { 59 cdie(c, "type error"); 60 } 61 62 kind = a.kind; 63 if (kind == TY_PTR) { 64 unify(c, a.val, b.val); 65 } else if (kind == TY_FUNC) { 66 unify(c, a.val, b.val); 67 unify(c, a.arg, b.arg); 68 } else if (kind == TY_ARG) { 69 unify(c, a.val, b.val); 70 unify(c, a.arg, b.arg); 71 } else if (kind == TY_STRUCT) { 72 if (a.st != b.st) { 73 cdie(c, "type error"); 74 } 75 } else if (kind == TY_UNION) { 76 if (a.st != b.st) { 77 cdie(c, "type error"); 78 } 79 } else if (kind != TY_VOID && kind != TY_INT && kind != TY_BYTE) { 80 cdie(c, "unify: invalid type"); 81 } 82 } 83 84 func mktype(c: *compiler, kind: int, a: *type, b: *type, st: *decl): *type { 85 var t: *type; 86 87 t = alloc(c.a, sizeof(*t)) as *type; 88 89 t.kind = kind; 90 t.st = st; 91 t.val = a; 92 t.arg = b; 93 94 return t; 95 } 96 97 func mktype_struct(c: *compiler, st: *decl): *type { 98 return mktype(c, TY_STRUCT, nil, nil, st); 99 } 100 101 func mktype_union(c: *compiler, st: *decl): *type { 102 return mktype(c, TY_UNION, nil, nil, st); 103 } 104 105 func mktype0(c: *compiler, kind: int): *type { 106 return mktype(c, kind, nil, nil, nil); 107 } 108 109 func mktype1(c: *compiler, kind: int, a: *type): *type { 110 return mktype(c, kind, a, nil, nil); 111 } 112 113 func mktype2(c: *compiler, kind: int, a: *type, b: *type): *type { 114 return mktype(c, kind, a, b, nil); 115 } 116 117 func type_isint(t: *type): int { 118 return t.kind == TY_INT || t.kind == TY_BYTE; 119 } 120 121 func type_isprim(t: *type): int { 122 return t.kind != TY_VOID && t.kind != TY_STRUCT && t.kind != TY_UNION; 123 } 124 125 func prototype(c: *compiler, n: *node): *type { 126 var a: *type; 127 var b: *type; 128 var st: *decl; 129 var kind: int; 130 131 if (!n) { 132 return nil; 133 } 134 135 c.lineno = n.lineno; 136 c.colno = 0; 137 138 kind = n.kind; 139 if (kind == N_IDENT) { 140 if (!strcmp(n.s, "void")) { 141 return mktype0(c, TY_VOID); 142 } 143 144 if (!strcmp(n.s, "int")) { 145 return mktype0(c, TY_INT); 146 } 147 148 if (!strcmp(n.s, "byte")) { 149 return mktype0(c, TY_BYTE); 150 } 151 152 st = find(c, n.s, nil, 0); 153 if (!st || !st.struct_defined) { 154 cdie(c, "unknown struct"); 155 } 156 157 if st.struct_def.kind == N_STRUCT { 158 return mktype_struct(c, st); 159 } else { 160 return mktype_union(c, st); 161 } 162 } else if (kind == N_ARGLIST) { 163 a = prototype(c, n.a.b); 164 b = prototype(c, n.b); 165 166 kind = a.kind; 167 if (kind != TY_INT && kind != TY_BYTE 168 && kind != TY_PTR && kind != TY_FUNC) { 169 cdie(c, "not a ptr arg"); 170 } 171 172 return mktype2(c, TY_ARG, a, b); 173 } else if (kind == N_FUNCTYPE) { 174 if (n.b) { 175 a = prototype(c, n.b); 176 } else{ 177 a = mktype0(c, TY_VOID); 178 } 179 180 b = prototype(c, n.a); 181 182 kind = a.kind; 183 if (kind != TY_VOID && kind != TY_INT && kind != TY_BYTE 184 && kind != TY_PTR && kind != TY_FUNC) { 185 cdie(c, "not a ptr return"); 186 } 187 188 return mktype2(c, TY_FUNC, a, b); 189 } else if (kind == N_PTRTYPE) { 190 return mktype1(c, TY_PTR, prototype(c, n.a)); 191 } else { 192 cdie(c, "prototype: invalid type"); 193 return nil; 194 } 195 }