====== Language plugins : Implementation ====== ===== parse, print module ===== ==== Background ==== A module is container of instances. To a compiler, a module can also contain code to be executed, but gnucap does not directly support that. A Spice "subckt" is a module. * type -- A module defines a new type. * [[.:label]] -- The label is the name of the new type. * [[.:ports]] -- This is the list of connections. * [[.:args]] -- The arg list is optional. If left out, the arg list is open. It accepts whatever it is fed. ==== parse_module ==== A module is a collection. Parsing it means to parse the header, then the body, then the trailer. Parsing the body is a loop, getting text and calling ''new_''''_instance'' on each pass, until some indication that it is done. It is important to have some kind of guarantee that the loop will exit. /*--------------------------------------------------------------------------*/ MODEL_SUBCKT* LANG_SPECTRE::parse_module(CS& cmd, MODEL_SUBCKT* x) { assert(x); // header cmd.reset(0).skipbl(); cmd >> "subckt "; parse_label(cmd, x); parse_ports(cmd, x); // body for (;;) { cmd.get_line("spectre-subckt>"); if (cmd >> "ends ") { break; }else{ new__instance(cmd, x, x->subckt()); } } return x; } /*--------------------------------------------------------------------------*/ ==== print_module ==== /*--------------------------------------------------------------------------*/ void LANG_SPICE_BASE::print_module(OMSTREAM& o, const MODEL_SUBCKT* x) { assert(x); assert(x->subckt()); o << ".subckt " << x->short_label(); print_ports(o, x); o << '\n'; for (CARD_LIST::const_iterator ci = x->subckt()->begin(); ci != x->subckt()->end(); ++ci) { print_item(o, *ci); } o << ".ends " << x->short_label() << "\n"; } /*--------------------------------------------------------------------------*/ ==== A command to get it started ==== In addition to the above, it is necessary to make a command to recognize a keyword to get it started. It needs to allocate a new ''MODEL_SUBCKT'', parse it, then store it. /*--------------------------------------------------------------------------*/ class CMD_SUBCKT : public CMD { void do_it(CS& cmd, CARD_LIST* Scope) { MODEL_SUBCKT* new_module = new MODEL_SUBCKT; assert(new_module); assert(!new_module->owner()); assert(new_module->subckt()); assert(new_module->subckt()->is_empty()); lang_spectre.parse_module(cmd, new_module); Scope->push_back(new_module); } } p2; DISPATCHER::INSTALL d2(&command_dispatcher, "subckt", &p2); /*--------------------------------------------------------------------------*/