void C4AulScriptEngine::Link(C4DefList *rDefs) { try { // resolve appends for (C4AulScript *s = Child0; s; s = s->Next) s->ResolveAppends(rDefs); // resolve includes for (C4AulScript *s = Child0; s; s = s->Next) s->ResolveIncludes(rDefs); // parse the scripts to byte code for (C4AulScript *s = Child0; s; s = s->Next) s->Parse(); // engine is always parsed (for global funcs) State = ASS_PARSED; if (rDefs) rDefs->CallEveryDefinition(); // Done modifying the proplists now for (C4AulScript *s = Child0; s; s = s->Next) s->GetPropList()->Freeze(); GetPropList()->Freeze(); } catch (C4AulError &err) { // error??! show it! err.show(); } }
BOOL C4AulScript::ResolveIncludes(C4DefList *rDefs) { // resolve children includes for (C4AulScript *s = Child0; s; s = s->Next) s->ResolveIncludes(rDefs); // Had been preparsed? if (State != ASS_PREPARSED) return FALSE; // has already been resolved? if (IncludesResolved) return TRUE; // catch circular includes if (Resolving) { C4AulParseError(this, "Circular include chain detected - ignoring all includes!") .show(); IncludesResolved = true; State = ASS_LINKED; return FALSE; } Resolving = true; // append all includes to local script for (C4AListEntry *i = Includes; i; i = i->next()) { C4Def *Def = rDefs->ID2Def(C4ID(i->Var)); if (Def) { // resolve #includes in included script first (#include-chains :( ) if (!((C4AulScript &)Def->Script).IncludesResolved) if (!Def->Script.ResolveIncludes(rDefs)) continue; // skip this #include Def->Script.AppendTo(*this, false); } else { // save id in buffer because AulWarn will use the buffer of C4IdText // to get the id of the object in which the error occurs... // (stupid static buffers...) char strID[5]; *strID = 0; strcpy(strID, C4IdText(C4ID(i->Var))); Warn("script to #include not found: ", strID); } } IncludesResolved = true; // includes/appends are resolved now (for this script) Resolving = false; State = ASS_LINKED; return TRUE; }