void xl_enter_prefix(Context *context, text name, native_fn fn, Tree *rtype, TreeList ¶meters, text symbol, text doc) // ---------------------------------------------------------------------------- // Enter a prefix into the context (called from .tbl files) // ---------------------------------------------------------------------------- { if (parameters.size()) { Tree *parmtree = xl_parameters_tree(parameters); Prefix *from = new Prefix(new Name(symbol), parmtree); Name *to = new Name(symbol); Rewrite *rw = context->Define(from, to); rw->native = fn; rw->type = rtype; Symbols *s = MAIN->globals; Rewrite *rw2 = s->EnterRewrite(from, to); rw2->type = rtype; to->code = fn; to->SetSymbols(s); xl_enter_builtin(MAIN, name, to, rw2->parameters, fn); xl_set_documentation(from, doc); } else { Name *n = new Name(symbol); n->SetInfo<PrefixDefinitionsInfo>(new PrefixDefinitionsInfo()); Rewrite *rw = context->Define(n, n); rw->native = fn; rw->type = rtype; Symbols *s = MAIN->globals; Rewrite *rw2 = s->EnterName(symbol, n, Rewrite::GLOBAL); rw2->type = rtype; n->code = fn; n->SetSymbols(s); TreeList noparms; xl_enter_builtin(MAIN, name, n, noparms, fn); xl_set_documentation(n, doc); } }
int Main::LoadFile(text file, bool updateContext, Context *importContext, Symbols *importSymbols) // ---------------------------------------------------------------------------- // Load an individual file // ---------------------------------------------------------------------------- { Tree_p tree = NULL; bool hadError = false; IFTRACE(fileload) std::cout << "Loading: " << file << "\n"; // Find which source file we are referencing SourceFile &sf = files[file]; // Parse program - Local parser to delete scanner and close file // This ensures positions are updated even if there is a 'load' // being called during execution. if (options.readSerialized) { if (!reader) reader = new Deserializer(std::cin); tree = reader->ReadTree(); if (!reader->IsValid()) { errors->Log(Error("Serialized stream cannot be read: $1") .Arg(file)); hadError = true; return hadError; } } else { utf8_ifstream ifs(file.c_str(), std::ios::in | std::ios::binary); Deserializer ds(ifs); tree = ds.ReadTree(); if (!ds.IsValid()) { std::string decrypted = MAIN->Decrypt(file.c_str()); if (decrypted != "") { // Parse decrypted string as XL source IFTRACE(fileload) std::cerr << "Info: file was succesfully decrypted\n"; std::istringstream iss; iss.str(decrypted); Parser parser (iss, syntax, positions, topLevelErrors); tree = parser.Parse(); } else { // Parse as XL source Parser parser (file.c_str(), syntax, positions, topLevelErrors); tree = parser.Parse(); } } else { IFTRACE(fileload) std::cerr << "Info: file is in serialized format\n"; } } if (options.writeSerialized) { if (!writer) writer = new Serializer(std::cout); if (tree) tree->Do(writer); } if (tree) { tree = Normalize(tree); } else { if (options.doDiff) { files[file] = SourceFile (file, NULL, NULL, NULL); hadError = false; } } // Create new symbol table for the file, or clear it if we had one Context *ctx = MAIN->context; Context *savedCtx = ctx; Symbols *syms = MAIN->globals; Symbols *savedSyms = syms; if (sf.context) { updateContext = false; ctx = sf.context; syms = sf.symbols; ctx->Clear(); syms->Clear(); } else { ctx = new Context(ctx, NULL); syms = new Symbols(syms); syms->name = file; } MAIN->context = ctx; MAIN->globals = syms; syms->is_global = true; // Connect imports if any if (importContext) importContext->Import(ctx); if (importSymbols) importSymbols->Import(syms); // HACK - do not hide imported .xl if (file.find(".ddd") == file.npos && file.find("tao.xl") == file.npos && file.find("builtins.xl") == file.npos) { Name_p module_file = new Name("module_file"); // TODO: Position Name_p module_dir = new Name("module_dir"); Text_p module_file_value = new Text(file); Text_p module_dir_value = new Text(ParentDir(file)); ctx->Define(module_file, module_file_value); ctx->Define(module_dir, module_dir_value); syms->EnterName(module_file->value, module_file_value,Rewrite::LOCAL); syms->EnterName(module_dir->value, module_dir_value,Rewrite::LOCAL); } // Register the source file we had sf = SourceFile (file, tree, ctx, syms); if (tree) { // Set symbols and compile if required if (!options.parseOnly) { if (options.optimize_level == 1) { tree->SetSymbols(syms); if (!tree) hadError = true; else files[file].tree = tree; syms->ProcessDeclarations(tree); } // TODO: At -O3, do we need to do anything here? } // Graph of the input tree if (options.showGV) { SetNodeIdAction sni; BreadthFirstSearch<SetNodeIdAction> bfs(sni); tree->Do(bfs); GvOutput gvout(std::cout); tree->Do(gvout); } } if (options.showSource) std::cout << tree << "\n"; if (options.verbose) debugp(tree); // Decide if we update symbols for next run if (!updateContext) { MAIN->context = savedCtx; MAIN->globals = savedSyms; } IFTRACE(symbols) std::cerr << "Loaded file " << file << " with context " << MAIN->context << '\n'; return hadError; }