changes made after tupshins reconstruction
authoradam <adam@megacz.com>
Fri, 30 Jan 2004 11:05:27 +0000 (11:05 +0000)
committeradam <adam@megacz.com>
Fri, 30 Jan 2004 11:05:27 +0000 (11:05 +0000)
darcs-hash:20040130110527-5007d-2b15423f0b601c2acb2d59befd2bd678d148e76f.gz

17 files changed:
Makefile
Makefile.upstream
next.build
src/org/xwt/Font.java
src/org/xwt/HTTP.java
src/org/xwt/Stream.java
src/org/xwt/Template.java
src/org/xwt/XMLRPC.java
src/org/xwt/XWT.java
src/org/xwt/js/Interpreter.java
src/org/xwt/js/Lexer.java
src/org/xwt/js/Parser.java
src/org/xwt/js/Tokens.java
src/org/xwt/translators/Freetype.java
src/org/xwt/util/Log.java
src/org/xwt/util/Queue.java
src/org/xwt/util/XML.java

index fc29a6a..9f13b38 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -80,11 +80,13 @@ java_sources              += build/java/org/xwt/mips/util/SeekableData.java
 java_sources              += build/java/org/xwt/mips/util/SeekableFile.java
 java_sources              += build/java/org/xwt/mips/util/SeekableInputStream.java
 
-build/java/org/xwt/mips/util/%: .install_mips2java
+build/java/org/xwt/mips/util/%:
+       @test -e .install_mips2java || make .install_mips2java
        @echo linking $@
        @mkdir -p $(@D)
        @cd $(@D); ln -sf ../../../../../../upstream/mips/org/xwt/mips/util/$*
-build/java/org/xwt/mips/%: .install_mips2java
+build/java/org/xwt/mips/%:
+       @test -e .install_mips2java || make .install_mips2java
        @echo linking $@
        @mkdir -p $(@D)
        @test -e upstream/mips/build/org/xwt/mips/$* && (cd $(@D); \
@@ -100,7 +102,7 @@ build/class/org/xwt/translators/MIPSApps.class: build/mips/mipsapps.mips .jikes
        @echo -e "\n\033[1mtranslating        .mips -> .java:  $<\033[0m"
        (echo -e 'package org.xwt.translators;\nimport org.xwt.mips.*;\n';                           \
         java -Xint -cp upstream/mips/build org.xwt.mips.Compiler MIPSApps build/mips/mipsapps.mips) \
-        | sed 's,//.*$$,,;'| tr -d '\n') > build/java/org/xwt/translators/MIPSApps.java
+        | sed 's,//.*$$,,;'| tr -d '\n' > build/java/org/xwt/translators/MIPSApps.java
        @echo -e "\n\033[1mcompiling          .java -> .class: $<\033[0m"
        ./.jikes -g:none build/java/org/xwt/translators/MIPSApps.java
 
@@ -127,13 +129,13 @@ compile: .compile
        @./.jikes $(java_sources)
        touch .compile
 
-build/JVM/xwt.jar: .compile build/res/builtin.jar
+build/JVM/xwt.jar: .compile build/res/builtin.jar build/class/org/xwt/translators/MIPSApps.class
        @echo -e "\n\033[1marchiving         .class -> .jar:   build/JVM/xwt.jar\033[0m"
        mkdir -p build/JVM
        echo -e "Manifest-Version: 1.0\nMain-Class: org.xwt.Main\n" > build/JVM/.manifest
        cd build/class/org/xwt; ln -sf ../../../res/builtin.jar
        cd build/class; $(jar) cfm ../JVM/xwt.jar ../JVM/.manifest \
-               `find . \! -type d \! -path './org/xwt/mips/*'` \
+               `find . \! -type d` \
                $(patsubst %,../../upstream/mips/build/org/xwt/mips/%*.class, Runtime Registers Syscalls Errno)
 
 
@@ -238,50 +240,14 @@ build/mips/mipsapps.mips: build/mips/org/xwt/translators/Freetype.c.o build/mips
 
 ### Maintainer ######################################################################################
 
-propose-patch:
-       @echo -n "Please type a one-line description of this bug: "; \
-       read A; \
-       echo; \
-       echo "Please type any additional comments that explain this patch."; \
-        echo "If this patch fixes a bug, include a link to bugs.xwt.org."; \
-        echo "When you are done, press control-d on a new line."; \
-       echo; \
-       (       echo -e "HELO patcher"; \
-               echo -e "MAIL FROM:$(USER)@xwt.org"; \
-               echo -e "RCPT TO: patches@xwt.org"; \
-               echo -e "DATA"; \
-               echo -e "From: $(USER)@xwt.org"; \
-               echo -e "To: patches@xwt.org"; \
-               echo -e "Subject: proposed patch to $(this_branch): $$A"; \
-               echo -e ""; \
-               cat; \
-               echo; \
-               cvs diff -Bud; \
-               echo .; \
-       ) > .message
-       bash -c "cat .message > /dev/tcp/mail.xwt.org/25"     # /dev/tcp is faked by bash; not part of the os
-
 current_build         := $(shell cat next.build)
-this_branch           := $(shell tail -c +2 CVS/Tag 2>/dev/null || echo HEAD)
-this_branch_flag      := $(shell test $(this_branch) = HEAD && echo || echo -r $(this_branch))
-
 strip_$(platform) := upstream/install/$(target)/bin/strip build/$(platform)/$(target_bin) -o 
 strip_JVM       := cp build/$(platform)/$(target_bin)
 install-dist:;     $(strip_$(platform)) /var/www/master.dist.xwt.org/xwt-$(current_build).$(target_bin_extension).unsigned
 dist: compile
-ifneq ($(shell uname -n),megacz.com)
-       echo "***********************************************************"
-       echo "*  This build is $(current_build)                                     *"
-       echo "***********************************************************"
-       cvs commit -m '' > /dev/null     # this will fail if we haven't checked-in since the comment is null; we want this.
-       echo -e 'cd /home/xwt/\nrm -rf xwt\n/usr/bin/cvs -d /cvs co xwt\nnohup make -C xwt dist 2>&1 >> .make-dist.out &\n' |\
-                ssh xwt@xwt.org | grep -v "make...:.\(Entering\|Leaving\).directory"
-else
        (echo -n 0000; (echo "10k16o16i"; cat next.build | tr a-z A-Z; echo "1+f") | dc) | tail --bytes=5 > next.build-
        mv next.build- next.build
        echo -n "Next build will be "; cat next.build
-       cvs update CHANGES; echo -e \n`date +%d-%b`" =========== build $(current_build) ================" >> CHANGES
-       cvs commit -m 'this comment should not appear in CHANGES' next.build CHANGES
        nice -n 19 make all
        make install-dist platform=Win32
        make install-dist platform=Linux
@@ -289,4 +255,4 @@ else
        make install-dist platform=Darwin
        make install-dist platform=JVM
        echo -e "\n\n\n*** DONE ******************************************"
-endif
+
index 69cad46..5f55f76 100644 (file)
@@ -173,6 +173,7 @@ endif
 #      echo '/1 :pserver:cvs@cvs.xwt.org:2401/ A' >> ~/.cvspass
 #      cd upstream; cvs -d :pserver:cvs@cvs.xwt.org:/ co mips
        cd upstream/mips/upstream; ln -sf `cd ../..; pwd`/install
+       touch $@
 
 .install_mips2java: .download_mips2java
        (cd upstream/mips; make)
index 2f35f09..0c68705 100644 (file)
@@ -1 +1 @@
-07DD
+07DF
index ed979b7..ae9a7d3 100644 (file)
@@ -71,6 +71,8 @@ public class Font {
                 glyphs[c] = g;
             }
             if (!g.isLoaded) {
+                //Log.debug(Font.class, "rasterizeGlyphs encountered unrasterized glyph " + g.c + " of font " + this);
+                //System.out.println("rasterizeGlyphs encountered unrasterized glyph " + g.c + " of font " + this);
                 glyphsToBeRendered.prepend(g);              // even if it's already in the queue, boost its priority
                 encounteredUnrenderedGlyph = true;
             } else if (!encounteredUnrenderedGlyph) {
@@ -121,6 +123,7 @@ public class Font {
     static final Scheduler.Task glyphRenderingTask = new Scheduler.Task() { public void perform() {
         Glyph g = (Glyph)glyphsToBeRendered.remove(false);
         if (g == null) { glyphRenderingTaskIsScheduled = false; return; }
+        Log.debug(Font.class, "glyphRenderingTask dequeued glyph " + g.c + " of font " + g.font);
         if (g.isLoaded) { perform(); /* tailcall to the next glyph */ return; }
         Log.debug(Glyph.class, "rendering glyph " + g.c);
         try { freetype.renderGlyph(g); } catch (IOException e) { Log.info(Freetype.class, e); }
index d94edc6..427fc70 100644 (file)
@@ -781,7 +781,7 @@ public class HTTP {
                 Scheduler.add(new Scheduler.Task() {
                         public void perform() throws Exception {
                             Box b = new Box();
-                            Template t = new Template(Stream.getInputStream((JS)Main.builtin.get("org/xwt/builtin/proxy_authorization.xwt")), new XWT(null));
+                            Template t = Template.buildTemplate(Stream.getInputStream((JS)Main.builtin.get("org/xwt/builtin/proxy_authorization.xwt")), new XWT(null));
                             t.apply(b);
                             b.put("realm", realm);
                             b.put("proxyIP", proxyIP);
index c28b070..3d847e8 100644 (file)
@@ -34,6 +34,7 @@ public abstract class Stream extends JS.Cloneable {
     /** HTTP or HTTPS resource */
     public static class HTTP extends Stream {
         private String url;
+        public String toString() { return "Stream.HTTP:" + url; }
         HTTP(String url) { while (url.endsWith("/")) url = url.substring(0, url.length() - 1); this.url = url; }
         public Object get(Object key) throws JSExn { return new HTTP(url + "/" + (String)key); }
         public String getCacheKey(Vec path) throws NotCacheableException { return url; }
index 40648f6..2cc6242 100644 (file)
@@ -30,15 +30,12 @@ public class Template {
     String redirect = null;             ///< the id of the redirect target; only meaningful on a root node
     private String[] keys;              ///< keys to be "put" to instances of this template; elements correspond to those of vals
     private Object[] vals;              ///< values to be "put" to instances of this template; elements correspond to those of keys
+    private String[] urikeys;
+    private String[] urivals;
     private Vec children = new Vec();   ///< during XML parsing, this holds the list of currently-parsed children; null otherwise
     private JS script = null;           ///< the script on this node
-    private String tagname = null;      ///< template to preapply (if any)
-
-
-    // Instance Members that are only meaningful on root Template //////////////////////////////////////
-
-    private JSScope staticScope = null;   ///< the scope in which the static block is executed
-    private JS staticscript = null;       ///< the script on the static node of this template, null already performed
+    Template prev;
+    JSScope staticScope = null;   ///< the scope in which the static block is executed
 
 
     // Only used during parsing /////////////////////////////////////////////////////////////////
@@ -52,24 +49,13 @@ public class Template {
     // Static data/methods ///////////////////////////////////////////////////////////////////
 
     // for non-root nodes
+    private Template(Template t, int startLine) { prev = t; this.xwt = t.xwt; this.startLine = startLine; }
     private Template(XWT xwt) { this.xwt = xwt; }
-    public Template(InputStream is, XWT xwt) throws IOException, JSExn, XML.Exn {
-        this.xwt = xwt; new TemplateHelper().parseit(is, this);
-    }
     
 
     // Methods to apply templates ////////////////////////////////////////////////////////
 
-    /** called before this template is applied or its static object can be externally referenced */
-    JSScope getStatic() throws JSExn {
-        if (staticScope == null) staticScope = new PerInstantiationScope(null, xwt, null, null);
-        if (staticscript == null) return staticScope;
-        JS temp = staticscript;
-        staticscript = null;
-        JS.cloneWithNewParentScope(temp, staticScope).call(null, null, null, null, 0);
-        return staticScope;
-    }
-    
+   
     /** Applies the template to Box b
      *  @param pboxes a vector of all box parents on which to put $-references
      *  @param ptemplates a vector of the fileNames to recieve private references on the pboxes
@@ -91,13 +77,16 @@ public class Template {
     }
 
     private void apply(Box b, PerInstantiationScope parentPis) throws JSExn, IOException {
-        getStatic();
+        if (prev != null) prev.apply(b, null);
 
         // FIXME this dollar stuff is all wrong
         if (id != null) parentPis.putDollar(id, b);
-        if (tagname != null) xwt.resolveString(tagname, false).call(b, null, null, null, 1);
 
         PerInstantiationScope pis = new PerInstantiationScope(b, xwt, parentPis, staticScope);
+        for(int i=0; i<urikeys.length; i++) {
+            pis.declare(urikeys[i]);
+            pis.put(urikeys[i], xwt.resolveString(urivals[i], true));
+        }
 
         // FIXME needs to obey the new application-ordering rules
         for (int i=0; children != null && i<children.size(); i++) {
@@ -137,82 +126,91 @@ public class Template {
 
     // XML Parsing /////////////////////////////////////////////////////////////////
 
+    public static Template buildTemplate(InputStream is, XWT xwt) {
+        try {
+            return new TemplateHelper(is, xwt).t;
+        } catch (Exception e) {
+            Log.error(Template.class, e);
+            return null;
+        }
+    }
+
     /** handles XML parsing; builds a Template tree as it goes */
     static final class TemplateHelper extends XML {
 
-        TemplateHelper() { }
-
-        private int state;
+        private int state = STATE_INITIAL;
         private static final int STATE_INITIAL = 0;
         private static final int STATE_IN_XWT_NODE = 1;
-        private static final int STATE_IN_TEMPLATE_NODE = 2;
-        private static final int STATE_FINISHED_TEMPLATE_NODE = 3;
+        private static final int STATE_IN_TEMPLATE_NODE = 2; 
+        private static final int STATE_IN_META_NODE = 3;
 
-        private String nameOfHeaderNodeBeingProcessed;
+        StringBuffer static_content = null;
+        int static_content_start = 0;
+        Vec nodeStack = new Vec();
+        Template t = null;
+        int meta = 0;
+        XWT xwt;
 
-        Vec nodeStack = new Vec();  ///< stack of Templates whose XML elements we have seen open-tags for but not close-tags
-        Template t = null;          ///< the template we're currently working on
+        public TemplateHelper(InputStream is, XWT xwt) throws XML.Exn, IOException, JSExn {
+            this.xwt = xwt;
+            parse(new InputStreamReader(is));
+            JS staticScript = parseScript(static_content, static_content_start);
+            t.staticScope = new PerInstantiationScope(null, xwt, null, null);
+            if (staticScript != null) JS.cloneWithNewParentScope(staticScript, t.staticScope).call(null, null, null, null, 0);
+        }
 
-        /** parse an XML input stream, building a Template tree off of <tt>root</tt> */
-        void parseit(InputStream is, Template root) throws XML.Exn, IOException {
-            state = STATE_INITIAL;
-            nameOfHeaderNodeBeingProcessed = null;
-            nodeStack.setSize(0);
-            t = root;
-            parse(new InputStreamReader(is)); 
+        private JS parseScript(StringBuffer content, int content_start) throws IOException {
+            if (content == null) return null;
+            String contentString = content.toString();
+            if (contentString.trim().length() > 0) return JS.fromReader("FIXME", content_start, new StringReader(contentString));
+            return null;
         }
 
         public void startElement(XML.Element c) throws XML.Exn {
             switch(state) {
-            case STATE_INITIAL:
-                if (!"xwt".equals(c.getLocalName()))
-                    throw new XML.Exn("root element was not <xwt>", XML.Exn.SCHEMA, getLine(), getCol());
-                if (c.getAttrLen() != 0)
-                    throw new XML.Exn("root element must not have attributes", XML.Exn.SCHEMA, getLine(), getCol());
-                state = STATE_IN_XWT_NODE;
-                return;
-
-            case STATE_IN_XWT_NODE:
-                if (nameOfHeaderNodeBeingProcessed != null)
-                    throw new XML.Exn("can't nest header nodes", XML.Exn.SCHEMA, getLine(), getCol());
-                nameOfHeaderNodeBeingProcessed = c.getLocalName();
-                //#switch(c.getLocalName())
-                case "doc":
-                    // FEATURE
+                case STATE_IN_META_NODE: { meta++; return; }
+                case STATE_INITIAL:
+                    if (!"ibex".equals(c.getLocalName()))
+                        throw new XML.Exn("root element was not <ibex>", XML.Exn.SCHEMA, getLine(), getCol());
+                    if (c.getAttrLen() != 0)
+                        throw new XML.Exn("root element must not have attributes", XML.Exn.SCHEMA, getLine(), getCol());
+                    state = STATE_IN_XWT_NODE;
                     return;
-                case "static":
-                    if (t.staticscript != null)
-                        throw new XML.Exn("the <static> header node may only appear once", XML.Exn.SCHEMA, getLine(), getCol());
-                    if (c.getAttrLen() > 0)
-                        throw new XML.Exn("the <static> node may not have attributes", XML.Exn.SCHEMA, getLine(), getCol());
-                    return;
-                case "template":
-                    t.startLine = getLine();
+                case STATE_IN_XWT_NODE:
+                    if ("meta".equals(c.getPrefix())) { state = STATE_IN_META_NODE; meta = 0; return; }
                     state = STATE_IN_TEMPLATE_NODE;
-                    processBodyElement(c);
-                    return;
-                //#end
-                throw new XML.Exn("unrecognized header node \"" + c.getLocalName() + "\"", XML.Exn.SCHEMA, getLine(), getCol());
-
-            case STATE_IN_TEMPLATE_NODE:
-                // push the last node we were in onto the stack
-                nodeStack.addElement(t);
-                // instantiate a new node, and set its fileName/importlist/preapply
-                Template t2 = new Template(t.xwt);
-                t2.startLine = getLine();
-                if (!c.getLocalName().equals("box") && !c.getLocalName().equals("template"))
-                    t2.tagname = ((c.getUri().equals("") ? "" : (c.getUri() + ".")) + c.getLocalName());
-                // make the new node the current node
-                t = t2;
-                processBodyElement(c);
-                return;
-
-            case STATE_FINISHED_TEMPLATE_NODE:
-                throw new XML.Exn("no elements may appear after the <template> node", XML.Exn.SCHEMA, getLine(), getCol());
+                    t = (t == null) ? new Template(xwt) : new Template(t, getLine());
+                    break;
+                case STATE_IN_TEMPLATE_NODE:
+                    nodeStack.addElement(t);
+                    t = new Template(xwt);
+                    break;
             }
-        }        
 
-        private void processBodyElement(XML.Element c) {
+            if (!("ui".equals(c.getPrefix()) && "box".equals(c.getLocalName()))) {
+                String tagname = (c.getUri().equals("") ? "" : (c.getUri() + ".")) + c.getLocalName();
+                // GROSS hack
+                try {
+                    t.prev = (Template)t.xwt.resolveString(tagname, false).call(null, null, null, null, 9999);
+                } catch (Exception e) {
+                    Log.error(Template.class, e);
+                }
+            }
+                
+            Hash urimap = c.getUriMap();
+            t.urikeys = new String[urimap.size()];
+            t.urivals = new String[urimap.size()];
+            Enumeration uriEnumeration = urimap.keys();
+            int ii = 0;
+            while(uriEnumeration.hasMoreElements()) {
+                String key = (String)uriEnumeration.nextElement();
+                String val = (String)urimap.get(key);
+                t.urikeys[ii] = key;
+                if (val.charAt(0) == '.') val = val.substring(1);
+                t.urivals[ii] = val;
+                ii++;
+            }
+            
             Vec keys = new Vec(c.getAttrLen());
             Vec vals = new Vec(c.getAttrLen());
 
@@ -268,55 +266,41 @@ public class Template {
             }
         }
 
-        private JS parseScript(boolean isstatic) throws IOException {
-            JS thisscript = null;
-            String contentString = t.content.toString();
-            if (contentString.trim().length() > 0)
-                thisscript = JS.fromReader("FIXME", t.content_start, new StringReader(contentString));
-            t.content = null;
-            t.content_start = 0;
-            return thisscript;
-        }
-
         public void endElement(XML.Element c) throws XML.Exn, IOException {
-            if (state == STATE_IN_XWT_NODE) {
-                if ("static".equals(nameOfHeaderNodeBeingProcessed) && t.content != null) t.staticscript = parseScript(true);
-                nameOfHeaderNodeBeingProcessed = null;
-                
-            } else if (state == STATE_IN_TEMPLATE_NODE) {
-                if (t.content != null) t.script = parseScript(false);
-                if (nodeStack.size() == 0) {
-                    // </template>
-                    state = STATE_FINISHED_TEMPLATE_NODE;
-                    
-                } else {
-                    // add this template as a child of its parent
+            switch(state) {
+                case STATE_IN_META_NODE: if (meta-- < 0) state = STATE_IN_XWT_NODE; return;
+                case STATE_IN_XWT_NODE: return;
+                case STATE_IN_TEMPLATE_NODE: {
+                    if (t.content != null) { t.script = parseScript(t.content, t.content_start); t.content = null; }
+                    if (nodeStack.size() == 0) { state = STATE_IN_XWT_NODE; return; }
                     Template oldt = t;
                     t = (Template)nodeStack.lastElement();
                     nodeStack.setSize(nodeStack.size() - 1);
                     t.children.addElement(oldt);
-
                     int oldt_lines = getLine() - oldt.startLine;
                     for (int i=0; oldt_lines > i; i++) t.content.append('\n');
                 }
             }
-         }
+        }
 
         public void characters(char[] ch, int start, int length) throws XML.Exn {
-            // invoke the no-tab crusade
             for (int i=0; length >i; i++) if (ch[start+i] == '\t')
                 Log.error(Template.class, "tabs are not allowed in XWT files ("+getLine()+":"+getCol()+")");
-
-            if ("static".equals(nameOfHeaderNodeBeingProcessed) || state == STATE_IN_TEMPLATE_NODE) {
-                if (t.content == null) {
-                    t.content_start = getLine();
-                    t.content = new StringBuffer();
-                }
-
-                t.content.append(ch, start, length);
-
-            } else if (nameOfHeaderNodeBeingProcessed != null && state != STATE_FINISHED_TEMPLATE_NODE) { throw new XML.Exn(
-                "header node <" +nameOfHeaderNodeBeingProcessed+ "> cannot have text content", XML.Exn.SCHEMA, getLine(), getCol());
+            switch(state) {
+                case STATE_IN_TEMPLATE_NODE:
+                    if (t.content == null) {
+                        t.content_start = getLine();
+                        t.content = new StringBuffer();
+                    }
+                    t.content.append(ch, start, length);
+                    return;
+                case STATE_IN_XWT_NODE:
+                    if (static_content == null) {
+                        static_content_start = getLine();
+                        static_content = new StringBuffer();
+                    }
+                    static_content.append(ch, start, length);
+                    return;
             }
         }
 
@@ -345,10 +329,6 @@ public class Template {
             if (key.equals("static")) return myStatic;
             return super.get(key);
         }
-        public void put(Object key, Object val) throws JSExn {
-            if (super.has(key)) super.put(key, val);
-            else super.put(key, val);
-        }
     }
 
 }
index 2bb107c..f78936a 100644 (file)
@@ -315,12 +315,12 @@ class XMLRPC extends JS {
     final void call(final JS.UnpauseCallback callback, final JSArray args) {
         try {
             if (Log.verbose) Log.info(this, "call to " + url + " : " + method);
+            if (tracker == null) tracker = new Hash();
+            if (objects == null) objects = new Vec();
             String request = buildRequest(args);
             if (Log.verbose) Log.info(this, "send:\n" + request);
             InputStream is = http.POST("text/xml", request);
             BufferedReader br = new BufferedReader(new InputStreamReader(is));
-            if (tracker == null) tracker = new Hash();
-            if (objects == null) objects = new Vec();
             try {
                 new Helper().parse(br);
                 final Object result = fault ? new JSExn(objects.elementAt(0)) : objects.size() == 0 ? null : objects.elementAt(0);
index d792776..e5c443f 100644 (file)
@@ -23,7 +23,9 @@ public final class XWT extends JS.Cloneable {
             throw new JSExn("absolute URL " + str + " not permitted here");
         }
         // root-relative
-        JS ret = (JS)getAndTriggerTraps("");
+        //JS ret = (JS)getAndTriggerTraps("");
+        //FIXME
+        JS ret = rr;
         while(str.indexOf('.') != -1) {
             String path = str.substring(0, str.indexOf('.'));
             str = str.substring(str.indexOf('.') + 1);
@@ -338,14 +340,16 @@ public final class XWT extends JS.Cloneable {
         public JSScope getStatic() {
             try {
                 // FIXME background?
-                if (t == null) t = new Template(Stream.getInputStream(parent.get(parentkey + ".xwt")), xwt);
-                return t.getStatic();
+                if (t == null) t = Template.buildTemplate(Stream.getInputStream(parent.get(parentkey + ".xwt")), xwt);
+                return t.staticScope;
             } catch (Exception e) {
                 Log.error(this, e);
                 return null;
             }
         }
         public Object call(Object a, Object b, Object c, Object[] rest, int nargs) throws JSExn {
+            // GROSS hack
+            if (nargs == 9999) return t;
             if (nargs != 1) throw new JSExn("FIXME can only call with one arg");
             getStatic();
             t.apply((Box)a);
index 359b844..b5becd0 100644 (file)
@@ -389,24 +389,27 @@ class Interpreter implements ByteCodes, Tokens {
                 break;
             }
 
+            case ADD_TRAP: case DEL_TRAP: {
+                Object val = stack.pop();
+                Object key = stack.pop();
+                Object obj = stack.peek();
+                // A trap addition/removal
+                JS js = obj instanceof JSScope ? ((JSScope)obj).top() : (JS) obj;
+                if(op == ADD_TRAP) js.addTrap(key, (JSFunction)val);
+                else js.delTrap(key, (JSFunction)val);
+                break;
+            }
+
             case ASSIGN_SUB: case ASSIGN_ADD: {
                 Object val = stack.pop();
                 Object key = stack.pop();
                 Object obj = stack.peek();
-                if (val instanceof JSFunction && obj instanceof JS) {
-                    // A trap addition/removal
-                    JS js = obj instanceof JSScope ? ((JSScope)obj).top() : (JS) obj;
-                    if(op == ASSIGN_ADD) js.addTrap(key, (JSFunction)val);
-                    else js.delTrap(key, (JSFunction)val);
-                    pc += ((Integer)arg).intValue() - 1;
-                } else {
-                    // The following setup is VERY important. The generated bytecode depends on the stack
-                    // being setup like this (top to bottom) KEY, OBJ, VAL, KEY, OBJ
-                    stack.push(key);
-                    stack.push(val);
-                    stack.push(obj);
-                    stack.push(key);
-                }
+                // The following setup is VERY important. The generated bytecode depends on the stack
+                // being setup like this (top to bottom) KEY, OBJ, VAL, KEY, OBJ
+                stack.push(key);
+                stack.push(val);
+                stack.push(obj);
+                stack.push(key);
                 break;
             }
 
index af0e8ef..0bf311f 100644 (file)
@@ -275,8 +275,8 @@ class Lexer implements Tokens {
         case '!': return !in.match('=') ? BANG : in.match('=') ? SHNE : NE;
         case '%': return in.match('=') ? ASSIGN_MOD : MOD;
         case '~': return BITNOT;
-        case '+': return in.match('=') ? ASSIGN_ADD : in.match('+') ? INC : ADD;
-        case '-': return in.match('=') ? ASSIGN_SUB: in.match('-') ? DEC : SUB;
+        case '+': return in.match('=') ? ASSIGN_ADD : in.match('+') ? (in.match('=') ? ADD_TRAP : INC) : ADD;
+        case '-': return in.match('=') ? ASSIGN_SUB: in.match('-') ? (in.match('=') ? DEL_TRAP : DEC) : SUB;
         case '*': return in.match('=') ? ASSIGN_MUL : MUL;
         case '<': return !in.match('<') ? (in.match('=') ? LE : LT) : in.match('=') ? ASSIGN_LSH : LSH;
         case '>': return !in.match('>') ? (in.match('=') ? GE : GT) :
index bffeeb4..1914cc7 100644 (file)
@@ -97,7 +97,10 @@ class Parser extends Lexer implements ByteCodes {
             isRightAssociative[ASSIGN_SUB] =
             isRightAssociative[ASSIGN_MUL] =
             isRightAssociative[ASSIGN_DIV] =
-            isRightAssociative[ASSIGN_MOD] = true;
+            isRightAssociative[ASSIGN_MOD] =
+            isRightAssociative[ADD_TRAP] =
+            isRightAssociative[DEL_TRAP] =
+            true;
 
         precedence[COMMA] = 1;
         // 2 is intentionally left unassigned. we use minPrecedence==2 for comma separated lists
@@ -112,6 +115,8 @@ class Parser extends Lexer implements ByteCodes {
             precedence[ASSIGN_SUB] =
             precedence[ASSIGN_MUL] =
             precedence[ASSIGN_DIV] =
+            precedence[ADD_TRAP] =
+            precedence[DEL_TRAP] =
             precedence[ASSIGN_MOD] = 3;
         precedence[HOOK] = 4;
         precedence[OR] = 5;
@@ -380,25 +385,22 @@ class Parser extends Lexer implements ByteCodes {
         }
 
         case ASSIGN_BITOR: case ASSIGN_BITXOR: case ASSIGN_BITAND: case ASSIGN_LSH: case ASSIGN_RSH: case ASSIGN_URSH:
-        case ASSIGN_MUL: case ASSIGN_DIV: case ASSIGN_MOD: case ASSIGN_ADD: case ASSIGN_SUB: {
-            if (tok != ASSIGN_ADD && tok != ASSIGN_SUB) b.add(parserLine, GET_PRESERVE);
+        case ASSIGN_MUL: case ASSIGN_DIV: case ASSIGN_MOD: case ASSIGN_ADD: case ASSIGN_SUB: case ADD_TRAP: case DEL_TRAP: {
+            if (tok != ADD_TRAP && tok != DEL_TRAP) b.add(parserLine, GET_PRESERVE);
             
             startExpr(b,  precedence[tok]);
             
             int size = b.size;
-            if (tok == ASSIGN_ADD || tok == ASSIGN_SUB) {
-                b.add(parserLine, tok);
-                b.add(parserLine, GET);
+            
+            if (tok != ADD_TRAP && tok != DEL_TRAP) {
+                // tok-1 is always s/^ASSIGN_// (0 is BITOR, 1 is ASSIGN_BITOR, etc) 
+                b.add(parserLine, tok - 1, tok-1==ADD ? JS.N(2) : null);
+                b.add(parserLine, PUT);
                 b.add(parserLine, SWAP);
+                b.add(parserLine, POP);
+            } else {
+                b.add(parserLine, tok);
             }
-            
-            // tok-1 is always s/^ASSIGN_// (0 is BITOR, 1 is ASSIGN_BITOR, etc) 
-            b.add(parserLine, tok - 1, tok-1==ADD ? JS.N(2) : null);
-            b.add(parserLine, PUT);
-            b.add(parserLine, SWAP);
-            b.add(parserLine, POP);
-            
-            if (tok == ASSIGN_ADD || tok == ASSIGN_SUB) b.set(size, tok, JS.N(b.size - size));
             break;
         }
         case INC: case DEC: { // postfix
index a9d5adb..28e57af 100644 (file)
@@ -94,8 +94,10 @@ interface Tokens {
     public static final int FINALLY       = 76;  // finally keyword
     public static final int RESERVED      = 77;  // reserved keyword
     public static final int GRAMMAR       = 78;  // the grammar-definition operator (::=)
+    public static final int ADD_TRAP      = 79;  // the add-trap operator (++=)
+    public static final int DEL_TRAP      = 80;  // the del-trap operator (--=)
  
-    public static final int MAX_TOKEN = GRAMMAR;
+    public static final int MAX_TOKEN = DEL_TRAP;
 
     public final static String[] codeToString = new String[] {
         "BITOR", "ASSIGN_BITOR", "BITXOR", "ASSIGN_BITXOR", "BITAND",
@@ -109,7 +111,8 @@ interface Tokens {
         "SEMI", "LB", "RB", "LC", "RC", "LP", "RP", "COMMA", "ASSIGN",
         "HOOK", "COLON", "INC", "DEC", "DOT", "FUNCTION", "IF",
         "ELSE", "SWITCH", "CASE", "DEFAULT", "WHILE", "DO", "FOR",
-        "VAR", "WITH", "CATCH", "FINALLY", "RESERVED", "GRAMMAR"
+        "VAR", "WITH", "CATCH", "FINALLY", "RESERVED", "GRAMMAR",
+        "ADD_TRAP", "DEL_TRAP"
     };
 
 }
index 8665998..c8406db 100644 (file)
@@ -40,6 +40,7 @@ public class Freetype {
 
     public synchronized void renderGlyph(Font.Glyph glyph) throws IOException {
         try {
+            Log.debug(this, "rasterizing glyph " + glyph.c + " of font " + glyph.font);
             if (loadedStream != glyph.font.stream) loadFontByteStream(glyph.font.stream);
             vm.setUserInfo(2, (int)glyph.c);
             vm.setUserInfo(3, (int)glyph.c);
index 03c5a52..ad266a0 100644 (file)
@@ -126,7 +126,7 @@ public class Log {
         switch (level) {
             case DIAGNOSTIC:  levelcolor = GREEN; bright = false; break;
             case ECHO:        levelcolor = BLUE;  bright = true;  break;
-            case DEBUG:       levelcolor = BLACK; bright = true;  break;
+            case DEBUG:       levelcolor = BROWN; bright = true;  break;
             case INFO:        levelcolor = GRAY;  bright = false; break;
             case WARN:        levelcolor = BROWN; bright = false; break;
             case ERROR:       levelcolor = RED;   bright = true;  break;
index eb36a4d..8da10d4 100644 (file)
@@ -71,13 +71,10 @@ public class Queue {
     public synchronized Object remove(boolean block) {
 
         while (size == 0 && block) {
-            try {
-                wait();
-            } catch (InterruptedException e) {
-            }
+            try { wait(); } catch (InterruptedException e) { }
         }
         
-        if (!block) return null;
+        if (!block && size == 0) return null;
         Object ret = vec[first];
         first++;
         size--;
index 3c9d31a..e3d0b14 100644 (file)
@@ -787,6 +787,8 @@ public abstract class XML
         /** Prefix of current element. Substring of qName. XML Namespace Spec 14-Jan-1999 [7] */
         public String getPrefix() { return prefix; }
 
+        public Hash getUriMap() { return urimap; } // HACK
+
         /** URI of current tag. XML Namespace Spec 14-Jan-1999 section 1 */
         public String getUri() { return getUri(prefix); }