Ejemplo n.º 1
0
ValueType codegen(Cons *cons, CodeBuilder *cb, int sp, bool spawn) {
	if(cons->type == CONS_INT) {
		cb->createIConst(sp, cons->i);
		return VT_INT;
	} else if(cons->type == CONS_STR) {
		const char *name = cons->str;
		if(strcmp(name, "t") == 0) {
			cb->createIConst(sp, 1);
			return VT_BOOLEAN;
		}
		if(strcmp(name, "nil") == 0) {
			cb->createIConst(sp, 0);
			return VT_BOOLEAN;
		}
		if(cb->getFunc() != NULL) {
			int n = getArgIndex(cb->getFunc(), name);
			if(n != -1) {
				cb->createMov(sp, n);
				return VT_INT;
			}
		}
		Variable *var = cb->getCtx()->getVar(name);
		if(var != NULL) {
			cb->createLoadGlobal(sp, var);
			return var->type;
		}
		fprintf(stderr, "symbol not found: %s\n", cons->str);
		throw "";
	} else if(cons->type == CONS_CAR) {
		if(cons->car == NULL || cons->car->type != CONS_STR) {
			fprintf(stderr, "not function\n");
			throw "";
		}
		const char *name = cons->car->str;
		Func *func = cb->getCtx()->getFunc(name);
		if(func == NULL) {
			fprintf(stderr, "not function\n");
			throw "";
		}
		Cons *args = cons->car->cdr;
		if(spawn && func->args != NULL) {
			return genSpawn(func, cons->car->cdr, cb, sp);
		} else {
			return func->codegen(func, args, cb, sp);
		}
	} else {
		fprintf(stderr, "integer require\n");
		throw "";
	}
}
Ejemplo n.º 2
0
// N-pass system.
// there's no point counting at this stage.
static void codegenTopLevel(CodegenInstance* cgi, int pass, std::deque<Expr*> expressions, bool isInsideNamespace)
{
	if(pass == 0)
	{
		// add all the types for order-independence -- if we encounter a need, we can
		// force codegen.

		for(Expr* e : expressions)
		{
			NamespaceDecl* ns		= dynamic_cast<NamespaceDecl*>(e);
			TypeAlias* ta			= dynamic_cast<TypeAlias*>(e);
			Struct* str				= dynamic_cast<Struct*>(e);
			Class* cls				= dynamic_cast<Class*>(e);		// enum : class, extension : class
			Func* fn				= dynamic_cast<Func*>(e);
			ForeignFuncDecl* ffi	= dynamic_cast<ForeignFuncDecl*>(e);
			OpOverload* oo			= dynamic_cast<OpOverload*>(e);

			if(ns)					ns->codegenPass(cgi, pass);
			else if(ta)				addTypeToFuncTree(cgi, ta, ta->name, TypeKind::TypeAlias);
			else if(str)			addTypeToFuncTree(cgi, str, str->name, TypeKind::Struct);
			else if(cls)			addTypeToFuncTree(cgi, cls, cls->name, TypeKind::Class);
			else if(fn)				addFuncDeclToFuncTree(cgi, fn->decl);
			else if(ffi)			addFuncDeclToFuncTree(cgi, ffi->decl);
			else if(oo)				addOpOverloadToFuncTree(cgi, oo);
		}
	}
	else if(pass == 1)
	{
		// pass 1: setup extensions
		for(Expr* e : expressions)
		{
			Extension* ext			= dynamic_cast<Extension*>(e);
			NamespaceDecl* ns		= dynamic_cast<NamespaceDecl*>(e);

			if(ext)					ext->mangledName = cgi->mangleWithNamespace(ext->name);
			else if(ns)				ns->codegenPass(cgi, pass);
		}

		// we need the 'Type' enum to be available, as well as the 'Any' type,
		// before any variables are encountered.

		if(!isInsideNamespace)
			TypeInfo::initialiseTypeInfo(cgi);
	}
	else if(pass == 2)
	{
		// pass 2: create types
		for(Expr* e : expressions)
		{
			Struct* str				= dynamic_cast<Struct*>(e);
			Class* cls				= dynamic_cast<Class*>(e);	// enums are handled, since enum : class
			NamespaceDecl* ns		= dynamic_cast<NamespaceDecl*>(e);

			if(str)					str->createType(cgi);
			if(cls)					cls->createType(cgi);
			else if(ns)				ns->codegenPass(cgi, pass);
		}
	}
	else if(pass == 3)
	{
		// pass 3: override types with any extensions
		for(Expr* e : expressions)
		{
			Extension* ext			= dynamic_cast<Extension*>(e);
			NamespaceDecl* ns		= dynamic_cast<NamespaceDecl*>(e);
			TypeAlias* ta			= dynamic_cast<TypeAlias*>(e);

			if(ext)					ext->createType(cgi);
			else if(ta)				ta->createType(cgi);
			else if(ns)				ns->codegenPass(cgi, pass);
		}

		// step 3: generate the type info.
		// now that we have all the types that we need, and they're all fully
		// processed, we create the Type enum.
		TypeInfo::generateTypeInfo(cgi);
	}
	else if(pass == 4)
	{
		// pass 4: create declarations
		for(Expr* e : expressions)
		{
			ForeignFuncDecl* ffi	= dynamic_cast<ForeignFuncDecl*>(e);
			Func* func				= dynamic_cast<Func*>(e);
			NamespaceDecl* ns		= dynamic_cast<NamespaceDecl*>(e);

			if(ffi)					ffi->codegen(cgi);
			else if(ns)				ns->codegenPass(cgi, pass);
			else if(func)
			{
				// func->decl->codegen(cgi);
			}
		}
	}
	else if(pass == 5)
	{
		// start semantic analysis before any typechecking needs to happen.
		SemAnalysis::rewriteDotOperators(cgi);

		// pass 4: everything else
		for(Expr* e : expressions)
		{
			Struct* str				= dynamic_cast<Struct*>(e);
			Class* cls				= dynamic_cast<Class*>(e);		// again, enums are handled since enum : class
			Extension* ext			= dynamic_cast<Extension*>(e);
			NamespaceDecl* ns		= dynamic_cast<NamespaceDecl*>(e);
			VarDecl* vd				= dynamic_cast<VarDecl*>(e);

			if(str)					str->codegen(cgi);
			else if(cls)			cls->codegen(cgi);
			else if(ext)			ext->codegen(cgi);
			else if(ns)				ns->codegenPass(cgi, pass);
			else if(vd)				vd->isGlobal = true, vd->codegen(cgi);
		}
	}
	else if(pass == 6)
	{
		// pass 7: functions. for generic shit.
		for(Expr* e : expressions)
		{
			Func* func						= dynamic_cast<Func*>(e);
			NamespaceDecl* ns				= dynamic_cast<NamespaceDecl*>(e);

			if(func && !func->didCodegen)	func->codegen(cgi);
			if(ns)							ns->codegenPass(cgi, pass);
		}
	}
	else
	{
		error("Invalid pass number '%d'\n", pass);
	}
}