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 ""; } }
// 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); } }