This is the mail archive of the kawa@sources.redhat.com mailing list for the Kawa project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Kawa's compilation of XQuery


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/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]