Exemple #1
0
Type* copyType(Type* t) {
	if(t == NULL) return NULL;

	Type* copy = malloc(sizeof(Type));
	copy->type = t->type;
	copy->optional = t->optional;
	if(t->type == TYPE_LAMBDA) {
		copy->typedata.lambda.arguments = copyTypeArray(t->typedata.lambda.arguments);
		copy->typedata.lambda.returntype = copyType(t->typedata.lambda.returntype);
		copy->typedata.lambda.body = t->typedata.lambda.body;
	} else if(t->type == TYPE_CLASS) {
		copy->typedata._class.classname = t->typedata._class.classname == NULL ? NULL : strdup(t->typedata._class.classname);
		copy->typedata._class.shadow = t->typedata._class.shadow;					// number of $s
		copy->typedata._class.parameters = copyTypeArray(t->typedata._class.parameters);			// Xxx{T from Yyy}
	} else if(t->type == TYPE_PARAMETERIZED) {
		copy->typedata.parameterized.label = t->typedata.parameterized.label == NULL ? NULL : strdup(t->typedata.parameterized.label);
		copy->typedata.parameterized.shadow = t->typedata.parameterized.shadow;					// number of $s
		copy->typedata.parameterized.lowerbound = copyType(t->typedata.parameterized.lowerbound);
		copy->typedata.parameterized.upperbound = copyType(t->typedata.parameterized.upperbound);
	}
	copy->arrayed = t->arrayed;
	copy->alias = t->alias == NULL ? NULL : strdup(t->alias);
	copy->specialty = t->specialty == NULL ? NULL : strdup(t->specialty);
	return copy;
}
boost::optional<SemanticError*> PropertySymbolTable::addMethod(Type* returntype, vector<pair<string, TypeArray*> >* segments_arguments, int flags) {
	string name = getSymbolNameOf(segments_arguments);

	if(properties.count(name)) {
		string temp = "duplicate method signature is " + name;
		return boost::optional<SemanticError*>(new SemanticError(MULTIPLE_METHOD_DEFINITION, temp));
	}

	if(flags & PROPERTY_ABSTRACT) {
		abstract = true;
	}

	Type* method = MakeType(TYPE_LAMBDA);
	method->typedata.lambda.returntype = copyType(returntype);

	TypeArray* conglomerate = MakeTypeArray();
	for(vector<pair<string, TypeArray*> >::iterator it = segments_arguments->begin(); it != segments_arguments->end(); ++it) {
		int i;
		for(i = 0; i < it->second->typecount; i++)
			AddTypeToTypeArray(copyType(it->second->types[i]), conglomerate);
	}

	method->typedata.lambda.arguments = conglomerate;

	ObjectProperty* prop = new ObjectProperty;
	prop->flags = flags;
	prop->type = method;
	prop->casing = getCasingNameOf(segments_arguments);
	prop->address = name;

	properties[name] = prop;

	return boost::optional<SemanticError*>();
}
ReadOnlyPropertySymbolTable* PropertySymbolTable::resolveParameters(vector<Type*>& parameters) {
	TypeParameterizer parameterizer;
	map<string, ObjectProperty*>* newprops = new map<string, ObjectProperty*>();
	for(map<string, ObjectProperty*>::iterator it = properties.begin(); it != properties.end(); ++it) {
		string casing, oldcasing = it->second->casing;
		ObjectProperty* newprop = new ObjectProperty();
		newprop->type = copyType(it->second->type);
		newprop->flags = it->second->flags;
		newprop->address = it->second->address;
		parameterizer.applyParameterizations(&newprop->type, getParameters(), parameters);
		int i = 0, c = 0;
		while(c < oldcasing.length()) {
			if(oldcasing.at(c) == '#') {
				casing += analyzer->getNameForType(newprop->type->typedata.lambda.arguments->types[i]);
				i++;
			} else {
				casing += oldcasing.at(c);
			}
			c++;
		}
		newprop->casing = casing;
		(*newprops)[casing] = newprop;
	}

	vector<Type*>* newneeds = new vector<Type*>();
	for(vector<Type*>::iterator it = needs->begin(); it != needs->end(); ++it) {
		Type* newneed = copyType(*it);
		parameterizer.applyParameterizations(&newneed, getParameters(), parameters);
		newneeds->push_back(newneed);
	}

	return new DerivedPropertySymbolTable(*analyzer, *newneeds, *newprops, parentage);
	return this;
}
void propagateInheritanceTables(PropertySymbolTable* child, PropertySymbolTable* parent, bool extend) {
	for(map<string, ObjectProperty*>::iterator it = parent->properties.begin(); it != parent->properties.end(); ++it) {
		if(!extend && !(it->second->flags & PROPERTY_PUBLIC)) continue;
		map<string, ObjectProperty*>::iterator searcher = child->properties.find(it->first);
		if(searcher == child->properties.end()) {
			ObjectProperty* propagate = new ObjectProperty;
			propagate->type = copyType(it->second->type);
			propagate->flags = it->second->flags;
			propagate->casing = it->second->casing;
			propagate->address = it->second->address;
			if(!extend) {
				propagate->flags |= PROPERTY_ABSTRACT;
				child->abstract = true;
			} else if(propagate->flags & PROPERTY_ABSTRACT) {
				child->abstract = true;
			}
			child->properties[it->first] = propagate;

			if(extend && propagate->flags & PROPERTY_NEED) {
				child->analyzer->assertNeedIsNotCircular(child->classname, propagate->type);
				child->getNeeds()->push_back(propagate->type);
			}

		} else {
			searcher->second->address = it->second->address;
		}
	}
}
Exemple #5
0
TypeArray* copyTypeArray(TypeArray* ta) {
	if(ta == NULL) return NULL;
	TypeArray* copy = malloc(sizeof(TypeArray));
	copy->typecount = ta->typecount;
	copy->types = malloc(copy->typecount * sizeof(Type*));
	int i;
	for(i = 0; i < ta->typecount; i++) {
		copy->types[i] = copyType(ta->types[i]);
	}
	return copy;
}
bool TypeAnalyzer::isAutoboxedType(Type* type, Type** boxed) {
	if(type->type == TYPE_MATCHALL) return false;

	// shouldn't be here...throw exception?
	if(type->type == TYPE_UNUSABLE) return false;

	// need to return a List<T>
	if(type->arrayed) {
		*boxed = MakeType(TYPE_CLASS);
		Type* loweredtype = copyType(type);
		loweredtype->arrayed--;
		(*boxed)->typedata._class.classname = strdup("List");
		(*boxed)->typedata._class.parameters = MakeTypeArray();
		AddTypeToTypeArray(loweredtype, (*boxed)->typedata._class.parameters);
		return true;
	}

	// need to return a generic autoboxed type according to arguments/return
	if(type->type == TYPE_LAMBDA) {
		*boxed = MakeType(TYPE_CLASS);
		(*boxed)->typedata._class.classname = strdup("lambda");
		return true;
	}

	// shouldn't ever get here,..unless I decide to make, say, T?.exists() and/or T?.applyIfExists(fn(T))
	if(type->optional) return false;

	if(isPrimitiveTypeBool(type)) {
		*boxed = MakeType(TYPE_CLASS);
		(*boxed)->typedata._class.classname = strdup("Bool");
		return true;
	}

	if(isPrimitiveTypeText(type)) {
		*boxed = MakeType(TYPE_CLASS);
		(*boxed)->typedata._class.classname = strdup("Text");
		return true;
	}

	if(isPrimitiveTypeNum(type)) {
		*boxed = MakeType(TYPE_CLASS);
		(*boxed)->typedata._class.classname = strdup("Num");
		return true;
	}

	return false;
}
void propagateInheritanceTables(PropertySymbolTable* child, PropertySymbolTable* parent, bool extend, ErrorTracker& errors) {
	for(map<string, ObjectProperty*>::iterator it = parent->properties.begin(); it != parent->properties.end(); ++it) {
		if(!extend && !(it->second->flags & PROPERTY_PUBLIC)) continue;
		map<string, ObjectProperty*>::iterator searcher = child->properties.find(it->first);
		if(searcher == child->properties.end()) {
			ObjectProperty* propagate = new ObjectProperty;
			propagate->type = copyType(it->second->type);
			propagate->flags = it->second->flags;
			propagate->casing = it->second->casing;
			propagate->address = it->second->address;
			if(!extend) {
				propagate->flags |= PROPERTY_ABSTRACT;
				child->abstract = true;
			} else if(propagate->flags & PROPERTY_ABSTRACT) {
				child->abstract = true;
			}
			child->properties[it->first] = propagate;

			if(extend && propagate->flags & PROPERTY_NEED) {
				child->analyzer->assertNeedIsNotCircular(child->classname, propagate->type);
				child->getNeeds()->push_back(propagate->type);
			}

		} else {
			searcher->second->address = it->second->address;
			if(searcher->second->type->type == TYPE_LAMBDA)
			if(it->second->type->typedata.lambda.returntype != NULL)
			if(searcher->second->type->typedata.lambda.returntype == NULL
				|| !child->analyzer->isASubtypeOfB(
					searcher->second->type->typedata.lambda.returntype,	// this is contravariance
					it->second->type->typedata.lambda.returntype 		// Check parent return is a subtype of child return
				)
			) {
				errors.addError(new SemanticError(INVALID_CHILD_RETURN_TYPE, "method " + searcher->second->address + " on class " + child->classname, NULL, ""));
			}
		}
	}
}
boost::optional<SemanticError*> PropertySymbolTable::addProvision(Type* provided, int flags) {
	string name = analyzer->getNameForType(provided) + "<-";
	if(provided->specialty != NULL) name += provided->specialty;

	if(properties.count(name)) {
		string temp = "duplicate provisoning is " + name;
		return boost::optional<SemanticError*>(new SemanticError(DUPLICATE_PROPERTY_DEFINITION, temp));
	}

	Type* method = MakeType(TYPE_LAMBDA);
	method->typedata.lambda.returntype = copyType(provided);

	method->typedata.lambda.arguments = MakeTypeArray(); //TODO injections with curried ctors or arguments!

	ObjectProperty* prop = new ObjectProperty;
	prop->type = method;
	prop->casing = name;
	prop->address = name;
	prop->flags = flags;

	properties[name] = prop;
	return boost::optional<SemanticError*>();
}