Subject: [OpenJade] defining primitives in scheme From: Matthias Clasen <clasen@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx> Date: Tue, 15 Jun 1999 21:13:01 +0200 |
OK, you voted for seeing the Jade-technical discussions, now get it :-) Here is an experimental patch (against stock jade-1.2.1) for supporting scheme primitives in Jade. This is not completely trivial, since the standard demands that any primitives can be redefined in stylesheets. But this must not influence their behaviour when used to implement primitives in scheme. The patch below achieves this by making Identifiers potentially have two values, a builtin one and a redefined one. If the value of a scheme primitive is computed, the builtin definition is used, even if it has been overriden by a redefinition for normal uses. This is definitively not production quality (see FIXME's in the code), but it seems to work for me on simple examples. If you want to try it, put a file "derived.dsl" containing dsssl definitions to be preloaded into the current directory. A simple test: -------- derived.dsl -------------- (define cde car) (define abc cde) -------- test.sgml ----------------- <!doctype foo [ <!element foo - o any> ]> <foo> -------- test.dsssl ------------------ <!DOCTYPE style-sheet PUBLIC "-//James Clark//DTD DSSSL Style Sheet//EN" []> <style-sheet> (define cde cdr) (define car cdr) (element foo (make sequence (literal (abc (cons "a" "b"))) ;; expected output: "a" (literal (cde (cons "a" "b"))) ;; expected output: "b" )) </style-sheet> ---------------------------------------- --- Interpreter.h.orig Tue Jun 15 20:14:12 1999 +++ Interpreter.h Tue Jun 15 20:20:25 1999 @@ -194,6 +194,9 @@ ConstPtr<InheritedC> inheritedC_; unsigned inheritedCPart_; Location inheritedCLoc_; + void maybeSaveBuiltin(); + Identifier *builtin_; + static int preferBuiltin_; }; class Unit : public Named { @@ -365,6 +368,7 @@ void installPortNames(); void installCValueSymbols(); void installPrimitives(); + void installDerived(); void installPrimitive(const char *s, PrimitiveObj *value); void installXPrimitive(const char *s, PrimitiveObj *value); void installUnits(); --- Interpreter.cxx.orig Tue Jun 15 20:14:23 1999 +++ Interpreter.cxx Tue Jun 15 20:25:51 1999 @@ -100,6 +100,8 @@ for (size_t i = 0; i < SIZEOF(lexCategories); i++) for (const char *s = lexCategories[i]; *s; s++) lexCategory_.setChar(*s, i); + // can't do this before installing lexical categories + installDerived(); initialProcessingMode_.setDefined(); } @@ -413,6 +415,36 @@ } } +void Interpreter::installDerived() +{ + StringC str; + int c; + // FIXME: this is not the proper way to turn a filename + // into an InputSource. The name should be configurable + // and maybe overridable by an envvar or catalog entry. + FILE *f = fopen("derived.dsl", "r"); + if (f == NULL) + return; + + while ((c = getc(f)) != EOF) + str += c; + + fclose(f); + + Text text_; + text_.clear(); + text_.addChars(str, Location()); + TextInputSourceOrigin *origin = new TextInputSourceOrigin(text_); + + Owner<InputSource> in; + in = new InternalInputSource(origin->text().string(), origin); + + SchemeParser scm(*this, in); + partIndex_ = unsigned(-1); + scm.parse(); + partIndex_ = 1; +} + bool Interpreter::sdataMap(GroveString name, GroveString, GroveChar &c) const { StringC tem(name.data(), name.size()); @@ -1542,15 +1574,30 @@ return h; } +int Identifier::preferBuiltin_ = 0; + Identifier::Identifier(const StringC &name) -: Named(name), value_(0), syntacticKey_(notKey), beingComputed_(0), flowObj_(0) +: Named(name), value_(0), syntacticKey_(notKey), beingComputed_(0), + flowObj_(0), builtin_(0), defPart_(0) { } +void Identifier::maybeSaveBuiltin() +{ + if (defPart_ == unsigned(-1) && !builtin_) { + builtin_ = new Identifier(name()); + if (value_) + builtin_->setValue(value_, defPart_); + else + builtin_->setDefinition(def_, defPart_, defLoc_); + } +} + void Identifier::setDefinition(Owner<Expression> &expr, unsigned part, const Location &loc) { + maybeSaveBuiltin(); def_.swap(expr); defPart_ = part; defLoc_ = loc; @@ -1559,6 +1606,7 @@ void Identifier::setValue(ELObj *value, unsigned partIndex) { + maybeSaveBuiltin(); value_ = value; // Built in functions have lowest priority. defPart_ = partIndex; @@ -1575,8 +1623,12 @@ ELObj *Identifier::computeValue(bool force, Interpreter &interp) const { + if (builtin_ && preferBuiltin_) + return builtin_->computeValue(force, interp); if (value_) return value_; + if (defPart_ == unsigned(-1)) + preferBuiltin_++; ASSERT(def_); if (beingComputed_) { if (force) { @@ -1600,6 +1652,8 @@ } ((Identifier *)this)->beingComputed_ = 0; } + if (defPart_ == unsigned(-1)) + preferBuiltin_--; return value_; } -- Matthias Clasen, Tel. 0761/203-5606 Email: clasen@xxxxxxxxxxxxxxxxxxxxxxxxxx Mathematisches Institut, Albert-Ludwigs-Universitaet Freiburg DSSSList info and archive: http://www.mulberrytech.com/dsssl/dssslist
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: Debian / Jade patches (was Re: , Adam Di Carlo | Thread | Re: Catalogs (was RE: SGML entity m, Ralph Ferris |
Re: page breaks and bottom alignmen, Joerg Wittenberger | Date | Re: page breaks and bottom alignmen, Matthias Clasen |
Month |