This is the mail archive of the
kawa@sources.redhat.com
mailing list for the Kawa project.
Kawa's compilation of XQuery
- To: kawa at sources dot redhat dot com
- Subject: Kawa's compilation of XQuery
- From: Per Bothner <per at bothner dot com>
- Date: 18 Jul 2001 14:34:11 -0700
As I mentioned, I've been adding a new programming language to the
Kawa. This is the new (early-draft) XML Query language from W3C (see
http://www.w3.org/XML/Query). The current implementation is very
limited, and doesn't handle some of the more interesting parts of
XQuery, such as for-expressions. But you might find this teaser
interesting:
let $x:=12,
$y:=(<a>{$x+$x}</a>)
return <b atr1='11' atr2="{$x}">{($y,99,$y)}</b>
When compiled: kawa --main --xquery -C test1.xql
and executed: java test1
you get this output:
<b atr1="11" atr2="12"><a>24</a>99<a>24</a></b>
What is particularly neat (I think) is this dump from test1.class:
Method name:"apply" public final Signature: 97=(gnu.mapping.CallContext)void
Attribute "Code", length:227, max_stack:6, max_locals:6, code_length:157
0: aload_1
1: getfield #6=<Field gnu.mapping.CallContext.consumer gnu.lists.Consumer>
4: astore_2
5: getstatic #12=<Field test1.Lit0 gnu.math.IntNum>
8: astore_3
9: invokestatic #18=<Method gnu.mapping.Values.make ()java.lang.Object>
12: astore 5
14: aload 5
16: dup
17: ldc #20=<String "a">
19: dup
20: invokevirtual #26=<Method java.lang.Object.toString ()java.lang.String>
23: dup_x2
24: swap
25: invokeinterface #32=<InterfaceMethod gnu.lists.Consumer.beginGroup (java.lang.String,java.lang.Object)void> nargs:3
30: aload_3
31: aload_3
32: invokestatic #38=<Method gnu.kawa.functions.AddOp.$Pl (java.lang.Object,java.lang.Object)java.lang.Object>
35: aload 5
37: swap
38: invokeinterface #42=<InterfaceMethod gnu.lists.Consumer.writeObject (java.lang.Object)void> nargs:2
43: invokeinterface #46=<InterfaceMethod gnu.lists.Consumer.endGroup (java.lang.String)void> nargs:2
48: aload 5
50: astore 4
52: aload_2
53: dup
54: ldc #48=<String "b">
56: dup
57: invokevirtual #26=<Method java.lang.Object.toString ()java.lang.String>
60: dup_x2
61: swap
62: invokeinterface #32=<InterfaceMethod gnu.lists.Consumer.beginGroup (java.lang.String,java.lang.Object)void> nargs:3
67: aload_2
68: dup
69: ldc #50=<String "atr1">
71: dup
72: invokevirtual #26=<Method java.lang.Object.toString ()java.lang.String>
75: swap
76: invokeinterface #53=<InterfaceMethod gnu.lists.Consumer.beginAttribute (java.lang.String,java.lang.Object)void> nargs:3
81: getstatic #57=<Field test1.Lit1 gnu.lists.FString>
84: aload_2
85: swap
86: invokeinterface #42=<InterfaceMethod gnu.lists.Consumer.writeObject (java.lang.Object)void> nargs:2
91: invokeinterface #61=<InterfaceMethod gnu.lists.Consumer.endAttribute ()void> nargs:1
96: aload_2
97: dup
98: ldc #63=<String "atr2">
100: dup
101: invokevirtual #26=<Method java.lang.Object.toString ()java.lang.String>
104: swap
105: invokeinterface #53=<InterfaceMethod gnu.lists.Consumer.beginAttribute (java.lang.String,java.lang.Object)void> nargs:3
110: aload_3
111: aload_2
112: swap
113: invokeinterface #42=<InterfaceMethod gnu.lists.Consumer.writeObject (java.lang.Object)void> nargs:2
118: invokeinterface #61=<InterfaceMethod gnu.lists.Consumer.endAttribute ()void> nargs:1
123: aload 4
125: aload_2
126: swap
127: invokeinterface #42=<InterfaceMethod gnu.lists.Consumer.writeObject (java.lang.Object)void> nargs:2
132: getstatic #66=<Field test1.Lit2 gnu.math.IntNum>
135: aload_2
136: swap
137: invokeinterface #42=<InterfaceMethod gnu.lists.Consumer.writeObject (java.lang.Object)void> nargs:2
142: aload 4
144: aload_2
145: swap
146: invokeinterface #42=<InterfaceMethod gnu.lists.Consumer.writeObject (java.lang.Object)void> nargs:2
151: invokeinterface #46=<InterfaceMethod gnu.lists.Consumer.endGroup (java.lang.String)void> nargs:2
156: return
Attribute "LocalVariableTable", length:52, count: 5
slot#0: name: 99=this, type: 100=test1 (pc: 0 length: 157)
slot#1: name: 101=stack, type: 102=gnu.mapping.CallContext (pc: 0 length: 157)
slot#2: name: 103=$result, type: 4=gnu.lists.Consumer (pc: 4 length: 153)
slot#3: name: 104=x, type: 105=java.lang.Object (pc: 8 length: 148)
slot#4: name: 106=y, type: 105=java.lang.Object (pc: 50 length: 106)
Yes, this can be improved (folding the addition of $x+$x when both are
known; there are unneeded swap instructions, etc), but I think it is
pretty good. Some points to note: The <b> element constructor
generates code which doesn't actually create temporary objects.
Instead the element is written to the passed-in Consumer, which is the
standard output file when test1 is run as a stand-alone application.
On the other hand we do need to construct a temporary value for the
<a> element constructor. So the compiler generates a call to
Values.make, where Values extends TreeList. This object is used as
the consumer for evaluating the <a> constructor.
Much of this functionality is implemented using functions
(make-element, make-attribute, append-values) that are callable
from Scheme, but there is no stable Scheme API yet.
--
--Per Bothner
per@bothner.com http://www.bothner.com/per/