Refactor compilation process around the new concept of packages.
1 /* vim: set ts=4 sw=4 tw=99 et:
3 * Copyright (C) 2012 David Anderson
5 * This file is part of SourcePawn.
7 * SourcePawn is free software: you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License as published by the Free
9 * Software Foundation, either version 3 of the License, or (at your option)
12 * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
13 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with
17 * SourcePawn. If not, see http://www.gnu.org/licenses/.
23 #include "Structures.h"
29 Type::init(Kind kind, Type *root)
32 this->root_ = root ? root : this;
36 Type::NewVoid(Zone *zone)
38 Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
47 Type::NewString(Zone *zone)
49 Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
58 Type::NewUnchecked(Zone *zone)
60 Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
64 type->init(UNCHECKED);
69 Type::NewPrimitive(Zone *zone, PrimitiveType prim)
71 Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
75 type->init(PRIMITIVE);
76 type->primitive_ = prim;
81 Type::NewQualified(Zone *zone, TypeQualifiers qual, Handle<Type> root)
83 Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
87 type->init(QUALTYPE, root);
93 ArrayType::New(Zone *zone, Handle<Type> contained, int elements)
95 if (contained->isArray() &&
96 ArrayType::cast(contained)->levels() == MAX_ARRAY_DEPTH)
98 zone->reportError(Message_MaximumArrayDepth);
102 Local<ArrayType> type(zone, (ArrayType *)zone->allocate(MapKind_ArrayType, sizeof(ArrayType), Heap::Tenure_Old));
107 type->contained_ = contained;
108 type->elements_ = elements;
109 if (!contained->isArray())
112 type->levels_ = ArrayType::cast(contained)->levels() + 1;
117 ArrayType::NewExternal(Zone *zone, Handle<Type> contained)
119 Local<ArrayType> type(zone, (ArrayType *)zone->allocate(MapKind_ArrayType, sizeof(ArrayType), Heap::Tenure_Old));
123 assert(contained->isPrimitive());
125 type->init(EXTERNAL_ARRAY);
126 type->contained_ = contained;
127 type->elements_ = DYNAMIC_ARRAY_SIZE;
133 ReferenceType::New(Zone *zone, Handle<Type> contained)
135 Local<ReferenceType> type(zone, (ReferenceType *)zone->allocate(MapKind_ReferenceType, sizeof(ReferenceType), Heap::Tenure_Old));
139 type->init(REFERENCE);
140 type->contained_ = contained;
145 EnumType::New(Zone *zone, Handle<String> name)
147 Local<EnumType> type(zone, (EnumType *)zone->allocate(MapKind_EnumType, sizeof(EnumType), Heap::Tenure_Old));
157 StructType::New(Zone *zone, Handle<String> name, Handle<FixedArray> fields)
159 Local<StructType> type(zone, (StructType *)zone->allocate(MapKind_StructType, sizeof(StructType), Heap::Tenure_Old));
164 type->newMap_ = NULL;
165 type->fields_ = fields;
168 // Fill in field offsets.
169 StructureBufferBuilder builder;
170 Local<Type> fieldType(zone);
171 for (size_t i = 0; i < fields->length(); i++) {
172 Descriptor *desc = Descriptor::cast(fields->at(i));
173 fieldType = desc->type();
176 if (!builder.add(fieldType, &offset))
178 desc->setOffset(offset);
181 Local<StructMap> map(zone, StructMap::New(zone, builder, type));
191 StructType::lookupField(Handle<String> name, unsigned *index)
193 for (unsigned i = 0; i < fields_->length(); i++) {
194 Descriptor *desc = Descriptor::cast(fields_->at(i));
195 if (desc->name() == name) {
206 FunctionType::New(Zone *zone, Handle<String> name, TokenKind token)
208 Local<FunctionType> type(zone, (FunctionType *)zone->allocate(MapKind_FunctionType, sizeof(FunctionType), Heap::Tenure_Old));
212 type->init(FUNCTION);
213 type->parameters_ = NULL;
214 type->defaults_ = NULL;
215 type->returnType_ = NULL;
217 type->token_ = token;
222 FormatVA(char *buffer, size_t maxlen, const char *text, va_list ap)
224 size_t len = vsnprintf(buffer, maxlen, text, ap);
226 buffer[maxlen - 1] = '\0';
233 Format(char *buffer, size_t maxlen, const char *text, ...)
237 size_t len = FormatVA(buffer, maxlen, text, ap);
243 FormatTypeName(Type *type, char *buffer, size_t maxlen)
245 if (type->isArray()) {
246 ArrayType *atype = ArrayType::cast(type);
247 Type *innermost = atype->innermost();
249 size_t len = FormatTypeName(innermost, buffer, maxlen);
251 if (atype->isFixedLength())
252 len += Format(buffer + len, maxlen - len, "[%d]", atype->fixedLength());
254 len += Format(buffer + len, maxlen - len, "[]");
255 if (!atype->contained()->isArray())
257 atype = ArrayType::cast(atype->contained());
261 if (type->hasTypeQualifiers()) {
263 if (type->quals() & TypeQual_Const)
264 len += Format(buffer, maxlen, "const ");
265 return len + FormatTypeName(type->unqualified(), buffer + len, maxlen - len);
267 if (type->isFunction())
268 return Format(buffer, maxlen, "function");
270 return Format(buffer, maxlen, "void");
271 if (type->isUnchecked())
272 return Format(buffer, maxlen, "unchecked");
274 return Format(buffer, maxlen, "%s", EnumType::cast(type)->name()->chars());
275 if (type->isStruct())
276 return Format(buffer, maxlen, "%s", StructType::cast(type)->name()->chars());
277 if (type->isReference()) {
278 ReferenceType *ref = ReferenceType::cast(type);
279 size_t len = Format(buffer, maxlen, "&");
280 return len + FormatTypeName(ref->contained(), buffer + len, maxlen - len);
282 switch (type->primitive()) {
283 case PrimitiveType_Bool:
284 return Format(buffer, maxlen, "bool");
285 case PrimitiveType_Char:
286 return Format(buffer, maxlen, "char");
287 case PrimitiveType_Int32:
288 return Format(buffer, maxlen, "int");
289 case PrimitiveType_Float:
290 return Format(buffer, maxlen, "float");
292 return Format(buffer, maxlen, "<UNKNOWN>");
297 ke::GetTypeName(Type *type, char *buffer, size_t maxlen)
299 FormatTypeName(type, buffer, maxlen);