|
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 |