1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
import "std/common.cup"
enum BaseType {
TYPE_VOID,
TYPE_ANY,
TYPE_PTR,
TYPE_ARRAY,
TYPE_STRUCT,
TYPE_UNION,
TYPE_INT,
TYPE_CHAR,
};
struct Type {
typ: int;
ptr: Type*;
struct_name: char*;
size: int;
array_size: int;
fields: struct {
names: char**;
types: Type**;
num_fields: int;
};
};
fn size_for_base_type(type: int): int {
if (type == TYPE_INT) return 8;
if (type == TYPE_PTR) return 8;
if (type == TYPE_CHAR) return 1;
// Need to be initialized explicitly for compound types
return 0;
}
fn size_for_type(typ: Type*): int {
if (typ.typ == TYPE_INT) return 8;
if (typ.typ == TYPE_PTR) return 8;
if (typ.typ == TYPE_CHAR) return 1;
if (typ.typ == TYPE_ARRAY) return typ.array_size * size_for_type(typ.ptr);
if (typ.typ == TYPE_STRUCT) return typ.size;
if (typ.typ == TYPE_UNION) return typ.size;
if (typ.typ == TYPE_VOID) return 0;
if (typ.typ == TYPE_ANY) return 8;
die("Unknown type in size_for_type");
}
let _type_int: Type* = null;
let _type_char: Type* = null;
let _type_void: Type* = null;
let _type_any: Type* = null;
fn type_new(typ: int): Type* {
if (_type_int == null) { _type_int = malloc(sizeof(Type)); _type_int.typ = TYPE_INT; _type_int.size = 8; }
if (_type_char == null) { _type_char = malloc(sizeof(Type)); _type_char.typ = TYPE_CHAR; _type_char.size = 1; }
if (_type_void == null) { _type_void = malloc(sizeof(Type)); _type_void.typ = TYPE_VOID; _type_void.size = 0; }
if (_type_any == null) { _type_any = malloc(sizeof(Type)); _type_any.typ = TYPE_ANY; _type_any.size = 8; }
if (typ == TYPE_INT) return _type_int;
if (typ == TYPE_CHAR) return _type_char;
if (typ == TYPE_VOID) return _type_void;
if (typ == TYPE_ANY) return _type_any;
putsln("Allocating Type*");
let t: Type* = malloc(sizeof(Type));
t.typ = typ;
t.size = size_for_base_type(typ);
return t;
}
fn type_new_ptr(typ: int): Type* {
let ptr = type_new(TYPE_PTR);
ptr.ptr = type_new(typ);
return ptr;
}
// This is named differently because it performs an allocation
fn create_type_string(typ: Type *): char* {
let buf: char* = malloc(32);
while (typ.typ == TYPE_PTR || typ.typ == TYPE_ARRAY) {
strcat(buf, typ.typ == TYPE_PTR ? "*" : "[]");
typ = typ.ptr;
}
if (typ.typ == TYPE_INT) strcat(buf, "int");
else if (typ.typ == TYPE_CHAR) strcat(buf, "char");
else if (typ.typ == TYPE_VOID) strcat(buf, "void");
else if (typ.typ == TYPE_ANY) strcat(buf, "any");
else die("type_to_string: unknown type");
return buf;
}
|