os

An operating system
git clone https://erai.gay/code/os/
Log | Files | Refs | README | LICENSE

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 }