[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.15-1-40151-g37bb677

kocienda kocienda at 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sat Sep 26 05:39:19 UTC 2009


The following commit has been merged in the debian/unstable branch:
commit 66a6d360850d1643dc51807f9c6c0e0029ce3459
Author: kocienda <kocienda at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Aug 24 14:24:45 2001 +0000

    Imported sources from kde-2.2 distribution
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@6 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/JavaScriptCore/kjs/ChangeLog b/JavaScriptCore/kjs/ChangeLog
new file mode 100644
index 0000000..8176cf4
--- /dev/null
+++ b/JavaScriptCore/kjs/ChangeLog
@@ -0,0 +1,24 @@
+2001-01-04  Harri Porten  <harri at trolltech.com>
+
+	* ustring.h: pack bytes to avoid alignment problems (ARM) reported
+	by Stefan Hanske <sh990154 at mail.uni-greifswald.de>
+	* nodes.cpp: typeof fix by Emmeran Seehuber <the_emmy at gmx.de>
+	* nodes.cpp: fixed order of function declaration proccessing
+
+2000-12-18  Harri Porten  <harri at trolltech.com>
+
+	* string_object.cpp: fixed out-of-bounds error in fromCharCode()
+
+2000-12-11  Harri Porten  <harri at trolltech.com>
+
+	* regexp.h: compile fix for buggy libc
+	* ustring.cpp: format string conversion of numbers with %g
+
+2000-12-10  Harri Porten  <harri at trolltech.com>
+
+	* lexer.cpp: parsing != was broken, added \v escape in strings,
+		fixed "\u" and "\x" and \x with non hex chars following.
+	* nodes.cpp: implemented <<=, >>=, >>>=, &=, ^=, |= and %=
+	* internal.cpp: create error message including line no on parse errors
+
+
diff --git a/JavaScriptCore/kjs/Makefile.am b/JavaScriptCore/kjs/Makefile.am
new file mode 100644
index 0000000..1cd1be0
--- /dev/null
+++ b/JavaScriptCore/kjs/Makefile.am
@@ -0,0 +1,66 @@
+#    This file is part of the KDE libraries
+#    Copyright (C) 1999 Harri Porten (porten at kde.org)
+
+#    This library is free software; you can redistribute it and/or
+#    modify it under the terms of the GNU Library General Public
+#    License as published by the Free Software Foundation; either
+#    version 2 of the License, or (at your option) any later version.
+
+#    This library is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#    Library General Public License for more details.
+
+#    You should have received a copy of the GNU Library General Public License
+#    along with this library; see the file COPYING.LIB.  If not, write to
+#    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+#    Boston, MA 02111-1307, USA.
+
+YACC = bison
+INCLUDES = $(all_includes)
+
+lib_LTLIBRARIES = libkjs.la
+
+libkjs_la_SOURCES =  kjs.cpp grammar.cpp lexer.cpp nodes.cpp object.cpp \
+	operations.cpp ustring.cpp function.cpp types.cpp lookup.cpp \
+	internal.cpp regexp.cpp global_object.cpp math_object.cpp \
+	bool_object.cpp object_object.cpp error_object.cpp \
+	array_object.cpp string_object.cpp number_object.cpp \
+	date_object.cpp regexp_object.cpp collector.cpp function_object.cpp \
+	debugger.cpp
+
+kjsincludedir = $(includedir)/kjs
+kjsinclude_HEADERS = kjs.h object.h operations.h ustring.h \
+	function.h lookup.h types.h
+
+noinst_HEADERS = nodes.h lexer.h regexp.h internal.h collector.h \
+	grammar.h object_object.h function_object.h function_object.h \
+	bool_object.h math_object.h array_object.h string_object.h \
+	number_object.h date_object.h regexp_object.h error_object.h \
+	debugger.h
+
+libkjs_la_LDFLAGS = -version-info 1:0 -no-undefined $(USER_LDFLAGS)
+libkjs_la_LIBADD = -lm $(LIBPCRE)
+
+parser: $(srcdir)/grammar.y
+	cd $(srcdir); \
+	$(YACC) -d -p kjsyy grammar.y && mv grammar.tab.c grammar.cpp; \
+	if test -f grammar.tab.h; then \
+	if cmp -s grammar.tab.h grammar.h; then rm -f grammar.tab.h; \
+	else mv grammar.tab.h grammar.h; fi \
+	else :; fi
+
+## with debugger interface
+debugger: $(libkjs_la_SOURCES) $(kjsinclude_HEADERS) $(noinst_HEADERS)
+	$(MAKE) DEFS="-DKJS_DEBUGGER $(DEFS)" libkjs.la
+
+## test program (in one program for easier profiling/memory debugging)
+EXTRA_PROGRAMS = testkjs_static
+testkjs_static_SOURCES = testkjs.cpp  $(libkjs_la_SOURCES)
+testkjs_static_LDADD = $(LIBPCRE)
+
+## test program (linked to libkjs)
+check_PROGRAMS = testkjs
+testkjs_SOURCES = testkjs.cpp
+testkjs_LDADD = libkjs.la
+
diff --git a/JavaScriptCore/kjs/Makefile.in b/JavaScriptCore/kjs/Makefile.in
new file mode 100644
index 0000000..dd601f3
--- /dev/null
+++ b/JavaScriptCore/kjs/Makefile.in
@@ -0,0 +1,738 @@
+# KDE tags expanded automatically by am_edit - $Revision$ 
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+#    This file is part of the KDE libraries
+#    Copyright (C) 1999 Harri Porten (porten at kde.org)
+
+#    This library is free software; you can redistribute it and/or
+#    modify it under the terms of the GNU Library General Public
+#    License as published by the Free Software Foundation; either
+#    version 2 of the License, or (at your option) any later version.
+
+#    This library is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#    Library General Public License for more details.
+
+#    You should have received a copy of the GNU Library General Public License
+#    along with this library; see the file COPYING.LIB.  If not, write to
+#    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+#    Boston, MA 02111-1307, USA.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+#>- 
+bindir = @bindir@
+#>+ 3
+DEPDIR = .deps
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_alias = @build_alias@
+build_triplet = @build@
+host_alias = @host_alias@
+host_triplet = @host@
+target_alias = @target_alias@
+target_triplet = @target@
+ARTSCCONFIG = @ARTSCCONFIG@
+ARTS_BUILD_GMCOP = @ARTS_BUILD_GMCOP@
+ARTS_BUILD_KDE = @ARTS_BUILD_KDE@
+ARTS_MAJOR_VERSION = @ARTS_MAJOR_VERSION@
+ARTS_MICRO_VERSION = @ARTS_MICRO_VERSION@
+ARTS_MINOR_VERSION = @ARTS_MINOR_VERSION@
+ARTS_VERSION = @ARTS_VERSION@
+AS = @AS@
+AUTODIRS = @AUTODIRS@
+BZIP2DIR = @BZIP2DIR@
+BZIP2_FILTER = @BZIP2_FILTER@
+CC = @CC@
+CONF_FILES = @CONF_FILES@
+CPP = @CPP@
+CUPSSUBDIR = @CUPSSUBDIR@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+DCOPIDL = @DCOPIDL@
+DCOPIDL2CPP = @DCOPIDL2CPP@
+DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@
+DLLTOOL = @DLLTOOL@
+DPMSINC = @DPMSINC@
+DPMSLIB = @DPMSLIB@
+EXEEXT = @EXEEXT@
+EXTRA_SUBDIRS = @EXTRA_SUBDIRS@
+GCJ = @GCJ@
+GCJFLAGS = @GCJFLAGS@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_DEPLIBS = @GLIB_DEPLIBS@
+GLIB_LIBS = @GLIB_LIBS@
+GLINC = @GLINC@
+GLLIB = @GLLIB@
+GMSGFMT = @GMSGFMT@
+HAVE_MITSHM = @HAVE_MITSHM@
+HELP_SUBDIR = @HELP_SUBDIR@
+ICE_RLIB = @ICE_RLIB@
+ICE_SUBDIR = @ICE_SUBDIR@
+IDL = @IDL@
+IDL_DEPENDENCIES = @IDL_DEPENDENCIES@
+JAR = @JAR@
+JAVAC = @JAVAC@
+JAVAH = @JAVAH@
+JVMLIBS = @JVMLIBS@
+KDECONFIG = @KDECONFIG@
+KDE_CXXFLAGS = @KDE_CXXFLAGS@
+KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@
+KDE_INCLUDES = @KDE_INCLUDES@
+KDE_LDFLAGS = @KDE_LDFLAGS@
+KDE_PLUGIN = @KDE_PLUGIN@
+KDE_RPATH = @KDE_RPATH@
+KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@
+KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@
+KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@
+KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@
+KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@
+LIBASOUND = @LIBASOUND@
+LIBAUDIOFILE = @LIBAUDIOFILE@
+LIBAUDIOIO = @LIBAUDIOIO@
+LIBAUDIONAS = @LIBAUDIONAS@
+LIBBZ2 = @LIBBZ2@
+LIBCOMPAT = @LIBCOMPAT@
+LIBCRYPT = @LIBCRYPT@
+LIBDL = @LIBDL@
+LIBFAM = @LIBFAM@
+LIBGEN = @LIBGEN@
+LIBICE = @LIBICE@
+LIBJPEG = @LIBJPEG@
+LIBMICO = @LIBMICO@
+LIBOBJS = @LIBOBJS@
+LIBOSSAUDIO = @LIBOSSAUDIO@
+LIBPCRE = @LIBPCRE@
+LIBPNG = @LIBPNG@
+LIBPOSIX1E = @LIBPOSIX1E@
+LIBPTHREAD = @LIBPTHREAD@
+LIBPYTHON = @LIBPYTHON@
+LIBQIMGIO = @LIBQIMGIO@
+LIBRESOLV = @LIBRESOLV@
+LIBSHADOW = @LIBSHADOW@
+LIBSM = @LIBSM@
+LIBSOCKET = @LIBSOCKET@
+LIBSSL = @LIBSSL@
+LIBTIFF = @LIBTIFF@
+LIBTOOL = @LIBTOOL@
+LIBUCB = @LIBUCB@
+LIBUTIL = @LIBUTIL@
+LIBVOLMGT = @LIBVOLMGT@
+LIBXINERAMA = @LIBXINERAMA@
+LIBXML_CFLAGS = @LIBXML_CFLAGS@
+LIBXML_LIBS = @LIBXML_LIBS@
+LIBXML_RPATH = @LIBXML_RPATH@
+LIBXSLT_MAJOR_VERSION = @LIBXSLT_MAJOR_VERSION@
+LIBXSLT_MICRO_VERSION = @LIBXSLT_MICRO_VERSION@
+LIBXSLT_MINOR_VERSION = @LIBXSLT_MINOR_VERSION@
+LIBXSLT_VERSION = @LIBXSLT_VERSION@
+LIBXSLT_VERSION_INFO = @LIBXSLT_VERSION_INFO@
+LIBXSLT_VERSION_NUMBER = @LIBXSLT_VERSION_NUMBER@
+LIBZ = @LIBZ@
+LIB_CUPS = @LIB_CUPS@
+LIB_DCOP = @LIB_DCOP@
+LIB_DMALLOC = @LIB_DMALLOC@
+LIB_KAB = @LIB_KAB@
+LIB_KDECORE = @LIB_KDECORE@
+LIB_KDEUI = @LIB_KDEUI@
+LIB_KFILE = @LIB_KFILE@
+LIB_KFM = @LIB_KFM@
+LIB_KFORMULA = @LIB_KFORMULA@
+LIB_KHTML = @LIB_KHTML@
+LIB_KIMGIO = @LIB_KIMGIO@
+LIB_KIO = @LIB_KIO@
+LIB_KPARTS = @LIB_KPARTS@
+LIB_KSPELL = @LIB_KSPELL@
+LIB_KSSL = @LIB_KSSL@
+LIB_KSYCOCA = @LIB_KSYCOCA@
+LIB_KWRITE = @LIB_KWRITE@
+LIB_QT = @LIB_QT@
+LIB_SMB = @LIB_SMB@
+LIB_X11 = @LIB_X11@
+LN_S = @LN_S@
+MAKEINFO = @MAKEINFO@
+MCOPIDL = @MCOPIDL@
+MEINPROC = @MEINPROC@
+MICO_INCLUDES = @MICO_INCLUDES@
+MICO_LDFLAGS = @MICO_LDFLAGS@
+MOC = @MOC@
+MSGFMT = @MSGFMT@
+M_LIBS = @M_LIBS@
+NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@
+NOREPO = @NOREPO@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PAMLIBS = @PAMLIBS@
+PASSWDLIBS = @PASSWDLIBS@
+PKG_CONFIG = @PKG_CONFIG@
+PYTHONINC = @PYTHONINC@
+PYTHONLIB = @PYTHONLIB@
+PYTHONMODDIR = @PYTHONMODDIR@
+QNAMESPACE_H = @QNAMESPACE_H@
+QTDOCDIR = @QTDOCDIR@
+QT_INCLUDES = @QT_INCLUDES@
+QT_LDFLAGS = @QT_LDFLAGS@
+RANLIB = @RANLIB@
+REPO = @REPO@
+SETUIDFLAGS = @SETUIDFLAGS@
+SSL_INCLUDES = @SSL_INCLUDES@
+SSL_LDFLAGS = @SSL_LDFLAGS@
+STRIP = @STRIP@
+TOPSUBDIRS = @TOPSUBDIRS@
+UIC = @UIC@
+USER_INCLUDES = @USER_INCLUDES@
+USER_LDFLAGS = @USER_LDFLAGS@
+USE_EXCEPTIONS = @USE_EXCEPTIONS@
+USE_RTTI = @USE_RTTI@
+USE_THREADS = @USE_THREADS@
+VERSION = @VERSION@
+WITH_MEM_DEBUG = @WITH_MEM_DEBUG@
+WITH_XSLT_DEBUG = @WITH_XSLT_DEBUG@
+XGETTEXT = @XGETTEXT@
+XPMINC = @XPMINC@
+XPMLIB = @XPMLIB@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_INCLUDES = @X_INCLUDES@
+X_LDFLAGS = @X_LDFLAGS@
+X_PRE_LIBS = @X_PRE_LIBS@
+all_includes = @all_includes@
+all_libraries = @all_libraries@
+idldir = @idldir@
+jni_includes = @jni_includes@
+kde_appsdir = @kde_appsdir@
+kde_bindir = @kde_bindir@
+kde_confdir = @kde_confdir@
+kde_datadir = @kde_datadir@
+kde_htmldir = @kde_htmldir@
+kde_icondir = @kde_icondir@
+kde_includes = @kde_includes@
+kde_libraries = @kde_libraries@
+kde_libs_htmldir = @kde_libs_htmldir@
+kde_libs_prefix = @kde_libs_prefix@
+kde_locale = @kde_locale@
+kde_mimedir = @kde_mimedir@
+kde_moduledir = @kde_moduledir@
+kde_servicesdir = @kde_servicesdir@
+kde_servicetypesdir = @kde_servicetypesdir@
+kde_sounddir = @kde_sounddir@
+kde_templatesdir = @kde_templatesdir@
+kde_wallpaperdir = @kde_wallpaperdir@
+micodir = @micodir@
+path_su = @path_su@
+qt_includes = @qt_includes@
+qt_libraries = @qt_libraries@
+x_includes = @x_includes@
+x_libraries = @x_libraries@
+
+YACC = bison
+INCLUDES = $(all_includes)
+
+lib_LTLIBRARIES = libkjs.la
+
+libkjs_la_SOURCES = kjs.cpp grammar.cpp lexer.cpp nodes.cpp object.cpp 	operations.cpp ustring.cpp function.cpp types.cpp lookup.cpp 	internal.cpp regexp.cpp global_object.cpp math_object.cpp 	bool_object.cpp object_object.cpp error_object.cpp 	array_object.cpp string_object.cpp number_object.cpp 	date_object.cpp regexp_object.cpp collector.cpp function_object.cpp 	debugger.cpp
+
+
+kjsincludedir = $(includedir)/kjs
+kjsinclude_HEADERS = kjs.h object.h operations.h ustring.h 	function.h lookup.h types.h
+
+
+noinst_HEADERS = nodes.h lexer.h regexp.h internal.h collector.h 	grammar.h object_object.h function_object.h function_object.h 	bool_object.h math_object.h array_object.h string_object.h 	number_object.h date_object.h regexp_object.h error_object.h 	debugger.h
+
+
+libkjs_la_LDFLAGS = -version-info 1:0 -no-undefined $(USER_LDFLAGS)
+libkjs_la_LIBADD = -lm $(LIBPCRE)
+
+EXTRA_PROGRAMS = testkjs_static
+testkjs_static_SOURCES = testkjs.cpp  $(libkjs_la_SOURCES)
+testkjs_static_LDADD = $(LIBPCRE)
+
+check_PROGRAMS = testkjs
+testkjs_SOURCES = testkjs.cpp
+testkjs_LDADD = libkjs.la
+mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs
+CONFIG_HEADER = ../config.h
+CONFIG_CLEAN_FILES = 
+LTLIBRARIES =  $(lib_LTLIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I..
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+libkjs_la_DEPENDENCIES = 
+#>- libkjs_la_OBJECTS =  kjs.lo grammar.lo lexer.lo nodes.lo object.lo \
+#>- operations.lo ustring.lo function.lo types.lo lookup.lo internal.lo \
+#>- regexp.lo global_object.lo math_object.lo bool_object.lo \
+#>- object_object.lo error_object.lo array_object.lo string_object.lo \
+#>- number_object.lo date_object.lo regexp_object.lo collector.lo \
+#>- function_object.lo debugger.lo
+#>+ 9
+libkjs_la_final_OBJECTS = libkjs_la.all_cpp.lo 
+libkjs_la_nofinal_OBJECTS = kjs.lo grammar.lo lexer.lo nodes.lo object.lo \
+operations.lo ustring.lo function.lo types.lo lookup.lo internal.lo \
+regexp.lo global_object.lo math_object.lo bool_object.lo \
+object_object.lo error_object.lo array_object.lo string_object.lo \
+number_object.lo date_object.lo regexp_object.lo collector.lo \
+function_object.lo debugger.lo
+ at KDE_USE_FINAL_FALSE@libkjs_la_OBJECTS = $(libkjs_la_nofinal_OBJECTS)
+ at KDE_USE_FINAL_TRUE@libkjs_la_OBJECTS = $(libkjs_la_final_OBJECTS)
+check_PROGRAMS =  testkjs$(EXEEXT)
+#>- testkjs_static_OBJECTS =  testkjs.$(OBJEXT) kjs.$(OBJEXT) \
+#>- grammar.$(OBJEXT) lexer.$(OBJEXT) nodes.$(OBJEXT) object.$(OBJEXT) \
+#>- operations.$(OBJEXT) ustring.$(OBJEXT) function.$(OBJEXT) \
+#>- types.$(OBJEXT) lookup.$(OBJEXT) internal.$(OBJEXT) regexp.$(OBJEXT) \
+#>- global_object.$(OBJEXT) math_object.$(OBJEXT) bool_object.$(OBJEXT) \
+#>- object_object.$(OBJEXT) error_object.$(OBJEXT) array_object.$(OBJEXT) \
+#>- string_object.$(OBJEXT) number_object.$(OBJEXT) date_object.$(OBJEXT) \
+#>- regexp_object.$(OBJEXT) collector.$(OBJEXT) function_object.$(OBJEXT) \
+#>- debugger.$(OBJEXT)
+#>+ 9
+testkjs_static_OBJECTS = testkjs.$(OBJEXT) kjs.$(OBJEXT) \
+grammar.$(OBJEXT) lexer.$(OBJEXT) nodes.$(OBJEXT) object.$(OBJEXT) \
+operations.$(OBJEXT) ustring.$(OBJEXT) function.$(OBJEXT) \
+types.$(OBJEXT) lookup.$(OBJEXT) internal.$(OBJEXT) regexp.$(OBJEXT) \
+global_object.$(OBJEXT) math_object.$(OBJEXT) bool_object.$(OBJEXT) \
+object_object.$(OBJEXT) error_object.$(OBJEXT) array_object.$(OBJEXT) \
+string_object.$(OBJEXT) number_object.$(OBJEXT) date_object.$(OBJEXT) \
+regexp_object.$(OBJEXT) collector.$(OBJEXT) function_object.$(OBJEXT) \
+debugger.$(OBJEXT)
+testkjs_static_DEPENDENCIES = 
+testkjs_static_LDFLAGS = 
+#>- testkjs_OBJECTS =  testkjs.$(OBJEXT)
+#>+ 1
+testkjs_OBJECTS = testkjs.$(OBJEXT)
+testkjs_DEPENDENCIES =  libkjs.la
+testkjs_LDFLAGS = 
+CXXFLAGS = @CXXFLAGS@
+#>- CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+#>+ 1
+CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS)
+#>- LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+#>+ 1
+LTCXXCOMPILE = $(LIBTOOL) --mode=compile --tag=CXX $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS)
+CXXLD = $(CXX)
+#>- CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@
+#>+ 1
+CXXLINK = $(LIBTOOL) --mode=link --tag=CXX $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) $(LDFLAGS) -o $@
+HEADERS =  $(kjsinclude_HEADERS) $(noinst_HEADERS)
+
+DIST_COMMON =  README ChangeLog Makefile.am Makefile.in THANKS
+
+
+#>- DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+#>+ 4
+KDE_DIST=configure.in.in grammar.y keywords.table math_object.lut.h test.js create_hash_table lexer.lut.h 
+
+DISTFILES= $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) $(KDE_DIST)
+
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(libkjs_la_SOURCES) $(testkjs_static_SOURCES) $(testkjs_SOURCES)
+OBJECTS = $(libkjs_la_OBJECTS) $(testkjs_static_OBJECTS) $(testkjs_OBJECTS)
+
+#>- all: all-redirect
+#>+ 1
+all: docs-am  all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .cpp .lo .o .obj .s
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
+#>- 	cd $(top_srcdir) && $(AUTOMAKE) --foreign --include-deps kjs/Makefile
+#>+ 2
+	cd $(top_srcdir) && $(AUTOMAKE) --foreign --include-deps kjs/Makefile
+	cd $(top_srcdir) && perl admin/am_edit kjs/Makefile.in
+
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+	cd $(top_builddir) \
+	  && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-libLTLIBRARIES:
+
+clean-libLTLIBRARIES:
+	-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+
+distclean-libLTLIBRARIES:
+
+maintainer-clean-libLTLIBRARIES:
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+	@$(NORMAL_INSTALL)
+	$(mkinstalldirs) $(DESTDIR)$(libdir)
+	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+	  if test -f $$p; then \
+	    echo "$(LIBTOOL)  --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \
+	    $(LIBTOOL)  --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \
+	  else :; fi; \
+	done
+
+uninstall-libLTLIBRARIES:
+	@$(NORMAL_UNINSTALL)
+	list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+	  $(LIBTOOL)  --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
+	done
+
+.c.o:
+	$(COMPILE) -c $<
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+	$(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+	$(COMPILE) -c $<
+
+.S.o:
+	$(COMPILE) -c $<
+
+mostlyclean-compile:
+	-rm -f *.o core *.core
+	-rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+	-rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+	$(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+	$(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+	$(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+#>- libkjs.la: $(libkjs_la_OBJECTS) $(libkjs_la_DEPENDENCIES)
+#>+ 2
+ at KDE_USE_CLOSURE_TRUE@libkjs.la: libkjs.la.closure $(libkjs_la_OBJECTS) $(libkjs_la_DEPENDENCIES)
+ at KDE_USE_CLOSURE_FALSE@libkjs.la: $(libkjs_la_OBJECTS) $(libkjs_la_DEPENDENCIES)
+	$(CXXLINK) -rpath $(libdir) $(libkjs_la_LDFLAGS) $(libkjs_la_OBJECTS) $(libkjs_la_LIBADD) $(LIBS)
+
+mostlyclean-checkPROGRAMS:
+
+clean-checkPROGRAMS:
+	-test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS)
+
+distclean-checkPROGRAMS:
+
+maintainer-clean-checkPROGRAMS:
+
+testkjs_static$(EXEEXT): $(testkjs_static_OBJECTS) $(testkjs_static_DEPENDENCIES)
+	@rm -f testkjs_static$(EXEEXT)
+	$(CXXLINK) $(testkjs_static_LDFLAGS) $(testkjs_static_OBJECTS) $(testkjs_static_LDADD) $(LIBS)
+
+testkjs$(EXEEXT): $(testkjs_OBJECTS) $(testkjs_DEPENDENCIES)
+	@rm -f testkjs$(EXEEXT)
+	$(CXXLINK) $(testkjs_LDFLAGS) $(testkjs_OBJECTS) $(testkjs_LDADD) $(LIBS)
+.cpp.o:
+	$(CXXCOMPILE) -c $<
+.cpp.obj:
+	$(CXXCOMPILE) -c `cygpath -w $<`
+.cpp.lo:
+	$(LTCXXCOMPILE) -c $<
+
+install-kjsincludeHEADERS: $(kjsinclude_HEADERS)
+	@$(NORMAL_INSTALL)
+	$(mkinstalldirs) $(DESTDIR)$(kjsincludedir)
+	@list='$(kjsinclude_HEADERS)'; for p in $$list; do \
+	  if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
+	  echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(kjsincludedir)/$$p"; \
+	  $(INSTALL_DATA) $$d$$p $(DESTDIR)$(kjsincludedir)/$$p; \
+	done
+
+uninstall-kjsincludeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	list='$(kjsinclude_HEADERS)'; for p in $$list; do \
+	  rm -f $(DESTDIR)$(kjsincludedir)/$$p; \
+	done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+	list='$(SOURCES) $(HEADERS)'; \
+	unique=`for i in $$list; do echo $$i; done | \
+	  awk '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	here=`pwd` && cd $(srcdir) \
+	  && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)'; \
+	unique=`for i in $$list; do echo $$i; done | \
+	  awk '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+	  || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags  $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+	-rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = kjs
+
+distdir: $(DISTFILES)
+#>- 	@for file in $(DISTFILES); do \
+#>- 	  d=$(srcdir); \
+#>- 	  if test -d $$d/$$file; then \
+#>- 	    cp -pr $$/$$file $(distdir)/$$file; \
+#>- 	  else \
+#>- 	    test -f $(distdir)/$$file \
+#>- 	    || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+#>- 	    || cp -p $$d/$$file $(distdir)/$$file || :; \
+#>- 	  fi; \
+#>- 	done
+#>+ 10
+	@for file in $(DISTFILES); do \
+	  d=$(srcdir); \
+	  if test -d $$d/$$file; then \
+	    cp -pr $$d/$$file $(distdir)/$$file; \
+	  else \
+	    test -f $(distdir)/$$file \
+	    || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+	    || cp -p $$d/$$file $(distdir)/$$file || :; \
+	  fi; \
+	done
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+	$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-libLTLIBRARIES
+install-exec: install-exec-am
+
+install-data-am: install-kjsincludeHEADERS
+install-data: install-data-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-libLTLIBRARIES uninstall-kjsincludeHEADERS
+uninstall: uninstall-am
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
+all-redirect: all-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+	$(mkinstalldirs)  $(DESTDIR)$(libdir) $(DESTDIR)$(kjsincludedir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-rm -f Makefile $(CONFIG_CLEAN_FILES)
+	-rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am:  mostlyclean-libLTLIBRARIES mostlyclean-compile \
+		mostlyclean-libtool mostlyclean-checkPROGRAMS \
+		mostlyclean-tags mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+#>- clean-am:  clean-libLTLIBRARIES clean-compile clean-libtool \
+#>- 		clean-checkPROGRAMS clean-tags clean-generic \
+#>- 		mostlyclean-am
+#>+ 3
+clean-am: clean-closures clean-final   clean-libLTLIBRARIES clean-compile clean-libtool \
+		clean-checkPROGRAMS clean-tags clean-generic \
+		mostlyclean-am
+
+#>- clean: clean-am
+#>+ 1
+clean: kde-rpo-clean  clean-am
+
+distclean-am:  distclean-libLTLIBRARIES distclean-compile \
+		distclean-libtool distclean-checkPROGRAMS \
+		distclean-tags distclean-generic clean-am
+	-rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am:  maintainer-clean-libLTLIBRARIES \
+		maintainer-clean-compile maintainer-clean-libtool \
+		maintainer-clean-checkPROGRAMS maintainer-clean-tags \
+		maintainer-clean-generic distclean-am
+	@echo "This command is intended for maintainers to use;"
+	@echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-libLTLIBRARIES distclean-libLTLIBRARIES \
+clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \
+uninstall-libLTLIBRARIES install-libLTLIBRARIES mostlyclean-compile \
+distclean-compile clean-compile maintainer-clean-compile \
+mostlyclean-libtool distclean-libtool clean-libtool \
+maintainer-clean-libtool mostlyclean-checkPROGRAMS \
+distclean-checkPROGRAMS clean-checkPROGRAMS \
+maintainer-clean-checkPROGRAMS uninstall-kjsincludeHEADERS \
+install-kjsincludeHEADERS tags mostlyclean-tags distclean-tags \
+clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \
+check-am installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+parser: $(srcdir)/grammar.y
+	cd $(srcdir); \
+	$(YACC) -d -p kjsyy grammar.y && mv grammar.tab.c grammar.cpp; \
+	if test -f grammar.tab.h; then \
+	if cmp -s grammar.tab.h grammar.h; then rm -f grammar.tab.h; \
+	else mv grammar.tab.h grammar.h; fi \
+	else :; fi
+
+debugger: $(libkjs_la_SOURCES) $(kjsinclude_HEADERS) $(noinst_HEADERS)
+	$(MAKE) DEFS="-DKJS_DEBUGGER $(DEFS)" libkjs.la
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
+
+#>+ 8
+libkjs.la.closure: $(libkjs_la_OBJECTS) $(libkjs_la_DEPENDENCIES)
+	@echo "int main() {return 0;}" > libkjs_la_closure.cpp
+	@$(LTCXXCOMPILE) -c libkjs_la_closure.cpp
+	@$(CXXLINK) libkjs_la_closure.lo $(libkjs_la_LDFLAGS) $(libkjs_la_OBJECTS) $(libkjs_la_LIBADD) $(LIBS)
+	@rm -f libkjs_la_closure.* libkjs.la.closure
+	@echo "timestamp" > libkjs.la.closure
+
+
+#>+ 3
+clean-closures:
+	-rm -f  libkjs.la.closure
+
+#>+ 2
+docs-am:
+
+#>+ 5
+force-reedit:
+		cd $(top_srcdir) && $(AUTOMAKE) --foreign --include-deps kjs/Makefile
+	cd $(top_srcdir) && perl admin/am_edit kjs/Makefile.in
+
+
+#>+ 11
+libkjs_la.all_cpp.cpp: $(srcdir)/Makefile.in $(srcdir)/kjs.cpp $(srcdir)/grammar.cpp $(srcdir)/lexer.cpp $(srcdir)/nodes.cpp $(srcdir)/object.cpp $(srcdir)/operations.cpp $(srcdir)/ustring.cpp $(srcdir)/function.cpp $(srcdir)/types.cpp $(srcdir)/lookup.cpp $(srcdir)/internal.cpp $(srcdir)/regexp.cpp $(srcdir)/global_object.cpp $(srcdir)/math_object.cpp $(srcdir)/bool_object.cpp $(srcdir)/object_object.cpp $(srcdir)/error_object.cpp $(srcdir)/array_object.cpp $(srcdir)/string_object.cpp $(srcdir)/number_object.cpp $(srcdir)/date_object.cpp $(srcdir)/regexp_object.cpp $(srcdir)/collector.cpp $(srcdir)/function_object.cpp $(srcdir)/debugger.cpp  
+	@echo 'creating libkjs_la.all_cpp.cpp ...'; \
+	rm -f libkjs_la.all_cpp.files libkjs_la.all_cpp.final; \
+	echo "#define KDE_USE_FINAL 1" >> libkjs_la.all_cpp.final; \
+	for file in kjs.cpp grammar.cpp lexer.cpp nodes.cpp object.cpp operations.cpp ustring.cpp function.cpp types.cpp lookup.cpp internal.cpp regexp.cpp global_object.cpp math_object.cpp bool_object.cpp object_object.cpp error_object.cpp array_object.cpp string_object.cpp number_object.cpp date_object.cpp regexp_object.cpp collector.cpp function_object.cpp debugger.cpp ; do \
+	  echo "#include \"$$file\"" >> libkjs_la.all_cpp.files; \
+	  test ! -f $(srcdir)/$$file || egrep '^#pragma +implementation' $(srcdir)/$$file >> libkjs_la.all_cpp.final; \
+	done; \
+	cat libkjs_la.all_cpp.final libkjs_la.all_cpp.files  > libkjs_la.all_cpp.cpp; \
+	rm -f libkjs_la.all_cpp.final libkjs_la.all_cpp.files
+
+#>+ 11
+testkjs.all_cpp.cpp: $(srcdir)/Makefile.in $(srcdir)/testkjs.cpp  
+	@echo 'creating testkjs.all_cpp.cpp ...'; \
+	rm -f testkjs.all_cpp.files testkjs.all_cpp.final; \
+	echo "#define KDE_USE_FINAL 1" >> testkjs.all_cpp.final; \
+	for file in testkjs.cpp ; do \
+	  echo "#include \"$$file\"" >> testkjs.all_cpp.files; \
+	  test ! -f $(srcdir)/$$file || egrep '^#pragma +implementation' $(srcdir)/$$file >> testkjs.all_cpp.final; \
+	done; \
+	cat testkjs.all_cpp.final testkjs.all_cpp.files  > testkjs.all_cpp.cpp; \
+	rm -f testkjs.all_cpp.final testkjs.all_cpp.files
+
+#>+ 3
+clean-final:
+	-rm -f libkjs_la.all_cpp.cpp testkjs.all_cpp.cpp
+
+#>+ 2
+final:
+	$(MAKE) libkjs_la_OBJECTS="$(libkjs_la_final_OBJECTS)" all-am
+#>+ 2
+no-final:
+	$(MAKE) libkjs_la_OBJECTS="$(libkjs_la_nofinal_OBJECTS)" all-am
+#>+ 3
+cvs-clean:
+	$(MAKE) -f $(top_srcdir)/admin/Makefile.common cvs-clean
+
+#>+ 3
+kde-rpo-clean:
+	-rm -f *.rpo
diff --git a/JavaScriptCore/kjs/README b/JavaScriptCore/kjs/README
new file mode 100644
index 0000000..b4a0fcc
--- /dev/null
+++ b/JavaScriptCore/kjs/README
@@ -0,0 +1,25 @@
+This library provides an ECMAScript compatible interpreter. The ECMA standard
+is based on well known scripting languages such as Netscape's JavaScript and
+Microsoft's JScript.
+
+I'm currently pursuing to be compliant with Edition 3 of ECMA-262. Postscript
+and pdf versions of the standard are avaiable at:
+
+http://www.ecma.ch
+
+About 90% of the required features should be covered by now. Note that this
+number covers the core language elements only. Features like the famous
+roll-over buttons on the www are NOT part of the standard. Those extensions
+are added via a module loaded dynamically by the KHTML Widget.
+
+I'll provide some examples of how to extend this library for various needs at
+a later point in time. Feel free to contact me via mail if you have any
+questions on how to provide scripting capabilites for your application.
+
+A debugger is being worked on. To compile it, add -DKJS_DEBUGGER to the CXXFLAGS
+section in the Makefile.am of kdelibs/kjs and kdelibs/khtml/ecma.
+
+Bug reports, patches or feedback of any kind is very welcome.
+
+Harri Porten <porten at kde.org>
+
diff --git a/JavaScriptCore/kjs/THANKS b/JavaScriptCore/kjs/THANKS
new file mode 100644
index 0000000..036e5e7
--- /dev/null
+++ b/JavaScriptCore/kjs/THANKS
@@ -0,0 +1,7 @@
+I would like to thank the following people for their help:
+
+Richard Moore <rich at kde.org> - for filling the Math object with some life
+Daegeun Lee <realking at mizi.com> - for pointing out some bugs and providing
+                                  much code for the String and Date object.
+Marco Pinelli <pinmc at libero.it> - for his patches
+Christian Kirsch <ck at held.mind.de> - for his contribution to the Date object
diff --git a/JavaScriptCore/kjs/array_object.cpp b/JavaScriptCore/kjs/array_object.cpp
new file mode 100644
index 0000000..cc97dff
--- /dev/null
+++ b/JavaScriptCore/kjs/array_object.cpp
@@ -0,0 +1,341 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "kjs.h"
+#include "operations.h"
+#include "types.h"
+#include "array_object.h"
+#include <stdio.h>
+
+using namespace KJS;
+
+ArrayObject::ArrayObject(const Object &funcProto,
+			 const Object &arrayProto)
+    : ConstructorImp(funcProto, 1)
+{
+  // ECMA 15.4.3.1 Array.prototype
+  setPrototypeProperty(arrayProto);
+}
+
+// ECMA 15.6.1
+Completion ArrayObject::execute(const List &args)
+{
+  // equivalent to 'new Array(....)'
+  KJSO result = construct(args);
+
+  return Completion(ReturnValue, result);
+}
+
+// ECMA 15.6.2
+Object ArrayObject::construct(const List &args)
+{
+  Object result = Object::create(ArrayClass);
+
+  unsigned int len;
+  ListIterator it = args.begin();
+  // a single argument might denote the array size
+  if (args.size() == 1 && it->isA(NumberType))
+    len = it->toUInt32();
+  else {
+    // initialize array
+    len = args.size();
+    for (unsigned int u = 0; it != args.end(); it++, u++)
+      result.put(UString::from(u), *it);
+  }
+
+  // array size
+  result.put("length", len, DontEnum | DontDelete);
+
+  return result;
+}
+
+// ECMA 15.6.4
+ArrayPrototype::ArrayPrototype(const Object& proto)
+  : ObjectImp(ArrayClass, Null(), proto)
+{
+  // The constructor will be added later in ArrayObject's constructor
+
+  put("length", 0u, DontEnum | DontDelete);
+}
+
+KJSO ArrayPrototype::get(const UString &p) const
+{
+  int id;
+  if(p == "toString")
+    id = ArrayProtoFunc::ToString;
+  else if(p == "toLocaleString")
+    id = ArrayProtoFunc::ToLocaleString;
+  else if(p == "concat")
+    id = ArrayProtoFunc::Concat;
+  else if (p == "join")
+    id = ArrayProtoFunc::Join;
+  else if(p == "pop")
+    id = ArrayProtoFunc::Pop;
+  else if(p == "push")
+    id = ArrayProtoFunc::Push;
+  else if(p == "reverse")
+    id = ArrayProtoFunc::Reverse;
+  else if(p == "shift")
+    id = ArrayProtoFunc::Shift;
+  else if(p == "slice")
+    id = ArrayProtoFunc::Slice;
+  else if(p == "sort")
+    id = ArrayProtoFunc::Sort;
+  else if(p == "splice")
+    id = ArrayProtoFunc::Splice;
+  else if(p == "unshift")
+    id = ArrayProtoFunc::UnShift;
+  else
+    return Imp::get(p);
+
+  return Function(new ArrayProtoFunc(id));
+}
+
+// ECMA 15.4.4
+Completion ArrayProtoFunc::execute(const List &args)
+{
+  KJSO result, obj, obj2;
+  Object thisObj = Object::dynamicCast(thisValue());
+  unsigned int length = thisObj.get("length").toUInt32();
+  unsigned int middle;
+  UString str = "", str2;
+  UString separator = ",";
+
+  switch (id) {
+  case ToLocaleString:
+    /* TODO */
+    // fall trough
+  case ToString:
+    if (!thisObj.getClass() == ArrayClass) {
+      result = Error::create(TypeError);
+      break;
+    }
+    // fall trough
+  case Join:
+    {
+      if (!args[0].isA(UndefinedType))
+	separator = args[0].toString().value();
+      for (unsigned int k = 0; k < length; k++) {
+	if (k >= 1)
+	  str += separator;
+	obj = thisObj.get(UString::from(k));
+	if (!obj.isA(UndefinedType) && !obj.isA(NullType))
+	  str += obj.toString().value();
+      }
+    }
+    result = String(str);
+    break;
+  case Concat: {
+    result = Object::create(ArrayClass);
+    int n = 0;
+    obj = thisObj;
+    ListIterator it = args.begin();
+    for (;;) {
+      if (obj.isA(ObjectType) &&
+	  static_cast<Object&>(obj).getClass() == ArrayClass) {
+	unsigned int k = 0;
+	if (n > 0)
+	  length = obj.get("length").toUInt32();
+	while (k < length) {
+	  UString p = UString::from(k);
+	  if (obj.hasProperty(p))
+	    result.put(UString::from(n), obj.get(p));
+	  n++;
+	  k++;
+	}
+      } else {
+	result.put(UString::from(n), obj);
+	n++;      
+      }
+      if (it == args.end())
+	break;
+      obj = it++;
+    }
+    result.put("length", Number(n), DontEnum | DontDelete);
+  }
+    break;
+  case Pop:
+    if (length == 0) {
+      thisObj.put("length", Number(length), DontEnum | DontDelete);
+      result = Undefined();
+    } else {
+      str = UString::from(length - 1);
+      result = thisObj.get(str);
+      thisObj.deleteProperty(str);
+      thisObj.put("length", length - 1, DontEnum | DontDelete);
+    }
+    break;
+  case Push:
+    {
+      for (int n = 0; n < args.size(); n++)
+	thisObj.put(UString::from(length + n), args[n]);
+      length += args.size();
+      thisObj.put("length", length, DontEnum | DontDelete);
+      result = Number(length);
+    }
+    break;
+  case Reverse:
+    {
+      middle = length / 2;
+      for (unsigned int k = 0; k < middle; k++) {
+	str = UString::from(k);
+	str2 = UString::from(length - k - 1);
+	obj = thisObj.get(str);
+	obj2 = thisObj.get(str2);
+	if (thisObj.hasProperty(str2)) {
+	  if (thisObj.hasProperty(str)) {
+	    thisObj.put(str, obj2);
+	    thisObj.put(str2, obj);
+	  } else {
+	    thisObj.put(str, obj2);
+	    thisObj.deleteProperty(str2);
+	  }
+	} else {
+	  if (thisObj.hasProperty(str)) {
+	    thisObj.deleteProperty(str);
+	    thisObj.put(str2, obj);
+	  } else {
+	    // why delete something that's not there ? Strange.
+	    thisObj.deleteProperty(str);
+	    thisObj.deleteProperty(str2);
+	  }
+	}
+      }
+    }
+    result = thisObj;
+    break;
+  case Shift:
+    if (length == 0) {
+      thisObj.put("length", Number(length), DontEnum | DontDelete);
+      result = Undefined();
+    } else {
+      result = thisObj.get("0");
+      for(unsigned int k = 1; k < length; k++) {
+	str = UString::from(k);
+	str2 = UString::from(k-1);
+	if (thisObj.hasProperty(str)) {
+	  obj = thisObj.get(str);
+	  thisObj.put(str2, obj);
+	} else
+	  thisObj.deleteProperty(str2);
+      }
+      thisObj.deleteProperty(UString::from(length - 1));
+      thisObj.put("length", length - 1, DontEnum | DontDelete);
+    }
+    break;
+  case Slice: // http://developer.netscape.com/docs/manuals/js/client/jsref/array.htm#1193713
+    {
+        result = Object::create(ArrayClass); // We return a new array
+        int begin = args[0].toUInt32();
+        int end = length;
+        if (!args[1].isA(UndefinedType))
+        {
+          end = args[1].toUInt32();
+          if ( end < 0 )
+            end += length;
+        }
+        // safety tests
+        if ( begin < 0 || end < 0 || begin >= end ) {
+            result.put("length", Number(0), DontEnum | DontDelete);
+            break;
+        }
+        //printf( "Slicing from %d to %d \n", begin, end );
+        for(unsigned int k = 0; k < (unsigned int) end-begin; k++) {
+            str = UString::from(k+begin);
+            str2 = UString::from(k);
+            if (thisObj.hasProperty(str)) {
+                obj = thisObj.get(str);
+                result.put(str2, obj);
+            }
+        }
+        result.put("length", end - begin, DontEnum | DontDelete);
+        break;
+    }
+  case Sort:
+    {
+#if 0
+        printf("KJS Array::Sort length=%d\n", length);
+        for ( unsigned int i = 0 ; i<length ; ++i )
+            printf("KJS Array::Sort: %d: %s\n", i, thisObj.get(UString::from(i)).toString().value().ascii() );
+#endif
+        Object sortFunction;
+        bool useSortFunction = !args[0].isA(UndefinedType);
+        if (useSortFunction)
+        {
+            sortFunction = args[0].toObject();
+            if (!sortFunction.implementsCall())
+                useSortFunction = false;
+        }
+
+        if (length == 0) {
+            thisObj.put("length", Number(0), DontEnum | DontDelete);
+            result = Undefined();
+            break;
+        }
+
+        // "Min" sort. Not the fastest, but definitely less code than heapsort
+        // or quicksort, and much less swapping than bubblesort/insertionsort.
+        for ( unsigned int i = 0 ; i<length-1 ; ++i )
+        {
+            KJSO iObj = thisObj.get(UString::from(i));
+            unsigned int themin = i;
+            KJSO minObj = iObj;
+            for ( unsigned int j = i+1 ; j<length ; ++j )
+            {
+                KJSO jObj = thisObj.get(UString::from(j));
+                int cmp;
+                if ( useSortFunction )
+                {
+                    List l;
+                    l.append(jObj);
+                    l.append(minObj);
+                    cmp = sortFunction.executeCall( Global::current(), &l ).toInt32();
+                }
+                else
+                    cmp = ( jObj.toString().value() < minObj.toString().value() ) ? -1 : 1;
+                if ( cmp < 0 )
+                {
+                    themin = j;
+                    minObj = jObj;
+                }
+            }
+            // Swap themin and i
+            if ( themin > i )
+            {
+                //printf("KJS Array::Sort: swapping %d and %d\n", i, themin );
+                thisObj.put( UString::from(i), minObj );
+                thisObj.put( UString::from(themin), iObj );
+            }
+        }
+#if 0
+        printf("KJS Array::Sort -- Resulting array:\n");
+        for ( unsigned int i = 0 ; i<length ; ++i )
+            printf("KJS Array::Sort: %d: %s\n", i, thisObj.get(UString::from(i)).toString().value().ascii() );
+#endif
+        result = thisObj;
+        break;
+    }
+  // TODO Splice
+  // TODO Unshift
+  default:
+    result = Undefined();
+  }
+
+  return Completion(ReturnValue, result);
+}
diff --git a/JavaScriptCore/kjs/array_object.h b/JavaScriptCore/kjs/array_object.h
new file mode 100644
index 0000000..f4d56e4
--- /dev/null
+++ b/JavaScriptCore/kjs/array_object.h
@@ -0,0 +1,53 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _ARRAY_OBJECT_H_
+#define _ARRAY_OBJECT_H_
+
+#include "object.h"
+#include "function.h"
+
+namespace KJS {
+
+  class ArrayObject : public ConstructorImp {
+  public:
+    ArrayObject(const Object &funcProto, const Object &arrayProto);
+    Completion execute(const List &);
+    Object construct(const List &);
+  };
+
+  class ArrayPrototype : public ObjectImp {
+  public:
+    ArrayPrototype(const Object& proto);
+    virtual KJSO get(const UString &p) const;
+  };
+
+  class ArrayProtoFunc : public InternalFunctionImp {
+  public:
+    ArrayProtoFunc(int i) : id(i) { }
+    Completion execute(const List &);
+    enum { ToString, ToLocaleString, Concat, Join, Pop, Push,
+	   Reverse, Shift, Slice, Sort, Splice, UnShift };
+  private:
+    int id;
+  };
+
+}; // namespace
+
+#endif
diff --git a/JavaScriptCore/kjs/bool_object.cpp b/JavaScriptCore/kjs/bool_object.cpp
new file mode 100644
index 0000000..08fcc5c
--- /dev/null
+++ b/JavaScriptCore/kjs/bool_object.cpp
@@ -0,0 +1,103 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "kjs.h"
+#include "operations.h"
+#include "types.h"
+#include "bool_object.h"
+#include "error_object.h"
+
+using namespace KJS;
+
+BooleanObject::BooleanObject(const KJSO& funcProto, const KJSO &booleanProto)
+  : ConstructorImp(funcProto, 1)
+{
+  // Boolean.prototype
+  setPrototypeProperty(booleanProto);
+}
+
+// ECMA 15.6.1
+Completion BooleanObject::execute(const List &args)
+{
+  Boolean b;
+
+  if (args.isEmpty())
+    b = Boolean(false);
+  else
+    b = args[0].toBoolean();
+
+  return Completion(ReturnValue, b);
+}
+
+// ECMA 15.6.2
+Object BooleanObject::construct(const List &args)
+{
+  Boolean b;
+  if (args.size() > 0)
+    b = args.begin()->toBoolean();
+  else
+    b = Boolean(false);
+
+  return Object::create(BooleanClass, b);
+}
+
+// ECMA 15.6.4
+BooleanPrototype::BooleanPrototype(const Object& proto)
+  : ObjectImp(BooleanClass, Boolean(false), proto)
+{
+  // The constructor will be added later in BooleanObject's constructor
+}
+
+KJSO BooleanPrototype::get(const UString &p) const
+{
+  if (p == "toString")
+    return Function(new BooleanProtoFunc(ToString));
+  else if (p == "valueOf")
+    return Function(new BooleanProtoFunc(ValueOf));
+  else
+    return Imp::get(p);
+}
+
+BooleanProtoFunc::BooleanProtoFunc(int i)
+  : id(i)
+{
+}
+
+// ECMA 15.6.4.2 + 15.6.4.3
+Completion BooleanProtoFunc::execute(const List &)
+{
+  KJSO result;
+
+  Object thisObj = Object::dynamicCast(thisValue());
+
+  // no generic function. "this" has to be a Boolean object
+  if (thisObj.isNull() || thisObj.getClass() != BooleanClass) {
+    result = Error::create(TypeError);
+    return Completion(ReturnValue, result);
+  }
+
+  // execute "toString()" or "valueOf()", respectively
+  KJSO v = thisObj.internalValue();
+  if (id == BooleanPrototype::ToString)
+    result = v.toString();
+  else
+    result = v.toBoolean();
+
+  return Completion(ReturnValue, result);
+}
diff --git a/JavaScriptCore/kjs/bool_object.h b/JavaScriptCore/kjs/bool_object.h
new file mode 100644
index 0000000..89dc451
--- /dev/null
+++ b/JavaScriptCore/kjs/bool_object.h
@@ -0,0 +1,52 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _BOOL_OBJECT_H_
+#define _BOOL_OBJECT_H_
+
+#include "object.h"
+#include "function.h"
+
+namespace KJS {
+
+  class BooleanObject : public ConstructorImp {
+  public:
+    BooleanObject(const KJSO& funcProto, const KJSO &booleanProto);
+    Completion execute(const List &);
+    Object construct(const List &);
+  };
+
+  class BooleanPrototype : public ObjectImp {
+  public:
+    BooleanPrototype(const Object& proto);
+    virtual KJSO get(const UString &p) const;
+    enum { ToString, ValueOf };
+  };
+
+  class BooleanProtoFunc : public InternalFunctionImp {
+  public:
+    BooleanProtoFunc(int i);
+    Completion execute(const List &);
+  private:
+    int id;
+  };
+
+}; // namespace
+
+#endif
diff --git a/JavaScriptCore/kjs/collector.cpp b/JavaScriptCore/kjs/collector.cpp
new file mode 100644
index 0000000..df79038
--- /dev/null
+++ b/JavaScriptCore/kjs/collector.cpp
@@ -0,0 +1,211 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "collector.h"
+#include "object.h"
+#include "internal.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+namespace KJS {
+
+  class CollectorBlock {
+  public:
+    CollectorBlock(int s);
+    ~CollectorBlock();
+    int size;
+    int filled;
+    void** mem;
+    CollectorBlock *prev, *next;
+  };
+
+}; // namespace
+
+using namespace KJS;
+
+CollectorBlock::CollectorBlock(int s)
+  : size(s),
+    filled(0),
+    prev(0L),
+    next(0L)
+{
+  mem = new void*[size];
+  memset(mem, 0, size * sizeof(void*));
+}
+
+CollectorBlock::~CollectorBlock()
+{
+  delete [] mem;
+  mem = 0L;
+}
+
+CollectorBlock* Collector::root = 0L;
+CollectorBlock* Collector::currentBlock = 0L;
+unsigned long Collector::filled = 0;
+unsigned long Collector::softLimit = KJS_MEM_INCREMENT;
+#ifdef KJS_DEBUG_MEM
+bool Collector::collecting = false;
+#endif
+
+void* Collector::allocate(size_t s)
+{
+  if (s == 0)
+    return 0L;
+
+  if (filled >= softLimit) {
+    collect();
+    if (filled >= softLimit && softLimit < KJS_MEM_LIMIT) // we are actually using all this memory
+      softLimit *= 2;
+  }
+
+  void *m = malloc(s);
+
+  // hack to ensure obj is protected from GC before any constructors are run
+  // (prev = marked, next = gcallowed)
+  static_cast<Imp*>(m)->prev = 0;
+  static_cast<Imp*>(m)->next = 0;
+
+  if (!root) {
+    root = new CollectorBlock(BlockSize);
+    currentBlock = root;
+  }
+
+  CollectorBlock *block = currentBlock;
+  if (!block)
+    block = root;
+
+  // search for a block with space left
+  while (block->next && block->filled == block->size)
+    block = block->next;
+
+  if (block->filled >= block->size) {
+#ifdef KJS_DEBUG_MEM
+    printf("allocating new block of size %d\n", block->size);
+#endif
+    CollectorBlock *tmp = new CollectorBlock(BlockSize);
+    block->next = tmp;
+    tmp->prev = block;
+    block = tmp;
+  }
+  currentBlock = block;
+  // look for a free spot in the block
+  void **r = block->mem;
+  while (*r)
+    r++;
+  *r = m;
+  filled++;
+  block->filled++;
+
+  if (softLimit >= KJS_MEM_LIMIT) {
+      KJScriptImp::setException("Out of memory");
+  }
+
+  return m;
+}
+
+/**
+ * Mark-sweep garbage collection.
+ */
+void Collector::collect()
+{
+#ifdef KJS_DEBUG_MEM
+  printf("collecting %d objects total\n", Imp::count);
+  collecting = true;
+#endif
+
+  // MARK: first set all ref counts to 0 ....
+  CollectorBlock *block = root;
+  while (block) {
+#ifdef KJS_DEBUG_MEM
+    printf("cleaning block filled %d out of %d\n", block->filled, block->size);
+#endif
+    Imp **r = (Imp**)block->mem;
+    assert(r);
+    for (int i = 0; i < block->size; i++, r++)
+      if (*r) {
+        (*r)->setMarked(false);
+      }
+    block = block->next;
+  }
+
+  // ... increase counter for all referenced objects recursively
+  // starting out from the set of root objects
+  if (KJScriptImp::hook) {
+    KJScriptImp *scr = KJScriptImp::hook;
+    do {
+      scr->mark();
+      scr = scr->next;
+    } while (scr != KJScriptImp::hook);
+  }
+
+  // mark any other objects that we wouldn't delete anyway
+  block = root;
+  while (block) {
+    Imp **r = (Imp**)block->mem;
+    assert(r);
+    for (int i = 0; i < block->size; i++, r++)
+      if (*r && (*r)->created() && ((*r)->refcount || !(*r)->gcAllowed()) && !(*r)->marked())
+        (*r)->mark();
+    block = block->next;
+  }
+
+  // SWEEP: delete everything with a zero refcount (garbage)
+  block = root;
+  while (block) {
+    Imp **r = (Imp**)block->mem;
+    int del = 0;
+    for (int i = 0; i < block->size; i++, r++) {
+      if (*r && ((*r)->refcount == 0) && !(*r)->marked() && (*r)->gcAllowed()) {
+	// emulate destructing part of 'operator delete()'
+	(*r)->~Imp();
+	free(*r);
+	*r = 0L;
+	del++;
+      }
+    }
+    filled -= del;
+    block->filled -= del;
+    block = block->next;
+  }
+
+  // delete the emtpy containers
+  block = root;
+  while (block) {
+    CollectorBlock *next = block->next;
+    if (block->filled == 0) {
+      if (block->prev)
+	block->prev->next = next;
+      if (block == root)
+	root = next;
+      if (next)
+	next->prev = block->prev;
+      if (block == currentBlock) // we don't want a dangling pointer
+	currentBlock = 0L;
+      assert(block != root);
+      delete block;
+    }
+    block = next;
+  }
+
+#ifdef KJS_DEBUG_MEM
+  collecting = false;
+#endif
+}
diff --git a/JavaScriptCore/kjs/collector.h b/JavaScriptCore/kjs/collector.h
new file mode 100644
index 0000000..7e88e7f
--- /dev/null
+++ b/JavaScriptCore/kjs/collector.h
@@ -0,0 +1,91 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _KJSCOLLECTOR_H_
+#define _KJSCOLLECTOR_H_
+
+// KJS_MEM_LIMIT and KJS_MEM_INCREMENT can be tweaked to adjust how the
+// garbage collector allocates memory. KJS_MEM_LIMIT is the largest # of objects
+// the collector will allow to be present in memory. Once this limit is reached,
+// a running script will get an "out of memory" exception.
+//
+// KJS_MEM_INCREMENT specifies the amount by which the "soft limit" on memory is
+// increased when the memory gets filled up. The soft limit is the amount after
+// which the GC will run and delete unused objects.
+//
+// If you are debugging seemingly random crashes where an object has been deleted,
+// try setting KJS_MEM_INCREMENT to something small, e.g. 300, to force garbage
+// collection to happen more often, and disable the softLimit increase &
+// out-of-memory testing code in Collector::allocate()
+
+#define KJS_MEM_LIMIT 500000
+#define KJS_MEM_INCREMENT 1000
+
+#include <stdlib.h>
+
+namespace KJS {
+
+  class Imp;
+  class CollectorBlock;
+
+  /**
+   * @short Garbage collector.
+   */
+  class Collector {
+    // disallow direct construction/destruction
+    Collector();
+  public:
+    /**
+     * Register an object with the collector. The following assumptions are
+     * made:
+     * @li the operator new() of the object class is overloaded.
+     * @li operator delete() has been overloaded as well and does not free
+     * the memory on its own.
+     *
+     * @param s Size of the memory to be registered.
+     * @return A pointer to the allocated memory.
+     */
+    static void* allocate(size_t s);
+    /**
+     * Run the garbage collection. This involves calling the delete operator
+     * on each object and freeing the used memory.
+     * In the current implemenation this will basically free all registered
+     * object regardless whether they are still references by others or not.
+     * 
+     */
+    static void collect();
+    static int size() { return filled; }
+
+#ifdef KJS_DEBUG_MEM
+    /**
+     * @internal
+     */
+    static bool collecting;
+#endif
+  private:
+    static CollectorBlock* root;
+    static CollectorBlock* currentBlock;
+    static unsigned long filled;
+    static unsigned long softLimit;
+    enum { BlockSize = 100 };
+  };
+
+};
+
+#endif
diff --git a/JavaScriptCore/kjs/configure.in.in b/JavaScriptCore/kjs/configure.in.in
new file mode 100644
index 0000000..d789ce3
--- /dev/null
+++ b/JavaScriptCore/kjs/configure.in.in
@@ -0,0 +1,51 @@
+dnl KDE JavaScript specific configure tests
+
+AC_CHECK_HEADERS(ieeefp.h float.h)
+AC_CHECK_LIB(m, isinf, [
+  AC_DEFINE_UNQUOTED(HAVE_FUNC_ISINF, 1, [Define if you have isinf])
+])
+AC_CHECK_LIB(m, finite, [
+  AC_DEFINE_UNQUOTED(HAVE_FUNC_FINITE, 1, [Define if you have finite])
+])
+AC_CHECK_LIB(m, _finite, [
+  AC_DEFINE_UNQUOTED(HAVE_FUNC__FINITE, 1, [Define if you have _finite])
+])
+AC_CHECK_LIB(m, isnan, [
+  AC_DEFINE_UNQUOTED(HAVE_FUNC_ISNAN, 1, [Define if you have isnan])
+])
+
+AC_DEFUN(AC_CHECK_PCREPOSIX,
+[
+  AC_MSG_CHECKING([for pcreposix])
+  AC_CACHE_VAL(ac_cv_have_pcreposix,
+  [
+    ac_save_libs="$LIBS"
+    KDE_FIND_PATH(pcre-config, PCRE_CONFIG, [${prefix}/bin /usr/local/bin /opt/local/bin], [PCRE_CONFIG="" ])
+    if test -n "$PCRE_CONFIG" && $PCRE_CONFIG --libs >/dev/null 2>&1; then
+        LIBS=`$PCRE_CONFIG --libs --libs-posix`
+        CPPFLAGS="$CPPFLAGS `$PCRE_CONFIG --cflags`"
+    else
+        LIBS="-lpcre -lpcreposix"
+    fi
+    ac_CPPFLAGS_save="$CPPFLAGS"
+    CPPFLAGS="$CPPFLAGS $all_includes"
+    ac_LDFLAGS_save="$LDFLAGS"
+    LDFLAGS="$LDFLAGS $all_libraries"
+    AC_TRY_LINK(
+      [#include <pcreposix.h>],
+      [regfree(0);],
+      [ac_cv_have_pcreposix="yes"],
+      [ac_cv_have_pcreposix="no"]
+    )
+    LIBS="$ac_save_libs"
+    LDFLAGS="$ac_LDFLAGS_save"
+    CPPFLAGS="$ac_CPPFLAGS_save"
+  ])
+  AC_MSG_RESULT($ac_cv_have_pcreposix)
+  if test "$ac_cv_have_pcreposix" = "yes"; then
+    LIBPCRE="-lpcre -lpcreposix"
+    AC_DEFINE(HAVE_PCREPOSIX, 1, [Define if you have pcreposix libraries and header files.])
+  fi
+])
+AC_CHECK_PCREPOSIX
+AC_SUBST(LIBPCRE)
diff --git a/JavaScriptCore/kjs/create_hash_table b/JavaScriptCore/kjs/create_hash_table
new file mode 100755
index 0000000..85c6744
--- /dev/null
+++ b/JavaScriptCore/kjs/create_hash_table
@@ -0,0 +1,116 @@
+#! /usr/bin/perl
+
+$file = $ARGV[0];
+open(IN, $file) or die "No such file $file";
+
+ at keys = ();
+ at values = ();
+ at attrs = ();
+
+my $inside = 0;
+my $name;
+my $size;
+my $hashsize;
+my $banner = 0;
+
+while (<IN>) {
+  chop; 
+  s/^\s*//g; 
+  if (/^\#|^$/) {
+      # comment. do nothing
+    } elsif (/^\@begin\s*(\w+)\s*(\d+)\s*$/ && !$inside) {
+      $inside = 1;
+      $name = $1;
+      $hashsize = $2;
+    } elsif (/^\@end\s*$/ && $inside) {
+      calcTable();
+      output();
+      @keys = ();
+      @values = ();
+      @attrs = ();
+      $inside = 0;
+    } elsif (/^(\w+)\s*([\w\:]+)\s*([\w\|]*)\s*$/ && $inside) {
+      push(@keys, $1);
+      push(@values, $2);
+      push(@attrs, length($3) > 0 ? $3 : "0");
+    } else {
+      die "invalid data";
+    }
+}
+
+die "missing closing \@end" if ($inside);
+
+sub calcTable() {
+  @table = ();
+  @links = ();
+  $size = $hashsize;
+  my $collisions = 0;
+  my $i = 0;
+  foreach $key (@keys) {
+    my $h = hashValue($key) % $hashsize;
+    while (defined($table[$h])) {
+      if (defined($links[$h])) {
+	$h = $links[$h];
+      } else {
+	$collisions++;
+	$links[$h] = $size;
+	$h = $size;
+	$size++;
+      }
+    }
+    $table[$h] = $i;
+    $i++;
+  }
+
+# print "// Number of collisions: $collisions\n";
+#  printf "total size: $size\n";
+#  my $i = 0;
+#  foreach $entry (@table) {
+#    print "$i " . $entry;
+#    print " -> " . $links[$i] if (defined($links[$i]));
+#    print "\n";
+#    $i++;
+#  }
+}
+
+sub hashValue {
+  @chars = split(/ */, @_[0]);
+  my $val = 0;
+  foreach $c (@chars) {
+    $val += ord($c);
+  }
+  return $val;
+}
+
+sub output {
+  if (!$banner) {
+    $banner = 1;
+    print "/* automatically generated from $file. DO NOT EDIT ! */\n";
+  }
+
+  print "\nnamespace KJS {\n";
+  print "\nconst struct HashEntry2 ${name}Entries[] = {\n";
+  my $i = 0;
+  foreach $entry (@table) {
+    if (defined($entry)) {
+      my $key = $keys[$entry];
+      print "   \{ \"" . $key . "\"";
+      print ", " . $values[$entry];
+      print ", " . $attrs[$entry] . ", ";
+      if (defined($links[$i])) {
+	print "&${name}Entries[$links[$i]]" . " \}";
+      } else {
+	print "0 \}"
+      }
+    } else {
+      print "   \{ 0, 0, 0, 0 \}";
+    }
+    print "," unless ($i == $size - 1);
+    print "\n";
+    $i++;
+  }
+  print "};\n";
+  print "\nconst struct HashTable2 $name = ";
+  print "\{ 2, $size, ${name}Entries, $hashsize \};\n\n";
+  print "}; // namespace\n";
+}
diff --git a/JavaScriptCore/kjs/date_object.cpp b/JavaScriptCore/kjs/date_object.cpp
new file mode 100644
index 0000000..ab81504
--- /dev/null
+++ b/JavaScriptCore/kjs/date_object.cpp
@@ -0,0 +1,466 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#ifndef HAVE_SYS_TIMEB_H
+#define HAVE_SYS_TIMEB_H 0
+#endif
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+#if HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#  include <time.h>
+# endif
+#endif
+#if HAVE_SYS_TIMEB_H
+#include <sys/timeb.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#  include <sys/param.h>
+#endif // HAVE_SYS_PARAM_H
+
+#include <math.h>
+#include <string.h>
+#include <stdio.h>
+#include <locale.h>
+
+#include "kjs.h"
+#include "date_object.h"
+
+namespace KJS {
+
+  class DateObjectFunc : public InternalFunctionImp {
+  public:
+    DateObjectFunc(int i) : id(i) { };
+    Completion execute(const List &);
+    enum { Parse, UTC };
+  private:
+    int id;
+  };
+
+  class DateProtoFunc : public InternalFunctionImp {
+  public:
+    DateProtoFunc(int i, bool u);
+    Completion execute(const List &);
+    enum { ToString, ToDateString, ToTimeString, ToLocaleString,
+	   ToLocaleDateString, ToLocaleTimeString, ValueOf, GetTime,
+	   GetFullYear, GetMonth, GetDate, GetDay, GetHours, GetMinutes,
+	   GetSeconds, GetMilliSeconds, GetTimezoneOffset, SetTime,
+	   SetMilliSeconds, SetSeconds, SetMinutes, SetHours, SetDate,
+	   SetMonth, SetFullYear, ToUTCString,
+	   // non-normative properties (Appendix B)
+	   GetYear, SetYear, ToGMTString };
+  private:
+    int id;
+    bool utc;
+  };
+
+  // helper functions
+  KJSO parseDate(const String &s);
+  KJSO timeClip(const KJSO &t);
+};
+
+using namespace KJS;
+
+KJSO KJS::parseDate(const String &s)
+{
+  UString u = s.value();
+  int firstSlash = u.find('/');
+  if ( firstSlash == -1 )
+  {
+    /* TODO parse dates like "December 25, 1995 23:15:00"*/
+    fprintf(stderr,"KJS::parseDate parsing for this format isn't implemented\n%s", u.ascii());
+    return Number(0);
+  }
+  else
+  {
+    // Found 12/31/2099 on some website -> obviously MM/DD/YYYY
+    int month = u.substr(0,firstSlash).toULong();
+    int secondSlash = u.find('/',firstSlash+1);
+    //fprintf(stdout,"KJS::parseDate firstSlash=%d, secondSlash=%d\n", firstSlash, secondSlash);
+    if ( secondSlash == -1 )
+    {
+      fprintf(stderr,"KJS::parseDate parsing for this format isn't implemented\n%s", u.ascii());
+      return Number(0);
+    }
+    int day = u.substr(firstSlash+1,secondSlash-firstSlash-1).toULong();
+    int year = u.substr(secondSlash+1).toULong();
+    //fprintf(stdout,"KJS::parseDate day=%d, month=%d, year=%d\n", day, month, year);
+    struct tm t;
+    memset( &t, 0, sizeof(t) );
+    year = (year > 2037) ? 2037 : year; // mktime is limited to 2037 !!!
+    t.tm_year = (year >= 0 && year <= 99) ? year : year - 1900;
+    t.tm_mon = month-1; // mktime wants 0-11 for some reason
+    t.tm_mday = day;
+    time_t seconds = mktime(&t);
+    if ( seconds == -1 )
+    {
+      fprintf(stderr,"KJS::parseDate mktime returned -1.\n%s", u.ascii());
+      return Undefined();
+    }
+    else
+      return Number(seconds * 1000.0);
+  }
+}
+
+KJSO KJS::timeClip(const KJSO &t)
+{
+  /* TODO */
+  return t;
+}
+
+DateObject::DateObject(const Object& funcProto, const Object &dateProto)
+    : ConstructorImp(funcProto, 7)
+{
+  // ECMA 15.9.4.1 Date.prototype
+  setPrototypeProperty(dateProto);
+}
+
+// ECMA 15.9.2
+Completion DateObject::execute(const List &)
+{
+  time_t t = time(0L);
+  UString s(ctime(&t));
+
+  // return formatted string minus trailing \n
+  return Completion(ReturnValue, String(s.substr(0, s.size() - 1)));
+}
+
+// ECMA 15.9.3
+Object DateObject::construct(const List &args)
+{
+  KJSO value;
+
+  int numArgs = args.size();
+
+  if (numArgs == 0) { // new Date() ECMA 15.9.3.3
+#if HAVE_SYS_TIMEB_H
+#  if defined(__BORLANDC__)
+    struct timeb timebuffer;
+    ftime(&timebuffer);
+#  else
+    struct _timeb timebuffer;
+    _ftime(&timebuffer);
+#  endif
+    double utc = floor((double)timebuffer.time * 1000.0 + (double)timebuffer.millitm);
+#else
+    struct timeval tv;
+    gettimeofday(&tv, 0L);
+    double utc = floor((double)tv.tv_sec * 1000.0 + (double)tv.tv_usec / 1000.0);
+#endif
+    value = Number(utc);
+  } else if (numArgs == 1) {
+    KJSO p = args[0].toPrimitive();
+    if (p.isA(StringType))
+      value = parseDate(p.toString());
+    else
+      value = p.toNumber();
+  } else {
+    struct tm t;
+    memset(&t, 0, sizeof(t));
+    Number y = args[0].toNumber();
+    /* TODO: check for NaN */
+    int year = y.toInt32();
+    t.tm_year = (year >= 0 && year <= 99) ? year : year - 1900;
+    t.tm_mon = args[1].toInt32();
+    t.tm_mday = (numArgs >= 3) ? args[2].toInt32() : 1;
+    t.tm_hour = (numArgs >= 4) ? args[3].toInt32() : 0;
+    t.tm_min = (numArgs >= 5) ? args[4].toInt32() : 0;
+    t.tm_sec = (numArgs >= 6) ? args[5].toInt32() : 0;
+    t.tm_isdst = -1;
+    int ms = (numArgs >= 7) ? args[6].toInt32() : 0;
+    value = Number(mktime(&t) * 1000.0 + ms);
+  }
+
+  return Object::create(DateClass, timeClip(value));
+}
+
+KJSO DateObject::get(const UString &p) const
+{
+  int id;
+
+  if (p == "parse")
+    id = DateObjectFunc::Parse;
+  else if (p == "UTC")
+    id = DateObjectFunc::UTC;
+  else
+    return Imp::get(p);
+
+  return Function(new DateObjectFunc(id));
+}
+
+// ECMA 15.9.4.2 - 3
+Completion DateObjectFunc::execute(const List &args)
+{
+  KJSO result;
+
+  if (id == Parse)
+    if (args[0].isA(StringType))
+      result = parseDate(args[0].toString());
+    else
+      result = Undefined();
+  else {
+    struct tm t;
+    memset(&t, 0, sizeof(t));
+    int n = args.size();
+    Number y = args[0].toNumber();
+    /* TODO: check for NaN */
+    int year = y.toInt32();
+    t.tm_year = (year >= 0 && year <= 99) ? year : year - 1900;
+    t.tm_mon = args[1].toInt32();
+    t.tm_mday = (n >= 3) ? args[2].toInt32() : 1;
+    t.tm_hour = (n >= 4) ? args[3].toInt32() : 0;
+    t.tm_min = (n >= 5) ? args[4].toInt32() : 0;
+    t.tm_sec = (n >= 6) ? args[5].toInt32() : 0;
+    int ms = (n >= 7) ? args[6].toInt32() : 0;
+    result = Number(mktime(&t) * 1000.0 + ms);
+  }
+
+  return Completion(ReturnValue, result);
+}
+
+// ECMA 15.9.4
+DatePrototype::DatePrototype(const Object& proto)
+  : ObjectImp(DateClass, Number(NaN), proto)
+{
+  // The constructor will be added later in DateObject's constructor
+}
+
+KJSO DatePrototype::get(const UString &p) const
+{
+  int id;
+
+  if (p == "toString" || p == "toUTCString")
+    id = DateProtoFunc::ToString;
+  else if (p == "toDateString")
+    id = DateProtoFunc::ToDateString;
+  else if (p == "toTimeString")
+    id = DateProtoFunc::ToTimeString;
+  else if (p == "toLocaleString")
+    id = DateProtoFunc::ToLocaleString;
+  else if (p == "toLocaleDateString")
+    id = DateProtoFunc::ToLocaleDateString;
+  else if (p == "toLocaleTimeString")
+    id = DateProtoFunc::ToLocaleTimeString;
+  else if (p == "valueOf")
+    id = DateProtoFunc::ValueOf;
+  else if (p == "getTime")
+    id = DateProtoFunc::GetTime;
+  else if (p == "getFullYear" || p == "getUTCFullYear")
+    id = DateProtoFunc::GetFullYear;
+  else if (p == "toGMTString")
+    id = DateProtoFunc::ToGMTString;
+  else if (p == "getMonth" || p == "getUTCMonth")
+    id = DateProtoFunc::GetMonth;
+  else if (p == "getDate" || p == "getUTCDate")
+    id = DateProtoFunc::GetDate;
+  else if (p == "getDay" || p == "getUTCDay")
+    id = DateProtoFunc::GetDay;
+  else if (p == "getHours" || p == "getUTCHours")
+    id = DateProtoFunc::GetHours;
+  else if (p == "getMinutes" || p == "getUTCMinutes")
+    id = DateProtoFunc::GetMinutes;
+  else if (p == "getSeconds" || p == "getUTCSeconds")
+    id = DateProtoFunc::GetSeconds;
+  else if (p == "getMilliseconds" || p == "getUTCMilliseconds")
+    id = DateProtoFunc::GetMilliSeconds;
+  else if (p == "getTimezoneOffset")
+    id = DateProtoFunc::GetTimezoneOffset;
+  else if (p == "setTime")
+    id = DateProtoFunc::SetTime;
+  else if (p == "setMilliseconds" || p == "setUTCMilliseconds")
+    id = DateProtoFunc::SetMilliSeconds;
+  else if (p == "setSeconds" || p == "setUTCSeconds")
+    id = DateProtoFunc::SetSeconds;
+  else if (p == "setMinutes" || p == "setUTCMinutes")
+    id = DateProtoFunc::SetMinutes;
+  else if (p == "setHours" || p == "setUTCHours")
+    id = DateProtoFunc::SetHours;
+  else if (p == "setDate" || p == "setUTCDate")
+    id = DateProtoFunc::SetDate;
+  else if (p == "setMonth" || p == "setUTCMonth")
+    id = DateProtoFunc::SetMonth;
+  else if (p == "setFullYear" || p == "setUTCFullYear")
+    id = DateProtoFunc::SetFullYear;
+  else if (p == "setYear" )
+    id = DateProtoFunc::SetYear;
+  // non-normative
+  else if (p == "getYear")
+    id = DateProtoFunc::GetYear;
+  else if (p == "toGMTString")
+    id = DateProtoFunc::ToGMTString;
+  else
+    return Undefined();
+
+  bool utc = (p.find("UTC") >= 0) ? true : false;
+  return Function(new DateProtoFunc(id, utc));
+}
+
+DateProtoFunc::DateProtoFunc(int i, bool u) : id(i), utc(u)
+{
+}
+
+Completion DateProtoFunc::execute(const List &args)
+{
+  KJSO result;
+  UString s;
+  const int bufsize=100;
+  char timebuffer[bufsize];
+  char *oldlocale = setlocale(LC_TIME,NULL);
+  if (!oldlocale)
+    oldlocale = setlocale(LC_ALL, NULL);
+  Object thisObj = Object::dynamicCast(thisValue());
+  KJSO v = thisObj.internalValue();
+  double milli = v.toNumber().value();
+  time_t tv = (time_t) floor(milli / 1000.0);
+  int ms = int(milli - tv * 1000.0);
+
+  struct tm *t;
+  if (utc)
+    t = gmtime(&tv);
+  else
+    t = localtime(&tv);
+
+  switch (id) {
+  case ToString:
+    s = ctime(&tv);
+    result = String(s.substr(0, s.size() - 1));
+    break;
+  case ToDateString:
+  case ToTimeString:
+  case ToGMTString:
+    setlocale(LC_TIME,"C");
+    if (id == DateProtoFunc::ToDateString) {
+      strftime(timebuffer, bufsize, "%x",t);
+    } else if (id == DateProtoFunc::ToTimeString) {
+      strftime(timebuffer, bufsize, "%X",t);
+    } else {
+      t = gmtime(&tv);
+      strftime(timebuffer, bufsize, "%a, %d-%b-%y %H:%M:%S %Z", t);
+    }
+    setlocale(LC_TIME,oldlocale);
+    result = String(timebuffer);
+    break;
+  case ToLocaleString:
+    strftime(timebuffer, bufsize, "%c", t);
+    result = String(timebuffer);
+    break;
+  case ToLocaleDateString:
+    strftime(timebuffer, bufsize, "%x", t);
+    result = String(timebuffer);
+    break;
+  case ToLocaleTimeString:
+    strftime(timebuffer, bufsize, "%X", t);
+    result = String(timebuffer);
+    break;
+  case ValueOf:
+    result = Number(milli);
+    break;
+  case GetTime:
+    if (thisObj.getClass() == DateClass)
+      result = Number(milli);
+    else
+      result = Error::create(TypeError);
+    break;
+  case GetYear:
+    result = Number(t->tm_year);
+    break;
+  case GetFullYear:
+    result = Number(1900 + t->tm_year);
+    break;
+  case GetMonth:
+    result = Number(t->tm_mon);
+    break;
+  case GetDate:
+    result = Number(t->tm_mday);
+    break;
+  case GetDay:
+    result = Number(t->tm_wday);
+    break;
+  case GetHours:
+    result = Number(t->tm_hour);
+    break;
+  case GetMinutes:
+    result = Number(t->tm_min);
+    break;
+  case GetSeconds:
+    result = Number(t->tm_sec);
+    break;
+  case GetMilliSeconds:
+    result = Undefined();
+    break;
+  case GetTimezoneOffset:
+#if defined BSD || defined(__APPLE__)
+    result = Number(-( t->tm_gmtoff / 60 ) + ( t->tm_isdst ? 60 : 0 ));
+#else
+#  if defined(__BORLANDC__)
+#error please add daylight savings offset here!
+    result = Number(_timezone / 60 - (_daylight ? 60 : 0));
+#  else
+    result = Number(( timezone / 60 - ( daylight ? 60 : 0 )));
+#  endif
+#endif
+    break;
+  case SetTime:
+    milli = args[0].round();
+    result = Number(milli);
+    thisObj.setInternalValue(result);
+    break;
+  case SetMilliSeconds:
+    ms = args[0].toInt32();
+    break;
+  case SetSeconds:
+    t->tm_sec = args[0].toInt32();
+    break;
+  case SetMinutes:
+    t->tm_min = args[0].toInt32();
+    break;
+  case SetHours:
+    t->tm_hour = args[0].toInt32();
+    break;
+  case SetDate:
+    t->tm_mday = args[0].toInt32();
+    break;
+  case SetMonth:
+    t->tm_mon = args[0].toInt32();
+    break;
+  case SetFullYear:
+    t->tm_year = args[0].toInt32() - 1900;
+    break;
+  case SetYear:
+    t->tm_year = args[0].toInt32() >= 1900 ? args[0].toInt32() - 1900 : args[0].toInt32();
+    break;
+  }
+
+  if (id == SetYear || id == SetMilliSeconds || id == SetSeconds ||
+      id == SetMinutes || id == SetHours || id == SetDate ||
+      id == SetMonth || id == SetFullYear ) {
+    result = Number(mktime(t) * 1000.0 + ms);
+    thisObj.setInternalValue(result);
+  }
+
+  return Completion(ReturnValue, result);
+}
diff --git a/JavaScriptCore/kjs/date_object.h b/JavaScriptCore/kjs/date_object.h
new file mode 100644
index 0000000..5eed675
--- /dev/null
+++ b/JavaScriptCore/kjs/date_object.h
@@ -0,0 +1,44 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _DATE_OBJECT_H_
+#define _DATE_OBJECT_H_
+
+#include "object.h"
+#include "function.h"
+
+namespace KJS {
+
+  class DateObject : public ConstructorImp {
+  public:
+    DateObject(const Object& funcProto, const Object &dateProto);
+    Completion execute(const List &);
+    Object construct(const List &);
+    KJSO get(const UString &p) const;
+  };
+
+  class DatePrototype : public ObjectImp {
+  public:
+    DatePrototype(const Object& proto);
+    virtual KJSO get(const UString &p) const;
+  };
+
+}; // namespace
+
+#endif
diff --git a/JavaScriptCore/kjs/debugger.cpp b/JavaScriptCore/kjs/debugger.cpp
new file mode 100644
index 0000000..e0f3859
--- /dev/null
+++ b/JavaScriptCore/kjs/debugger.cpp
@@ -0,0 +1,229 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2001 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef KJS_DEBUGGER
+
+#include "debugger.h"
+#include "kjs.h"
+#include "internal.h"
+#include "ustring.h"
+
+using namespace KJS;
+
+Debugger::Debugger(KJScript *engine)
+  : eng(0L),
+    sid(-1)
+{
+  attach(engine);
+}
+
+Debugger::~Debugger()
+{
+  detach();
+}
+
+void Debugger::attach(KJScript *e)
+{
+  dmode = Disabled;
+  if (e) {
+    if (!eng || e->rep != eng->rep) {
+      eng = e;
+      eng->rep->attachDebugger(this);
+    }
+  } else {
+    eng = 0L;
+  }
+  reset();
+}
+
+KJScript *Debugger::engine() const
+{
+  return eng;
+}
+
+void Debugger::detach()
+{
+  reset();
+  if (!eng)
+    return;
+  eng->rep->attachDebugger(0L);
+  eng = 0L;
+}
+
+void Debugger::setMode(Mode m)
+{
+  dmode = m;
+}
+
+Debugger::Mode Debugger::mode() const
+{
+  return dmode;
+}
+
+// supposed to be overriden by the user
+bool Debugger::stopEvent()
+{
+  return true;
+}
+
+void Debugger::callEvent(const UString &, const UString &)
+{
+}
+
+void Debugger::returnEvent()
+{
+}
+
+void Debugger::reset()
+{
+  l = -1;
+}
+
+int Debugger::freeSourceId() const
+{
+  return eng ? eng->rep->sourceId()+1 : -1;
+}
+
+bool Debugger::setBreakpoint(int id, int line)
+{
+  if (!eng)
+    return false;
+  return eng->rep->setBreakpoint(id, line, true);
+}
+
+bool Debugger::deleteBreakpoint(int id, int line)
+{
+  if (!eng)
+    return false;
+  return eng->rep->setBreakpoint(id, line, false);
+}
+
+void Debugger::clearAllBreakpoints(int id)
+{
+  if (!eng)
+    return;
+  eng->rep->setBreakpoint(id, -1, false);
+}
+
+UString Debugger::varInfo(const UString &ident)
+{
+  if (!eng)
+    return UString();
+
+  int dot = ident.find('.');
+  if (dot < 0)
+      dot = ident.size();
+  UString sub = ident.substr(0, dot);
+  KJSO obj;
+  // resolve base
+  if (sub == "this") {
+      obj = Context::current()->thisValue();
+  } else {
+      const List *chain = Context::current()->pScopeChain();
+      ListIterator scope = chain->begin();
+      while (scope != chain->end()) {
+	  if (scope->hasProperty(ident)) {
+	      obj = scope->get(ident);
+	      break;
+	  }
+	  scope++;
+      }
+      if (scope == chain->end())
+	return UString();
+  }
+  // look up each part of a.b.c.
+  while (dot < ident.size()) {
+    int olddot = dot;
+    dot = ident.find('.', olddot+1);
+    if (dot < 0)
+      dot = ident.size();
+    sub = ident.substr(olddot+1, dot-olddot-1);
+    obj = obj.get(sub);
+    if (!obj.isDefined())
+      break;
+  }
+
+  return sub + "=" + objInfo(obj) + ":" + UString(obj.imp()->typeInfo()->name);
+}
+
+// called by varInfo() and recursively by itself on each properties
+UString Debugger::objInfo(const KJSO &obj) const
+{
+  const char *cnames[] = { "Undefined", "Array", "String", "Boolean",
+			   "Number", "Object", "Date", "RegExp",
+			   "Error", "Function" };
+  PropList *plist = obj.imp()->propList(0, 0, false);
+  if (!plist)
+    return obj.toString().value();
+  else {
+    UString result = "{";
+    while (1) {
+      result += plist->name + "=";
+      KJSO p = obj.get(plist->name);
+      result += objInfo(p) + ":";
+      Object obj = Object::dynamicCast(p);
+      if (obj.isNull())
+	result += p.imp()->typeInfo()->name;
+      else
+	result += cnames[int(obj.getClass())];
+      plist = plist->next;
+      if (!plist)
+	break;
+      result += ",";
+    }
+    result += "}";
+    return result;
+  }
+}
+
+bool Debugger::setVar(const UString &ident, const KJSO &value)
+{
+  if (!eng)
+    return false;
+  const List *chain = Context::current()->pScopeChain();
+  ListIterator scope = chain->begin();
+  while (scope != chain->end()) {
+    if (scope->hasProperty(ident)) {
+      if (!scope->canPut(ident))
+	return false;
+      scope->put(ident, value);
+      return true;
+    }
+    scope++;
+  }
+  // didn't find variable
+  return false;
+}
+
+// called from the scripting engine each time a statement node is hit.
+bool Debugger::hit(int line, bool breakPoint)
+{
+  l = line;
+  if (!eng)
+    return true;
+
+  if (!breakPoint && ( mode() == Continue || mode() == Disabled ) )
+      return true;
+
+  bool ret = stopEvent();
+  eng->init();	// in case somebody used a different interpreter meanwhile
+  return ret;
+}
+
+#endif
diff --git a/JavaScriptCore/kjs/debugger.h b/JavaScriptCore/kjs/debugger.h
new file mode 100644
index 0000000..b0e97fe
--- /dev/null
+++ b/JavaScriptCore/kjs/debugger.h
@@ -0,0 +1,150 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2001 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _KJSDEBUGGER_H_
+#define _KJSDEBUGGER_H_
+
+#include "internal.h"
+
+namespace KJS {
+
+  //
+  // NOTE: this interface is not ready, yet. Do not use unless you
+  // don't mind source and binary incompatible changes that may arise
+  // before the final version is released.
+  //
+
+#ifdef KJS_DEBUGGER
+  class Debugger {
+    friend class KJScriptImp;
+    friend class StatementNode;
+    friend class DeclaredFunctionImp;
+    friend class FunctionImp;
+  public:
+    /**
+     * Available modes of the debugger.
+     */
+    enum Mode { Disabled = 0, Next, Step, Continue, Stop };
+    /**
+     * Construct a debugger and attach it to the scripting engine s.
+     */
+    Debugger(KJScript *s);
+    /**
+     * Destruct the debugger and detach from the scripting engine we
+     * might have been attached to.
+     */
+    virtual ~Debugger();
+    /**
+     * Attaches the debugger to specified scripting engine.
+     */
+    void attach(KJScript *e);
+    /**
+     * Returns the engine the interpreter is currently attached to. Null
+     * if there isn't any.
+     */
+    KJScript* engine() const;
+    /**
+     * Detach the debugger from any scripting engine.
+     */
+    void detach();
+    /**
+     * Set debugger into specified mode. This will influence further behaviour
+     * if execution of the programm is started or continued.
+     */
+    virtual void setMode(Mode m);
+    /**
+     * Returns the current operation mode.
+     */
+    Mode mode() const;
+    /**
+     * Returns the line number the debugger currently has stopped at.
+     * -1 if the debugger is not in a break status.
+     */
+    int lineNumber() const { return l; }
+    /**
+     * Returns the source id the debugger currently has stopped at.
+     * -1 if the debugger is not in a break status.
+     */
+    int sourceId() const { return sid; }
+    /**
+     * Sets a breakpoint in the first statement where line lies in between
+     * the statements range. Returns true if sucessfull, false if no
+     * matching statement could be found.
+     */
+    bool setBreakpoint(int id, int line);
+    bool deleteBreakpoint(int id, int line);
+    void clearAllBreakpoints(int id=-1);
+    /**
+     * Returns the value of ident out of the current context in string form
+     */
+    UString varInfo(const UString &ident);
+    /**
+     * Set variable ident to value. Returns true if successful, false if
+     * the specified variable doesn't exist or isn't writable.
+     */
+    bool setVar(const UString &ident, const KJSO &value);
+
+  protected:
+    /**
+     * Invoked in case a breakpoint or the next statement is reached in step
+     * mode. The return value decides whether execution will continue. True
+     * denotes continuation, false an abortion, respectively.
+     *
+     * The default implementation does nothing. Overload this method if
+     * you want to process this event.
+     */
+    virtual bool stopEvent();
+    /**
+     * Returns an integer that will be assigned to the code passed
+     * next to one of the KJScript::evaluate() methods. It's basically
+     * a counter to will only be reset to 0 on KJScript::clear().
+     *
+     * This information is useful in case you evaluate multiple blocks of
+     * code containing some function declarations. Keep a map of source id/
+     * code pairs, query sourceId() in case of a stopEvent() and update
+     * your debugger window with the matching source code.
+     */
+    int freeSourceId() const;
+    /**
+     * Invoked on each function call. Use together with @ref returnEvent
+     * if you want to keep track of the call stack.
+     */
+    virtual void callEvent(const UString &fn = UString::null,
+				    const UString &s = UString::null);
+    /**
+     * Invoked on each function exit.
+     */
+    virtual void returnEvent();
+
+  private:
+    void reset();
+    bool hit(int line, bool breakPoint);
+    void setSourceId(int i) { sid = i; }
+    UString objInfo(const KJSO &obj) const;
+
+    KJScript *eng;
+    Mode dmode;
+    int l;
+    int sid;
+  };
+#endif
+
+};
+
+#endif
diff --git a/JavaScriptCore/kjs/error_object.cpp b/JavaScriptCore/kjs/error_object.cpp
new file mode 100644
index 0000000..a5aa6d8
--- /dev/null
+++ b/JavaScriptCore/kjs/error_object.cpp
@@ -0,0 +1,125 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "kjs.h"
+#include "operations.h"
+#include "types.h"
+#include "internal.h"
+#include "error_object.h"
+#include "debugger.h"
+
+using namespace KJS;
+
+const char *ErrorObject::errName[] = {
+  "No Error",
+  "Error",
+  "EvalError",
+  "RangeError",
+  "ReferenceError",
+  "SyntaxError",
+  "TypeError",
+  "URIError"
+};
+
+ErrorObject::ErrorObject(const Object &funcProto, const Object &errProto,
+			 ErrorType t)
+  : ConstructorImp(funcProto, 1), errType(t)
+{
+  // ECMA 15.11.3.1 Error.prototype
+  setPrototypeProperty(errProto);
+  const char *n = errName[errType];
+
+  put("name", String(n));
+}
+
+ErrorObject::ErrorObject(const Object& proto, ErrorType t,
+			 const char *m, int l)
+  : ConstructorImp(proto, 1), errType(t)
+{
+  const char *n = errName[errType];
+
+  put("name", String(n));
+  put("message", String(m));
+  put("line", Number(l));
+#ifdef KJS_DEBUGGER
+  Debugger *dbg = KJScriptImp::current()->debugger();
+  if (dbg)
+    put("sid", Number(dbg->sourceId()));
+#endif
+}
+
+// ECMA 15.9.2
+Completion ErrorObject::execute(const List &args)
+{
+  // "Error()" gives the sames result as "new Error()"
+  return Completion(ReturnValue, construct(args));
+}
+
+// ECMA 15.9.3
+Object ErrorObject::construct(const List &args)
+{
+  if (args.isEmpty() == 1 || !args[0].isDefined())
+    return Object::create(ErrorClass, Undefined());
+
+  String message = args[0].toString();
+  return Object::create(ErrorClass, message);
+}
+
+Object ErrorObject::create(ErrorType e, const char *m, int l)
+{
+  Global global(Global::current());
+  KJSO prot = Global::current().get("[[Error.prototype]]");
+  assert(prot.isObject());
+  Imp *d = new ErrorObject(Object(prot.imp()), e, m, l);
+
+  return Object(d);
+}
+
+// ECMA 15.9.4
+ErrorPrototype::ErrorPrototype(const Object& proto)
+  : ObjectImp(ErrorClass, Undefined(), proto)
+{
+  // The constructor will be added later in ErrorObject's constructor
+}
+
+KJSO ErrorPrototype::get(const UString &p) const
+{
+  const char *s;
+
+  /* TODO: are these properties dynamic, i.e. should we put() them ? */
+  if (p == "name")
+    s = "Error";
+  else if (p == "message")
+    s = "Error message.";
+  else if (p == "toString")
+    return Function(new ErrorProtoFunc());
+  else
+    return Imp::get(p);
+
+  return String(s);
+}
+
+Completion ErrorProtoFunc::execute(const List &)
+{
+  // toString()
+  const char *s = "Error message.";
+
+  return Completion(ReturnValue, String(s));
+}
+
diff --git a/JavaScriptCore/kjs/error_object.h b/JavaScriptCore/kjs/error_object.h
new file mode 100644
index 0000000..8e515f0
--- /dev/null
+++ b/JavaScriptCore/kjs/error_object.h
@@ -0,0 +1,55 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _ERROR_OBJECT_H_
+#define _ERROR_OBJECT_H_
+
+#include "object.h"
+#include "function.h"
+
+namespace KJS {
+
+  class ErrorObject : public ConstructorImp {
+  public:
+    ErrorObject(const Object &funcProto, const Object &errProto,
+		ErrorType t = GeneralError);
+    ErrorObject(const Object& proto, ErrorType t, const char *m, int l = -1);
+    Completion execute(const List &);
+    Object construct(const List &);
+    static Object create(ErrorType e, const char *m, int ln);
+  private:
+    ErrorType errType;
+    static const char *errName[];
+  };
+
+  class ErrorPrototype : public ObjectImp {
+  public:
+    ErrorPrototype(const Object& proto);
+    virtual KJSO get(const UString &p) const;
+  };
+
+  class ErrorProtoFunc : public InternalFunctionImp {
+  public:
+    ErrorProtoFunc() { }
+    Completion execute(const List &);
+  };
+
+}; // namespace
+
+#endif
diff --git a/JavaScriptCore/kjs/function.cpp b/JavaScriptCore/kjs/function.cpp
new file mode 100644
index 0000000..22db1d2
--- /dev/null
+++ b/JavaScriptCore/kjs/function.cpp
@@ -0,0 +1,355 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#include "function.h"
+
+#include "kjs.h"
+#include "types.h"
+#include "internal.h"
+#include "operations.h"
+#include "nodes.h"
+#ifndef NDEBUG
+#include <stdio.h>
+#endif
+
+using namespace KJS;
+
+const TypeInfo FunctionImp::info = { "Function", FunctionType,
+				      &ObjectImp::info, 0, 0 };
+const TypeInfo InternalFunctionImp::info = { "InternalFunction",
+					      InternalFunctionType,
+					      &FunctionImp::info, 0, 0 };
+const TypeInfo ConstructorImp::info = { "Function", ConstructorType,
+					 &InternalFunctionImp::info, 0, 0 };
+
+namespace KJS {
+
+  class Parameter {
+  public:
+    Parameter(const UString &n) : name(n), next(0L) { }
+    ~Parameter() { delete next; }
+    UString name;
+    Parameter *next;
+  };
+
+};
+
+FunctionImp::FunctionImp()
+  : ObjectImp(/*TODO*/BooleanClass), param(0L)
+{
+}
+
+FunctionImp::FunctionImp(const UString &n)
+  : ObjectImp(/*TODO*/BooleanClass), ident(n), param(0L)
+{
+}
+
+FunctionImp::~FunctionImp()
+{
+  delete param;
+}
+
+KJSO FunctionImp::thisValue() const
+{
+  return KJSO(Context::current()->thisValue());
+}
+
+void FunctionImp::addParameter(const UString &n)
+{
+  Parameter **p = &param;
+  while (*p)
+    p = &(*p)->next;
+
+  *p = new Parameter(n);
+}
+
+void FunctionImp::setLength(int l)
+{
+  put("length", Number(l), ReadOnly|DontDelete|DontEnum);
+}
+
+// ECMA 10.1.3
+void FunctionImp::processParameters(const List *args)
+{
+  KJSO variable = Context::current()->variableObject();
+
+  assert(args);
+
+#ifdef KJS_VERBOSE
+  fprintf(stderr, "---------------------------------------------------\n"
+	  "processing parameters for %s call\n",
+	  name().isEmpty() ? "(internal)" : name().ascii());
+#endif
+
+  if (param) {
+    ListIterator it = args->begin();
+    Parameter **p = &param;
+    while (*p) {
+      if (it != args->end()) {
+#ifdef KJS_VERBOSE
+	fprintf(stderr, "setting parameter %s ", (*p)->name.ascii());
+	printInfo("to", *it);
+#endif
+	variable.put((*p)->name, *it);
+	it++;
+      } else
+	variable.put((*p)->name, Undefined());
+      p = &(*p)->next;
+    }
+  }
+#ifdef KJS_VERBOSE
+  else {
+    for (int i = 0; i < args->size(); i++)
+      printInfo("setting argument", (*args)[i]);
+  }
+#endif
+#ifdef KJS_DEBUGGER
+  if (KJScriptImp::current()->debugger()) {
+    UString argStr;
+    for (int i = 0; i < args->size(); i++) {
+      if (i > 0)
+	argStr += ", ";
+      Imp *a = (*args)[i].imp();
+      argStr += a->toString().value() + " : " +	UString(a->typeInfo()->name);
+    }
+    UString n = name().isEmpty() ? UString( "(internal)" ) : name();
+    KJScriptImp::current()->debugger()->callEvent(n, argStr);
+  }
+#endif
+}
+
+// ECMA 13.2.1
+KJSO FunctionImp::executeCall(Imp *thisV, const List *args)
+{
+  return executeCall(thisV,args,0);
+}
+
+KJSO FunctionImp::executeCall(Imp *thisV, const List *args, const List *extraScope)
+{
+  bool dummyList = false;
+  if (!args) {
+    args = new List();
+    dummyList = true;
+  }
+
+  KJScriptImp *curr = KJScriptImp::current();
+  Context *save = curr->context();
+
+  Context *ctx = new Context(codeType(), save, this, args, thisV);
+  curr->setContext(ctx);
+
+  int numScopes = 0;
+  if (extraScope) {
+    ListIterator scopeIt = extraScope->begin();
+    for (; scopeIt != extraScope->end(); scopeIt++) {
+      KJSO obj(*scopeIt);
+      ctx->pushScope(obj);
+      numScopes++;
+    }
+  }
+
+  // assign user supplied arguments to parameters
+  processParameters(args);
+
+  Completion comp = execute(*args);
+
+  if (dummyList)
+    delete args;
+
+  int i;
+  for (i = 0; i < numScopes; i++)
+    ctx->popScope();
+
+  put("arguments", Null());
+  delete ctx;
+  curr->setContext(save);
+
+#ifdef KJS_VERBOSE
+  if (comp.complType() == Throw)
+    printInfo("throwing", comp.value());
+  else if (comp.complType() == ReturnValue)
+    printInfo("returning", comp.value());
+  else
+    fprintf(stderr, "returning: undefined\n");
+#endif
+#ifdef KJS_DEBUGGER
+  if (KJScriptImp::current()->debugger())
+    KJScriptImp::current()->debugger()->returnEvent();
+#endif
+
+  if (comp.complType() == Throw)
+    return comp.value();
+  else if (comp.complType() == ReturnValue)
+    return comp.value();
+  else
+    return Undefined();
+}
+
+UString FunctionImp::name() const
+{
+  return ident;
+}
+
+InternalFunctionImp::InternalFunctionImp()
+{
+}
+
+InternalFunctionImp::InternalFunctionImp(int l)
+{
+  if (l >= 0)
+    setLength(l);
+}
+
+InternalFunctionImp::InternalFunctionImp(const UString &n)
+  : FunctionImp(n)
+{
+}
+
+String InternalFunctionImp::toString() const
+{
+  if (name().isNull())
+    return UString("(Internal function)");
+  else
+    return UString("function " + name() + "()");
+}
+
+Completion InternalFunctionImp::execute(const List &)
+{
+  return Completion(ReturnValue, Undefined());
+}
+
+ConstructorImp::ConstructorImp() {
+  setPrototype(Global::current().functionPrototype());
+  // TODO ???  put("constructor", this);
+  setLength(1);
+}
+
+ConstructorImp::ConstructorImp(const UString &n)
+  : InternalFunctionImp(n)
+{
+}
+
+ConstructorImp::ConstructorImp(const KJSO &p, int len)
+{
+  setPrototype(p);
+  // TODO ???  put("constructor", *this);
+  setLength(len);
+}
+
+ConstructorImp::ConstructorImp(const UString &n, const KJSO &p, int len)
+  : InternalFunctionImp(n)
+{
+  setPrototype(p);
+  // TODO ???  put("constructor", *this);
+  setLength(len);
+}
+
+ConstructorImp::~ConstructorImp() { }
+
+Completion ConstructorImp::execute(const List &)
+{
+  /* TODO */
+  return Completion(ReturnValue, Null());
+}
+
+Function::Function(Imp *d)
+  : KJSO(d)
+{
+  if (d) {
+    static_cast<FunctionImp*>(rep)->attr = ImplicitNone;
+    assert(Global::current().hasProperty("[[Function.prototype]]"));
+    setPrototype(Global::current().functionPrototype());
+  }
+}
+
+Completion Function::execute(const List &args)
+{
+  assert(rep);
+  return static_cast<FunctionImp*>(rep)->execute(args);
+}
+
+bool Function::hasAttribute(FunctionAttribute a) const
+{
+  assert(rep);
+  return static_cast<FunctionImp*>(rep)->hasAttribute(a);
+}
+
+#if 0
+InternalFunction::InternalFunction(Imp *d)
+  : Function(d)
+{
+  param = 0L;
+}
+
+InternalFunction::~InternalFunction()
+{
+}
+#endif
+
+Constructor::Constructor(Imp *d)
+  : Function(d)
+{
+  if (d) {
+    assert(Global::current().hasProperty("[[Function.prototype]]"));
+    setPrototype(Global::current().get("[[Function.prototype]]"));
+    put("constructor", *this);
+    KJSO tmp(d); // protect from GC
+    ((FunctionImp*)d)->setLength(1);
+  }
+}
+
+#if 0
+Constructor::Constructor(const Object& proto, int len)
+{
+  setPrototype(proto);
+  put("constructor", *this);
+  put("length", len, DontEnum);
+}
+#endif
+
+Constructor::~Constructor()
+{
+}
+
+Completion Constructor::execute(const List &)
+{
+  /* TODO: call construct instead ? */
+  return Completion(ReturnValue, Undefined());
+}
+
+Object Constructor::construct(const List &args)
+{
+  assert(rep && rep->type() == ConstructorType);
+  return ((ConstructorImp*)rep)->construct(args);
+}
+
+Constructor Constructor::dynamicCast(const KJSO &obj)
+{
+  // return null object on type mismatch
+  if (!obj.isA(ConstructorType))
+    return Constructor(0L);
+
+  return Constructor(obj.imp());
+}
+
+KJSO Function::thisValue() const
+{
+  return KJSO(Context::current()->thisValue());
+}
diff --git a/JavaScriptCore/kjs/function.h b/JavaScriptCore/kjs/function.h
new file mode 100644
index 0000000..70c1f3a
--- /dev/null
+++ b/JavaScriptCore/kjs/function.h
@@ -0,0 +1,134 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _KJS_FUNCTION_H_
+#define _KJS_FUNCTION_H_
+
+#include <assert.h>
+
+#include "object.h"
+#include "types.h"
+
+namespace KJS {
+
+  enum CodeType { GlobalCode,
+		  EvalCode,
+		  FunctionCode,
+		  AnonymousCode,
+		  HostCode };
+
+  enum FunctionAttribute { ImplicitNone, ImplicitThis, ImplicitParents };
+
+  class Function;
+  class Parameter;
+
+  /**
+   * @short Implementation class for Functions.
+   */
+  class FunctionImp : public ObjectImp {
+    friend class Function;
+  public:
+    FunctionImp();
+    FunctionImp(const UString &n);
+    virtual ~FunctionImp();
+    virtual const TypeInfo* typeInfo() const { return &info; }
+    static const TypeInfo info;
+    virtual Completion execute(const List &) = 0;
+    bool hasAttribute(FunctionAttribute a) const { return (attr & a) != 0; }
+    virtual CodeType codeType() const = 0;
+    KJSO thisValue() const;
+    void addParameter(const UString &n);
+    void setLength(int l);
+    KJSO executeCall(Imp *thisV, const List *args);
+    KJSO executeCall(Imp *thisV, const List *args, const List *extraScope);
+    UString name() const;
+  protected:
+    UString ident;
+    FunctionAttribute attr;
+    Parameter *param;
+  private:
+    void processParameters(const List *);
+  };
+
+  /**
+   * @short Abstract base class for internal functions.
+   */
+  class InternalFunctionImp : public FunctionImp {
+  public:
+    InternalFunctionImp();
+    InternalFunctionImp(int l);
+    InternalFunctionImp(const UString &n);
+    virtual ~InternalFunctionImp() { }
+    virtual String toString() const;
+    virtual KJSO toPrimitive(Type) const { return toString(); }
+    virtual const TypeInfo* typeInfo() const { return &info; }
+    static const TypeInfo info;
+    virtual Completion execute(const List &);
+    virtual CodeType codeType() const { return HostCode; }
+  };
+
+  /**
+   * @short Base class for Function objects.
+   */
+  class Function : public KJSO {
+  public:
+    Function(Imp *);
+    virtual ~Function() { }
+    Completion execute(const List &);
+    bool hasAttribute(FunctionAttribute a) const;
+    CodeType codeType() const { return HostCode; }
+    KJSO thisValue() const;
+  };
+  
+  /**
+   * @short Implementation class for Constructors.
+   */
+  class ConstructorImp : public InternalFunctionImp {
+  public:
+    ConstructorImp();
+    ConstructorImp(const UString &n);	/* TODO: add length */
+    ConstructorImp(const KJSO &, int);
+    ConstructorImp(const UString &n, const KJSO &p, int len);
+    virtual ~ConstructorImp();
+    virtual const TypeInfo* typeInfo() const { return &info; }
+    static const TypeInfo info;
+    virtual Completion execute(const List &);
+    virtual Object construct(const List &) = 0;
+  };
+
+  /**
+    * @short Constructor object for use with the 'new' operator
+    */
+  class Constructor : public Function {
+  public:
+    Constructor(Imp *);
+    virtual ~Constructor();
+    //    Constructor(const Object& proto, int len);
+    /**
+     * @return @ref ConstructorType
+     */
+    Completion execute(const List &);
+    Object construct(const List &args);
+    static Constructor dynamicCast(const KJSO &obj);
+  };
+
+}; // namespace
+
+#endif
diff --git a/JavaScriptCore/kjs/function_object.cpp b/JavaScriptCore/kjs/function_object.cpp
new file mode 100644
index 0000000..63b8b63
--- /dev/null
+++ b/JavaScriptCore/kjs/function_object.cpp
@@ -0,0 +1,121 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "function_object.h"
+
+#include "lexer.h"
+#include "nodes.h"
+#include "error_object.h"
+
+extern int kjsyyparse();
+
+using namespace KJS;
+
+FunctionObject::FunctionObject(const Object& funcProto)
+  : ConstructorImp(funcProto, 1)
+{
+  // ECMA 15.3.3.1 Function.prototype
+  setPrototypeProperty(funcProto);
+}
+
+// ECMA 15.3.1 The Function Constructor Called as a Function
+Completion FunctionObject::execute(const List &args)
+{
+  return Completion(ReturnValue, construct(args));
+}
+
+// ECMA 15.3.2 The Function Constructor
+Object FunctionObject::construct(const List &args)
+{
+  UString p("");
+  UString body;
+  int argsSize = args.size();
+  if (argsSize == 0) {
+    body = "";
+  } else if (argsSize == 1) {
+    body = args[0].toString().value();
+  } else {
+    p = args[0].toString().value();
+    for (int k = 1; k < argsSize - 1; k++)
+      p += "," + args[k].toString().value();
+    body = args[argsSize-1].toString().value();
+  }
+
+  Lexer::curr()->setCode(body.data(), body.size());
+
+  KJScriptImp::current()->pushStack();
+  int yp = kjsyyparse();
+  ProgramNode *progNode = KJScriptImp::current()->progNode();
+  KJScriptImp::current()->popStack();
+  if (yp) {
+    /* TODO: free nodes */
+    return ErrorObject::create(SyntaxError,
+			       I18N_NOOP("Syntax error in function body"), -1);
+  }
+
+  List scopeChain;
+  scopeChain.append(Global::current());
+  FunctionBodyNode *bodyNode = progNode;
+  FunctionImp *fimp = new DeclaredFunctionImp(UString::null, bodyNode,
+					      &scopeChain);
+  Object ret(fimp); // protect from GC
+
+  // parse parameter list. throw syntax error on illegal identifiers
+  int len = p.size();
+  const UChar *c = p.data();
+  int i = 0, params = 0;
+  UString param;
+  while (i < len) {
+      while (*c == ' ' && i < len)
+	  c++, i++;
+      if (Lexer::isIdentLetter(c->unicode())) {  // else error
+	  param = UString(c, 1);
+	  c++, i++;
+	  while (i < len && (Lexer::isIdentLetter(c->unicode()) ||
+			     Lexer::isDecimalDigit(c->unicode()))) {
+	      param += UString(c, 1);
+	      c++, i++;
+	  }
+	  while (i < len && *c == ' ')
+	      c++, i++;
+	  if (i == len) {
+	      fimp->addParameter(param);
+	      params++;
+	      break;
+	  } else if (*c == ',') {
+	      fimp->addParameter(param);
+	      params++;
+	      c++, i++;
+	      continue;
+	  } // else error
+      }
+      return ErrorObject::create(SyntaxError,
+				 I18N_NOOP("Syntax error in parameter list"),
+				 -1);
+  }
+
+  fimp->setLength(params);
+  fimp->setPrototypeProperty(Global::current().functionPrototype());
+  return ret;
+}
+
+FunctionPrototype::FunctionPrototype(const Object &p)
+    : ObjectImp(FunctionClass, Null(), p)
+{
+}
diff --git a/JavaScriptCore/kjs/function_object.h b/JavaScriptCore/kjs/function_object.h
new file mode 100644
index 0000000..9617ac0
--- /dev/null
+++ b/JavaScriptCore/kjs/function_object.h
@@ -0,0 +1,42 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _FUNCTION_OBJECT_H_
+#define _FUNCTION_OBJECT_H_
+
+#include "object.h"
+#include "function.h"
+
+namespace KJS {
+
+  class FunctionPrototype : public ObjectImp {
+  public:
+    FunctionPrototype(const Object &p);
+  };
+
+  class FunctionObject : public ConstructorImp {
+  public:
+    FunctionObject(const Object &funcProto);
+    Completion execute(const List &);
+    Object construct(const List &);
+  };
+
+}; // namespace
+
+#endif
diff --git a/JavaScriptCore/kjs/global_object.cpp b/JavaScriptCore/kjs/global_object.cpp
new file mode 100644
index 0000000..c5bb3ed
--- /dev/null
+++ b/JavaScriptCore/kjs/global_object.cpp
@@ -0,0 +1,373 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2001 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "kjs.h"
+#include "object.h"
+#include "operations.h"
+#include "internal.h"
+#include "types.h"
+#include "lexer.h"
+#include "nodes.h"
+#include "lexer.h"
+
+#include "object_object.h"
+#include "function_object.h"
+#include "array_object.h"
+#include "bool_object.h"
+#include "string_object.h"
+#include "number_object.h"
+#include "math_object.h"
+#include "date_object.h"
+#include "regexp_object.h"
+#include "error_object.h"
+
+extern int kjsyyparse();
+
+namespace KJS {
+
+  class GlobalImp : public ObjectImp {
+  public:
+    GlobalImp();
+    virtual ~GlobalImp();
+    virtual void mark(Imp*);
+    void init();
+    virtual KJSO get(const UString &p) const;
+    virtual void put(const UString &p, const KJSO& v);
+    virtual bool hasProperty(const UString &p, bool recursive = true) const;
+    Imp *filter;
+    void *extraData;
+  private:
+    class GlobalInternal;
+    GlobalInternal *internal;
+  };
+
+};
+
+using namespace KJS;
+
+class GlobalFunc : public InternalFunctionImp {
+public:
+  GlobalFunc(int i) : id(i) { }
+  Completion execute(const List &c);
+  virtual CodeType codeType() const;
+  enum { Eval, ParseInt, ParseFloat, IsNaN, IsFinite, Escape, UnEscape };
+private:
+  int id;
+};
+
+Global::Global()
+  : Object(0L)
+{
+  rep = 0;
+  init();
+}
+
+Global::Global(void *)
+  : Object(0L)
+{
+}
+
+Global::~Global()
+{
+}
+
+void Global::init()
+{
+  if (rep)
+    rep->deref();
+  GlobalImp *g = new GlobalImp();
+  rep = g;
+  rep->ref();
+  g->init();
+}
+
+void Global::clear()
+{
+//   if (rep && rep->deref())
+//     delete rep;
+//   rep = 0L;
+}
+
+Global Global::current()
+{
+  assert(KJScriptImp::current());
+  return KJScriptImp::current()->glob;
+}
+
+KJSO Global::objectPrototype() const
+{
+  return get("[[Object.prototype]]");
+}
+
+KJSO Global::functionPrototype() const
+{
+  return get("[[Function.prototype]]");
+}
+
+void Global::setFilter(const KJSO &f)
+{
+  static_cast<GlobalImp*>(rep)->filter = f.imp();
+}
+
+KJSO Global::filter() const
+{
+  Imp *f = static_cast<GlobalImp*>(rep)->filter;
+  return f ? KJSO(f) : KJSO(Null());
+}
+
+void *Global::extra() const
+{
+  return static_cast<GlobalImp*>(rep)->extraData;
+}
+
+void Global::setExtra(void *e)
+{
+  static_cast<GlobalImp*>(rep)->extraData = e;
+}
+
+GlobalImp::GlobalImp()
+  : ObjectImp(ObjectClass),
+    filter(0L),
+    extraData(0L)
+{
+  // constructor properties. prototypes as Global's member variables first.
+  Object objProto(new ObjectPrototype());
+  Object funcProto(new FunctionPrototype(objProto));
+  Object arrayProto(new ArrayPrototype(objProto));
+  Object stringProto(new StringPrototype(objProto));
+  Object booleanProto(new BooleanPrototype(objProto));
+  Object numberProto(new NumberPrototype(objProto));
+  Object dateProto(new DatePrototype(objProto));
+  Object regexpProto(new RegExpPrototype(objProto));
+  Object errorProto(new ErrorPrototype(objProto));
+
+  put("[[Object.prototype]]", objProto);
+  put("[[Function.prototype]]", funcProto);
+  put("[[Array.prototype]]", arrayProto);
+  put("[[String.prototype]]", stringProto);
+  put("[[Boolean.prototype]]", booleanProto);
+  put("[[Number.prototype]]", numberProto);
+  put("[[Date.prototype]]", dateProto);
+  put("[[RegExp.prototype]]", regexpProto);
+  put("[[Error.prototype]]", errorProto);
+
+  Object objectObj(new ObjectObject(funcProto, objProto));
+  Object funcObj(new FunctionObject(funcProto));
+  Object arrayObj(new ArrayObject(funcProto, arrayProto));
+  Object stringObj(new StringObject(funcProto, stringProto));
+  Object boolObj(new BooleanObject(funcProto, booleanProto));
+  Object numObj(new NumberObject(funcProto, numberProto));
+  Object dateObj(new DateObject(funcProto, dateProto));
+  Object regObj(new RegExpObject(funcProto, regexpProto));
+  Object errObj(new ErrorObject(funcProto, errorProto));
+
+  Imp::put("Object", objectObj, DontEnum);
+  Imp::put("Function", funcObj, DontEnum);
+  Imp::put("Array", arrayObj, DontEnum);
+  Imp::put("Boolean", boolObj, DontEnum);
+  Imp::put("String", stringObj, DontEnum);
+  Imp::put("Number", numObj, DontEnum);
+  Imp::put("Date", dateObj, DontEnum);
+  Imp::put("RegExp", regObj, DontEnum);
+  Imp::put("Error", errObj, DontEnum);
+
+  objProto.setConstructor(objectObj);
+  funcProto.setConstructor(funcObj);
+  arrayProto.setConstructor(arrayObj);
+  booleanProto.setConstructor(boolObj);
+  stringProto.setConstructor(stringObj);
+  numberProto.setConstructor(numObj);
+  dateProto.setConstructor(dateObj);
+  regexpProto.setConstructor(regObj);
+  errorProto.setConstructor(errObj);
+};
+
+void GlobalImp::init()
+{
+  Imp::put("eval", Function(new GlobalFunc(GlobalFunc::Eval)));
+  Imp::put("parseInt", Function(new GlobalFunc(GlobalFunc::ParseInt)));
+  Imp::put("parseFloat", Function(new GlobalFunc(GlobalFunc::ParseFloat)));
+  Imp::put("isNaN", Function(new GlobalFunc(GlobalFunc::IsNaN)));
+  Imp::put("isFinite", Function(new GlobalFunc(GlobalFunc::IsFinite)));
+  Imp::put("escape", Function(new GlobalFunc(GlobalFunc::Escape)));
+  Imp::put("unescape", Function(new GlobalFunc(GlobalFunc::UnEscape)));
+
+  // other properties
+  Imp::put("Math", Object(new Math()), DontEnum);
+}
+
+GlobalImp::~GlobalImp() { }
+
+void GlobalImp::mark(Imp*)
+{
+  ObjectImp::mark();
+  /* TODO: remove in next version */
+  if (filter && !filter->marked())
+    filter->mark();
+}
+
+KJSO GlobalImp::get(const UString &p) const
+{
+  if (p == "NaN")
+    return Number(NaN);
+  else if (p == "Infinity")
+    return Number(Inf);
+  else if (p == "undefined")
+    return Undefined();
+
+  return Imp::get(p);
+}
+
+void GlobalImp::put(const UString &p, const KJSO& v)
+{
+  // if we already have this property (added by init() or a variable
+  // declaration) overwrite it. Otherwise pass it to the prototype.
+  // Needed to get something like a browser's window object working.
+  if (!prototype() || hasProperty(p, false) || Imp::hasProperty(p, false))
+    Imp::put(p, v);
+  else
+    prototype()->put(p, v);
+#if 0    
+  if (filter)
+    filter->put(p, v);   /* TODO: remove in next version */
+  else
+    Imp::put(p, v);
+#endif  
+}
+
+bool GlobalImp::hasProperty(const UString &p, bool recursive) const
+{
+    if (p == "NaN" || p == "Infinity" || p == "undefined")
+	return true;
+    return (recursive && Imp::hasProperty(p, recursive));
+}
+
+CodeType GlobalFunc::codeType() const
+{
+  return id == Eval ? EvalCode : InternalFunctionImp::codeType();
+}
+
+Completion GlobalFunc::execute(const List &args)
+{
+  KJSO res;
+
+  static const char non_escape[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+				   "abcdefghijklmnopqrstuvwxyz"
+				   "0123456789@*_+-./";
+
+  if (id == Eval) { // eval()
+    KJSO x = args[0];
+    if (x.type() != StringType)
+      return Completion(ReturnValue, x);
+    else {
+      UString s = x.toString().value();
+      Lexer::curr()->setCode(s.data(), s.size());
+      Node::setFirstNode(KJScriptImp::current()->firstNode());      
+      int yp = kjsyyparse();
+      KJScriptImp::current()->setFirstNode(Node::firstNode());
+      if (yp) {
+	// TODO: stop this from growing (will be deleted at end of global eval)
+	//	KJS::Node::deleteAllNodes();
+	return Completion(ReturnValue, Error::create(SyntaxError));
+      }
+
+      Completion c = KJScriptImp::current()->progNode()->execute();
+      if (c.complType() == ReturnValue)
+	  return c;
+      else if (c.complType() == Normal) {
+	  if (c.isValueCompletion())
+	      return Completion(ReturnValue, c.value());
+	  else
+	      return Completion(ReturnValue, Undefined());
+      } else
+	  return c;
+
+      //      if (KJS::Node::progNode())
+      //	KJS::Node::progNode()->deleteStatements();
+    }
+  } else if (id == ParseInt) {
+    String str = args[0].toString();
+    int radix = args[1].toInt32();
+    if (radix == 0)
+      radix = 10;
+    else if (radix < 2 || radix > 36) {
+      res = Number(NaN);
+      return Completion(ReturnValue, res);
+    }
+    /* TODO: use radix */
+    int i = 0;
+    sscanf(str.value().ascii(), "%d", &i);
+    res = Number(i);
+  } else if (id == ParseFloat) {
+    String str = args[0].toString();
+    double d = 0.0;
+    sscanf(str.value().ascii(), "%lf", &d);
+    res = Number(d);
+  } else if (id == IsNaN) {
+    res = Boolean(args[0].toNumber().isNaN());
+  } else if (id == IsFinite) {
+    Number n = args[0].toNumber();
+    res = Boolean(!n.isNaN() && !n.isInf());
+  } else if (id == Escape) {
+    UString r = "", s, str = args[0].toString().value();
+    const UChar *c = str.data();
+    for (int k = 0; k < str.size(); k++, c++) {
+      int u = c->unicode();
+      if (u > 255) {
+	char tmp[7];
+	sprintf(tmp, "%%u%04x", u);
+	s = UString(tmp);
+      } else if (strchr(non_escape, (char)u)) {
+	s = UString(c, 1);
+      } else {
+	char tmp[4];
+	sprintf(tmp, "%%%02x", u);
+	s = UString(tmp);
+      }
+      r += s;
+    }
+    res = String(r);
+  } else if (id == UnEscape) {
+    UString s, str = args[0].toString().value();
+    int k = 0, len = str.size();
+    while (k < len) {
+      const UChar *c = str.data() + k;
+      UChar u;
+      if (*c == UChar('%') && k <= len - 6 && *(c+1) == UChar('u')) {
+	u = Lexer::convertUnicode((c+2)->unicode(), (c+3)->unicode(),
+				  (c+4)->unicode(), (c+5)->unicode());
+	c = &u;
+	k += 5;
+      } else if (*c == UChar('%') && k <= len - 3) {
+	u = UChar(Lexer::convertHex((c+1)->unicode(), (c+2)->unicode()));
+	c = &u;
+	k += 2;
+      }
+      k++;
+      s += UString(c, 1);
+    }
+    res = String(s);
+  }
+
+  return Completion(ReturnValue, res);
+}
diff --git a/JavaScriptCore/kjs/grammar.cpp b/JavaScriptCore/kjs/grammar.cpp
new file mode 100644
index 0000000..9639e01
--- /dev/null
+++ b/JavaScriptCore/kjs/grammar.cpp
@@ -0,0 +1,2220 @@
+
+/*  A Bison parser, made from grammar.y
+    by GNU Bison version 1.28  */
+
+#define YYBISON 1  /* Identify Bison output.  */
+
+#define yyparse kjsyyparse
+#define yylex kjsyylex
+#define yyerror kjsyyerror
+#define yylval kjsyylval
+#define yychar kjsyychar
+#define yydebug kjsyydebug
+#define yynerrs kjsyynerrs
+#define YYLSP_NEEDED
+
+#define	NULLTOKEN	257
+#define	TRUETOKEN	258
+#define	FALSETOKEN	259
+#define	STRING	260
+#define	NUMBER	261
+#define	BREAK	262
+#define	CASE	263
+#define	DEFAULT	264
+#define	FOR	265
+#define	NEW	266
+#define	VAR	267
+#define	CONTINUE	268
+#define	FUNCTION	269
+#define	RETURN	270
+#define	VOID	271
+#define	DELETE	272
+#define	IF	273
+#define	THIS	274
+#define	DO	275
+#define	WHILE	276
+#define	ELSE	277
+#define	IN	278
+#define	INSTANCEOF	279
+#define	TYPEOF	280
+#define	SWITCH	281
+#define	WITH	282
+#define	RESERVED	283
+#define	THROW	284
+#define	TRY	285
+#define	CATCH	286
+#define	FINALLY	287
+#define	EQEQ	288
+#define	NE	289
+#define	STREQ	290
+#define	STRNEQ	291
+#define	LE	292
+#define	GE	293
+#define	OR	294
+#define	AND	295
+#define	PLUSPLUS	296
+#define	MINUSMINUS	297
+#define	LSHIFT	298
+#define	RSHIFT	299
+#define	URSHIFT	300
+#define	PLUSEQUAL	301
+#define	MINUSEQUAL	302
+#define	MULTEQUAL	303
+#define	DIVEQUAL	304
+#define	LSHIFTEQUAL	305
+#define	RSHIFTEQUAL	306
+#define	URSHIFTEQUAL	307
+#define	ANDEQUAL	308
+#define	MODEQUAL	309
+#define	XOREQUAL	310
+#define	OREQUAL	311
+#define	IDENT	312
+#define	AUTO	313
+
+#line 1 "grammar.y"
+
+
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <string.h>
+#include "kjs.h"
+#include "nodes.h"
+#include "lexer.h"
+
+/* default values for bison */
+#define YYDEBUG 0
+#define YYMAXDEPTH 0
+#ifdef KJS_DEBUGGER
+#define YYERROR_VERBOSE
+#define DBG(l, s, e) { l->setLoc(s.first_line, e.last_line); } // location
+#else
+#undef YYLSP_NEEDED
+#define DBG(l, s, e)
+#endif
+
+extern int yylex();
+int yyerror (const char *);
+bool automatic();
+
+using namespace KJS;
+
+
+#line 49 "grammar.y"
+typedef union {
+  int                 ival;
+  double              dval;
+  UString             *ustr;
+  Node                *node;
+  StatementNode       *stat;
+  ParameterNode       *param;
+  FunctionBodyNode    *body;
+  FuncDeclNode        *func;
+  ProgramNode         *prog;
+  AssignExprNode      *init;
+  SourceElementNode   *src;
+  SourceElementsNode  *srcs;
+  StatListNode        *slist;
+  ArgumentsNode       *args;
+  ArgumentListNode    *alist;
+  VarDeclNode         *decl;
+  VarDeclListNode     *vlist;
+  CaseBlockNode       *cblk;
+  ClauseListNode      *clist;
+  CaseClauseNode      *ccl;
+  ElementNode         *elm;
+  ElisionNode         *eli;
+  Operator            op;
+} YYSTYPE;
+
+#ifndef YYLTYPE
+typedef
+  struct yyltype
+    {
+      int timestamp;
+      int first_line;
+      int first_column;
+      int last_line;
+      int last_column;
+      char *text;
+   }
+  yyltype;
+
+#define YYLTYPE yyltype
+#endif
+
+#include <stdio.h>
+
+#ifndef __cplusplus
+#ifndef __STDC__
+#define const
+#endif
+#endif
+
+
+
+#define	YYFINAL		358
+#define	YYFLAG		-32768
+#define	YYNTBASE	84
+
+#define YYTRANSLATE(x) ((unsigned)(x) <= 313 ? yytranslate[x] : 148)
+
+static const char yytranslate[] = {     0,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,    73,     2,     2,     2,    75,    78,     2,    61,
+    62,    74,    70,    67,    71,    69,    60,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,    68,    83,    76,
+    82,    77,    81,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+    65,     2,    66,    79,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,    63,    80,    64,    72,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     1,     3,     4,     5,     6,
+     7,     8,     9,    10,    11,    12,    13,    14,    15,    16,
+    17,    18,    19,    20,    21,    22,    23,    24,    25,    26,
+    27,    28,    29,    30,    31,    32,    33,    34,    35,    36,
+    37,    38,    39,    40,    41,    42,    43,    44,    45,    46,
+    47,    48,    49,    50,    51,    52,    53,    54,    55,    56,
+    57,    58,    59
+};
+
+#if YYDEBUG != 0
+static const short yyprhs[] = {     0,
+     0,     2,     4,     6,     8,    10,    12,    14,    16,    18,
+    20,    24,    27,    31,    35,    39,    45,    48,    53,    54,
+    56,    58,    61,    65,    71,    73,    75,    77,    79,    81,
+    86,    90,    94,    96,    99,   102,   105,   110,   114,   117,
+   121,   123,   127,   129,   131,   133,   136,   139,   141,   144,
+   147,   150,   153,   157,   160,   164,   167,   170,   173,   176,
+   178,   182,   186,   190,   192,   196,   200,   202,   206,   210,
+   214,   216,   220,   224,   228,   232,   236,   240,   242,   246,
+   250,   254,   258,   260,   264,   266,   270,   272,   276,   278,
+   282,   284,   288,   290,   296,   298,   302,   304,   306,   308,
+   310,   312,   314,   316,   318,   320,   322,   324,   326,   328,
+   332,   334,   336,   338,   340,   342,   344,   346,   348,   350,
+   352,   354,   356,   358,   360,   363,   367,   369,   372,   376,
+   380,   382,   386,   388,   391,   394,   396,   399,   402,   408,
+   416,   423,   429,   439,   450,   458,   467,   477,   478,   480,
+   483,   486,   490,   494,   497,   500,   504,   508,   511,   514,
+   518,   522,   528,   534,   538,   544,   545,   547,   549,   552,
+   556,   561,   564,   568,   572,   576,   580,   584,   589,   595,
+   598,   604,   611,   616,   622,   624,   628,   631,   635,   637,
+   639,   642,   644
+};
+
+static const short yyrhs[] = {     3,
+     0,     4,     0,     5,     0,     7,     0,     6,     0,    60,
+     0,    20,     0,    58,     0,    84,     0,    86,     0,    61,
+   113,    62,     0,    63,    64,     0,    63,    90,    64,     0,
+    65,    88,    66,     0,    65,    87,    66,     0,    65,    87,
+    67,    88,    66,     0,    88,   111,     0,    87,    67,    88,
+   111,     0,     0,    89,     0,    67,     0,    89,    67,     0,
+    91,    68,   111,     0,    90,    67,    91,    68,   111,     0,
+    58,     0,     6,     0,     7,     0,    85,     0,   142,     0,
+    92,    65,   113,    66,     0,    92,    69,    58,     0,    12,
+    92,    95,     0,    92,     0,    12,    93,     0,    92,    95,
+     0,    94,    95,     0,    94,    65,   113,    66,     0,    94,
+    69,    58,     0,    61,    62,     0,    61,    96,    62,     0,
+   111,     0,    96,    67,   111,     0,    93,     0,    94,     0,
+    97,     0,    97,    42,     0,    97,    43,     0,    98,     0,
+    18,    99,     0,    17,    99,     0,    26,    99,     0,    42,
+    99,     0,    59,    42,    99,     0,    43,    99,     0,    59,
+    43,    99,     0,    70,    99,     0,    71,    99,     0,    72,
+    99,     0,    73,    99,     0,    99,     0,   100,    74,    99,
+     0,   100,    60,    99,     0,   100,    75,    99,     0,   100,
+     0,   101,    70,   100,     0,   101,    71,   100,     0,   101,
+     0,   102,    44,   101,     0,   102,    45,   101,     0,   102,
+    46,   101,     0,   102,     0,   103,    76,   102,     0,   103,
+    77,   102,     0,   103,    38,   102,     0,   103,    39,   102,
+     0,   103,    25,   102,     0,   103,    24,   102,     0,   103,
+     0,   104,    34,   103,     0,   104,    35,   103,     0,   104,
+    36,   103,     0,   104,    37,   103,     0,   104,     0,   105,
+    78,   104,     0,   105,     0,   106,    79,   104,     0,   106,
+     0,   107,    80,   104,     0,   107,     0,   108,    41,   107,
+     0,   108,     0,   109,    40,   108,     0,   109,     0,   109,
+    81,   111,    68,   111,     0,   110,     0,    97,   112,   111,
+     0,    82,     0,    47,     0,    48,     0,    49,     0,    50,
+     0,    51,     0,    52,     0,    53,     0,    54,     0,    56,
+     0,    57,     0,    55,     0,   111,     0,   113,    67,   111,
+     0,   115,     0,   117,     0,   121,     0,   122,     0,   123,
+     0,   124,     0,   126,     0,   127,     0,   128,     0,   129,
+     0,   130,     0,   136,     0,   137,     0,   138,     0,    63,
+    64,     0,    63,   116,    64,     0,   114,     0,   116,   114,
+     0,    13,   118,    83,     0,    13,   118,     1,     0,   119,
+     0,   118,    67,   119,     0,    58,     0,    58,   120,     0,
+    82,   111,     0,    83,     0,   113,    83,     0,   113,     1,
+     0,    19,    61,   113,    62,   114,     0,    19,    61,   113,
+    62,   114,    23,   114,     0,    21,   114,    22,    61,   113,
+    62,     0,    22,    61,   113,    62,   114,     0,    11,    61,
+   125,    83,   125,    83,   125,    62,   114,     0,    11,    61,
+    13,   118,    83,   125,    83,   125,    62,   114,     0,    11,
+    61,    97,    24,   113,    62,   114,     0,    11,    61,    13,
+    58,    24,   113,    62,   114,     0,    11,    61,    13,    58,
+   120,    24,   113,    62,   114,     0,     0,   113,     0,    14,
+    83,     0,    14,     1,     0,    14,    58,    83,     0,    14,
+    58,     1,     0,     8,    83,     0,     8,     1,     0,     8,
+    58,    83,     0,     8,    58,     1,     0,    16,    83,     0,
+    16,     1,     0,    16,   113,    83,     0,    16,   113,     1,
+     0,    28,    61,   113,    62,   114,     0,    27,    61,   113,
+    62,   131,     0,    63,   132,    64,     0,    63,   132,   135,
+   132,    64,     0,     0,   133,     0,   134,     0,   133,   134,
+     0,     9,   113,    68,     0,     9,   113,    68,   116,     0,
+    10,    68,     0,    10,    68,   116,     0,    58,    68,   114,
+     0,    30,   113,    83,     0,    31,   115,   139,     0,    31,
+   115,   140,     0,    31,   115,   139,   140,     0,    32,    61,
+    58,    62,   115,     0,    33,   115,     0,    15,    58,    61,
+    62,   144,     0,    15,    58,    61,   143,    62,   144,     0,
+    15,    61,    62,   144,     0,    15,    61,   143,    62,   144,
+     0,    58,     0,   143,    67,    58,     0,    63,    64,     0,
+    63,   146,    64,     0,   146,     0,   147,     0,   146,   147,
+     0,   114,     0,   141,     0
+};
+
+#endif
+
+#if YYDEBUG != 0
+static const short yyrline[] = { 0,
+   156,   158,   159,   160,   161,   162,   167,   169,   171,   172,
+   173,   174,   175,   178,   180,   181,   184,   186,   190,   192,
+   195,   197,   200,   202,   206,   209,   210,   213,   215,   216,
+   217,   219,   222,   224,   227,   229,   230,   231,   234,   236,
+   239,   241,   244,   246,   249,   251,   252,   255,   257,   258,
+   259,   260,   261,   262,   263,   264,   265,   266,   267,   270,
+   272,   273,   274,   277,   279,   280,   283,   285,   286,   287,
+   290,   292,   294,   296,   298,   300,   302,   306,   308,   309,
+   310,   311,   314,   316,   319,   321,   324,   326,   329,   331,
+   335,   337,   341,   343,   347,   349,   353,   355,   356,   357,
+   358,   359,   360,   361,   362,   363,   364,   365,   368,   370,
+   373,   375,   376,   377,   378,   379,   380,   381,   382,   383,
+   384,   385,   386,   387,   390,   392,   395,   397,   400,   403,
+   412,   414,   418,   420,   423,   427,   431,   434,   441,   443,
+   447,   449,   450,   453,   456,   459,   463,   469,   471,   474,
+   476,   480,   482,   489,   491,   495,   497,   505,   507,   511,
+   512,   518,   523,   528,   530,   534,   536,   539,   541,   544,
+   546,   549,   551,   554,   560,   564,   566,   567,   570,   574,
+   578,   581,   585,   587,   592,   594,   598,   600,   603,   608,
+   610,   613,   615
+};
+#endif
+
+
+#if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
+
+static const char * const yytname[] = {   "$","error","$undefined.","NULLTOKEN",
+"TRUETOKEN","FALSETOKEN","STRING","NUMBER","BREAK","CASE","DEFAULT","FOR","NEW",
+"VAR","CONTINUE","FUNCTION","RETURN","VOID","DELETE","IF","THIS","DO","WHILE",
+"ELSE","IN","INSTANCEOF","TYPEOF","SWITCH","WITH","RESERVED","THROW","TRY","CATCH",
+"FINALLY","EQEQ","NE","STREQ","STRNEQ","LE","GE","OR","AND","PLUSPLUS","MINUSMINUS",
+"LSHIFT","RSHIFT","URSHIFT","PLUSEQUAL","MINUSEQUAL","MULTEQUAL","DIVEQUAL",
+"LSHIFTEQUAL","RSHIFTEQUAL","URSHIFTEQUAL","ANDEQUAL","MODEQUAL","XOREQUAL",
+"OREQUAL","IDENT","AUTO","'/'","'('","')'","'{'","'}'","'['","']'","','","':'",
+"'.'","'+'","'-'","'~'","'!'","'*'","'%'","'<'","'>'","'&'","'^'","'|'","'?'",
+"'='","';'","Literal","PrimaryExpr","ArrayLiteral","ElementList","ElisionOpt",
+"Elision","PropertyNameAndValueList","PropertyName","MemberExpr","NewExpr","CallExpr",
+"Arguments","ArgumentList","LeftHandSideExpr","PostfixExpr","UnaryExpr","MultiplicativeExpr",
+"AdditiveExpr","ShiftExpr","RelationalExpr","EqualityExpr","BitwiseANDExpr",
+"BitwiseXORExpr","BitwiseORExpr","LogicalANDExpr","LogicalORExpr","ConditionalExpr",
+"AssignmentExpr","AssignmentOperator","Expr","Statement","Block","StatementList",
+"VariableStatement","VariableDeclarationList","VariableDeclaration","Initializer",
+"EmptyStatement","ExprStatement","IfStatement","IterationStatement","ExprOpt",
+"ContinueStatement","BreakStatement","ReturnStatement","WithStatement","SwitchStatement",
+"CaseBlock","CaseClausesOpt","CaseClauses","CaseClause","DefaultClause","LabelledStatement",
+"ThrowStatement","TryStatement","Catch","Finally","FunctionDeclaration","FunctionExpr",
+"FormalParameterList","FunctionBody","Program","SourceElements","SourceElement", NULL
+};
+#endif
+
+static const short yyr1[] = {     0,
+    84,    84,    84,    84,    84,    84,    85,    85,    85,    85,
+    85,    85,    85,    86,    86,    86,    87,    87,    88,    88,
+    89,    89,    90,    90,    91,    91,    91,    92,    92,    92,
+    92,    92,    93,    93,    94,    94,    94,    94,    95,    95,
+    96,    96,    97,    97,    98,    98,    98,    99,    99,    99,
+    99,    99,    99,    99,    99,    99,    99,    99,    99,   100,
+   100,   100,   100,   101,   101,   101,   102,   102,   102,   102,
+   103,   103,   103,   103,   103,   103,   103,   104,   104,   104,
+   104,   104,   105,   105,   106,   106,   107,   107,   108,   108,
+   109,   109,   110,   110,   111,   111,   112,   112,   112,   112,
+   112,   112,   112,   112,   112,   112,   112,   112,   113,   113,
+   114,   114,   114,   114,   114,   114,   114,   114,   114,   114,
+   114,   114,   114,   114,   115,   115,   116,   116,   117,   117,
+   118,   118,   119,   119,   120,   121,   122,   122,   123,   123,
+   124,   124,   124,   124,   124,   124,   124,   125,   125,   126,
+   126,   126,   126,   127,   127,   127,   127,   128,   128,   128,
+   128,   129,   130,   131,   131,   132,   132,   133,   133,   134,
+   134,   135,   135,   136,   137,   138,   138,   138,   139,   140,
+   141,   141,   142,   142,   143,   143,   144,   144,   145,   146,
+   146,   147,   147
+};
+
+static const short yyr2[] = {     0,
+     1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+     3,     2,     3,     3,     3,     5,     2,     4,     0,     1,
+     1,     2,     3,     5,     1,     1,     1,     1,     1,     4,
+     3,     3,     1,     2,     2,     2,     4,     3,     2,     3,
+     1,     3,     1,     1,     1,     2,     2,     1,     2,     2,
+     2,     2,     3,     2,     3,     2,     2,     2,     2,     1,
+     3,     3,     3,     1,     3,     3,     1,     3,     3,     3,
+     1,     3,     3,     3,     3,     3,     3,     1,     3,     3,
+     3,     3,     1,     3,     1,     3,     1,     3,     1,     3,
+     1,     3,     1,     5,     1,     3,     1,     1,     1,     1,
+     1,     1,     1,     1,     1,     1,     1,     1,     1,     3,
+     1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+     1,     1,     1,     1,     2,     3,     1,     2,     3,     3,
+     1,     3,     1,     2,     2,     1,     2,     2,     5,     7,
+     6,     5,     9,    10,     7,     8,     9,     0,     1,     2,
+     2,     3,     3,     2,     2,     3,     3,     2,     2,     3,
+     3,     5,     5,     3,     5,     0,     1,     1,     2,     3,
+     4,     2,     3,     3,     3,     3,     3,     4,     5,     2,
+     5,     6,     4,     5,     1,     3,     2,     3,     1,     1,
+     2,     1,     1
+};
+
+static const short yydefact[] = {     0,
+     1,     2,     3,     5,     4,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     7,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     8,     0,     6,     0,     0,
+    19,     0,     0,     0,     0,   136,     9,    28,    10,    33,
+    43,    44,    45,    48,    60,    64,    67,    71,    78,    83,
+    85,    87,    89,    91,    93,    95,   109,     0,   192,   111,
+   112,   113,   114,   115,   116,   117,   118,   119,   120,   121,
+   122,   123,   124,   193,    29,   189,   190,   155,     0,   154,
+   148,     0,     8,     0,    33,    34,   133,     0,   131,   151,
+     0,   150,     0,     0,   159,   158,     0,    45,    50,    49,
+     0,     0,     0,    51,     0,     0,     0,     0,     0,    52,
+    54,     0,     0,     0,     0,     5,     4,     8,    12,     0,
+     0,   127,     0,    21,     0,     0,    20,    56,    57,    58,
+    59,     0,     0,     0,    35,     0,     0,    36,    46,    47,
+    98,    99,   100,   101,   102,   103,   104,   105,   108,   106,
+   107,    97,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,   138,     0,   137,
+   191,   157,   156,     0,    45,   149,     0,    26,    27,    25,
+    12,    32,     0,   134,   130,     0,   129,   153,   152,     0,
+   185,     0,     0,   161,   160,     0,     0,     0,     0,     0,
+   175,   125,     0,     0,   176,   177,   174,    53,    55,    11,
+    13,     0,     0,   126,   128,    15,    19,    14,    17,    22,
+    39,     0,    41,     0,    31,     0,    38,    96,    62,    61,
+    63,    65,    66,    68,    69,    70,    77,    76,    74,    75,
+    72,    73,    79,    80,    81,    82,    84,    86,    88,    90,
+    92,     0,   110,   133,     0,     0,   148,   135,   132,     0,
+     0,     0,   183,     0,     0,     0,     0,     0,     0,     0,
+     0,   180,   178,     0,    23,     0,    40,     0,    30,    37,
+     0,     0,   134,   148,     0,     0,   181,     0,   187,     0,
+   184,   186,   139,     0,   142,   166,   163,   162,     0,     0,
+    16,    18,    42,    94,     0,     0,     0,     0,   148,   182,
+   188,     0,   141,     0,     0,   167,   168,     0,    24,     0,
+     0,   148,   145,     0,   140,     0,     0,   164,   166,   169,
+   179,   146,     0,     0,     0,   170,   172,     0,   147,     0,
+   143,   171,   173,   165,   144,     0,     0,     0
+};
+
+static const short yydefgoto[] = {    37,
+    38,    39,   125,   126,   127,   120,   121,    40,    41,    42,
+   135,   232,    43,    44,    45,    46,    47,    48,    49,    50,
+    51,    52,    53,    54,    55,    56,    57,   153,    58,    59,
+    60,   123,    61,    88,    89,   194,    62,    63,    64,    65,
+   187,    66,    67,    68,    69,    70,   307,   325,   326,   327,
+   339,    71,    72,    73,   215,   216,    74,    75,   203,   273,
+   356,    76,    77
+};
+
+static const short yypact[] = {   699,
+-32768,-32768,-32768,-32768,-32768,     2,   -29,   121,    34,     4,
+   129,   227,  1171,  1171,    42,-32768,   772,    89,  1171,   107,
+   128,  1171,    -7,  1171,  1171,    62,    -2,-32768,  1171,   334,
+   124,  1171,  1171,  1171,  1171,-32768,-32768,-32768,-32768,    51,
+-32768,    73,   769,-32768,-32768,    69,    90,   210,    72,   201,
+   115,    60,   145,   186,   -13,-32768,-32768,    11,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,   699,-32768,-32768,     5,-32768,
+   887,   168,-32768,   101,    51,-32768,   161,    15,-32768,-32768,
+     6,-32768,   185,    28,-32768,-32768,    16,    27,-32768,-32768,
+  1171,   230,  1171,-32768,  1171,  1171,   -59,   407,   144,-32768,
+-32768,   772,  1171,  1171,    -4,   192,   194,    62,   853,   157,
+   196,-32768,   480,-32768,   153,   958,   215,-32768,-32768,-32768,
+-32768,  1029,  1171,   225,-32768,  1171,   226,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,  1171,  1171,  1171,  1171,  1171,  1171,  1171,  1171,
+  1171,  1171,  1171,  1171,  1171,  1171,  1171,  1171,  1171,  1171,
+  1171,  1171,  1171,  1171,  1171,  1171,  1171,-32768,  1171,-32768,
+-32768,-32768,-32768,   231,    -5,   228,   211,-32768,-32768,-32768,
+-32768,-32768,  1171,-32768,-32768,    34,-32768,-32768,-32768,    61,
+-32768,   233,    17,-32768,-32768,    55,   241,    78,    84,    85,
+-32768,-32768,   242,    -7,   271,-32768,-32768,-32768,-32768,-32768,
+-32768,    23,  1171,-32768,-32768,-32768,   124,-32768,-32768,-32768,
+-32768,    96,-32768,   174,-32768,   191,-32768,-32768,-32768,-32768,
+-32768,    69,    69,    90,    90,    90,   210,   210,   210,   210,
+   210,   210,    72,    72,    72,    72,   201,   201,   201,   145,
+   186,   239,-32768,   -15,   -44,  1171,  1171,-32768,-32768,   233,
+   100,   553,-32768,   233,   250,   772,  1171,   772,   246,   772,
+   253,-32768,-32768,   244,-32768,  1100,-32768,  1171,-32768,-32768,
+  1171,  1171,   290,  1171,   116,   234,-32768,   233,-32768,   626,
+-32768,-32768,   293,   118,-32768,   310,-32768,-32768,   258,  1171,
+-32768,-32768,-32768,-32768,   155,  1171,   238,   772,  1171,-32768,
+-32768,   772,-32768,  1171,    12,   310,-32768,    -7,-32768,   772,
+   156,  1171,-32768,   260,-32768,   200,   256,-32768,   310,-32768,
+-32768,-32768,   772,   263,   772,   772,   772,   268,-32768,   772,
+-32768,   772,   772,-32768,-32768,   327,   343,-32768
+};
+
+static const short yypgoto[] = {-32768,
+-32768,-32768,-32768,   130,-32768,-32768,   122,   326,   350,-32768,
+   -24,-32768,    40,-32768,     1,   117,   112,     8,    80,   105,
+-32768,-32768,   184,   187,-32768,-32768,  -122,-32768,    -1,   -17,
+   -22,   -66,-32768,   182,   171,   104,-32768,-32768,-32768,-32768,
+  -201,-32768,-32768,-32768,-32768,-32768,-32768,    30,-32768,    44,
+-32768,-32768,-32768,-32768,-32768,   158,-32768,-32768,   172,  -161,
+-32768,    99,   -74
+};
+
+
+#define	YYLAST		1244
+
+
+static const short yytable[] = {   102,
+   109,   181,    78,   229,    90,   182,   198,   179,   292,   233,
+    97,   178,   122,    99,   100,   195,   204,   138,   266,   104,
+   107,   337,   196,   211,   110,   111,   176,   115,   188,   189,
+   238,    81,   128,   129,   130,   131,   139,   140,   294,   113,
+   114,   141,   142,   143,   144,   145,   146,   147,   148,   149,
+   150,   151,    98,    98,   262,   108,   263,   220,    98,    79,
+   192,    91,   179,    98,    98,   296,   193,   177,   139,   140,
+   268,    98,    98,    98,    98,   338,   152,   179,   274,   186,
+   190,   196,   179,   275,    80,   201,    92,   183,   199,   202,
+   122,    87,   317,   180,   217,   162,   163,   197,   205,   206,
+   285,   208,   101,   209,   210,   225,   188,   189,   297,   164,
+   165,   132,   301,   218,   219,   133,   276,   334,   201,   134,
+   185,   179,   270,     1,     2,     3,     4,     5,   154,   112,
+   344,   234,     8,   132,   236,    82,   320,   136,   173,   278,
+    16,   137,   155,   156,   179,   279,   280,   166,   167,   103,
+   179,   179,    98,    98,   239,   240,   241,   287,   190,   157,
+   158,   298,   288,   312,   191,   313,   275,   105,   314,   247,
+   248,   249,   250,   251,   252,   213,   214,   318,    83,   323,
+    28,    29,   179,    84,   179,    31,    93,   329,   106,    94,
+   124,   282,   172,    98,    98,    98,    98,    98,    98,    98,
+    98,    98,    98,    98,    98,    98,    98,    98,    98,    98,
+    98,    98,    98,    98,    98,    98,   330,   343,   226,   227,
+   221,   179,   179,   222,   174,   181,   175,    95,    94,     1,
+     2,     3,     4,     5,   168,   169,   170,   171,     8,   289,
+   179,    82,   193,    13,    14,   200,    16,   253,   254,   255,
+   256,   207,    19,   159,   160,   161,   290,   179,   303,   -26,
+   305,   -27,   308,   223,   295,   186,   179,   346,    24,    25,
+   244,   245,   246,   242,   243,   304,   257,   258,   259,   352,
+   353,   230,   235,   237,    83,    27,    28,    29,   264,    84,
+   315,    31,   186,   267,   179,   272,    32,    33,    34,    35,
+   333,   277,   281,   214,   335,   341,   291,   302,   306,    96,
+   309,   310,   342,   316,   331,   322,   319,   186,   324,   328,
+   332,   345,   336,   347,   350,   349,   357,   351,   122,   122,
+   186,   354,   355,    85,   225,   225,     1,     2,     3,   116,
+   117,     6,   358,   284,     7,     8,     9,    10,    82,    12,
+    13,    14,    15,    16,    17,    18,   286,    86,   260,    19,
+    20,    21,   261,    22,    23,   265,   269,   293,   348,   340,
+   300,   271,   283,     0,     0,    24,    25,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,   118,    27,    28,    29,     0,    30,   119,    31,     0,
+     0,     0,     0,    32,    33,    34,    35,     0,     0,     1,
+     2,     3,     4,     5,     6,     0,    36,     7,     8,     9,
+    10,    82,    12,    13,    14,    15,    16,    17,    18,     0,
+     0,     0,    19,    20,    21,     0,    22,    23,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,    24,    25,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,    26,    27,    28,    29,     0,    30,
+   212,    31,     0,     0,     0,     0,    32,    33,    34,    35,
+     0,     0,     1,     2,     3,     4,     5,     6,     0,    36,
+     7,     8,     9,    10,    82,    12,    13,    14,    15,    16,
+    17,    18,     0,     0,     0,    19,    20,    21,     0,    22,
+    23,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,    24,    25,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,    26,    27,    28,
+    29,     0,    30,   224,    31,     0,     0,     0,     0,    32,
+    33,    34,    35,     0,     0,     1,     2,     3,     4,     5,
+     6,     0,    36,     7,     8,     9,    10,    11,    12,    13,
+    14,    15,    16,    17,    18,     0,     0,     0,    19,    20,
+    21,     0,    22,    23,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,    24,    25,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+    26,    27,    28,    29,     0,    30,   299,    31,     0,     0,
+     0,     0,    32,    33,    34,    35,     0,     0,     1,     2,
+     3,     4,     5,     6,     0,    36,     7,     8,     9,    10,
+    11,    12,    13,    14,    15,    16,    17,    18,     0,     0,
+     0,    19,    20,    21,     0,    22,    23,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,    24,    25,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,    26,    27,    28,    29,     0,    30,   321,
+    31,     0,     0,     0,     0,    32,    33,    34,    35,     0,
+     0,     1,     2,     3,     4,     5,     6,     0,    36,     7,
+     8,     9,    10,    11,    12,    13,    14,    15,    16,    17,
+    18,     0,     0,     0,    19,    20,    21,     0,    22,    23,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+    24,    25,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,    26,    27,    28,    29,
+     0,    30,     0,    31,     0,     0,     0,     0,    32,    33,
+    34,    35,     0,     0,     1,     2,     3,     4,     5,     6,
+     0,    36,     7,     8,     9,    10,    82,    12,    13,    14,
+    15,    16,    17,    18,     0,     0,     0,    19,    20,    21,
+     0,    22,    23,     0,     0,     0,     0,     0,     0,     0,
+   139,   140,     0,    24,    25,   141,   142,   143,   144,   145,
+   146,   147,   148,   149,   150,   151,     0,     0,     0,    26,
+    27,    28,    29,     0,    30,     0,    31,     0,     0,     0,
+     0,    32,    33,    34,    35,     0,     0,     0,     0,     0,
+   152,     0,  -125,     0,    36,  -125,  -125,  -125,  -125,  -125,
+  -125,  -125,  -125,  -125,  -125,  -125,  -125,  -125,  -125,  -125,
+  -125,  -125,  -125,  -125,  -125,  -125,     0,     0,  -125,  -125,
+  -125,     0,  -125,  -125,     0,     0,     0,     0,     0,     1,
+     2,     3,     4,     5,     0,     0,     0,     0,     8,   184,
+     0,    82,     0,    13,    14,     0,    16,     0,     0,     0,
+  -125,  -125,    19,     0,     0,  -125,  -125,     0,     0,     0,
+     0,     0,     0,     0,  -125,  -125,     0,     0,    24,    25,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,    83,    27,    28,    29,     0,    84,
+     0,    31,     0,     0,     0,     0,    32,    33,    34,    35,
+     1,     2,     3,     4,     5,     0,     0,     0,     0,     8,
+     0,     0,    82,     0,    13,    14,     0,    16,     0,     0,
+     0,     0,     0,    19,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,    24,
+    25,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,    83,    27,    28,    29,     0,
+    84,     0,    31,   228,     0,     0,     0,    32,    33,    34,
+    35,     1,     2,     3,     4,     5,     0,     0,     0,     0,
+     8,     0,     0,    82,     0,    13,    14,     0,    16,     0,
+     0,     0,     0,     0,    19,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+    24,    25,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,    83,    27,    28,    29,
+   231,    84,     0,    31,     0,     0,     0,     0,    32,    33,
+    34,    35,     1,     2,     3,     4,     5,     0,     0,     0,
+     0,     8,     0,     0,    82,     0,    13,    14,     0,    16,
+     0,     0,     0,     0,     0,    19,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,    24,    25,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,    83,    27,    28,
+    29,     0,    84,     0,    31,   311,     0,     0,     0,    32,
+    33,    34,    35,     1,     2,     3,     4,     5,     0,     0,
+     0,     0,     8,     0,     0,    82,     0,    13,    14,     0,
+    16,     0,     0,     0,     0,     0,    19,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,    24,    25,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,    83,    27,
+    28,    29,     0,    84,     0,    31,     0,     0,     0,     0,
+    32,    33,    34,    35
+};
+
+static const short yycheck[] = {    17,
+    23,    76,     1,   126,     1,     1,     1,    67,    24,   132,
+    12,     1,    30,    13,    14,     1,     1,    42,    24,    19,
+    22,    10,    67,    83,    24,    25,    40,    29,     6,     7,
+   153,    61,    32,    33,    34,    35,    42,    43,    83,    42,
+    43,    47,    48,    49,    50,    51,    52,    53,    54,    55,
+    56,    57,    13,    14,   177,    63,   179,    62,    19,    58,
+    85,    58,    67,    24,    25,   267,    82,    81,    42,    43,
+   193,    32,    33,    34,    35,    64,    82,    67,    62,    81,
+    58,    67,    67,    67,    83,    58,    83,    83,    83,    62,
+   108,    58,   294,    83,   112,    24,    25,    83,    83,   101,
+   223,   103,    61,   105,   106,   123,     6,     7,   270,    38,
+    39,    61,   274,   113,   114,    65,    62,   319,    58,    69,
+    81,    67,    62,     3,     4,     5,     6,     7,    60,    68,
+   332,   133,    12,    61,   136,    15,   298,    65,    79,    62,
+    20,    69,    74,    75,    67,    62,    62,    76,    77,    61,
+    67,    67,   113,   114,   154,   155,   156,    62,    58,    70,
+    71,    62,    67,   286,    64,   288,    67,    61,   291,   162,
+   163,   164,   165,   166,   167,    32,    33,    62,    58,    62,
+    60,    61,    67,    63,    67,    65,    58,   310,    61,    61,
+    67,   214,    78,   154,   155,   156,   157,   158,   159,   160,
+   161,   162,   163,   164,   165,   166,   167,   168,   169,   170,
+   171,   172,   173,   174,   175,   176,    62,    62,    66,    67,
+    64,    67,    67,    67,    80,   300,    41,     1,    61,     3,
+     4,     5,     6,     7,    34,    35,    36,    37,    12,    66,
+    67,    15,    82,    17,    18,    61,    20,   168,   169,   170,
+   171,    22,    26,    44,    45,    46,    66,    67,   276,    68,
+   278,    68,   280,    68,   266,   267,    67,    68,    42,    43,
+   159,   160,   161,   157,   158,   277,   172,   173,   174,   346,
+   347,    67,    58,    58,    58,    59,    60,    61,    58,    63,
+   292,    65,   294,    83,    67,    63,    70,    71,    72,    73,
+   318,    61,    61,    33,   322,   328,    68,    58,    63,    83,
+    58,    68,   330,    24,   316,    23,    83,   319,     9,    62,
+    83,    62,   324,    68,    62,   343,     0,   345,   346,   347,
+   332,    64,   350,     8,   352,   353,     3,     4,     5,     6,
+     7,     8,     0,   222,    11,    12,    13,    14,    15,    16,
+    17,    18,    19,    20,    21,    22,   227,     8,   175,    26,
+    27,    28,   176,    30,    31,   184,   196,   264,   339,   326,
+   272,   200,   215,    -1,    -1,    42,    43,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    58,    59,    60,    61,    -1,    63,    64,    65,    -1,
+    -1,    -1,    -1,    70,    71,    72,    73,    -1,    -1,     3,
+     4,     5,     6,     7,     8,    -1,    83,    11,    12,    13,
+    14,    15,    16,    17,    18,    19,    20,    21,    22,    -1,
+    -1,    -1,    26,    27,    28,    -1,    30,    31,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    42,    43,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    58,    59,    60,    61,    -1,    63,
+    64,    65,    -1,    -1,    -1,    -1,    70,    71,    72,    73,
+    -1,    -1,     3,     4,     5,     6,     7,     8,    -1,    83,
+    11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
+    21,    22,    -1,    -1,    -1,    26,    27,    28,    -1,    30,
+    31,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    42,    43,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    58,    59,    60,
+    61,    -1,    63,    64,    65,    -1,    -1,    -1,    -1,    70,
+    71,    72,    73,    -1,    -1,     3,     4,     5,     6,     7,
+     8,    -1,    83,    11,    12,    13,    14,    15,    16,    17,
+    18,    19,    20,    21,    22,    -1,    -1,    -1,    26,    27,
+    28,    -1,    30,    31,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    42,    43,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    58,    59,    60,    61,    -1,    63,    64,    65,    -1,    -1,
+    -1,    -1,    70,    71,    72,    73,    -1,    -1,     3,     4,
+     5,     6,     7,     8,    -1,    83,    11,    12,    13,    14,
+    15,    16,    17,    18,    19,    20,    21,    22,    -1,    -1,
+    -1,    26,    27,    28,    -1,    30,    31,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    42,    43,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    58,    59,    60,    61,    -1,    63,    64,
+    65,    -1,    -1,    -1,    -1,    70,    71,    72,    73,    -1,
+    -1,     3,     4,     5,     6,     7,     8,    -1,    83,    11,
+    12,    13,    14,    15,    16,    17,    18,    19,    20,    21,
+    22,    -1,    -1,    -1,    26,    27,    28,    -1,    30,    31,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    42,    43,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    58,    59,    60,    61,
+    -1,    63,    -1,    65,    -1,    -1,    -1,    -1,    70,    71,
+    72,    73,    -1,    -1,     3,     4,     5,     6,     7,     8,
+    -1,    83,    11,    12,    13,    14,    15,    16,    17,    18,
+    19,    20,    21,    22,    -1,    -1,    -1,    26,    27,    28,
+    -1,    30,    31,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    42,    43,    -1,    42,    43,    47,    48,    49,    50,    51,
+    52,    53,    54,    55,    56,    57,    -1,    -1,    -1,    58,
+    59,    60,    61,    -1,    63,    -1,    65,    -1,    -1,    -1,
+    -1,    70,    71,    72,    73,    -1,    -1,    -1,    -1,    -1,
+    82,    -1,     0,    -1,    83,     3,     4,     5,     6,     7,
+     8,     9,    10,    11,    12,    13,    14,    15,    16,    17,
+    18,    19,    20,    21,    22,    23,    -1,    -1,    26,    27,
+    28,    -1,    30,    31,    -1,    -1,    -1,    -1,    -1,     3,
+     4,     5,     6,     7,    -1,    -1,    -1,    -1,    12,    13,
+    -1,    15,    -1,    17,    18,    -1,    20,    -1,    -1,    -1,
+    58,    59,    26,    -1,    -1,    63,    64,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    72,    73,    -1,    -1,    42,    43,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    58,    59,    60,    61,    -1,    63,
+    -1,    65,    -1,    -1,    -1,    -1,    70,    71,    72,    73,
+     3,     4,     5,     6,     7,    -1,    -1,    -1,    -1,    12,
+    -1,    -1,    15,    -1,    17,    18,    -1,    20,    -1,    -1,
+    -1,    -1,    -1,    26,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    42,
+    43,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    58,    59,    60,    61,    -1,
+    63,    -1,    65,    66,    -1,    -1,    -1,    70,    71,    72,
+    73,     3,     4,     5,     6,     7,    -1,    -1,    -1,    -1,
+    12,    -1,    -1,    15,    -1,    17,    18,    -1,    20,    -1,
+    -1,    -1,    -1,    -1,    26,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    42,    43,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    58,    59,    60,    61,
+    62,    63,    -1,    65,    -1,    -1,    -1,    -1,    70,    71,
+    72,    73,     3,     4,     5,     6,     7,    -1,    -1,    -1,
+    -1,    12,    -1,    -1,    15,    -1,    17,    18,    -1,    20,
+    -1,    -1,    -1,    -1,    -1,    26,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    42,    43,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    58,    59,    60,
+    61,    -1,    63,    -1,    65,    66,    -1,    -1,    -1,    70,
+    71,    72,    73,     3,     4,     5,     6,     7,    -1,    -1,
+    -1,    -1,    12,    -1,    -1,    15,    -1,    17,    18,    -1,
+    20,    -1,    -1,    -1,    -1,    -1,    26,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    42,    43,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    58,    59,
+    60,    61,    -1,    63,    -1,    65,    -1,    -1,    -1,    -1,
+    70,    71,    72,    73
+};
+/* -*-C-*-  Note some compilers choke on comments on `#line' lines.  */
+#line 3 "/usr/share/misc/bison.simple"
+/* This file comes from bison-1.28.  */
+
+/* Skeleton output parser for bison,
+   Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, when this file is copied by Bison into a
+   Bison output file, you may use that output file without restriction.
+   This special exception was added by the Free Software Foundation
+   in version 1.24 of Bison.  */
+
+/* This is the parser code that is written into each bison parser
+  when the %semantic_parser declaration is not specified in the grammar.
+  It was written by Richard Stallman by simplifying the hairy parser
+  used when %semantic_parser is specified.  */
+
+#ifndef YYSTACK_USE_ALLOCA
+#ifdef alloca
+#define YYSTACK_USE_ALLOCA
+#else /* alloca not defined */
+#ifdef __GNUC__
+#define YYSTACK_USE_ALLOCA
+#define alloca __builtin_alloca
+#else /* not GNU C.  */
+#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386))
+#define YYSTACK_USE_ALLOCA
+#include <alloca.h>
+#else /* not sparc */
+/* We think this test detects Watcom and Microsoft C.  */
+/* This used to test MSDOS, but that is a bad idea
+   since that symbol is in the user namespace.  */
+#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__)
+#if 0 /* No need for malloc.h, which pollutes the namespace;
+	 instead, just don't use alloca.  */
+#include <malloc.h>
+#endif
+#else /* not MSDOS, or __TURBOC__ */
+#if defined(_AIX)
+/* I don't know what this was needed for, but it pollutes the namespace.
+   So I turned it off.   rms, 2 May 1997.  */
+/* #include <malloc.h>  */
+ #pragma alloca
+#define YYSTACK_USE_ALLOCA
+#else /* not MSDOS, or __TURBOC__, or _AIX */
+#if 0
+#ifdef __hpux /* haible at ilog.fr says this works for HPUX 9.05 and up,
+		 and on HPUX 10.  Eventually we can turn this on.  */
+#define YYSTACK_USE_ALLOCA
+#define alloca __builtin_alloca
+#endif /* __hpux */
+#endif
+#endif /* not _AIX */
+#endif /* not MSDOS, or __TURBOC__ */
+#endif /* not sparc */
+#endif /* not GNU C */
+#endif /* alloca not defined */
+#endif /* YYSTACK_USE_ALLOCA not defined */
+
+#ifdef YYSTACK_USE_ALLOCA
+#define YYSTACK_ALLOC alloca
+#else
+#define YYSTACK_ALLOC malloc
+#endif
+
+/* Note: there must be only one dollar sign in this file.
+   It is replaced by the list of actions, each action
+   as one case of the switch.  */
+
+#define yyerrok		(yyerrstatus = 0)
+#define yyclearin	(yychar = YYEMPTY)
+#define YYEMPTY		-2
+#define YYEOF		0
+#define YYACCEPT	goto yyacceptlab
+#define YYABORT 	goto yyabortlab
+#define YYERROR		goto yyerrlab1
+/* Like YYERROR except do call yyerror.
+   This remains here temporarily to ease the
+   transition to the new meaning of YYERROR, for GCC.
+   Once GCC version 2 has supplanted version 1, this can go.  */
+#define YYFAIL		goto yyerrlab
+#define YYRECOVERING()  (!!yyerrstatus)
+#define YYBACKUP(token, value) \
+do								\
+  if (yychar == YYEMPTY && yylen == 1)				\
+    { yychar = (token), yylval = (value);			\
+      yychar1 = YYTRANSLATE (yychar);				\
+      YYPOPSTACK;						\
+      goto yybackup;						\
+    }								\
+  else								\
+    { yyerror ("syntax error: cannot back up"); YYERROR; }	\
+while (0)
+
+#define YYTERROR	1
+#define YYERRCODE	256
+
+#ifndef YYPURE
+#define YYLEX		yylex()
+#endif
+
+#ifdef YYPURE
+#ifdef YYLSP_NEEDED
+#ifdef YYLEX_PARAM
+#define YYLEX		yylex(&yylval, &yylloc, YYLEX_PARAM)
+#else
+#define YYLEX		yylex(&yylval, &yylloc)
+#endif
+#else /* not YYLSP_NEEDED */
+#ifdef YYLEX_PARAM
+#define YYLEX		yylex(&yylval, YYLEX_PARAM)
+#else
+#define YYLEX		yylex(&yylval)
+#endif
+#endif /* not YYLSP_NEEDED */
+#endif
+
+/* If nonreentrant, generate the variables here */
+
+#ifndef YYPURE
+
+int	yychar;			/*  the lookahead symbol		*/
+YYSTYPE	yylval;			/*  the semantic value of the		*/
+				/*  lookahead symbol			*/
+
+#ifdef YYLSP_NEEDED
+YYLTYPE yylloc;			/*  location data for the lookahead	*/
+				/*  symbol				*/
+#endif
+
+int yynerrs;			/*  number of parse errors so far       */
+#endif  /* not YYPURE */
+
+#if YYDEBUG != 0
+int yydebug;			/*  nonzero means print parse trace	*/
+/* Since this is uninitialized, it does not stop multiple parsers
+   from coexisting.  */
+#endif
+
+/*  YYINITDEPTH indicates the initial size of the parser's stacks	*/
+
+#ifndef	YYINITDEPTH
+#define YYINITDEPTH 200
+#endif
+
+/*  YYMAXDEPTH is the maximum size the stacks can grow to
+    (effective only if the built-in stack extension method is used).  */
+
+#if YYMAXDEPTH == 0
+#undef YYMAXDEPTH
+#endif
+
+#ifndef YYMAXDEPTH
+#define YYMAXDEPTH 10000
+#endif
+
+/* Define __yy_memcpy.  Note that the size argument
+   should be passed with type unsigned int, because that is what the non-GCC
+   definitions require.  With GCC, __builtin_memcpy takes an arg
+   of type size_t, but it can handle unsigned int.  */
+
+#if __GNUC__ > 1		/* GNU C and GNU C++ define this.  */
+#define __yy_memcpy(TO,FROM,COUNT)	__builtin_memcpy(TO,FROM,COUNT)
+#else				/* not GNU C or C++ */
+#ifndef __cplusplus
+
+/* This is the most reliable way to avoid incompatibilities
+   in available built-in functions on various systems.  */
+static void
+__yy_memcpy (to, from, count)
+     char *to;
+     char *from;
+     unsigned int count;
+{
+  register char *f = from;
+  register char *t = to;
+  register int i = count;
+
+  while (i-- > 0)
+    *t++ = *f++;
+}
+
+#else /* __cplusplus */
+
+/* This is the most reliable way to avoid incompatibilities
+   in available built-in functions on various systems.  */
+static void
+__yy_memcpy (char *to, char *from, unsigned int count)
+{
+  register char *t = to;
+  register char *f = from;
+  register int i = count;
+
+  while (i-- > 0)
+    *t++ = *f++;
+}
+
+#endif
+#endif
+
+#line 217 "/usr/share/misc/bison.simple"
+
+/* The user can define YYPARSE_PARAM as the name of an argument to be passed
+   into yyparse.  The argument should have type void *.
+   It should actually point to an object.
+   Grammar actions can access the variable by casting it
+   to the proper pointer type.  */
+
+#ifdef YYPARSE_PARAM
+#ifdef __cplusplus
+#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
+#define YYPARSE_PARAM_DECL
+#else /* not __cplusplus */
+#define YYPARSE_PARAM_ARG YYPARSE_PARAM
+#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
+#endif /* not __cplusplus */
+#else /* not YYPARSE_PARAM */
+#define YYPARSE_PARAM_ARG
+#define YYPARSE_PARAM_DECL
+#endif /* not YYPARSE_PARAM */
+
+/* Prevent warning if -Wstrict-prototypes.  */
+#ifdef __GNUC__
+#ifdef YYPARSE_PARAM
+int yyparse (void *);
+#else
+int yyparse (void);
+#endif
+#endif
+
+int
+yyparse(YYPARSE_PARAM_ARG)
+     YYPARSE_PARAM_DECL
+{
+  register int yystate;
+  register int yyn;
+  register short *yyssp;
+  register YYSTYPE *yyvsp;
+  int yyerrstatus;	/*  number of tokens to shift before error messages enabled */
+  int yychar1 = 0;		/*  lookahead token as an internal (translated) token number */
+
+  short	yyssa[YYINITDEPTH];	/*  the state stack			*/
+  YYSTYPE yyvsa[YYINITDEPTH];	/*  the semantic value stack		*/
+
+  short *yyss = yyssa;		/*  refer to the stacks thru separate pointers */
+  YYSTYPE *yyvs = yyvsa;	/*  to allow yyoverflow to reallocate them elsewhere */
+
+#ifdef YYLSP_NEEDED
+  YYLTYPE yylsa[YYINITDEPTH];	/*  the location stack			*/
+  YYLTYPE *yyls = yylsa;
+  YYLTYPE *yylsp;
+
+#define YYPOPSTACK   (yyvsp--, yyssp--, yylsp--)
+#else
+#define YYPOPSTACK   (yyvsp--, yyssp--)
+#endif
+
+  int yystacksize = YYINITDEPTH;
+  int yyfree_stacks = 0;
+
+#ifdef YYPURE
+  int yychar;
+  YYSTYPE yylval;
+  int yynerrs;
+#ifdef YYLSP_NEEDED
+  YYLTYPE yylloc;
+#endif
+#endif
+
+  YYSTYPE yyval;		/*  the variable used to return		*/
+				/*  semantic values from the action	*/
+				/*  routines				*/
+
+  int yylen;
+
+#if YYDEBUG != 0
+  if (yydebug)
+    fprintf(stderr, "Starting parse\n");
+#endif
+
+  yystate = 0;
+  yyerrstatus = 0;
+  yynerrs = 0;
+  yychar = YYEMPTY;		/* Cause a token to be read.  */
+
+  /* Initialize stack pointers.
+     Waste one element of value and location stack
+     so that they stay on the same level as the state stack.
+     The wasted elements are never initialized.  */
+
+  yyssp = yyss - 1;
+  yyvsp = yyvs;
+#ifdef YYLSP_NEEDED
+  yylsp = yyls;
+#endif
+
+/* Push a new state, which is found in  yystate  .  */
+/* In all cases, when you get here, the value and location stacks
+   have just been pushed. so pushing a state here evens the stacks.  */
+yynewstate:
+
+  *++yyssp = yystate;
+
+  if (yyssp >= yyss + yystacksize - 1)
+    {
+      /* Give user a chance to reallocate the stack */
+      /* Use copies of these so that the &'s don't force the real ones into memory. */
+      YYSTYPE *yyvs1 = yyvs;
+      short *yyss1 = yyss;
+#ifdef YYLSP_NEEDED
+      YYLTYPE *yyls1 = yyls;
+#endif
+
+      /* Get the current used size of the three stacks, in elements.  */
+      int size = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+      /* Each stack pointer address is followed by the size of
+	 the data in use in that stack, in bytes.  */
+#ifdef YYLSP_NEEDED
+      /* This used to be a conditional around just the two extra args,
+	 but that might be undefined if yyoverflow is a macro.  */
+      yyoverflow("parser stack overflow",
+		 &yyss1, size * sizeof (*yyssp),
+		 &yyvs1, size * sizeof (*yyvsp),
+		 &yyls1, size * sizeof (*yylsp),
+		 &yystacksize);
+#else
+      yyoverflow("parser stack overflow",
+		 &yyss1, size * sizeof (*yyssp),
+		 &yyvs1, size * sizeof (*yyvsp),
+		 &yystacksize);
+#endif
+
+      yyss = yyss1; yyvs = yyvs1;
+#ifdef YYLSP_NEEDED
+      yyls = yyls1;
+#endif
+#else /* no yyoverflow */
+      /* Extend the stack our own way.  */
+      if (yystacksize >= YYMAXDEPTH)
+	{
+	  yyerror("parser stack overflow");
+	  if (yyfree_stacks)
+	    {
+	      free (yyss);
+	      free (yyvs);
+#ifdef YYLSP_NEEDED
+	      free (yyls);
+#endif
+	    }
+	  return 2;
+	}
+      yystacksize *= 2;
+      if (yystacksize > YYMAXDEPTH)
+	yystacksize = YYMAXDEPTH;
+#ifndef YYSTACK_USE_ALLOCA
+      yyfree_stacks = 1;
+#endif
+      yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp));
+      __yy_memcpy ((char *)yyss, (char *)yyss1,
+		   size * (unsigned int) sizeof (*yyssp));
+      yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp));
+      __yy_memcpy ((char *)yyvs, (char *)yyvs1,
+		   size * (unsigned int) sizeof (*yyvsp));
+#ifdef YYLSP_NEEDED
+      yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp));
+      __yy_memcpy ((char *)yyls, (char *)yyls1,
+		   size * (unsigned int) sizeof (*yylsp));
+#endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + size - 1;
+      yyvsp = yyvs + size - 1;
+#ifdef YYLSP_NEEDED
+      yylsp = yyls + size - 1;
+#endif
+
+#if YYDEBUG != 0
+      if (yydebug)
+	fprintf(stderr, "Stack size increased to %d\n", yystacksize);
+#endif
+
+      if (yyssp >= yyss + yystacksize - 1)
+	YYABORT;
+    }
+
+#if YYDEBUG != 0
+  if (yydebug)
+    fprintf(stderr, "Entering state %d\n", yystate);
+#endif
+
+  goto yybackup;
+ yybackup:
+
+/* Do appropriate processing given the current state.  */
+/* Read a lookahead token if we need one and don't already have one.  */
+/* yyresume: */
+
+  /* First try to decide what to do without reference to lookahead token.  */
+
+  yyn = yypact[yystate];
+  if (yyn == YYFLAG)
+    goto yydefault;
+
+  /* Not known => get a lookahead token if don't already have one.  */
+
+  /* yychar is either YYEMPTY or YYEOF
+     or a valid token in external form.  */
+
+  if (yychar == YYEMPTY)
+    {
+#if YYDEBUG != 0
+      if (yydebug)
+	fprintf(stderr, "Reading a token: ");
+#endif
+      yychar = YYLEX;
+    }
+
+  /* Convert token to internal form (in yychar1) for indexing tables with */
+
+  if (yychar <= 0)		/* This means end of input. */
+    {
+      yychar1 = 0;
+      yychar = YYEOF;		/* Don't call YYLEX any more */
+
+#if YYDEBUG != 0
+      if (yydebug)
+	fprintf(stderr, "Now at end of input.\n");
+#endif
+    }
+  else
+    {
+      yychar1 = YYTRANSLATE(yychar);
+
+#if YYDEBUG != 0
+      if (yydebug)
+	{
+	  fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
+	  /* Give the individual parser a way to print the precise meaning
+	     of a token, for further debugging info.  */
+#ifdef YYPRINT
+	  YYPRINT (stderr, yychar, yylval);
+#endif
+	  fprintf (stderr, ")\n");
+	}
+#endif
+    }
+
+  yyn += yychar1;
+  if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
+    goto yydefault;
+
+  yyn = yytable[yyn];
+
+  /* yyn is what to do for this token type in this state.
+     Negative => reduce, -yyn is rule number.
+     Positive => shift, yyn is new state.
+       New state is final state => don't bother to shift,
+       just return success.
+     0, or most negative number => error.  */
+
+  if (yyn < 0)
+    {
+      if (yyn == YYFLAG)
+	goto yyerrlab;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+  else if (yyn == 0)
+    goto yyerrlab;
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  /* Shift the lookahead token.  */
+
+#if YYDEBUG != 0
+  if (yydebug)
+    fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
+#endif
+
+  /* Discard the token being shifted unless it is eof.  */
+  if (yychar != YYEOF)
+    yychar = YYEMPTY;
+
+  *++yyvsp = yylval;
+#ifdef YYLSP_NEEDED
+  *++yylsp = yylloc;
+#endif
+
+  /* count tokens shifted since error; after three, turn off error status.  */
+  if (yyerrstatus) yyerrstatus--;
+
+  yystate = yyn;
+  goto yynewstate;
+
+/* Do the default action for the current state.  */
+yydefault:
+
+  yyn = yydefact[yystate];
+  if (yyn == 0)
+    goto yyerrlab;
+
+/* Do a reduction.  yyn is the number of a rule to reduce with.  */
+yyreduce:
+  yylen = yyr2[yyn];
+  if (yylen > 0)
+    yyval = yyvsp[1-yylen]; /* implement default value of the action */
+
+#if YYDEBUG != 0
+  if (yydebug)
+    {
+      int i;
+
+      fprintf (stderr, "Reducing via rule %d (line %d), ",
+	       yyn, yyrline[yyn]);
+
+      /* Print the symbols being reduced, and their result.  */
+      for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
+	fprintf (stderr, "%s ", yytname[yyrhs[i]]);
+      fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
+    }
+#endif
+
+
+  switch (yyn) {
+
+case 1:
+#line 157 "grammar.y"
+{ yyval.node = new NullNode(); ;
+    break;}
+case 2:
+#line 158 "grammar.y"
+{ yyval.node = new BooleanNode(true); ;
+    break;}
+case 3:
+#line 159 "grammar.y"
+{ yyval.node = new BooleanNode(false); ;
+    break;}
+case 4:
+#line 160 "grammar.y"
+{ yyval.node = new NumberNode(yyvsp[0].dval); ;
+    break;}
+case 5:
+#line 161 "grammar.y"
+{ yyval.node = new StringNode(yyvsp[0].ustr); delete yyvsp[0].ustr; ;
+    break;}
+case 6:
+#line 162 "grammar.y"
+{ Lexer *l = Lexer::curr();
+                                     if (!l->scanRegExp()) YYABORT;
+                                     yyval.node = new RegExpNode(l->pattern,l->flags);;
+    break;}
+case 7:
+#line 168 "grammar.y"
+{ yyval.node = new ThisNode(); ;
+    break;}
+case 8:
+#line 169 "grammar.y"
+{ yyval.node = new ResolveNode(yyvsp[0].ustr);
+                                     delete yyvsp[0].ustr; ;
+    break;}
+case 11:
+#line 173 "grammar.y"
+{ yyval.node = new GroupNode(yyvsp[-1].node); ;
+    break;}
+case 12:
+#line 174 "grammar.y"
+{ yyval.node = new ObjectLiteralNode(0L); ;
+    break;}
+case 13:
+#line 175 "grammar.y"
+{ yyval.node = new ObjectLiteralNode(yyvsp[-1].node); ;
+    break;}
+case 14:
+#line 179 "grammar.y"
+{ yyval.node = new ArrayNode(yyvsp[-1].eli); ;
+    break;}
+case 15:
+#line 180 "grammar.y"
+{ yyval.node = new ArrayNode(yyvsp[-1].elm); ;
+    break;}
+case 16:
+#line 181 "grammar.y"
+{ yyval.node = new ArrayNode(yyvsp[-1].eli, yyvsp[-3].elm); ;
+    break;}
+case 17:
+#line 185 "grammar.y"
+{ yyval.elm = new ElementNode(yyvsp[-1].eli, yyvsp[0].node); ;
+    break;}
+case 18:
+#line 187 "grammar.y"
+{ yyval.elm = new ElementNode(yyvsp[-3].elm, yyvsp[-1].eli, yyvsp[0].node); ;
+    break;}
+case 19:
+#line 191 "grammar.y"
+{ yyval.eli = 0L; ;
+    break;}
+case 21:
+#line 196 "grammar.y"
+{ yyval.eli = new ElisionNode(0L); ;
+    break;}
+case 22:
+#line 197 "grammar.y"
+{ yyval.eli = new ElisionNode(yyvsp[-1].eli); ;
+    break;}
+case 23:
+#line 201 "grammar.y"
+{ yyval.node = new PropertyValueNode(yyvsp[-2].node, yyvsp[0].node); ;
+    break;}
+case 24:
+#line 203 "grammar.y"
+{ yyval.node = new PropertyValueNode(yyvsp[-2].node, yyvsp[0].node, yyvsp[-4].node); ;
+    break;}
+case 25:
+#line 207 "grammar.y"
+{ yyval.node = new PropertyNode(yyvsp[0].ustr);
+                                     delete yyvsp[0].ustr; ;
+    break;}
+case 26:
+#line 209 "grammar.y"
+{ yyval.node = new PropertyNode(yyvsp[0].ustr); delete yyvsp[0].ustr; ;
+    break;}
+case 27:
+#line 210 "grammar.y"
+{ yyval.node = new PropertyNode(yyvsp[0].dval); ;
+    break;}
+case 30:
+#line 216 "grammar.y"
+{ yyval.node = new AccessorNode1(yyvsp[-3].node, yyvsp[-1].node); ;
+    break;}
+case 31:
+#line 217 "grammar.y"
+{ yyval.node = new AccessorNode2(yyvsp[-2].node, yyvsp[0].ustr);
+                                     delete yyvsp[0].ustr; ;
+    break;}
+case 32:
+#line 219 "grammar.y"
+{ yyval.node = new NewExprNode(yyvsp[-1].node, yyvsp[0].args); ;
+    break;}
+case 34:
+#line 224 "grammar.y"
+{ yyval.node = new NewExprNode(yyvsp[0].node); ;
+    break;}
+case 35:
+#line 228 "grammar.y"
+{ yyval.node = new FunctionCallNode(yyvsp[-1].node, yyvsp[0].args); ;
+    break;}
+case 36:
+#line 229 "grammar.y"
+{ yyval.node = new FunctionCallNode(yyvsp[-1].node, yyvsp[0].args); ;
+    break;}
+case 37:
+#line 230 "grammar.y"
+{ yyval.node = new AccessorNode1(yyvsp[-3].node, yyvsp[-1].node); ;
+    break;}
+case 38:
+#line 231 "grammar.y"
+{ yyval.node = new AccessorNode2(yyvsp[-2].node, yyvsp[0].ustr); ;
+    break;}
+case 39:
+#line 235 "grammar.y"
+{ yyval.args = new ArgumentsNode(0L); ;
+    break;}
+case 40:
+#line 236 "grammar.y"
+{ yyval.args = new ArgumentsNode(yyvsp[-1].alist); ;
+    break;}
+case 41:
+#line 240 "grammar.y"
+{ yyval.alist = new ArgumentListNode(yyvsp[0].node); ;
+    break;}
+case 42:
+#line 241 "grammar.y"
+{ yyval.alist = new ArgumentListNode(yyvsp[-2].alist, yyvsp[0].node); ;
+    break;}
+case 46:
+#line 251 "grammar.y"
+{ yyval.node = new PostfixNode(yyvsp[-1].node, OpPlusPlus); ;
+    break;}
+case 47:
+#line 252 "grammar.y"
+{ yyval.node = new PostfixNode(yyvsp[-1].node, OpMinusMinus); ;
+    break;}
+case 49:
+#line 257 "grammar.y"
+{ yyval.node = new DeleteNode(yyvsp[0].node); ;
+    break;}
+case 50:
+#line 258 "grammar.y"
+{ yyval.node = new VoidNode(yyvsp[0].node); ;
+    break;}
+case 51:
+#line 259 "grammar.y"
+{ yyval.node = new TypeOfNode(yyvsp[0].node); ;
+    break;}
+case 52:
+#line 260 "grammar.y"
+{ yyval.node = new PrefixNode(OpPlusPlus, yyvsp[0].node); ;
+    break;}
+case 53:
+#line 261 "grammar.y"
+{ yyval.node = new PrefixNode(OpPlusPlus, yyvsp[0].node); ;
+    break;}
+case 54:
+#line 262 "grammar.y"
+{ yyval.node = new PrefixNode(OpMinusMinus, yyvsp[0].node); ;
+    break;}
+case 55:
+#line 263 "grammar.y"
+{ yyval.node = new PrefixNode(OpMinusMinus, yyvsp[0].node); ;
+    break;}
+case 56:
+#line 264 "grammar.y"
+{ yyval.node = new UnaryPlusNode(yyvsp[0].node); ;
+    break;}
+case 57:
+#line 265 "grammar.y"
+{ yyval.node = new NegateNode(yyvsp[0].node); ;
+    break;}
+case 58:
+#line 266 "grammar.y"
+{ yyval.node = new BitwiseNotNode(yyvsp[0].node); ;
+    break;}
+case 59:
+#line 267 "grammar.y"
+{ yyval.node = new LogicalNotNode(yyvsp[0].node); ;
+    break;}
+case 61:
+#line 272 "grammar.y"
+{ yyval.node = new MultNode(yyvsp[-2].node, yyvsp[0].node, '*'); ;
+    break;}
+case 62:
+#line 273 "grammar.y"
+{ yyval.node = new MultNode(yyvsp[-2].node, yyvsp[0].node, '/'); ;
+    break;}
+case 63:
+#line 274 "grammar.y"
+{ yyval.node = new MultNode(yyvsp[-2].node,yyvsp[0].node,'%'); ;
+    break;}
+case 65:
+#line 279 "grammar.y"
+{ yyval.node = new AddNode(yyvsp[-2].node, yyvsp[0].node, '+'); ;
+    break;}
+case 66:
+#line 280 "grammar.y"
+{ yyval.node = new AddNode(yyvsp[-2].node, yyvsp[0].node, '-'); ;
+    break;}
+case 68:
+#line 285 "grammar.y"
+{ yyval.node = new ShiftNode(yyvsp[-2].node, OpLShift, yyvsp[0].node); ;
+    break;}
+case 69:
+#line 286 "grammar.y"
+{ yyval.node = new ShiftNode(yyvsp[-2].node, OpRShift, yyvsp[0].node); ;
+    break;}
+case 70:
+#line 287 "grammar.y"
+{ yyval.node = new ShiftNode(yyvsp[-2].node, OpURShift, yyvsp[0].node); ;
+    break;}
+case 72:
+#line 293 "grammar.y"
+{ yyval.node = new RelationalNode(yyvsp[-2].node, OpLess, yyvsp[0].node); ;
+    break;}
+case 73:
+#line 295 "grammar.y"
+{ yyval.node = new RelationalNode(yyvsp[-2].node, OpGreater, yyvsp[0].node); ;
+    break;}
+case 74:
+#line 297 "grammar.y"
+{ yyval.node = new RelationalNode(yyvsp[-2].node, OpLessEq, yyvsp[0].node); ;
+    break;}
+case 75:
+#line 299 "grammar.y"
+{ yyval.node = new RelationalNode(yyvsp[-2].node, OpGreaterEq, yyvsp[0].node); ;
+    break;}
+case 76:
+#line 301 "grammar.y"
+{ yyval.node = new RelationalNode(yyvsp[-2].node, OpInstanceOf, yyvsp[0].node); ;
+    break;}
+case 77:
+#line 303 "grammar.y"
+{ yyval.node = new RelationalNode(yyvsp[-2].node, OpIn, yyvsp[0].node); ;
+    break;}
+case 79:
+#line 308 "grammar.y"
+{ yyval.node = new EqualNode(yyvsp[-2].node, OpEqEq, yyvsp[0].node); ;
+    break;}
+case 80:
+#line 309 "grammar.y"
+{ yyval.node = new EqualNode(yyvsp[-2].node, OpNotEq, yyvsp[0].node); ;
+    break;}
+case 81:
+#line 310 "grammar.y"
+{ yyval.node = new EqualNode(yyvsp[-2].node, OpStrEq, yyvsp[0].node); ;
+    break;}
+case 82:
+#line 311 "grammar.y"
+{ yyval.node = new EqualNode(yyvsp[-2].node, OpStrNEq, yyvsp[0].node);;
+    break;}
+case 84:
+#line 316 "grammar.y"
+{ yyval.node = new BitOperNode(yyvsp[-2].node, OpBitAnd, yyvsp[0].node); ;
+    break;}
+case 86:
+#line 321 "grammar.y"
+{ yyval.node = new BitOperNode(yyvsp[-2].node, OpBitXOr, yyvsp[0].node); ;
+    break;}
+case 88:
+#line 326 "grammar.y"
+{ yyval.node = new BitOperNode(yyvsp[-2].node, OpBitOr, yyvsp[0].node); ;
+    break;}
+case 90:
+#line 332 "grammar.y"
+{ yyval.node = new BinaryLogicalNode(yyvsp[-2].node, OpAnd, yyvsp[0].node); ;
+    break;}
+case 92:
+#line 338 "grammar.y"
+{ yyval.node = new BinaryLogicalNode(yyvsp[-2].node, OpOr, yyvsp[0].node); ;
+    break;}
+case 94:
+#line 344 "grammar.y"
+{ yyval.node = new ConditionalNode(yyvsp[-4].node, yyvsp[-2].node, yyvsp[0].node); ;
+    break;}
+case 96:
+#line 350 "grammar.y"
+{ yyval.node = new AssignNode(yyvsp[-2].node, yyvsp[-1].op, yyvsp[0].node);;
+    break;}
+case 97:
+#line 354 "grammar.y"
+{ yyval.op = OpEqual; ;
+    break;}
+case 98:
+#line 355 "grammar.y"
+{ yyval.op = OpPlusEq; ;
+    break;}
+case 99:
+#line 356 "grammar.y"
+{ yyval.op = OpMinusEq; ;
+    break;}
+case 100:
+#line 357 "grammar.y"
+{ yyval.op = OpMultEq; ;
+    break;}
+case 101:
+#line 358 "grammar.y"
+{ yyval.op = OpDivEq; ;
+    break;}
+case 102:
+#line 359 "grammar.y"
+{ yyval.op = OpLShift; ;
+    break;}
+case 103:
+#line 360 "grammar.y"
+{ yyval.op = OpRShift; ;
+    break;}
+case 104:
+#line 361 "grammar.y"
+{ yyval.op = OpURShift; ;
+    break;}
+case 105:
+#line 362 "grammar.y"
+{ yyval.op = OpAndEq; ;
+    break;}
+case 106:
+#line 363 "grammar.y"
+{ yyval.op = OpXOrEq; ;
+    break;}
+case 107:
+#line 364 "grammar.y"
+{ yyval.op = OpOrEq; ;
+    break;}
+case 108:
+#line 365 "grammar.y"
+{ yyval.op = OpModEq; ;
+    break;}
+case 110:
+#line 370 "grammar.y"
+{ yyval.node = new CommaNode(yyvsp[-2].node, yyvsp[0].node); ;
+    break;}
+case 125:
+#line 391 "grammar.y"
+{ yyval.stat = new BlockNode(0L); DBG(yyval.stat, yylsp[0], yylsp[0]); ;
+    break;}
+case 126:
+#line 392 "grammar.y"
+{ yyval.stat = new BlockNode(yyvsp[-1].slist); DBG(yyval.stat, yylsp[0], yylsp[0]); ;
+    break;}
+case 127:
+#line 396 "grammar.y"
+{ yyval.slist = new StatListNode(yyvsp[0].stat); ;
+    break;}
+case 128:
+#line 397 "grammar.y"
+{ yyval.slist = new StatListNode(yyvsp[-1].slist, yyvsp[0].stat); ;
+    break;}
+case 129:
+#line 401 "grammar.y"
+{ yyval.stat = new VarStatementNode(yyvsp[-1].vlist);
+                                      DBG(yyval.stat, yylsp[-2], yylsp[0]); ;
+    break;}
+case 130:
+#line 403 "grammar.y"
+{ if (automatic()) {
+                                          yyval.stat = new VarStatementNode(yyvsp[-1].vlist);
+					  DBG(yyval.stat, yylsp[-2], yylsp[-1]);
+                                        } else {
+					  YYABORT;
+					}
+                                      ;
+    break;}
+case 131:
+#line 413 "grammar.y"
+{ yyval.vlist = new VarDeclListNode(yyvsp[0].decl); ;
+    break;}
+case 132:
+#line 415 "grammar.y"
+{ yyval.vlist = new VarDeclListNode(yyvsp[-2].vlist, yyvsp[0].decl); ;
+    break;}
+case 133:
+#line 419 "grammar.y"
+{ yyval.decl = new VarDeclNode(yyvsp[0].ustr, 0); delete yyvsp[0].ustr; ;
+    break;}
+case 134:
+#line 420 "grammar.y"
+{ yyval.decl = new VarDeclNode(yyvsp[-1].ustr, yyvsp[0].init); delete yyvsp[-1].ustr; ;
+    break;}
+case 135:
+#line 424 "grammar.y"
+{ yyval.init = new AssignExprNode(yyvsp[0].node); ;
+    break;}
+case 136:
+#line 428 "grammar.y"
+{ yyval.stat = new EmptyStatementNode(); ;
+    break;}
+case 137:
+#line 432 "grammar.y"
+{ yyval.stat = new ExprStatementNode(yyvsp[-1].node);
+                                     DBG(yyval.stat, yylsp[-1], yylsp[0]); ;
+    break;}
+case 138:
+#line 434 "grammar.y"
+{ if (automatic()) {
+                                       yyval.stat = new ExprStatementNode(yyvsp[-1].node);
+				       DBG(yyval.stat, yylsp[-1], yylsp[-1]);
+                                     } else
+				       YYABORT; ;
+    break;}
+case 139:
+#line 442 "grammar.y"
+{ yyval.stat = new IfNode(yyvsp[-2].node,yyvsp[0].stat,0L);DBG(yyval.stat,yylsp[-4],yylsp[-1]); ;
+    break;}
+case 140:
+#line 444 "grammar.y"
+{ yyval.stat = new IfNode(yyvsp[-4].node,yyvsp[-2].stat,yyvsp[0].stat);DBG(yyval.stat,yylsp[-6],yylsp[-3]); ;
+    break;}
+case 141:
+#line 448 "grammar.y"
+{ yyval.stat=new DoWhileNode(yyvsp[-4].stat,yyvsp[-1].node);DBG(yyval.stat,yylsp[-5],yylsp[-3]);;
+    break;}
+case 142:
+#line 449 "grammar.y"
+{ yyval.stat = new WhileNode(yyvsp[-2].node,yyvsp[0].stat);DBG(yyval.stat,yylsp[-4],yylsp[-1]); ;
+    break;}
+case 143:
+#line 451 "grammar.y"
+{ yyval.stat = new ForNode(yyvsp[-6].node,yyvsp[-4].node,yyvsp[-2].node,yyvsp[0].stat);
+	                             DBG(yyval.stat,yylsp[-8],yylsp[-1]); ;
+    break;}
+case 144:
+#line 454 "grammar.y"
+{ yyval.stat = new ForNode(yyvsp[-6].vlist,yyvsp[-4].node,yyvsp[-2].node,yyvsp[0].stat);
+	                             DBG(yyval.stat,yylsp[-9],yylsp[-1]); ;
+    break;}
+case 145:
+#line 457 "grammar.y"
+{ yyval.stat = new ForInNode(yyvsp[-4].node, yyvsp[-2].node, yyvsp[0].stat);
+	                             DBG(yyval.stat,yylsp[-6],yylsp[-1]); ;
+    break;}
+case 146:
+#line 460 "grammar.y"
+{ yyval.stat = new ForInNode(yyvsp[-4].ustr,0L,yyvsp[-2].node,yyvsp[0].stat);
+	                             DBG(yyval.stat,yylsp[-7],yylsp[-1]);
+                                     delete yyvsp[-4].ustr; ;
+    break;}
+case 147:
+#line 464 "grammar.y"
+{ yyval.stat = new ForInNode(yyvsp[-5].ustr,yyvsp[-4].init,yyvsp[-2].node,yyvsp[0].stat);
+	                             DBG(yyval.stat,yylsp[-8],yylsp[-1]);
+                                     delete yyvsp[-5].ustr; ;
+    break;}
+case 148:
+#line 470 "grammar.y"
+{ yyval.node = 0L; ;
+    break;}
+case 150:
+#line 475 "grammar.y"
+{ yyval.stat = new ContinueNode(); DBG(yyval.stat,yylsp[-1],yylsp[0]); ;
+    break;}
+case 151:
+#line 476 "grammar.y"
+{ if (automatic()) {
+                                       yyval.stat = new ContinueNode(); DBG(yyval.stat,yylsp[-1],yylsp[0]);
+                                     } else
+				       YYABORT; ;
+    break;}
+case 152:
+#line 480 "grammar.y"
+{ yyval.stat = new ContinueNode(yyvsp[-1].ustr); DBG(yyval.stat,yylsp[-2],yylsp[0]);
+                                     delete yyvsp[-1].ustr; ;
+    break;}
+case 153:
+#line 482 "grammar.y"
+{ if (automatic()) {
+                                       yyval.stat = new ContinueNode(yyvsp[-1].ustr);DBG(yyval.stat,yylsp[-2],yylsp[-1]);
+				       delete yyvsp[-1].ustr;
+                                     } else
+				       YYABORT; ;
+    break;}
+case 154:
+#line 490 "grammar.y"
+{ yyval.stat = new BreakNode();DBG(yyval.stat,yylsp[-1],yylsp[0]); ;
+    break;}
+case 155:
+#line 491 "grammar.y"
+{ if (automatic()) {
+                                       yyval.stat = new BreakNode(); DBG(yyval.stat,yylsp[-1],yylsp[-1]);
+                                     } else
+				       YYABORT; ;
+    break;}
+case 156:
+#line 495 "grammar.y"
+{ yyval.stat = new BreakNode(yyvsp[-1].ustr); DBG(yyval.stat,yylsp[-2],yylsp[0]);
+                                     delete yyvsp[-1].ustr; ;
+    break;}
+case 157:
+#line 497 "grammar.y"
+{ if (automatic()) {
+                                       yyval.stat = new BreakNode(yyvsp[-1].ustr); DBG(yyval.stat,yylsp[-2],yylsp[-1]);
+				       delete yyvsp[-1].ustr;
+                                     } else
+				       YYABORT;
+                                   ;
+    break;}
+case 158:
+#line 506 "grammar.y"
+{ yyval.stat = new ReturnNode(0L); DBG(yyval.stat,yylsp[-1],yylsp[0]); ;
+    break;}
+case 159:
+#line 507 "grammar.y"
+{ if (automatic()) {
+                                       yyval.stat = new ReturnNode(0L); DBG(yyval.stat,yylsp[-1],yylsp[-1]);
+                                     } else
+				       YYABORT; ;
+    break;}
+case 160:
+#line 511 "grammar.y"
+{ yyval.stat = new ReturnNode(yyvsp[-1].node); ;
+    break;}
+case 161:
+#line 512 "grammar.y"
+{ if (automatic())
+                                       yyval.stat = new ReturnNode(yyvsp[-1].node);
+                                     else
+				       YYABORT; ;
+    break;}
+case 162:
+#line 519 "grammar.y"
+{ yyval.stat = new WithNode(yyvsp[-2].node,yyvsp[0].stat);
+                                     DBG(yyval.stat, yylsp[-4], yylsp[-1]); ;
+    break;}
+case 163:
+#line 524 "grammar.y"
+{ yyval.stat = new SwitchNode(yyvsp[-2].node, yyvsp[0].cblk);
+                                     DBG(yyval.stat, yylsp[-4], yylsp[-1]); ;
+    break;}
+case 164:
+#line 529 "grammar.y"
+{ yyval.cblk = new CaseBlockNode(yyvsp[-1].clist, 0L, 0L); ;
+    break;}
+case 165:
+#line 531 "grammar.y"
+{ yyval.cblk = new CaseBlockNode(yyvsp[-3].clist, yyvsp[-2].ccl, yyvsp[-1].clist); ;
+    break;}
+case 166:
+#line 535 "grammar.y"
+{ yyval.clist = 0L; ;
+    break;}
+case 168:
+#line 540 "grammar.y"
+{ yyval.clist = new ClauseListNode(yyvsp[0].ccl); ;
+    break;}
+case 169:
+#line 541 "grammar.y"
+{ yyval.clist = yyvsp[-1].clist->append(yyvsp[0].ccl); ;
+    break;}
+case 170:
+#line 545 "grammar.y"
+{ yyval.ccl = new CaseClauseNode(yyvsp[-1].node, 0L); ;
+    break;}
+case 171:
+#line 546 "grammar.y"
+{ yyval.ccl = new CaseClauseNode(yyvsp[-2].node, yyvsp[0].slist); ;
+    break;}
+case 172:
+#line 550 "grammar.y"
+{ yyval.ccl = new CaseClauseNode(0L, 0L);; ;
+    break;}
+case 173:
+#line 551 "grammar.y"
+{ yyval.ccl = new CaseClauseNode(0L, yyvsp[0].slist); ;
+    break;}
+case 174:
+#line 555 "grammar.y"
+{ yyvsp[0].stat->pushLabel(yyvsp[-2].ustr);
+                                     yyval.stat = new LabelNode(yyvsp[-2].ustr, yyvsp[0].stat);
+                                     delete yyvsp[-2].ustr; ;
+    break;}
+case 175:
+#line 561 "grammar.y"
+{ yyval.stat = new ThrowNode(yyvsp[-1].node); ;
+    break;}
+case 176:
+#line 565 "grammar.y"
+{ yyval.stat = new TryNode(yyvsp[-1].stat, yyvsp[0].node); ;
+    break;}
+case 177:
+#line 566 "grammar.y"
+{ yyval.stat = new TryNode(yyvsp[-1].stat, 0L, yyvsp[0].node); ;
+    break;}
+case 178:
+#line 567 "grammar.y"
+{ yyval.stat = new TryNode(yyvsp[-2].stat, yyvsp[-1].node, yyvsp[0].node); ;
+    break;}
+case 179:
+#line 571 "grammar.y"
+{ yyval.node = new CatchNode(yyvsp[-2].ustr, yyvsp[0].stat); delete yyvsp[-2].ustr; ;
+    break;}
+case 180:
+#line 575 "grammar.y"
+{ yyval.node = new FinallyNode(yyvsp[0].stat); ;
+    break;}
+case 181:
+#line 579 "grammar.y"
+{ yyval.func = new FuncDeclNode(yyvsp[-3].ustr, 0L, yyvsp[0].body);
+                                             delete yyvsp[-3].ustr; ;
+    break;}
+case 182:
+#line 582 "grammar.y"
+{ yyval.func = new FuncDeclNode(yyvsp[-4].ustr, yyvsp[-2].param, yyvsp[0].body);
+                                     delete yyvsp[-4].ustr; ;
+    break;}
+case 183:
+#line 586 "grammar.y"
+{ yyval.node = new FuncExprNode(0L, yyvsp[0].body); ;
+    break;}
+case 184:
+#line 588 "grammar.y"
+{ yyval.node = new FuncExprNode(yyvsp[-2].param, yyvsp[0].body); ;
+    break;}
+case 185:
+#line 593 "grammar.y"
+{ yyval.param = new ParameterNode(yyvsp[0].ustr); delete yyvsp[0].ustr; ;
+    break;}
+case 186:
+#line 594 "grammar.y"
+{ yyval.param = yyvsp[-2].param->append(yyvsp[0].ustr);
+	                             delete yyvsp[0].ustr; ;
+    break;}
+case 187:
+#line 599 "grammar.y"
+{ yyval.body = new FunctionBodyNode(0L); ;
+    break;}
+case 188:
+#line 600 "grammar.y"
+{ yyval.body = new FunctionBodyNode(yyvsp[-1].srcs); ;
+    break;}
+case 189:
+#line 604 "grammar.y"
+{ yyval.prog = new ProgramNode(yyvsp[0].srcs);
+                                     KJScriptImp::current()->setProgNode(yyval.prog); ;
+    break;}
+case 190:
+#line 609 "grammar.y"
+{ yyval.srcs = new SourceElementsNode(yyvsp[0].src); ;
+    break;}
+case 191:
+#line 610 "grammar.y"
+{ yyval.srcs = new SourceElementsNode(yyvsp[-1].srcs, yyvsp[0].src); ;
+    break;}
+case 192:
+#line 614 "grammar.y"
+{ yyval.src = new SourceElementNode(yyvsp[0].stat); ;
+    break;}
+case 193:
+#line 615 "grammar.y"
+{ yyval.src = new SourceElementNode(yyvsp[0].func); ;
+    break;}
+}
+   /* the action file gets copied in in place of this dollarsign */
+#line 543 "/usr/share/misc/bison.simple"
+
+  yyvsp -= yylen;
+  yyssp -= yylen;
+#ifdef YYLSP_NEEDED
+  yylsp -= yylen;
+#endif
+
+#if YYDEBUG != 0
+  if (yydebug)
+    {
+      short *ssp1 = yyss - 1;
+      fprintf (stderr, "state stack now");
+      while (ssp1 != yyssp)
+	fprintf (stderr, " %d", *++ssp1);
+      fprintf (stderr, "\n");
+    }
+#endif
+
+  *++yyvsp = yyval;
+
+#ifdef YYLSP_NEEDED
+  yylsp++;
+  if (yylen == 0)
+    {
+      yylsp->first_line = yylloc.first_line;
+      yylsp->first_column = yylloc.first_column;
+      yylsp->last_line = (yylsp-1)->last_line;
+      yylsp->last_column = (yylsp-1)->last_column;
+      yylsp->text = 0;
+    }
+  else
+    {
+      yylsp->last_line = (yylsp+yylen-1)->last_line;
+      yylsp->last_column = (yylsp+yylen-1)->last_column;
+    }
+#endif
+
+  /* Now "shift" the result of the reduction.
+     Determine what state that goes to,
+     based on the state we popped back to
+     and the rule number reduced by.  */
+
+  yyn = yyr1[yyn];
+
+  yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
+  if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+    yystate = yytable[yystate];
+  else
+    yystate = yydefgoto[yyn - YYNTBASE];
+
+  goto yynewstate;
+
+yyerrlab:   /* here on detecting error */
+
+  if (! yyerrstatus)
+    /* If not already recovering from an error, report this error.  */
+    {
+      ++yynerrs;
+
+#ifdef YYERROR_VERBOSE
+      yyn = yypact[yystate];
+
+      if (yyn > YYFLAG && yyn < YYLAST)
+	{
+	  int size = 0;
+	  char *msg;
+	  int x, count;
+
+	  count = 0;
+	  /* Start X at -yyn if nec to avoid negative indexes in yycheck.  */
+	  for (x = (yyn < 0 ? -yyn : 0);
+	       x < (sizeof(yytname) / sizeof(char *)); x++)
+	    if (yycheck[x + yyn] == x)
+	      size += strlen(yytname[x]) + 15, count++;
+	  msg = (char *) malloc(size + 15);
+	  if (msg != 0)
+	    {
+	      strcpy(msg, "parse error");
+
+	      if (count < 5)
+		{
+		  count = 0;
+		  for (x = (yyn < 0 ? -yyn : 0);
+		       x < (sizeof(yytname) / sizeof(char *)); x++)
+		    if (yycheck[x + yyn] == x)
+		      {
+			strcat(msg, count == 0 ? ", expecting `" : " or `");
+			strcat(msg, yytname[x]);
+			strcat(msg, "'");
+			count++;
+		      }
+		}
+	      yyerror(msg);
+	      free(msg);
+	    }
+	  else
+	    yyerror ("parse error; also virtual memory exceeded");
+	}
+      else
+#endif /* YYERROR_VERBOSE */
+	yyerror("parse error");
+    }
+
+  goto yyerrlab1;
+yyerrlab1:   /* here on error raised explicitly by an action */
+
+  if (yyerrstatus == 3)
+    {
+      /* if just tried and failed to reuse lookahead token after an error, discard it.  */
+
+      /* return failure if at end of input */
+      if (yychar == YYEOF)
+	YYABORT;
+
+#if YYDEBUG != 0
+      if (yydebug)
+	fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
+#endif
+
+      yychar = YYEMPTY;
+    }
+
+  /* Else will try to reuse lookahead token
+     after shifting the error token.  */
+
+  yyerrstatus = 3;		/* Each real token shifted decrements this */
+
+  goto yyerrhandle;
+
+yyerrdefault:  /* current state does not do anything special for the error token. */
+
+#if 0
+  /* This is wrong; only states that explicitly want error tokens
+     should shift them.  */
+  yyn = yydefact[yystate];  /* If its default is to accept any token, ok.  Otherwise pop it.*/
+  if (yyn) goto yydefault;
+#endif
+
+yyerrpop:   /* pop the current state because it cannot handle the error token */
+
+  if (yyssp == yyss) YYABORT;
+  yyvsp--;
+  yystate = *--yyssp;
+#ifdef YYLSP_NEEDED
+  yylsp--;
+#endif
+
+#if YYDEBUG != 0
+  if (yydebug)
+    {
+      short *ssp1 = yyss - 1;
+      fprintf (stderr, "Error: state stack now");
+      while (ssp1 != yyssp)
+	fprintf (stderr, " %d", *++ssp1);
+      fprintf (stderr, "\n");
+    }
+#endif
+
+yyerrhandle:
+
+  yyn = yypact[yystate];
+  if (yyn == YYFLAG)
+    goto yyerrdefault;
+
+  yyn += YYTERROR;
+  if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
+    goto yyerrdefault;
+
+  yyn = yytable[yyn];
+  if (yyn < 0)
+    {
+      if (yyn == YYFLAG)
+	goto yyerrpop;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+  else if (yyn == 0)
+    goto yyerrpop;
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+#if YYDEBUG != 0
+  if (yydebug)
+    fprintf(stderr, "Shifting error token, ");
+#endif
+
+  *++yyvsp = yylval;
+#ifdef YYLSP_NEEDED
+  *++yylsp = yylloc;
+#endif
+
+  yystate = yyn;
+  goto yynewstate;
+
+ yyacceptlab:
+  /* YYACCEPT comes here.  */
+  if (yyfree_stacks)
+    {
+      free (yyss);
+      free (yyvs);
+#ifdef YYLSP_NEEDED
+      free (yyls);
+#endif
+    }
+  return 0;
+
+ yyabortlab:
+  /* YYABORT comes here.  */
+  if (yyfree_stacks)
+    {
+      free (yyss);
+      free (yyvs);
+#ifdef YYLSP_NEEDED
+      free (yyls);
+#endif
+    }
+  return 1;
+}
+#line 618 "grammar.y"
+
+
+int yyerror (const char *)  /* Called by yyparse on error */
+{
+//  fprintf(stderr, "ERROR: %s at line %d\n",
+//	  s, KJScript::lexer()->lineNo());
+  return 1;
+}
+
+/* may we automatically insert a semicolon ? */
+bool automatic()
+{
+  if (yychar == '}' || yychar == 0)
+    return true;
+  else if (Lexer::curr()->prevTerminator())
+    return true;
+
+  return false;
+}
diff --git a/JavaScriptCore/kjs/grammar.h b/JavaScriptCore/kjs/grammar.h
new file mode 100644
index 0000000..38eb0ba
--- /dev/null
+++ b/JavaScriptCore/kjs/grammar.h
@@ -0,0 +1,102 @@
+typedef union {
+  int                 ival;
+  double              dval;
+  UString             *ustr;
+  Node                *node;
+  StatementNode       *stat;
+  ParameterNode       *param;
+  FunctionBodyNode    *body;
+  FuncDeclNode        *func;
+  ProgramNode         *prog;
+  AssignExprNode      *init;
+  SourceElementNode   *src;
+  SourceElementsNode  *srcs;
+  StatListNode        *slist;
+  ArgumentsNode       *args;
+  ArgumentListNode    *alist;
+  VarDeclNode         *decl;
+  VarDeclListNode     *vlist;
+  CaseBlockNode       *cblk;
+  ClauseListNode      *clist;
+  CaseClauseNode      *ccl;
+  ElementNode         *elm;
+  ElisionNode         *eli;
+  Operator            op;
+} YYSTYPE;
+
+#ifndef YYLTYPE
+typedef
+  struct yyltype
+    {
+      int timestamp;
+      int first_line;
+      int first_column;
+      int last_line;
+      int last_column;
+      char *text;
+   }
+  yyltype;
+
+#define YYLTYPE yyltype
+#endif
+
+#define	NULLTOKEN	257
+#define	TRUETOKEN	258
+#define	FALSETOKEN	259
+#define	STRING	260
+#define	NUMBER	261
+#define	BREAK	262
+#define	CASE	263
+#define	DEFAULT	264
+#define	FOR	265
+#define	NEW	266
+#define	VAR	267
+#define	CONTINUE	268
+#define	FUNCTION	269
+#define	RETURN	270
+#define	VOID	271
+#define	DELETE	272
+#define	IF	273
+#define	THIS	274
+#define	DO	275
+#define	WHILE	276
+#define	ELSE	277
+#define	IN	278
+#define	INSTANCEOF	279
+#define	TYPEOF	280
+#define	SWITCH	281
+#define	WITH	282
+#define	RESERVED	283
+#define	THROW	284
+#define	TRY	285
+#define	CATCH	286
+#define	FINALLY	287
+#define	EQEQ	288
+#define	NE	289
+#define	STREQ	290
+#define	STRNEQ	291
+#define	LE	292
+#define	GE	293
+#define	OR	294
+#define	AND	295
+#define	PLUSPLUS	296
+#define	MINUSMINUS	297
+#define	LSHIFT	298
+#define	RSHIFT	299
+#define	URSHIFT	300
+#define	PLUSEQUAL	301
+#define	MINUSEQUAL	302
+#define	MULTEQUAL	303
+#define	DIVEQUAL	304
+#define	LSHIFTEQUAL	305
+#define	RSHIFTEQUAL	306
+#define	URSHIFTEQUAL	307
+#define	ANDEQUAL	308
+#define	MODEQUAL	309
+#define	XOREQUAL	310
+#define	OREQUAL	311
+#define	IDENT	312
+#define	AUTO	313
+
+
+extern YYSTYPE kjsyylval;
diff --git a/JavaScriptCore/kjs/grammar.y b/JavaScriptCore/kjs/grammar.y
new file mode 100644
index 0000000..cf07456
--- /dev/null
+++ b/JavaScriptCore/kjs/grammar.y
@@ -0,0 +1,636 @@
+%{
+
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <string.h>
+#include "kjs.h"
+#include "nodes.h"
+#include "lexer.h"
+
+/* default values for bison */
+#define YYDEBUG 0
+#define YYMAXDEPTH 0
+#ifdef KJS_DEBUGGER
+#define YYERROR_VERBOSE
+#define DBG(l, s, e) { l->setLoc(s.first_line, e.last_line); } // location
+#else
+#undef YYLSP_NEEDED
+#define DBG(l, s, e)
+#endif
+
+extern int yylex();
+int yyerror (const char *);
+bool automatic();
+
+using namespace KJS;
+
+%}
+
+%union {
+  int                 ival;
+  double              dval;
+  UString             *ustr;
+  Node                *node;
+  StatementNode       *stat;
+  ParameterNode       *param;
+  FunctionBodyNode    *body;
+  FuncDeclNode        *func;
+  ProgramNode         *prog;
+  AssignExprNode      *init;
+  SourceElementNode   *src;
+  SourceElementsNode  *srcs;
+  StatListNode        *slist;
+  ArgumentsNode       *args;
+  ArgumentListNode    *alist;
+  VarDeclNode         *decl;
+  VarDeclListNode     *vlist;
+  CaseBlockNode       *cblk;
+  ClauseListNode      *clist;
+  CaseClauseNode      *ccl;
+  ElementNode         *elm;
+  ElisionNode         *eli;
+  Operator            op;
+}
+
+%start Program
+
+/* expect a shift/reduce conflict from the "dangling else" problem
+   when using bison the warning can be supressed */
+// %expect 1
+
+/* literals */
+%token NULLTOKEN TRUETOKEN FALSETOKEN
+%token STRING NUMBER
+
+/* keywords */
+%token BREAK CASE DEFAULT FOR NEW VAR CONTINUE
+%token FUNCTION RETURN VOID DELETE
+%token IF THIS DO WHILE ELSE IN INSTANCEOF TYPEOF
+%token SWITCH WITH RESERVED
+%token THROW TRY CATCH FINALLY
+
+/* punctuators */
+%token EQEQ NE                     /* == and != */
+%token STREQ STRNEQ                /* === and !== */
+%token LE GE                       /* < and > */
+%token OR AND                      /* || and && */
+%token PLUSPLUS MINUSMINUS         /* ++ and --  */
+%token LSHIFT                      /* << */
+%token RSHIFT URSHIFT              /* >> and >>> */
+%token PLUSEQUAL MINUSEQUAL        /* += and -= */
+%token MULTEQUAL DIVEQUAL          /* *= and /= */
+%token LSHIFTEQUAL                 /* <<= */
+%token RSHIFTEQUAL URSHIFTEQUAL    /* >>= and >>>= */
+%token ANDEQUAL MODEQUAL           /* &= and %= */
+%token XOREQUAL OREQUAL            /* ^= and |= */
+
+/* terminal types */
+%token <dval> NUMBER
+%token <ustr> STRING
+%token <ustr> IDENT
+
+/* automatically inserted semicolon */
+%token AUTO
+
+/* non-terminal types */
+%type <node>  Literal PrimaryExpr Expr MemberExpr FunctionExpr NewExpr CallExpr
+%type <node>  ArrayLiteral PropertyName PropertyNameAndValueList
+%type <node>  LeftHandSideExpr PostfixExpr UnaryExpr
+%type <node>  MultiplicativeExpr AdditiveExpr
+%type <node>  ShiftExpr RelationalExpr EqualityExpr
+%type <node>  BitwiseANDExpr BitwiseXORExpr BitwiseORExpr
+%type <node>  LogicalANDExpr LogicalORExpr
+%type <node>  ConditionalExpr AssignmentExpr
+%type <node>  ExprOpt
+%type <node>  CallExpr
+%type <node>  Catch Finally
+
+%type <stat>  Statement Block
+%type <stat>  VariableStatement EmptyStatement ExprStatement
+%type <stat>  IfStatement IterationStatement ContinueStatement
+%type <stat>  BreakStatement ReturnStatement WithStatement
+%type <stat>  SwitchStatement LabelledStatement
+%type <stat>  ThrowStatement TryStatement
+
+%type <slist> StatementList
+%type <init>  Initializer
+%type <func>  FunctionDeclaration
+%type <body>  FunctionBody
+%type <src>   SourceElement
+%type <srcs>  SourceElements
+%type <param> FormalParameterList
+%type <op>    AssignmentOperator
+%type <prog>  Program
+%type <args>  Arguments
+%type <alist> ArgumentList
+%type <vlist> VariableDeclarationList
+%type <decl>  VariableDeclaration
+%type <cblk>  CaseBlock
+%type <ccl>   CaseClause DefaultClause
+%type <clist> CaseClauses  CaseClausesOpt
+%type <eli>   Elision ElisionOpt
+%type <elm>   ElementList
+
+%%
+
+Literal:
+    NULLTOKEN                      { $$ = new NullNode(); }
+  | TRUETOKEN                      { $$ = new BooleanNode(true); }
+  | FALSETOKEN                     { $$ = new BooleanNode(false); }
+  | NUMBER                         { $$ = new NumberNode($1); }
+  | STRING                         { $$ = new StringNode($1); delete $1; }
+  | '/'       /* a RegExp ? */     { Lexer *l = Lexer::curr();
+                                     if (!l->scanRegExp()) YYABORT;
+                                     $$ = new RegExpNode(l->pattern,l->flags);}
+;
+
+PrimaryExpr:
+    THIS                           { $$ = new ThisNode(); }
+  | IDENT                          { $$ = new ResolveNode($1);
+                                     delete $1; }
+  | Literal
+  | ArrayLiteral
+  | '(' Expr ')'                   { $$ = new GroupNode($2); }
+  | '{' '}'                        { $$ = new ObjectLiteralNode(0L); }
+  | '{' PropertyNameAndValueList '}'   { $$ = new ObjectLiteralNode($2); }
+;
+
+ArrayLiteral:
+    '[' ElisionOpt ']'                 { $$ = new ArrayNode($2); }
+  | '[' ElementList ']'                { $$ = new ArrayNode($2); }
+  | '[' ElementList ',' ElisionOpt ']' { $$ = new ArrayNode($4, $2); }
+;
+
+ElementList:
+    ElisionOpt AssignmentExpr      { $$ = new ElementNode($1, $2); }
+  | ElementList ',' ElisionOpt AssignmentExpr
+                                   { $$ = new ElementNode($1, $3, $4); }
+;
+
+ElisionOpt:
+    /* nothing */                  { $$ = 0L; }
+  | Elision
+;
+
+Elision:
+    ','                            { $$ = new ElisionNode(0L); }
+  | Elision ','                    { $$ = new ElisionNode($1); }
+;
+
+PropertyNameAndValueList:
+    PropertyName ':' AssignmentExpr     { $$ = new PropertyValueNode($1, $3); }
+  | PropertyNameAndValueList ',' PropertyName ':' AssignmentExpr
+                                   { $$ = new PropertyValueNode($3, $5, $1); }
+;
+
+PropertyName:
+    IDENT                          { $$ = new PropertyNode($1);
+                                     delete $1; }
+  | STRING                         { $$ = new PropertyNode($1); delete $1; }
+  | NUMBER                         { $$ = new PropertyNode($1); }
+;
+
+MemberExpr:
+    PrimaryExpr
+  | FunctionExpr
+  | MemberExpr '[' Expr ']'        { $$ = new AccessorNode1($1, $3); }
+  | MemberExpr '.' IDENT           { $$ = new AccessorNode2($1, $3);
+                                     delete $3; }
+  | NEW MemberExpr Arguments       { $$ = new NewExprNode($2, $3); }
+;
+
+NewExpr:
+    MemberExpr
+  | NEW NewExpr                    { $$ = new NewExprNode($2); }
+;
+
+CallExpr:
+    MemberExpr Arguments           { $$ = new FunctionCallNode($1, $2); }
+  | CallExpr Arguments             { $$ = new FunctionCallNode($1, $2); }
+  | CallExpr '[' Expr ']'          { $$ = new AccessorNode1($1, $3); }
+  | CallExpr '.' IDENT             { $$ = new AccessorNode2($1, $3); }
+;
+
+Arguments:
+    '(' ')'                        { $$ = new ArgumentsNode(0L); }
+  | '(' ArgumentList ')'           { $$ = new ArgumentsNode($2); }
+;
+
+ArgumentList:
+    AssignmentExpr                  { $$ = new ArgumentListNode($1); }
+  | ArgumentList ',' AssignmentExpr { $$ = new ArgumentListNode($1, $3); }
+;
+
+LeftHandSideExpr:
+    NewExpr
+  | CallExpr
+;
+
+PostfixExpr:    /* TODO: no line terminator here */
+    LeftHandSideExpr
+  | LeftHandSideExpr PLUSPLUS      { $$ = new PostfixNode($1, OpPlusPlus); }
+  | LeftHandSideExpr MINUSMINUS    { $$ = new PostfixNode($1, OpMinusMinus); }
+;
+
+UnaryExpr:
+    PostfixExpr
+  | DELETE UnaryExpr               { $$ = new DeleteNode($2); }
+  | VOID UnaryExpr                 { $$ = new VoidNode($2); }
+  | TYPEOF UnaryExpr               { $$ = new TypeOfNode($2); }
+  | PLUSPLUS UnaryExpr             { $$ = new PrefixNode(OpPlusPlus, $2); }
+  | AUTO PLUSPLUS UnaryExpr        { $$ = new PrefixNode(OpPlusPlus, $3); }
+  | MINUSMINUS UnaryExpr           { $$ = new PrefixNode(OpMinusMinus, $2); }
+  | AUTO MINUSMINUS UnaryExpr      { $$ = new PrefixNode(OpMinusMinus, $3); }
+  | '+' UnaryExpr                  { $$ = new UnaryPlusNode($2); }
+  | '-' UnaryExpr                  { $$ = new NegateNode($2); }
+  | '~' UnaryExpr                  { $$ = new BitwiseNotNode($2); }
+  | '!' UnaryExpr                  { $$ = new LogicalNotNode($2); }
+;
+
+MultiplicativeExpr:
+    UnaryExpr
+  | MultiplicativeExpr '*' UnaryExpr { $$ = new MultNode($1, $3, '*'); }
+  | MultiplicativeExpr '/' UnaryExpr { $$ = new MultNode($1, $3, '/'); }
+  | MultiplicativeExpr '%' UnaryExpr { $$ = new MultNode($1,$3,'%'); }
+;
+
+AdditiveExpr:
+    MultiplicativeExpr
+  | AdditiveExpr '+' MultiplicativeExpr { $$ = new AddNode($1, $3, '+'); }
+  | AdditiveExpr '-' MultiplicativeExpr { $$ = new AddNode($1, $3, '-'); }
+;
+
+ShiftExpr:
+    AdditiveExpr
+  | ShiftExpr LSHIFT AdditiveExpr  { $$ = new ShiftNode($1, OpLShift, $3); }
+  | ShiftExpr RSHIFT AdditiveExpr  { $$ = new ShiftNode($1, OpRShift, $3); }
+  | ShiftExpr URSHIFT AdditiveExpr { $$ = new ShiftNode($1, OpURShift, $3); }
+;
+
+RelationalExpr:
+    ShiftExpr
+  | RelationalExpr '<' ShiftExpr
+                           { $$ = new RelationalNode($1, OpLess, $3); }
+  | RelationalExpr '>' ShiftExpr
+                           { $$ = new RelationalNode($1, OpGreater, $3); }
+  | RelationalExpr LE ShiftExpr
+                           { $$ = new RelationalNode($1, OpLessEq, $3); }
+  | RelationalExpr GE ShiftExpr
+                           { $$ = new RelationalNode($1, OpGreaterEq, $3); }
+  | RelationalExpr INSTANCEOF ShiftExpr
+                           { $$ = new RelationalNode($1, OpInstanceOf, $3); }
+  | RelationalExpr IN ShiftExpr
+                           { $$ = new RelationalNode($1, OpIn, $3); }
+;
+
+EqualityExpr:
+    RelationalExpr
+  | EqualityExpr EQEQ RelationalExpr   { $$ = new EqualNode($1, OpEqEq, $3); }
+  | EqualityExpr NE RelationalExpr     { $$ = new EqualNode($1, OpNotEq, $3); }
+  | EqualityExpr STREQ RelationalExpr  { $$ = new EqualNode($1, OpStrEq, $3); }
+  | EqualityExpr STRNEQ RelationalExpr { $$ = new EqualNode($1, OpStrNEq, $3);}
+;
+
+BitwiseANDExpr:
+    EqualityExpr
+  | BitwiseANDExpr '&' EqualityExpr { $$ = new BitOperNode($1, OpBitAnd, $3); }
+;
+
+BitwiseXORExpr:
+    BitwiseANDExpr
+  | BitwiseXORExpr '^' EqualityExpr { $$ = new BitOperNode($1, OpBitXOr, $3); }
+;
+
+BitwiseORExpr:
+    BitwiseXORExpr
+  | BitwiseORExpr '|' EqualityExpr  { $$ = new BitOperNode($1, OpBitOr, $3); }
+;
+
+LogicalANDExpr:
+    BitwiseORExpr
+  | LogicalANDExpr AND BitwiseORExpr
+                           { $$ = new BinaryLogicalNode($1, OpAnd, $3); }
+;
+
+LogicalORExpr:
+    LogicalANDExpr
+  | LogicalORExpr OR LogicalANDExpr
+                           { $$ = new BinaryLogicalNode($1, OpOr, $3); }
+;
+
+ConditionalExpr:
+    LogicalORExpr
+  | LogicalORExpr '?' AssignmentExpr ':' AssignmentExpr
+                           { $$ = new ConditionalNode($1, $3, $5); }
+;
+
+AssignmentExpr:
+    ConditionalExpr
+  | LeftHandSideExpr AssignmentOperator AssignmentExpr
+                           { $$ = new AssignNode($1, $2, $3);}
+;
+
+AssignmentOperator:
+    '='                            { $$ = OpEqual; }
+  | PLUSEQUAL                      { $$ = OpPlusEq; }
+  | MINUSEQUAL                     { $$ = OpMinusEq; }
+  | MULTEQUAL                      { $$ = OpMultEq; }
+  | DIVEQUAL                       { $$ = OpDivEq; }
+  | LSHIFTEQUAL                    { $$ = OpLShift; }
+  | RSHIFTEQUAL                    { $$ = OpRShift; }
+  | URSHIFTEQUAL                   { $$ = OpURShift; }
+  | ANDEQUAL                       { $$ = OpAndEq; }
+  | XOREQUAL                       { $$ = OpXOrEq; }
+  | OREQUAL                        { $$ = OpOrEq; }
+  | MODEQUAL                       { $$ = OpModEq; }
+;
+
+Expr:
+    AssignmentExpr
+  | Expr ',' AssignmentExpr        { $$ = new CommaNode($1, $3); }
+;
+
+Statement:
+    Block
+  | VariableStatement
+  | EmptyStatement
+  | ExprStatement
+  | IfStatement
+  | IterationStatement
+  | ContinueStatement
+  | BreakStatement
+  | ReturnStatement
+  | WithStatement
+  | SwitchStatement
+  | LabelledStatement
+  | ThrowStatement
+  | TryStatement
+;
+
+Block:
+    '{' '}'                        { $$ = new BlockNode(0L); DBG($$, @2, @2); }
+  | '{' StatementList '}'          { $$ = new BlockNode($2); DBG($$, @3, @3); }
+;
+
+StatementList:
+    Statement                      { $$ = new StatListNode($1); }
+  | StatementList Statement        { $$ = new StatListNode($1, $2); }
+;
+
+VariableStatement:
+    VAR VariableDeclarationList ';' { $$ = new VarStatementNode($2);
+                                      DBG($$, @1, @3); }
+  | VAR VariableDeclarationList error { if (automatic()) {
+                                          $$ = new VarStatementNode($2);
+					  DBG($$, @1, @2);
+                                        } else {
+					  YYABORT;
+					}
+                                      }
+;
+
+VariableDeclarationList:
+    VariableDeclaration            { $$ = new VarDeclListNode($1); }
+  | VariableDeclarationList ',' VariableDeclaration
+                                   { $$ = new VarDeclListNode($1, $3); }
+;
+
+VariableDeclaration:
+    IDENT                          { $$ = new VarDeclNode($1, 0); delete $1; }
+  | IDENT Initializer              { $$ = new VarDeclNode($1, $2); delete $1; }
+;
+
+Initializer:
+    '=' AssignmentExpr             { $$ = new AssignExprNode($2); }
+;
+
+EmptyStatement:
+    ';'                            { $$ = new EmptyStatementNode(); }
+;
+
+ExprStatement:
+    Expr ';'                       { $$ = new ExprStatementNode($1);
+                                     DBG($$, @1, @2); }
+  | Expr error                     { if (automatic()) {
+                                       $$ = new ExprStatementNode($1);
+				       DBG($$, @1, @1);
+                                     } else
+				       YYABORT; }
+;
+
+IfStatement: /* shift/reduce conflict due to dangling else */
+    IF '(' Expr ')' Statement      { $$ = new IfNode($3,$5,0L);DBG($$, at 1, at 4); }
+  | IF '(' Expr ')' Statement ELSE Statement
+                                   { $$ = new IfNode($3,$5,$7);DBG($$, at 1, at 4); }
+;
+
+IterationStatement:
+    DO Statement WHILE '(' Expr ')' { $$=new DoWhileNode($2,$5);DBG($$, at 1, at 3);}
+  | WHILE '(' Expr ')' Statement   { $$ = new WhileNode($3,$5);DBG($$, at 1, at 4); }
+  | FOR '(' ExprOpt ';' ExprOpt ';' ExprOpt ')'
+            Statement              { $$ = new ForNode($3,$5,$7,$9);
+	                             DBG($$, at 1, at 8); }
+  | FOR '(' VAR VariableDeclarationList ';' ExprOpt ';' ExprOpt ')'
+            Statement              { $$ = new ForNode($4,$6,$8,$10);
+	                             DBG($$, at 1, at 9); }
+  | FOR '(' LeftHandSideExpr IN Expr ')'
+            Statement              { $$ = new ForInNode($3, $5, $7);
+	                             DBG($$, at 1, at 6); }
+  | FOR '(' VAR IDENT IN Expr ')'
+            Statement              { $$ = new ForInNode($4,0L,$6,$8);
+	                             DBG($$, at 1, at 7);
+                                     delete $4; }
+  | FOR '(' VAR IDENT Initializer IN Expr ')'
+            Statement              { $$ = new ForInNode($4,$5,$7,$9);
+	                             DBG($$, at 1, at 8);
+                                     delete $4; }
+;
+
+ExprOpt:
+    /* nothing */                  { $$ = 0L; }
+  | Expr
+;
+
+ContinueStatement:
+    CONTINUE ';'                   { $$ = new ContinueNode(); DBG($$, at 1, at 2); }
+  | CONTINUE error                 { if (automatic()) {
+                                       $$ = new ContinueNode(); DBG($$, at 1, at 2);
+                                     } else
+				       YYABORT; }
+  | CONTINUE IDENT ';'             { $$ = new ContinueNode($2); DBG($$, at 1, at 3);
+                                     delete $2; }
+  | CONTINUE IDENT error           { if (automatic()) {
+                                       $$ = new ContinueNode($2);DBG($$, at 1, at 2);
+				       delete $2;
+                                     } else
+				       YYABORT; }
+;
+
+BreakStatement:
+    BREAK ';'                      { $$ = new BreakNode();DBG($$, at 1, at 2); }
+  | BREAK error                    { if (automatic()) {
+                                       $$ = new BreakNode(); DBG($$, at 1, at 1);
+                                     } else
+				       YYABORT; }
+  | BREAK IDENT ';'                { $$ = new BreakNode($2); DBG($$, at 1, at 3);
+                                     delete $2; }
+  | BREAK IDENT error              { if (automatic()) {
+                                       $$ = new BreakNode($2); DBG($$, at 1, at 2);
+				       delete $2;
+                                     } else
+				       YYABORT;
+                                   }
+;
+
+ReturnStatement:
+    RETURN ';'                     { $$ = new ReturnNode(0L); DBG($$, at 1, at 2); }
+  | RETURN error                   { if (automatic()) {
+                                       $$ = new ReturnNode(0L); DBG($$, at 1, at 1);
+                                     } else
+				       YYABORT; }
+  | RETURN Expr ';'                { $$ = new ReturnNode($2); }
+  | RETURN Expr error              { if (automatic())
+                                       $$ = new ReturnNode($2);
+                                     else
+				       YYABORT; }
+;
+
+WithStatement:
+    WITH '(' Expr ')' Statement    { $$ = new WithNode($3,$5);
+                                     DBG($$, @1, @4); }
+;
+
+SwitchStatement:
+    SWITCH '(' Expr ')' CaseBlock  { $$ = new SwitchNode($3, $5);
+                                     DBG($$, @1, @4); }
+;
+
+CaseBlock:
+    '{' CaseClausesOpt '}'         { $$ = new CaseBlockNode($2, 0L, 0L); }
+  | '{' CaseClausesOpt DefaultClause CaseClausesOpt '}'
+                                   { $$ = new CaseBlockNode($2, $3, $4); }
+;
+
+CaseClausesOpt:
+    /* nothing */                  { $$ = 0L; }
+  | CaseClauses
+;
+
+CaseClauses:
+    CaseClause                     { $$ = new ClauseListNode($1); }
+  | CaseClauses CaseClause         { $$ = $1->append($2); }
+;
+
+CaseClause:
+    CASE Expr ':'                  { $$ = new CaseClauseNode($2, 0L); }
+  | CASE Expr ':' StatementList    { $$ = new CaseClauseNode($2, $4); }
+;
+
+DefaultClause:
+    DEFAULT ':'                    { $$ = new CaseClauseNode(0L, 0L);; }
+  | DEFAULT ':' StatementList      { $$ = new CaseClauseNode(0L, $3); }
+;
+
+LabelledStatement:
+    IDENT ':' Statement            { $3->pushLabel($1);
+                                     $$ = new LabelNode($1, $3);
+                                     delete $1; }
+;
+
+ThrowStatement:
+    THROW Expr ';'                 { $$ = new ThrowNode($2); }
+;
+
+TryStatement:
+    TRY Block Catch                { $$ = new TryNode($2, $3); }
+  | TRY Block Finally              { $$ = new TryNode($2, 0L, $3); }
+  | TRY Block Catch Finally        { $$ = new TryNode($2, $3, $4); }
+;
+
+Catch:
+    CATCH '(' IDENT ')' Block      { $$ = new CatchNode($3, $5); delete $3; }
+;
+
+Finally:
+    FINALLY Block                  { $$ = new FinallyNode($2); }
+;
+
+FunctionDeclaration:
+    FUNCTION IDENT '(' ')' FunctionBody    { $$ = new FuncDeclNode($2, 0L, $5);
+                                             delete $2; }
+  | FUNCTION IDENT '(' FormalParameterList ')' FunctionBody
+                                   { $$ = new FuncDeclNode($2, $4, $6);
+                                     delete $2; }
+
+FunctionExpr:
+    FUNCTION '(' ')' FunctionBody  { $$ = new FuncExprNode(0L, $4); }
+  | FUNCTION '(' FormalParameterList ')' FunctionBody
+                                   { $$ = new FuncExprNode($3, $5); }
+
+;
+
+FormalParameterList:
+    IDENT                          { $$ = new ParameterNode($1); delete $1; }
+  | FormalParameterList ',' IDENT  { $$ = $1->append($3);
+	                             delete $3; }
+;
+
+FunctionBody:
+    '{' '}'  /* TODO: spec ??? */  { $$ = new FunctionBodyNode(0L); }
+  | '{' SourceElements '}'         { $$ = new FunctionBodyNode($2); }
+;
+
+Program:
+    SourceElements                 { $$ = new ProgramNode($1);
+                                     KJScriptImp::current()->setProgNode($$); }
+;
+
+SourceElements:
+    SourceElement                  { $$ = new SourceElementsNode($1); }
+  | SourceElements SourceElement   { $$ = new SourceElementsNode($1, $2); }
+;
+
+SourceElement:
+    Statement                      { $$ = new SourceElementNode($1); }
+  | FunctionDeclaration            { $$ = new SourceElementNode($1); }
+;
+
+%%
+
+int yyerror (const char *)  /* Called by yyparse on error */
+{
+//  fprintf(stderr, "ERROR: %s at line %d\n",
+//	  s, KJScript::lexer()->lineNo());
+  return 1;
+}
+
+/* may we automatically insert a semicolon ? */
+bool automatic()
+{
+  if (yychar == '}' || yychar == 0)
+    return true;
+  else if (Lexer::curr()->prevTerminator())
+    return true;
+
+  return false;
+}
diff --git a/JavaScriptCore/kjs/internal.cpp b/JavaScriptCore/kjs/internal.cpp
new file mode 100644
index 0000000..9fc40fa
--- /dev/null
+++ b/JavaScriptCore/kjs/internal.cpp
@@ -0,0 +1,912 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2001 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#include "internal.h"
+
+#include <assert.h>
+#include <stdio.h>
+
+#include "kjs.h"
+#include "object.h"
+#include "types.h"
+#include "operations.h"
+#include "regexp.h"
+#include "nodes.h"
+#include "lexer.h"
+#include "collector.h"
+#include "debugger.h"
+
+#define I18N_NOOP(s) s
+
+extern int kjsyyparse();
+
+using namespace KJS;
+
+const TypeInfo UndefinedImp::info = { "Undefined", UndefinedType, 0, 0, 0 };
+const TypeInfo NullImp::info = { "Null", NullType, 0, 0, 0 };
+const TypeInfo NumberImp::info = { "Number", NumberType, 0, 0,0  };
+const TypeInfo StringImp::info = { "String", StringType, 0, 0, 0 };
+const TypeInfo BooleanImp::info = { "Boolean", BooleanType, 0, 0, 0 };
+const TypeInfo CompletionImp::info = { "Completion", CompletionType, 0, 0, 0 };
+const TypeInfo ReferenceImp::info = { "Reference", ReferenceType, 0, 0, 0 };
+
+UndefinedImp *UndefinedImp::staticUndefined = 0;
+
+UndefinedImp::UndefinedImp()
+{
+}
+
+KJSO UndefinedImp::toPrimitive(Type) const
+{
+  return (Imp*)this;
+}
+
+Boolean UndefinedImp::toBoolean() const
+{
+  return Boolean(false);
+}
+
+Number UndefinedImp::toNumber() const
+{
+  return Number(NaN);
+}
+
+String UndefinedImp::toString() const
+{
+  return String("undefined");
+}
+
+Object UndefinedImp::toObject() const
+{
+  return Error::createObject(TypeError, I18N_NOOP("Undefined value"));
+}
+
+NullImp *NullImp::staticNull = 0;
+
+NullImp::NullImp()
+{
+}
+
+KJSO NullImp::toPrimitive(Type) const
+{
+  return (Imp*)this;
+}
+
+Boolean NullImp::toBoolean() const
+{
+  return Boolean(false);
+}
+
+Number NullImp::toNumber() const
+{
+  return Number(0);
+}
+
+String NullImp::toString() const
+{
+  return String("null");
+}
+
+Object NullImp::toObject() const
+{
+  return Error::createObject(TypeError, I18N_NOOP("Null value"));
+}
+
+BooleanImp* BooleanImp::staticTrue = 0;
+BooleanImp* BooleanImp::staticFalse = 0;
+
+KJSO BooleanImp::toPrimitive(Type) const
+{
+  return (Imp*)this;
+}
+
+Boolean BooleanImp::toBoolean() const
+{
+  return Boolean((BooleanImp*)this);
+}
+
+Number BooleanImp::toNumber() const
+{
+  return Number(val ? 1 : 0);
+}
+
+String BooleanImp::toString() const
+{
+  return String(val ? "true" : "false");
+}
+
+Object BooleanImp::toObject() const
+{
+  return Object::create(BooleanClass, Boolean((BooleanImp*)this));
+}
+
+NumberImp::NumberImp(double v)
+  : val(v)
+{
+}
+
+KJSO NumberImp::toPrimitive(Type) const
+{
+  return (Imp*)this;
+}
+
+Boolean NumberImp::toBoolean() const
+{
+  bool b = !((val == 0) /* || (iVal() == N0) */ || isNaN(val));
+
+  return Boolean(b);
+}
+
+Number NumberImp::toNumber() const
+{
+  return Number((NumberImp*)this);
+}
+
+String NumberImp::toString() const
+{
+  return String(UString::from(val));
+}
+
+Object NumberImp::toObject() const
+{
+  return Object::create(NumberClass, Number((NumberImp*)this));
+}
+
+StringImp::StringImp(const UString& v)
+  : val(v)
+{
+}
+
+KJSO StringImp::toPrimitive(Type) const
+{
+  return (Imp*)this;
+}
+
+Boolean StringImp::toBoolean() const
+{
+  return Boolean(val.size() > 0);
+}
+
+Number StringImp::toNumber() const
+{
+  return Number(val.toDouble());
+}
+
+String StringImp::toString() const
+{
+  return String((StringImp*)this);
+}
+
+Object StringImp::toObject() const
+{
+  return Object::create(StringClass, String((StringImp*)this));
+}
+
+ReferenceImp::ReferenceImp(const KJSO& b, const UString& p)
+  : base(b), prop(p)
+{
+}
+
+void ReferenceImp::mark(Imp*)
+{
+  Imp::mark();
+  Imp *im = base.imp();
+  if (im && !im->marked())
+    im->mark();
+}
+
+CompletionImp::CompletionImp(Compl c, const KJSO& v, const UString& t)
+  : comp(c), val(v), tar(t)
+{
+}
+
+void CompletionImp::mark(Imp*)
+{
+  Imp::mark();
+  Imp *im = val.imp();
+  if (im && !im->marked())
+    im->mark();
+}
+
+RegExpImp::RegExpImp()
+  : ObjectImp(RegExpClass), reg(0L)
+{
+}
+
+RegExpImp::~RegExpImp()
+{
+  delete reg;
+}
+
+// ECMA 10.2
+Context::Context(CodeType type, Context *callingContext,
+		 FunctionImp *func, const List *args, Imp *thisV)
+{
+  Global glob(Global::current());
+
+  // create and initialize activation object (ECMA 10.1.6)
+  if (type == FunctionCode || type == AnonymousCode || type == HostCode) {
+    activation = new ActivationImp(func, args);
+    variable = activation;
+  } else {
+    activation = KJSO();
+    variable = glob;
+  }
+
+  // ECMA 10.2
+  switch(type) {
+    case EvalCode:
+      if (callingContext) {
+	scopeChain = callingContext->copyOfChain();
+	variable = callingContext->variableObject();
+	thisVal = callingContext->thisValue();
+	break;
+      } // else same as GlobalCode
+    case GlobalCode:
+      scopeChain = new List();
+      scopeChain->append(glob);
+      thisVal = glob.imp();
+      break;
+    case FunctionCode:
+    case AnonymousCode:
+      if (type == FunctionCode) {
+	scopeChain = ((DeclaredFunctionImp*)func)->scopeChain()->copy();
+	scopeChain->prepend(activation);
+      } else {
+	scopeChain = new List();
+	scopeChain->append(activation);
+	scopeChain->append(glob);
+      }
+      variable = activation; /* TODO: DontDelete ? (ECMA 10.2.3) */
+      if (thisV->type() >= ObjectType) {
+	thisVal = thisV;
+      }
+      else
+	thisVal = glob.imp();
+      break;
+    case HostCode:
+      if (thisV->type() >= ObjectType)
+	thisVal = thisV;
+      else
+	thisVal = glob;
+      variable = activation; /* TODO: DontDelete (ECMA 10.2.4) */
+      scopeChain = new List();
+      scopeChain->append(activation);
+      if (func->hasAttribute(ImplicitThis))
+	scopeChain->append(KJSO(thisVal));
+      if (func->hasAttribute(ImplicitParents)) {
+	/* TODO ??? */
+      }
+      scopeChain->append(glob);
+      break;
+    }
+}
+
+Context::~Context()
+{
+  delete scopeChain;
+}
+
+Context *Context::current()
+{
+  return KJScriptImp::curr ? KJScriptImp::curr->con : 0L;
+}
+
+void Context::setCurrent(Context *c)
+{
+  KJScriptImp::current()->con = c;
+}
+
+void Context::pushScope(const KJSO &s)
+{
+  scopeChain->prepend(s);
+}
+
+void Context::popScope()
+{
+  scopeChain->removeFirst();
+}
+
+List* Context::copyOfChain()
+{
+  return scopeChain->copy();
+}
+
+
+AnonymousFunction::AnonymousFunction()
+  : Function(0L)
+{
+  /* TODO */
+}
+
+DeclaredFunctionImp::DeclaredFunctionImp(const UString &n,
+					 FunctionBodyNode *b, const List *sc)
+  : ConstructorImp(n), body(b), scopes(sc->copy())
+{
+}
+
+DeclaredFunctionImp::~DeclaredFunctionImp()
+{
+  delete scopes;
+}
+
+// step 2 of ECMA 13.2.1. rest in FunctionImp::executeCall()
+Completion DeclaredFunctionImp::execute(const List &)
+{
+ /* TODO */
+
+#ifdef KJS_DEBUGGER
+  Debugger *dbg = KJScriptImp::current()->debugger();
+  int oldSourceId = -1;
+  if (dbg) {
+    oldSourceId = dbg->sourceId();
+    dbg->setSourceId(body->sourceId());
+  }
+#endif
+
+  Completion result = body->execute();
+
+#ifdef KJS_DEBUGGER
+  if (dbg) {
+    dbg->setSourceId(oldSourceId);
+  }
+#endif
+
+  if (result.complType() == Throw || result.complType() == ReturnValue)
+      return result;
+  return Completion(Normal, Undefined()); /* TODO: or ReturnValue ? */
+}
+
+// ECMA 13.2.2 [[Construct]]
+Object DeclaredFunctionImp::construct(const List &args)
+{
+  Object obj(ObjectClass);
+  KJSO p = get("prototype");
+  if (p.isObject())
+    obj.setPrototype(p);
+  else
+    obj.setPrototype(Global::current().objectPrototype());
+
+  KJSO res = executeCall(obj.imp(), &args);
+
+  Object v = Object::dynamicCast(res);
+  if (v.isNull())
+    return obj;
+  else
+    return v;
+}
+
+Completion AnonymousFunction::execute(const List &)
+{
+ /* TODO */
+  return Completion(Normal, Null());
+}
+
+// ECMA 10.1.8
+class ArgumentsObject : public ObjectImp {
+public:
+  ArgumentsObject(FunctionImp *func, const List *args);
+};
+
+ArgumentsObject::ArgumentsObject(FunctionImp *func, const List *args)
+  : ObjectImp(UndefClass)
+{
+  put("callee", Function(func), DontEnum);
+  if (args) {
+    put("length", Number(args->size()), DontEnum);
+    ListIterator arg = args->begin();
+    for (int i = 0; arg != args->end(); arg++, i++) {
+      put(UString::from(i), *arg, DontEnum);
+    }
+  }
+}
+
+const TypeInfo ActivationImp::info = { "Activation", ActivationType, 0, 0, 0 };
+
+// ECMA 10.1.6
+ActivationImp::ActivationImp(FunctionImp *f, const List *args)
+{
+  KJSO aobj(new ArgumentsObject(f, args));
+  put("arguments", aobj, DontDelete);
+  /* TODO: this is here to get myFunc.arguments and myFunc.a1 going.
+     I can't see this described in the spec but it's possible in browsers. */
+  if (!f->name().isNull())
+    f->put("arguments", aobj);
+}
+
+ExecutionStack::ExecutionStack()
+  : progNode(0L), firstNode(0L), prev(0)
+{
+}
+
+ExecutionStack* ExecutionStack::push()
+{
+  ExecutionStack *s = new ExecutionStack();
+  s->prev = this;
+
+  return s;
+}
+
+ExecutionStack* ExecutionStack::pop()
+{
+  ExecutionStack *s = prev;
+  delete this;
+
+  return s;
+}
+
+KJScriptImp* KJScriptImp::curr = 0L;
+KJScriptImp* KJScriptImp::hook = 0L;
+int          KJScriptImp::instances = 0;
+int          KJScriptImp::running = 0;
+
+KJScriptImp::KJScriptImp(KJScript *s)
+  : scr(s),
+    initialized(false),
+    glob(0L),
+#ifdef KJS_DEBUGGER
+    dbg(0L),
+#endif
+    retVal(0L)
+{
+  instances++;
+  KJScriptImp::curr = this;
+  // are we the first interpreter instance ? Initialize some stuff
+  if (instances == 1)
+    globalInit();
+  stack = new ExecutionStack();
+  clearException();
+  lex = new Lexer();
+}
+
+KJScriptImp::~KJScriptImp()
+{
+  KJScriptImp::curr = this;
+
+#ifdef KJS_DEBUGGER
+  attachDebugger(0L);
+#endif
+
+  clear();
+
+  delete lex;
+  lex = 0L;
+
+  delete stack;
+  stack = 0L;
+
+  KJScriptImp::curr = 0L;
+  // are we the last of our kind ? Free global stuff.
+  if (instances == 1)
+    globalClear();
+  instances--;
+}
+
+void KJScriptImp::globalInit()
+{
+  UndefinedImp::staticUndefined = new UndefinedImp();
+  UndefinedImp::staticUndefined->ref();
+  NullImp::staticNull = new NullImp();
+  NullImp::staticNull->ref();
+  BooleanImp::staticTrue = new BooleanImp(true);
+  BooleanImp::staticTrue->ref();
+  BooleanImp::staticFalse = new BooleanImp(false);
+  BooleanImp::staticFalse->ref();
+}
+
+void KJScriptImp::globalClear()
+{
+  UndefinedImp::staticUndefined->deref();
+  UndefinedImp::staticUndefined = 0L;
+  NullImp::staticNull->deref();
+  NullImp::staticNull = 0L;
+  BooleanImp::staticTrue->deref();
+  BooleanImp::staticTrue = 0L;
+  BooleanImp::staticFalse->deref();
+  BooleanImp::staticFalse = 0L;
+}
+
+void KJScriptImp::mark()
+{
+  if (exVal && !exVal->marked())
+    exVal->mark();
+  if (retVal && !retVal->marked())
+    retVal->mark();
+  UndefinedImp::staticUndefined->mark();
+  NullImp::staticNull->mark();
+  BooleanImp::staticTrue->mark();
+  BooleanImp::staticFalse->mark();
+}
+
+void KJScriptImp::init()
+{
+  KJScriptImp::curr = this;
+
+  clearException();
+  retVal = 0L;
+
+  if (!initialized) {
+    // add this interpreter to the global chain
+    // as a root set for garbage collection
+    if (hook) {
+      prev = hook;
+      next = hook->next;
+      hook->next->prev = this;
+      hook->next = this;
+    } else {
+      hook = next = prev = this;
+    }
+
+    glob.init();
+    con = new Context();
+    firstN = 0L;
+    progN = 0L;
+    recursion = 0;
+    errMsg = "";
+    initialized = true;
+#ifdef KJS_DEBUGGER
+    sid = -1;
+#endif
+  }
+}
+
+void KJScriptImp::clear()
+{
+  if ( recursion ) {
+#ifndef NDEBUG
+      fprintf(stderr, "KJS: ignoring clear() while running\n");
+#endif
+      return;
+  }
+  KJScriptImp *old = curr;
+  if (initialized) {
+    KJScriptImp::curr = this;
+
+    Node::setFirstNode(firstNode());
+    Node::deleteAllNodes();
+    setFirstNode(0L);
+    setProgNode(0L);
+
+    clearException();
+    retVal = 0L;
+
+    delete con; con = 0L;
+    glob.clear();
+
+    Collector::collect();
+
+    // remove from global chain (see init())
+    next->prev = prev;
+    prev->next = next;
+    hook = next;
+    if (hook == this)
+      hook = 0L;
+
+#ifdef KJS_DEBUGGER
+    sid = -1;
+#endif
+
+    initialized = false;
+  }
+  if (old != this)
+      KJScriptImp::curr = old;
+}
+
+bool KJScriptImp::evaluate(const UChar *code, unsigned int length, const KJSO &thisV,
+			   bool onlyCheckSyntax)
+{
+  init();
+
+#ifdef KJS_DEBUGGER
+  sid++;
+  if (debugger())
+    debugger()->setSourceId(sid);
+#endif
+  if (recursion > 7) {
+    fprintf(stderr, "KJS: breaking out of recursion\n");
+    return true;
+  } else if (recursion > 0) {
+#ifndef NDEBUG
+    fprintf(stderr, "KJS: entering recursion level %d\n", recursion);
+#endif
+    pushStack();
+  }
+
+  assert(Lexer::curr());
+  Lexer::curr()->setCode(code, length);
+  Node::setFirstNode(firstNode());
+  int parseError = kjsyyparse();
+  setFirstNode(Node::firstNode());
+
+  if (parseError) {
+    errType = 99; /* TODO */
+    errLine = Lexer::curr()->lineNo();
+    errMsg = "Parse error at line " + UString::from(errLine);
+#ifndef NDEBUG
+    fprintf(stderr, "JavaScript parse error at line %d.\n", errLine);
+#endif
+    /* TODO: either clear everything or keep previously
+       parsed function definitions */
+    //    Node::deleteAllNodes();
+    return false;
+  }
+
+  if (onlyCheckSyntax)
+      return true;
+
+  clearException();
+
+  KJSO oldVar;
+  if (!thisV.isNull()) {
+    context()->setThisValue(thisV);
+    context()->pushScope(thisV);
+    oldVar = context()->variableObject();
+    context()->setVariableObject(thisV);
+  }
+
+  running++;
+  recursion++;
+  assert(progNode());
+  Completion res = progNode()->execute();
+  recursion--;
+  running--;
+
+  if (hadException()) {
+    KJSO err = exception();
+    errType = 99; /* TODO */
+    errLine = err.get("line").toInt32();
+    errMsg = err.get("name").toString().value() + ". ";
+    errMsg += err.get("message").toString().value();
+#ifdef KJS_DEBUGGER
+    if (dbg)
+      dbg->setSourceId(err.get("sid").toInt32());
+#endif
+    clearException();
+  } else {
+    errType = 0;
+    errLine = -1;
+    errMsg = "";
+
+    // catch return value
+    retVal = 0L;
+    if (res.complType() == ReturnValue || !thisV.isNull())
+	retVal = res.value().imp();
+  }
+
+  if (!thisV.isNull()) {
+    context()->popScope();
+    context()->setVariableObject(oldVar);
+  }
+
+  if (progNode())
+    progNode()->deleteGlobalStatements();
+
+  if (recursion > 0) {
+    popStack();
+  }
+
+  return !errType;
+}
+
+void KJScriptImp::pushStack()
+{
+    stack = stack->push();
+}
+
+void KJScriptImp::popStack()
+{
+    stack = stack->pop();
+    assert(stack);
+}
+
+bool KJScriptImp::call(const KJSO &scope, const UString &func, const List &args)
+{
+  init();
+  KJSO callScope(scope);
+  if (callScope.isNull())
+    callScope = Global::current().imp();
+  if (!callScope.hasProperty(func)) {
+#ifndef NDEBUG
+      fprintf(stderr, "couldn't resolve function name %s. call() failed\n",
+	      func.ascii());
+#endif
+      return false;
+  }
+  KJSO v = callScope.get(func);
+  if (!v.isA(ConstructorType)) {
+#ifndef NDEBUG
+      fprintf(stderr, "%s is not a function. call() failed.\n", func.ascii());
+#endif
+      return false;
+  }
+  running++;
+  recursion++;
+  static_cast<ConstructorImp*>(v.imp())->executeCall(scope.imp(), &args);
+  recursion--;
+  running--;
+  return !hadException();
+}
+
+bool KJScriptImp::call(const KJSO &func, const KJSO &thisV,
+		       const List &args, const List &extraScope)
+{
+  init();
+  if(!func.implementsCall())
+    return false;
+
+  running++;
+  recursion++;
+  retVal = func.executeCall(thisV, &args, &extraScope).imp();
+  recursion--;
+  running--;
+
+  return !hadException();
+}
+
+void KJScriptImp::setException(Imp *e)
+{
+  assert(curr);
+  curr->exVal = e;
+  curr->exMsg = "Exception"; // not very meaningful but we use !0L to test
+}
+
+void KJScriptImp::setException(const char *msg)
+{
+  assert(curr);
+  curr->exVal = 0L;		// will be created later on exception()
+  curr->exMsg = msg;
+}
+
+KJSO KJScriptImp::exception()
+{
+  assert(curr);
+  if (!curr->exMsg)
+    return Undefined();
+  if (curr->exVal)
+    return curr->exVal;
+  return Error::create(GeneralError, curr->exMsg);
+}
+
+void KJScriptImp::clearException()
+{
+  assert(curr);
+  curr->exMsg = 0L;
+  curr->exVal = 0L;
+}
+
+#ifdef KJS_DEBUGGER
+void KJScriptImp::attachDebugger(Debugger *d)
+{
+  static bool detaching = false;
+  if (detaching) // break circular detaching
+    return;
+
+  if (dbg) {
+    detaching = true;
+    dbg->detach();
+    detaching = false;
+  }
+
+  dbg = d;
+}
+
+bool KJScriptImp::setBreakpoint(int id, int line, bool set)
+{
+  init();
+  return Node::setBreakpoint(firstNode(), id, line, set);
+}
+
+#endif
+
+bool PropList::contains(const UString &name)
+{
+  PropList *p = this;
+  while (p) {
+    if (name == p->name)
+      return true;
+    p = p->next;
+  }
+  return false;
+}
+
+bool LabelStack::push(const UString &id)
+{
+  if (id.isEmpty() || contains(id))
+    return false;
+
+  StackElm *newtos = new StackElm;
+  newtos->id = id;
+  newtos->prev = tos;
+  tos = newtos;
+  return true;
+}
+
+bool LabelStack::contains(const UString &id) const
+{
+  if (id.isEmpty())
+    return true;
+
+  for (StackElm *curr = tos; curr; curr = curr->prev)
+    if (curr->id == id)
+      return true;
+
+  return false;
+}
+
+void LabelStack::pop()
+{
+  if (tos) {
+    StackElm *prev = tos->prev;
+    delete tos;
+    tos = prev;
+  }
+}
+
+LabelStack::~LabelStack()
+{
+  StackElm *prev;
+
+  while (tos) {
+    prev = tos->prev;
+    delete tos;
+    tos = prev;
+  }
+}
+
+// ECMA 15.3.5.3 [[HasInstance]]
+// see comment in header file
+KJSO KJS::hasInstance(const KJSO &F, const KJSO &V)
+{
+  if (V.isObject()) {
+    KJSO prot = F.get("prototype");
+    if (!prot.isObject())
+      return Error::create(TypeError, "Invalid prototype encountered "
+			   "in instanceof operation.");
+    Imp *v = V.imp();
+    while ((v = v->prototype())) {
+      if (v == prot.imp())
+	return Boolean(true);
+    }
+  }
+  return Boolean(false);
+}
+
+#ifndef NDEBUG
+#include <stdio.h>
+void KJS::printInfo( const char *s, const KJSO &o )
+{
+    if (o.isNull())
+      fprintf(stderr, "%s: (null)\n", s);
+    else {
+      KJSO v = o;
+      if (o.isA(ReferenceType))
+	  v = o.getValue();
+      fprintf(stderr, "JS: %s: %s : %s (%p)\n",
+	      s,
+	      v.toString().value().ascii(),
+	      v.imp()->typeInfo()->name,
+	      (void*)v.imp());
+      if (o.isA(ReferenceType)) {
+	  fprintf(stderr, "JS: Was property '%s'\n", o.getPropertyName().ascii());
+	  printInfo("of", o.getBase());
+      }
+    }
+}
+#endif
diff --git a/JavaScriptCore/kjs/internal.h b/JavaScriptCore/kjs/internal.h
new file mode 100644
index 0000000..51a8ece
--- /dev/null
+++ b/JavaScriptCore/kjs/internal.h
@@ -0,0 +1,406 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _INTERNAL_H_
+#define _INTERNAL_H_
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "kjs.h"
+#include "object.h"
+#include "function.h"
+
+#define I18N_NOOP(s) s
+
+namespace KJS {
+
+  class Boolean;
+  class Number;
+  class String;
+  class Object;
+  class RegExp;
+  class Node;
+  class FunctionBodyNode;
+  class ProgramNode;
+#ifdef KJS_DEBUGGER
+  class Debugger;
+#endif
+
+  class UndefinedImp : public Imp {
+  public:
+    UndefinedImp();
+    virtual ~UndefinedImp() { }
+    virtual KJSO toPrimitive(Type preferred = UndefinedType) const;
+    virtual Boolean toBoolean() const;
+    virtual Number toNumber() const;
+    virtual String toString() const;
+    virtual Object toObject() const;
+
+    virtual const TypeInfo* typeInfo() const { return &info; }
+    static const TypeInfo info;
+      
+    static UndefinedImp *staticUndefined;
+  };
+
+  class NullImp : public Imp {
+  public:
+    NullImp();
+    virtual ~NullImp() { }
+    virtual KJSO toPrimitive(Type preferred = UndefinedType) const;
+    virtual Boolean toBoolean() const;
+    virtual Number toNumber() const;
+    virtual String toString() const;
+    virtual Object toObject() const;
+
+    virtual const TypeInfo* typeInfo() const { return &info; }
+    static const TypeInfo info;
+
+    static NullImp *staticNull;
+  };
+
+  class BooleanImp : public Imp {
+  public:
+    virtual ~BooleanImp() { }
+    BooleanImp(bool v = false) : val(v) { }
+    bool value() const { return val; }
+    virtual KJSO toPrimitive(Type preferred = UndefinedType) const;
+    virtual Boolean toBoolean() const;
+    virtual Number toNumber() const;
+    virtual String toString() const;
+    virtual Object toObject() const;
+
+    virtual const TypeInfo* typeInfo() const { return &info; }
+    static const TypeInfo info;
+
+    static BooleanImp *staticTrue, *staticFalse;
+  private:
+    bool val;
+  };
+
+  class NumberImp : public Imp {
+  public:
+    NumberImp(double v);
+    virtual ~NumberImp() { }
+    double value() const { return val; }
+    virtual KJSO toPrimitive(Type preferred = UndefinedType) const;
+    virtual Boolean toBoolean() const;
+    virtual Number toNumber() const;
+    virtual String toString() const;
+    virtual Object toObject() const;
+
+    virtual const TypeInfo* typeInfo() const { return &info; }
+    static const TypeInfo info;
+  private:
+    double val;
+  };
+
+  class StringImp : public Imp {
+  public:
+    StringImp(const UString& v);
+    virtual ~StringImp() { }
+    UString value() const { return val; }
+    virtual KJSO toPrimitive(Type preferred = UndefinedType) const;
+    virtual Boolean toBoolean() const;
+    virtual Number toNumber() const;
+    virtual String toString() const;
+    virtual Object toObject() const;
+
+    virtual const TypeInfo* typeInfo() const { return &info; }
+    static const TypeInfo info;
+  private:
+    UString val;
+  };
+
+  class ReferenceImp : public Imp {
+  public:
+    ReferenceImp(const KJSO& b, const UString& p);
+    virtual ~ReferenceImp() { }
+    virtual void mark(Imp*);
+    KJSO getBase() const { return base; }
+    UString getPropertyName() const { return prop; }
+
+    virtual const TypeInfo* typeInfo() const { return &info; }
+    static const TypeInfo info;
+  private:
+    KJSO base;
+    UString prop;
+  };
+
+  class CompletionImp : public Imp {
+  public:
+    CompletionImp(Compl c, const KJSO& v, const UString& t);
+    virtual ~CompletionImp() { }
+    virtual void mark(Imp*);
+    Compl completion() const { return comp; }
+    KJSO value() const { return val; }
+    UString target() const { return tar; }
+
+    virtual const TypeInfo* typeInfo() const { return &info; }
+    static const TypeInfo info;
+  private:
+    Compl comp;
+    KJSO val;
+    UString tar;
+  };
+
+  class RegExpImp : public ObjectImp {
+  public:
+    RegExpImp();
+    ~RegExpImp();
+    void setRegExp(RegExp *r) { reg = r; }
+    RegExp* regExp() const { return reg; }
+  private:
+    RegExp *reg;
+  };
+
+  class StatementNode;
+  class UString;
+
+  class Reference : public KJSO {
+  public:
+    Reference(const KJSO& b, const UString &p);
+    virtual ~Reference();
+  };
+
+  /**
+   * @short The "label set" in Ecma-262 spec
+   */
+  class LabelStack {
+  public:
+    LabelStack(): tos(0L) {}
+    ~LabelStack();
+
+    /**
+     * If id is not empty and is not in the stack already, puts it on top of
+     * the stack and returns true, otherwise returns false
+     */
+    bool push(const UString &id);
+    /**
+     * Is the id in the stack?
+     */
+    bool contains(const UString &id) const;
+    /**
+     * Removes from the stack the last pushed id (what else?)
+     */
+    void pop();
+  private:
+    struct StackElm {
+      UString id;
+      StackElm *prev;
+    };
+
+    StackElm *tos;
+  };
+
+  /**
+   * @short Execution context.
+   */
+  class Context {
+  public:
+    Context(CodeType type = GlobalCode, Context *callingContext = 0L,
+	       FunctionImp *func = 0L, const List *args = 0L, Imp *thisV = 0L);
+    virtual ~Context();
+    static Context *current();
+    static void setCurrent(Context *c);
+    const List *pScopeChain() const { return scopeChain; }
+    void pushScope(const KJSO &s);
+    void popScope();
+    List *copyOfChain();
+    KJSO variableObject() const { return variable; }
+    void setVariableObject( const KJSO &obj ) { variable = obj; }
+    KJSO thisValue() const { return thisVal; }
+    void setThisValue(const KJSO &t) { thisVal = t; }
+    LabelStack *seenLabels() { return &ls; }
+  private:
+    LabelStack ls;
+    KJSO thisVal;
+    KJSO activation;
+    KJSO variable;
+    List *scopeChain;
+  };
+
+  class DeclaredFunctionImp : public ConstructorImp {
+  public:
+    DeclaredFunctionImp(const UString &n, FunctionBodyNode *b,
+			const List *sc);
+    ~DeclaredFunctionImp();
+    Completion execute(const List &);
+    Object construct(const List &);
+    CodeType codeType() const { return FunctionCode; }
+    List *scopeChain() const { return scopes; }
+  private:
+    FunctionBodyNode *body;
+    List *scopes;
+  };
+
+  class AnonymousFunction : public Function {
+  public:
+    AnonymousFunction();
+    Completion execute(const List &);
+    CodeType codeType() const { return AnonymousCode; }
+  };
+
+  class ActivationImp : public Imp {
+  public:
+    ActivationImp(FunctionImp *f, const List *args);
+    virtual const TypeInfo* typeInfo() const { return &info; }
+    static const TypeInfo info;
+  };
+
+  class ExecutionStack {
+  public:
+    ExecutionStack();
+    ExecutionStack *push();
+    ExecutionStack *pop();
+    
+    ProgramNode *progNode;
+    Node *firstNode;
+  private:
+    ExecutionStack *prev;
+  };
+
+  class KJScriptImp {
+    friend class ::KJScript;
+    friend class Lexer;
+    friend class Context;
+    friend class Global;
+    friend class Collector;
+  public:
+    KJScriptImp(KJScript *s);
+    ~KJScriptImp();
+    void mark();
+    static KJScriptImp *current() { return curr; }
+    static void setException(Imp *e);
+    static void setException(const char *msg);
+    static bool hadException();
+    static KJSO exception();
+    static void clearException();
+
+    Context *context() const { return con; }
+    void setContext(Context *c) { con = c; }
+
+#ifdef KJS_DEBUGGER
+    /**
+     * Attach debugger d to this engine. If there already was another instance
+     * attached it will be detached.
+     */
+    void attachDebugger(Debugger *d);
+    Debugger *debugger() const { return dbg; }
+    int sourceId() const { return sid; }
+    bool setBreakpoint(int id, int line, bool set);
+#endif
+  private:
+    /**
+     * Initialize global object and context. For internal use only.
+     */
+    void init();
+    void clear();
+    /**
+     * Called when the first interpreter is instanciated. Initializes
+     * global pointers.
+     */
+    void globalInit();
+    /**
+     * Called when the last interpreter instance is destroyed. Frees
+     * globally allocated memory.
+     */
+    void globalClear();
+    bool evaluate(const UChar *code, unsigned int length, const KJSO &thisV = KJSO(),
+		  bool onlyCheckSyntax = false);
+    bool call(const KJSO &scope, const UString &func, const List &args);
+    bool call(const KJSO &func, const KJSO &thisV,
+	      const List &args, const List &extraScope);
+
+  public:
+    ProgramNode *progNode() const { return stack->progNode; }
+    void setProgNode(ProgramNode *p) { stack->progNode = p; }
+    Node *firstNode() const { return stack->firstNode; }
+    void setFirstNode(Node *n) { stack->firstNode = n; }
+    void pushStack();
+    void popStack();
+    KJScriptImp *next, *prev;
+    KJScript *scr;
+    ExecutionStack *stack;
+
+  private:
+    ProgramNode *progN;
+    Node *firstN;
+
+    static KJScriptImp *curr, *hook;
+    static int instances; // total number of instances
+    static int running;	// total number running
+    bool initialized;
+    Lexer *lex;
+    Context *con;
+    Global glob;
+    int errType, errLine;
+    UString errMsg;
+#ifdef KJS_DEBUGGER
+    Debugger *dbg;
+    int sid;
+#endif
+    const char *exMsg;
+    Imp *exVal;
+    Imp *retVal;
+    int recursion;
+  };
+
+  inline bool KJScriptImp::hadException()
+  {
+    assert(curr);
+    return curr->exMsg;
+  }
+
+  /**
+   * @short Struct used to return the property names of an object
+   */
+  class PropList {
+  public:
+    PropList(UString nm = UString::null, PropList *nx = 0) :
+			  name(nm), next(nx) {};
+    ~PropList() {
+      if(next) delete next;
+    }
+    /**
+     * The property name
+     */
+    UString name;
+    /**
+     * The next property
+     */
+    PropList *next;
+    bool contains(const UString &name);
+  };
+
+  /* TODO just temporary until functions are objects and this becomes
+     a member function. Called by RelationNode for 'instanceof' operator. */
+  KJSO hasInstance(const KJSO &F, const KJSO &V);
+
+// #define KJS_VERBOSE
+#ifndef NDEBUG
+  void printInfo( const char *s, const KJSO &o );
+#endif
+
+}; // namespace
+
+
+#endif
diff --git a/JavaScriptCore/kjs/keywords.table b/JavaScriptCore/kjs/keywords.table
new file mode 100644
index 0000000..391aa34
--- /dev/null
+++ b/JavaScriptCore/kjs/keywords.table
@@ -0,0 +1,66 @@
+# main keywords
+ at begin mainTable 41
+# types
+null		NULLTOKEN
+true		TRUETOKEN
+false		FALSETOKEN
+# keywords
+break		BREAK
+case		CASE
+catch		CATCH
+default		DEFAULT
+finally		FINALLY
+for		FOR
+instanceof	INSTANCEOF
+new		NEW
+var		VAR
+continue	CONTINUE
+function	FUNCTION
+return		RETURN
+void		VOID
+delete		DELETE
+if		IF
+this		THIS
+do		DO
+while		WHILE
+else		ELSE
+in		IN
+switch		SWITCH
+throw		THROW
+try		TRY
+typeof		TYPEOF
+with		WITH
+# reserved for future use
+abstract	RESERVED
+boolean		RESERVED
+byte		RESERVED
+char		RESERVED
+class		RESERVED
+const		RESERVED
+debugger	RESERVED
+double		RESERVED
+enum		RESERVED
+export		RESERVED
+extends		RESERVED
+final		RESERVED
+float		RESERVED
+goto		RESERVED
+implements	RESERVED
+import		RESERVED
+int		RESERVED
+interface	RESERVED
+long		RESERVED
+native		RESERVED
+package		RESERVED
+private		RESERVED
+protected	RESERVED
+public		RESERVED
+short		RESERVED
+static		RESERVED
+super		RESERVED
+synchronized	RESERVED
+throws		RESERVED
+transient	RESERVED
+volatile	RESERVED
+ at end
+
diff --git a/JavaScriptCore/kjs/kjs.cpp b/JavaScriptCore/kjs/kjs.cpp
new file mode 100644
index 0000000..d6c0260
--- /dev/null
+++ b/JavaScriptCore/kjs/kjs.cpp
@@ -0,0 +1,156 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "kjs.h"
+#include "types.h"
+#include "internal.h"
+#include "collector.h"
+
+using namespace KJS;
+
+KJScript::KJScript()
+{
+  rep = new KJScriptImp(this);
+  rep->init();
+}
+
+KJScript::~KJScript()
+{
+  delete rep;
+
+#ifdef KJS_DEBUG_MEM
+  //printf("Imp::count: %d\n", Imp::count);
+  //  assert(Imp::count == 0);
+#endif
+}
+
+void KJScript::init()
+{
+  rep->init();
+}
+
+Imp *KJScript::globalObject() const
+{
+  return rep->glob.imp();
+}
+
+void KJScript::setCurrent( KJScript *newCurr )
+{
+  KJScriptImp::curr = newCurr ? newCurr->rep : 0L;
+}
+
+KJScript *KJScript::current()
+{
+  return KJScriptImp::current() ? KJScriptImp::current()->scr : 0L;
+}
+
+int KJScript::recursion() const
+{
+  return rep->recursion;
+}
+
+bool KJScript::evaluate(const char *code)
+{
+  return rep->evaluate(UString(code).data(), strlen(code));
+}
+
+bool KJScript::evaluate(const UString &code)
+{
+  return rep->evaluate(code.data(), code.size());
+}
+
+bool KJScript::evaluate(const KJSO &thisV,
+			const QChar *code, unsigned int length)
+{
+  return rep->evaluate((UChar*)code, length, thisV);
+}
+
+bool KJScript::call(const KJS::UString &func, const List &args)
+{
+  return rep->call(0, func, args);
+}
+
+bool KJScript::call(const KJSO &scope, const KJS::UString &func,
+		    const KJS::List &args)
+{
+  return rep->call(scope.imp(), func, args);
+}
+
+bool KJScript::call(const KJS::KJSO &func, const KJSO &thisV,
+		    const KJS::List &args, const KJS::List &extraScope)
+{
+  return rep->call(func, thisV, args, extraScope);
+}
+
+void KJScript::clear()
+{
+  rep->clear();
+}
+
+Imp *KJScript::returnValue() const
+{
+  return rep->retVal;
+}
+
+int KJScript::errorType() const
+{
+  return rep->errType;
+}
+
+int KJScript::errorLine() const
+{
+  return rep->errLine;
+}
+
+const char* KJScript::errorMsg() const
+{
+  return rep->errMsg.ascii();
+}
+
+bool KJScript::checkSyntax(const KJS::UString &code )
+{
+  return rep->evaluate(code.data(), code.size(), 0, true);
+}
+
+/**
+ * @short Print to stderr for debugging purposes.
+ */
+namespace KJS {
+  class DebugPrint : public InternalFunctionImp {
+  public:
+    Completion execute(const List &args)
+      {
+	KJSO v = args[0];
+	String s = v.toString();
+	fprintf(stderr, "---> %s\n", s.value().cstring().c_str());
+
+	return Completion(Normal);
+      }
+  };
+};
+
+void KJScript::enableDebug()
+{
+  rep->init();
+  Global::current().put("debug", Function(new DebugPrint()));
+}
diff --git a/JavaScriptCore/kjs/kjs.h b/JavaScriptCore/kjs/kjs.h
new file mode 100644
index 0000000..42a866d
--- /dev/null
+++ b/JavaScriptCore/kjs/kjs.h
@@ -0,0 +1,170 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _KJS_H_
+#define _KJS_H_
+
+class QChar;
+
+namespace KJS {
+  class UString;
+  class Lexer;
+  class Context;
+  class Global;
+  class KJSO;
+  class Object;
+  class Imp;
+  class List;
+  class KJScriptImp;
+#ifdef KJS_DEBUGGER
+  class Debugger;
+#endif
+};
+
+/**
+ * @libdoc ECMAScript interpreter
+ *
+ * This library provides an interpreter for ECMAScript aka JavaScript.
+ * It currently aims at compliance with Edition 3 of the standard.
+ */
+
+/**
+ * @short ECMAScript interpreter
+ */
+class KJScript {
+  friend class KJS::KJScriptImp;
+  friend class KJS::KJSO;
+  friend class KJS::Context;
+  friend class KJS::Lexer;
+  friend class KJS::Global;
+public:
+  /**
+   * Create a new ECMAScript interpreter. You can later ask it to interprete
+   * code by passing it via @ref #evaluate.
+   */
+  KJScript();
+  /**
+   *  Destructor
+   */
+  ~KJScript();
+  /**
+   * Force a "context switch". You usually do not need to do that,
+   * evaluate() does it too.
+   */
+  void init();
+  /**
+   * Returns a pointer to the Global object.
+   */
+  KJS::Imp *globalObject() const;
+  /**
+   * Don't use. May disappear.
+   */
+  static KJScript *current();
+  /**
+   * Don't use. May disappear.
+   */
+  static void setCurrent( KJScript *newCurr );
+
+  /**
+   * Current level of recursive calls to this interpreter. 0 initially.
+   */
+  int recursion() const;
+  /**
+   * Asks the interpreter to evaluate a piece of code. If called more than
+   * once the state (global variables, functions etc.) will be preserved
+   * between each call.
+   * @param code is a string containing the code to be executed.
+   * @return True if the code was evaluated successfully, false if an error
+   * occured.
+   */
+  bool evaluate(const char *code);
+  /**
+   * Same as above. Only differing in the arguments accepted.
+   * @param code is a pointer to an Unicode string containing the code to
+   * be executed.
+   * @param length number of characters.
+   */
+  bool evaluate(const KJS::KJSO &thisV,
+		const QChar *code, unsigned int length);
+  /**
+   * Added for convenience in case you have the code in available in
+   * internal representation already.
+   * @param code is an Unicode string containing the code to be executed.
+   */
+  bool evaluate(const KJS::UString &code);
+  /**
+   * Call the specified function directly, optionally passing args as a
+   * list of arguments. Return value and treatment of errors is analog
+   * to the evaluate() calls.
+   */
+  bool call(const KJS::UString &func, const KJS::List &args);
+  bool call(const KJS::KJSO &scope, const KJS::UString &func,
+	    const KJS::List &args);
+  bool call(const KJS::KJSO &func, const KJS::KJSO &thisV,
+	    const KJS::List &args, const KJS::List &extraScope );
+  /**
+   * Clear the interpreter's memory. Otherwise, function declarations
+   * and global variables will be remembered after each invokation of
+   * @ref KJScript::evaluate.
+   */
+  void clear();
+  /**
+   * @return Return value from the last call to @ref evaluate(). Null if there
+   * hasn't been any.
+   */
+  KJS::Imp *returnValue() const;
+  /**
+   * @return Return code from last call to @ref evaluate(). 0 on success.
+   */
+  int errorType() const;
+  /**
+   * @return Return line of last error. -1 if last call didn't have an error.
+   */
+  int errorLine() const;
+  /**
+   * @return Error message from last call to @ref evaluate(). Empty string
+   * if no error occured.
+   */
+  const char *errorMsg() const;
+  /**
+   * Check the syntax of a piece of code. Return true if the code could be
+   * parsed without errors, false otherwise. @ref errorLine() will tell you
+   * approximately where the syntax error happened.
+   */
+  bool checkSyntax(const KJS::UString &code);
+  /**
+   * Adds a debug() function to the set of pre-defined properties.
+   * debug(arg) tries to convert 'arg' to a string and prints the result
+   * to stderr. If you want to debug self defined Host Objects this way
+   * you should provide them with a toString() method that returns a string.
+   */
+  void enableDebug();
+private:
+  KJS::KJScriptImp *rep;
+  // not implemented
+  KJScript(const KJScript&);
+  KJScript operator=(const KJScript&);
+
+#ifdef KJS_DEBUGGER
+  friend class KJS::Debugger;
+#endif
+};
+
+#endif
diff --git a/JavaScriptCore/kjs/lexer.cpp b/JavaScriptCore/kjs/lexer.cpp
new file mode 100644
index 0000000..7ce1a3d
--- /dev/null
+++ b/JavaScriptCore/kjs/lexer.cpp
@@ -0,0 +1,744 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include "kjs.h"
+#include "nodes.h"
+#include "lexer.h"
+#include "ustring.h"
+#include "lookup.h"
+#include "internal.h"
+
+// we can't specify the namespace in yacc's C output, so do it here
+using namespace KJS;
+
+#ifndef KDE_USE_FINAL
+#include "grammar.h"
+#endif
+
+#include "lexer.lut.h"
+
+#ifdef KJS_DEBUGGER
+extern YYLTYPE yylloc;	// global bison variable holding token info
+#endif
+
+// a bridge for yacc from the C world to C++
+int kjsyylex()
+{
+  return Lexer::curr()->lex();
+}
+
+Lexer::Lexer()
+  : yylineno(0),
+    size8(128), size16(128), restrKeyword(false),
+    stackToken(-1), pos(0),
+    code(0), length(0),
+#ifndef KJS_PURE_ECMA
+    bol(true),
+#endif
+    current(0), next1(0), next2(0), next3(0)
+{
+  // allocate space for read buffers
+  buffer8 = new char[size8];
+  buffer16 = new UChar[size16];
+
+}
+
+Lexer::~Lexer()
+{
+  delete [] buffer8;
+  delete [] buffer16;
+}
+
+Lexer *Lexer::curr()
+{
+  assert(KJScriptImp::current());
+  return KJScriptImp::current()->lex;
+}
+
+void Lexer::setCode(const UChar *c, unsigned int len)
+{
+  yylineno = 0;
+  restrKeyword = false;
+  delimited = false;
+  stackToken = -1;
+  pos = 0;
+  code = c;
+  length = len;
+#ifndef KJS_PURE_ECMA
+  bol = true;
+#endif
+
+  // read first characters
+  current = (length > 0) ? code[0].unicode() : 0;
+  next1 = (length > 1) ? code[1].unicode() : 0;
+  next2 = (length > 2) ? code[2].unicode() : 0;
+  next3 = (length > 3) ? code[3].unicode() : 0;
+}
+
+void Lexer::shift(unsigned int p)
+{
+  while (p--) {
+    pos++;
+    current = next1;
+    next1 = next2;
+    next2 = next3;
+    next3 = (pos + 3 < length) ? code[pos+3].unicode() : 0;
+  }
+}
+
+void Lexer::setDone(State s)
+{
+  state = s;
+  done = true;
+}
+
+int Lexer::lex()
+{
+  int token = 0;
+  state = Start;
+  unsigned short stringType = 0; // either single or double quotes
+  pos8 = pos16 = 0;
+  done = false;
+  terminator = false;
+
+  // did we push a token on the stack previously ?
+  // (after an automatic semicolon insertion)
+  if (stackToken >= 0) {
+    setDone(Other);
+    token = stackToken;
+    stackToken = 0;
+  }
+
+  while (!done) {
+    switch (state) {
+    case Start:
+      if (isWhiteSpace()) {
+	// do nothing
+      } else if (current == '/' && next1 == '/') {
+	shift(1);
+	state = InSingleLineComment;
+      } else if (current == '/' && next1 == '*') {
+	shift(1);
+	state = InMultiLineComment;
+      } else if (current == 0) {
+	if (!terminator && !delimited) {
+	  // automatic semicolon insertion if program incomplete
+	  token = ';';
+	  stackToken = 0;
+	  setDone(Other);
+	} else
+	  setDone(Eof);
+      } else if (isLineTerminator()) {
+	yylineno++;
+#ifndef KJS_PURE_ECMA
+	bol = true;
+#endif
+	terminator = true;
+	if (restrKeyword) {
+	  token = ';';
+	  setDone(Other);
+	}
+      } else if (current == '"' || current == '\'') {
+	state = InString;
+	stringType = current;
+      } else if (isIdentLetter(current)) {
+	record16(current);
+	state = InIdentifier;
+      } else if (current == '0') {
+	record8(current);
+	state = InNum0;
+      } else if (isDecimalDigit(current)) {
+	record8(current);
+	state = InNum;
+      } else if (current == '.' && isDecimalDigit(next1)) {
+	record8(current);
+	state = InDecimal;
+#ifndef KJS_PURE_ECMA
+	// <!-- marks the beginning of a line comment (for www usage)
+      } else if (bol && current == '<' && next1 == '!' &&
+		 next2 == '-' && next3 == '-') {
+	shift(3);
+	state = InSingleLineComment;
+	// same of -->
+      } else if (bol && current == '-' && next1 == '-' &&  next2 == '>') {
+	shift(2);
+	state = InSingleLineComment;
+#endif
+      } else {
+	token = matchPunctuator(current, next1, next2, next3);
+	if (token != -1) {
+	  setDone(Other);
+	} else {
+	  //	  cerr << "encountered unknown character" << endl;
+	  setDone(Bad);
+	}
+      }
+      break;
+    case InString:
+      if (current == stringType) {
+	shift(1);
+	setDone(String);
+      } else if (current == 0 || isLineTerminator()) {
+	setDone(Bad);
+      } else if (current == '\\') {
+	state = InEscapeSequence;
+      } else {
+	record16(current);
+      }
+      break;
+    // Escape Sequences inside of strings
+    case InEscapeSequence:
+      if (isOctalDigit(current)) {
+	if (current >= '0' && current <= '3' &&
+	    isOctalDigit(next1) && isOctalDigit(next2)) {
+	  record16(convertOctal(current, next1, next2));
+	  shift(2);
+	  state = InString;
+	} else if (isOctalDigit(current) && isOctalDigit(next1)) {
+	  record16(convertOctal('0', current, next1));
+	  shift(1);
+	  state = InString;
+	} else if (isOctalDigit(current)) {
+	  record16(convertOctal('0', '0', current));
+	  state = InString;
+	} else {
+	  setDone(Bad);
+	}
+      } else if (current == 'x')
+	state = InHexEscape;
+      else if (current == 'u')
+	state = InUnicodeEscape;
+      else {
+	record16(singleEscape(current));
+	state = InString;
+      }
+      break;
+    case InHexEscape:
+      if (isHexDigit(current) && isHexDigit(next1)) {
+	state = InString;
+	record16(convertHex(current, next1));
+	shift(1);
+      } else if (current == stringType) {
+	record16('x');
+	shift(1);
+	setDone(String);
+      } else {
+	record16('x');
+	record16(current);
+	state = InString;
+      }
+      break;
+    case InUnicodeEscape:
+      if (isHexDigit(current) && isHexDigit(next1) &&
+	  isHexDigit(next2) && isHexDigit(next3)) {
+	record16(convertUnicode(current, next1, next2, next3));
+	shift(3);
+	state = InString;
+      } else if (current == stringType) {
+	record16('u');
+	shift(1);
+	setDone(String);
+      } else {
+	setDone(Bad);
+      }
+      break;
+    case InSingleLineComment:
+      if (isLineTerminator()) {
+	yylineno++;
+	terminator = true;
+#ifndef KJS_PURE_ECMA
+	bol = true;
+#endif
+	if (restrKeyword) {
+	  token = ';';
+	  setDone(Other);
+	} else
+	  state = Start;
+      } else if (current == 0) {
+	setDone(Eof);
+      }
+      break;
+    case InMultiLineComment:
+      if (current == 0) {
+	setDone(Bad);
+      } else if (isLineTerminator()) {
+	yylineno++;
+      } else if (current == '*' && next1 == '/') {
+	state = Start;
+	shift(1);
+      }
+      break;
+    case InIdentifier:
+      if (isIdentLetter(current) || isDecimalDigit(current)) {
+	record16(current);
+	break;
+      }
+      setDone(Identifier);
+      break;
+    case InNum0:
+      if (current == 'x' || current == 'X') {
+	record8(current);
+	state = InHex;
+      } else if (current == '.') {
+	record8(current);
+	state = InDecimal;
+      } else if (current == 'e' || current == 'E') {
+	record8(current);
+	state = InExponentIndicator;
+      } else if (isOctalDigit(current)) {
+	record8(current);
+	state = InOctal;
+      } else {
+	setDone(Number);
+      }
+      break;
+    case InHex:
+      if (isHexDigit(current)) {
+	record8(current);
+      } else {
+	setDone(Hex);
+      }
+      break;
+    case InOctal:
+      if (isOctalDigit(current)) {
+	record8(current);
+      } else
+	setDone(Octal);
+      break;
+    case InNum:
+      if (isDecimalDigit(current)) {
+	record8(current);
+      } else if (current == '.') {
+	record8(current);
+	state = InDecimal;
+      } else if (current == 'e' || current == 'E') {
+	record8(current);
+	state = InExponentIndicator;
+      } else
+	setDone(Number);
+      break;
+    case InDecimal:
+      if (isDecimalDigit(current)) {
+	record8(current);
+      } else if (current == 'e' || current == 'E') {
+	record8(current);
+	state = InExponentIndicator;
+      } else
+	setDone(Number);
+      break;
+    case InExponentIndicator:
+      if (current == '+' || current == '-') {
+	record8(current);
+      } else if (isDecimalDigit(current)) {
+	record8(current);
+	state = InExponent;
+      } else
+	setDone(Bad);
+      break;
+    case InExponent:
+      if (isDecimalDigit(current)) {
+	record8(current);
+      } else
+	setDone(Number);
+      break;
+    default:
+      assert(!"Unhandled state in switch statement");
+    }
+
+    // move on to the next character
+    if (!done)
+      shift(1);
+#ifndef KJS_PURE_ECMA
+    if (state != Start && state != InSingleLineComment)
+      bol = false;
+#endif
+  }
+
+  // no identifiers allowed directly after numeric literal, e.g. "3in" is bad
+  if ((state == Number || state == Octal || state == Hex)
+      && isIdentLetter(current))
+    state = Bad;
+
+  // terminate string
+  buffer8[pos8] = '\0';
+
+#ifdef KJS_DEBUG_LEX
+  fprintf(stderr, "line: %d ", lineNo());
+  fprintf(stderr, "yytext (%x): ", buffer8[0]);
+  fprintf(stderr, "%s ", buffer8);
+#endif
+
+  double dval = 0;
+  if (state == Number) {
+    dval = strtod(buffer8, 0L);
+  } else if (state == Hex) { // scan hex numbers
+    // TODO: support long unsigned int
+    unsigned int i;
+    sscanf(buffer8, "%x", &i);
+    dval = i;
+    state = Number;
+  } else if (state == Octal) {   // scan octal number
+    unsigned int ui;
+    sscanf(buffer8, "%o", &ui);
+    dval = ui;
+    state = Number;
+  }
+
+#ifdef KJS_DEBUG_LEX
+  switch (state) {
+  case Eof:
+    printf("(EOF)\n");
+    break;
+  case Other:
+    printf("(Other)\n");
+    break;
+  case Identifier:
+    printf("(Identifier)/(Keyword)\n");
+    break;
+  case String:
+    printf("(String)\n");
+    break;
+  case Number:
+    printf("(Number)\n");
+    break;
+  default:
+    printf("(unknown)");
+  }
+#endif
+
+  restrKeyword = false;
+  delimited = false;
+#ifdef KJS_DEBUGGER
+  yylloc.first_line = yylineno; // ???
+  yylloc.last_line = yylineno;
+#endif
+
+  switch (state) {
+  case Eof:
+    return 0;
+  case Other:
+    if(token == '}' || token == ';') {
+      delimited = true;
+    }
+    return token;
+  case Identifier:
+    if ((token = Lookup::find(&mainTable, buffer16, pos16)) < 0) {
+      /* TODO: close leak on parse error. same holds true for String */
+      kjsyylval.ustr = new UString(buffer16, pos16);
+      return IDENT;
+    }
+    if (token == CONTINUE || token == BREAK ||
+	token == RETURN || token == THROW)
+      restrKeyword = true;
+    return token;
+  case String:
+    kjsyylval.ustr = new UString(buffer16, pos16); return STRING;
+  case Number:
+    kjsyylval.dval = dval;
+    return NUMBER;
+  case Bad:
+    fprintf(stderr, "yylex: ERROR.\n");
+    return -1;
+  default:
+    assert(!"unhandled numeration value in switch");
+    return -1;
+  }
+}
+
+bool Lexer::isWhiteSpace() const
+{
+  return (current == ' ' || current == '\t' ||
+	  current == 0x0b || current == 0x0c);
+}
+
+bool Lexer::isLineTerminator() const
+{
+  return (current == '\n' || current == '\r');
+}
+
+bool Lexer::isIdentLetter(unsigned short c)
+{
+  /* TODO: allow other legitimate unicode chars */
+  return (c >= 'a' && c <= 'z' ||
+	  c >= 'A' && c <= 'Z' ||
+	  c == '$' || c == '_');
+}
+
+bool Lexer::isDecimalDigit(unsigned short c)
+{
+  return (c >= '0' && c <= '9');
+}
+
+bool Lexer::isHexDigit(unsigned short c) const
+{
+  return (c >= '0' && c <= '9' ||
+	  c >= 'a' && c <= 'f' ||
+	  c >= 'A' && c <= 'F');
+}
+
+bool Lexer::isOctalDigit(unsigned short c) const
+{
+  return (c >= '0' && c <= '7');
+}
+
+int Lexer::matchPunctuator(unsigned short c1, unsigned short c2,
+			      unsigned short c3, unsigned short c4)
+{
+  if (c1 == '>' && c2 == '>' && c3 == '>' && c4 == '=') {
+    shift(4);
+    return URSHIFTEQUAL;
+  } else if (c1 == '=' && c2 == '=' && c3 == '=') {
+    shift(3);
+    return STREQ;
+  } else if (c1 == '!' && c2 == '=' && c3 == '=') {
+    shift(3);
+    return STRNEQ;
+   } else if (c1 == '>' && c2 == '>' && c3 == '>') {
+    shift(3);
+    return URSHIFT;
+  } else if (c1 == '<' && c2 == '<' && c3 == '=') {
+    shift(3);
+    return LSHIFTEQUAL;
+  } else if (c1 == '>' && c2 == '>' && c3 == '=') {
+    shift(3);
+    return RSHIFTEQUAL;
+  } else if (c1 == '<' && c2 == '=') {
+    shift(2);
+    return LE;
+  } else if (c1 == '>' && c2 == '=') {
+    shift(2);
+    return GE;
+  } else if (c1 == '!' && c2 == '=') {
+    shift(2);
+    return NE;
+  } else if (c1 == '+' && c2 == '+') {
+    shift(2);
+    if (terminator) {
+      // automatic semicolon insertion
+      stackToken = PLUSPLUS;
+      return AUTO;
+    } else
+      return PLUSPLUS;
+  } else if (c1 == '-' && c2 == '-') {
+    shift(2);
+    if (terminator) {
+      // automatic semicolon insertion
+      stackToken = MINUSMINUS;
+      return AUTO;
+    } else
+      return MINUSMINUS;
+  } else if (c1 == '=' && c2 == '=') {
+    shift(2);
+    return EQEQ;
+  } else if (c1 == '+' && c2 == '=') {
+    shift(2);
+    return PLUSEQUAL;
+  } else if (c1 == '-' && c2 == '=') {
+    shift(2);
+    return MINUSEQUAL;
+  } else if (c1 == '*' && c2 == '=') {
+    shift(2);
+    return MULTEQUAL;
+  } else if (c1 == '/' && c2 == '=') {
+    shift(2);
+    return DIVEQUAL;
+  } else if (c1 == '&' && c2 == '=') {
+    shift(2);
+    return ANDEQUAL;
+  } else if (c1 == '^' && c2 == '=') {
+    shift(2);
+    return XOREQUAL;
+  } else if (c1 == '%' && c2 == '=') {
+    shift(2);
+    return MODEQUAL;
+  } else if (c1 == '|' && c2 == '=') {
+    shift(2);
+    return OREQUAL;
+  } else if (c1 == '<' && c2 == '<') {
+    shift(2);
+    return LSHIFT;
+  } else if (c1 == '>' && c2 == '>') {
+    shift(2);
+    return RSHIFT;
+  } else if (c1 == '&' && c2 == '&') {
+    shift(2);
+    return AND;
+  } else if (c1 == '|' && c2 == '|') {
+    shift(2);
+    return OR;
+  }
+
+  switch(c1) {
+    case '=':
+    case '>':
+    case '<':
+    case ',':
+    case '!':
+    case '~':
+    case '?':
+    case ':':
+    case '.':
+    case '+':
+    case '-':
+    case '*':
+    case '/':
+    case '&':
+    case '|':
+    case '^':
+    case '%':
+    case '(':
+    case ')':
+    case '{':
+    case '}':
+    case '[':
+    case ']':
+    case ';':
+      shift(1);
+      return static_cast<int>(c1);
+    default:
+      return -1;
+  }
+}
+
+unsigned short Lexer::singleEscape(unsigned short c) const
+{
+  switch(c) {
+  case 'b':
+    return 0x08;
+  case 't':
+    return 0x09;
+  case 'n':
+    return 0x0A;
+  case 'v':
+    return 0x0B;
+  case 'f':
+    return 0x0C;
+  case 'r':
+    return 0x0D;
+  case '"':
+    return 0x22;
+  case '\'':
+    return 0x27;
+  case '\\':
+    return 0x5C;
+  default:
+    return c;
+  }
+}
+
+unsigned short Lexer::convertOctal(unsigned short c1, unsigned short c2,
+                                      unsigned short c3) const
+{
+  return ((c1 - '0') * 64 + (c2 - '0') * 8 + c3 - '0');
+}
+
+unsigned char Lexer::convertHex(unsigned short c)
+{
+  if (c >= '0' && c <= '9')
+    return (c - '0');
+  else if (c >= 'a' && c <= 'f')
+    return (c - 'a' + 10);
+  else
+    return (c - 'A' + 10);
+}
+
+unsigned char Lexer::convertHex(unsigned short c1, unsigned short c2)
+{
+  return ((convertHex(c1) << 4) + convertHex(c2));
+}
+
+UChar Lexer::convertUnicode(unsigned short c1, unsigned short c2,
+                                     unsigned short c3, unsigned short c4)
+{
+  return UChar((convertHex(c1) << 4) + convertHex(c2),
+	       (convertHex(c3) << 4) + convertHex(c4));
+}
+
+void Lexer::record8(unsigned short c)
+{
+  assert(c <= 0xff);
+
+  // enlarge buffer if full
+  if (pos8 >= size8 - 1) {
+    char *tmp = new char[2 * size8];
+    memcpy(tmp, buffer8, size8 * sizeof(char));
+    delete [] buffer8;
+    buffer8 = tmp;
+    size8 *= 2;
+  }
+
+  buffer8[pos8++] = (char) c;
+}
+
+void Lexer::record16(UChar c)
+{
+  // enlarge buffer if full
+  if (pos16 >= size16 - 1) {
+    UChar *tmp = new UChar[2 * size16];
+    memcpy(tmp, buffer16, size16 * sizeof(UChar));
+    delete [] buffer16;
+    buffer16 = tmp;
+    size16 *= 2;
+  }
+
+  buffer16[pos16++] = c;
+}
+
+bool Lexer::scanRegExp()
+{
+  pos16 = 0;
+  bool lastWasEscape = false;
+
+  while (1) {
+    if (isLineTerminator() || current == 0)
+      return false;
+    else if (current != '/' || lastWasEscape == true)
+    {
+        record16(current);
+        lastWasEscape =
+            !lastWasEscape && (current == '\\');
+    }
+    else {
+      pattern = UString(buffer16, pos16);
+      pos16 = 0;
+      shift(1);
+      break;
+    }
+    shift(1);
+  }
+
+  while (isIdentLetter(current)) {
+    record16(current);
+    shift(1);
+  }
+  flags = UString(buffer16, pos16);
+
+  return true;
+}
diff --git a/JavaScriptCore/kjs/lexer.h b/JavaScriptCore/kjs/lexer.h
new file mode 100644
index 0000000..0acc130
--- /dev/null
+++ b/JavaScriptCore/kjs/lexer.h
@@ -0,0 +1,134 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _KJSLEXER_H_
+#define _KJSLEXER_H_
+
+#include "ustring.h"
+
+namespace KJS {
+
+  class RegExp;
+
+  class Lexer {
+  public:
+    Lexer();
+    ~Lexer();
+    static Lexer *curr();
+
+    void setCode(const UChar *c, unsigned int len);
+    int lex();
+
+    int lineNo() const { return yylineno + 1; }
+
+    bool prevTerminator() const { return terminator; }
+
+    enum State { Start,
+		 Identifier,
+		 InIdentifier,
+		 InSingleLineComment,
+		 InMultiLineComment,
+		 InNum,
+		 InNum0,
+		 InHex,
+		 InOctal,
+		 InDecimal,
+		 InExponentIndicator,
+		 InExponent,
+		 Hex,
+		 Octal,
+		 Number,
+		 String,
+		 Eof,
+		 InString,
+		 InEscapeSequence,
+		 InHexEscape,
+		 InUnicodeEscape,
+		 Other,
+		 Bad };
+    
+    bool scanRegExp();
+    UString pattern, flags;
+
+  private:
+    int yylineno;
+    bool done;
+    char *buffer8;
+    UChar *buffer16;
+    unsigned int size8, size16;
+    unsigned int pos8, pos16;
+    bool terminator;
+    bool restrKeyword;
+    // encountered delimiter like "'" and "}" on last run
+    bool delimited;
+    int stackToken;
+
+    State state;
+    void setDone(State s);
+    unsigned int pos;
+    void shift(unsigned int p);
+    int lookupKeyword(const char *);
+
+    bool isWhiteSpace() const;
+    bool isLineTerminator() const;
+    bool isHexDigit(unsigned short c) const;
+    bool isOctalDigit(unsigned short c) const;
+
+    int matchPunctuator(unsigned short c1, unsigned short c2,
+			unsigned short c3, unsigned short c4);
+    unsigned short singleEscape(unsigned short c) const;
+    unsigned short convertOctal(unsigned short c1, unsigned short c2,
+                                unsigned short c3) const;
+  public:
+    static unsigned char convertHex(unsigned short c1);
+    static unsigned char convertHex(unsigned short c1, unsigned short c2);
+    static UChar convertUnicode(unsigned short c1, unsigned short c2,
+				unsigned short c3, unsigned short c4);
+    static bool isIdentLetter(unsigned short c);
+    static bool isDecimalDigit(unsigned short c);
+
+  private:
+
+    void record8(unsigned short c);
+    void record16(UChar c);
+
+    const UChar *code;
+    unsigned int length;
+    int yycolumn;
+#ifndef KJS_PURE_ECMA
+    int bol;     // begin of line
+#endif
+
+    // current and following unicode characters
+    unsigned short current, next1, next2, next3;
+
+    struct keyword {
+      const char *name;
+      int token;
+    };
+
+    // for future extensions
+    class LexerPrivate;
+    LexerPrivate *priv;
+  };
+
+}; // namespace
+
+#endif
diff --git a/JavaScriptCore/kjs/lexer.lut.h b/JavaScriptCore/kjs/lexer.lut.h
new file mode 100644
index 0000000..2ddc9d8
--- /dev/null
+++ b/JavaScriptCore/kjs/lexer.lut.h
@@ -0,0 +1,77 @@
+/* automatically generated from keywords.table. DO NOT EDIT ! */
+
+namespace KJS {
+
+const struct HashEntry2 mainTableEntries[] = {
+   { "instanceof", INSTANCEOF, 0, &mainTableEntries[63] },
+   { "var", VAR, 0, &mainTableEntries[47] },
+   { "case", CASE, 0, &mainTableEntries[41] },
+   { "default", DEFAULT, 0, &mainTableEntries[54] },
+   { "while", WHILE, 0, &mainTableEntries[46] },
+   { 0, 0, 0, 0 },
+   { "do", DO, 0, 0 },
+   { "typeof", TYPEOF, 0, 0 },
+   { "continue", CONTINUE, 0, 0 },
+   { "function", FUNCTION, 0, 0 },
+   { "in", IN, 0, 0 },
+   { "import", RESERVED, 0, 0 },
+   { "delete", DELETE, 0, 0 },
+   { "finally", FINALLY, 0, 0 },
+   { 0, 0, 0, 0 },
+   { "else", ELSE, 0, 0 },
+   { "return", RETURN, 0, 0 },
+   { "debugger", RESERVED, 0, 0 },
+   { "const", RESERVED, 0, &mainTableEntries[48] },
+   { "package", RESERVED, 0, 0 },
+   { "double", RESERVED, 0, &mainTableEntries[53] },
+   { 0, 0, 0, 0 },
+   { "long", RESERVED, 0, 0 },
+   { "catch", CATCH, 0, &mainTableEntries[45] },
+   { "void", VOID, 0, &mainTableEntries[59] },
+   { "break", BREAK, 0, &mainTableEntries[49] },
+   { "byte", RESERVED, 0, &mainTableEntries[62] },
+   { "enum", RESERVED, 0, &mainTableEntries[58] },
+   { 0, 0, 0, 0 },
+   { 0, 0, 0, 0 },
+   { "this", THIS, 0, &mainTableEntries[50] },
+   { "false", FALSETOKEN, 0, &mainTableEntries[44] },
+   { "abstract", RESERVED, 0, &mainTableEntries[56] },
+   { "null", NULLTOKEN, 0, &mainTableEntries[61] },
+   { "with", WITH, 0, 0 },
+   { 0, 0, 0, 0 },
+   { 0, 0, 0, 0 },
+   { 0, 0, 0, 0 },
+   { "true", TRUETOKEN, 0, 0 },
+   { "boolean", RESERVED, 0, 0 },
+   { "for", FOR, 0, 0 },
+   { "new", NEW, 0, &mainTableEntries[42] },
+   { "if", IF, 0, &mainTableEntries[43] },
+   { "switch", SWITCH, 0, &mainTableEntries[55] },
+   { "throw", THROW, 0, &mainTableEntries[52] },
+   { "try", TRY, 0, &mainTableEntries[64] },
+   { "char", RESERVED, 0, 0 },
+   { "class", RESERVED, 0, &mainTableEntries[51] },
+   { "export", RESERVED, 0, 0 },
+   { "extends", RESERVED, 0, &mainTableEntries[57] },
+   { "final", RESERVED, 0, 0 },
+   { "float", RESERVED, 0, 0 },
+   { "goto", RESERVED, 0, 0 },
+   { "implements", RESERVED, 0, 0 },
+   { "int", RESERVED, 0, &mainTableEntries[66] },
+   { "interface", RESERVED, 0, 0 },
+   { "native", RESERVED, 0, 0 },
+   { "private", RESERVED, 0, 0 },
+   { "protected", RESERVED, 0, &mainTableEntries[60] },
+   { "public", RESERVED, 0, 0 },
+   { "short", RESERVED, 0, 0 },
+   { "static", RESERVED, 0, 0 },
+   { "super", RESERVED, 0, 0 },
+   { "synchronized", RESERVED, 0, &mainTableEntries[65] },
+   { "throws", RESERVED, 0, 0 },
+   { "transient", RESERVED, 0, 0 },
+   { "volatile", RESERVED, 0, 0 }
+};
+
+const struct HashTable2 mainTable = { 2, 67, mainTableEntries, 41 };
+
+}; // namespace
diff --git a/JavaScriptCore/kjs/lookup.cpp b/JavaScriptCore/kjs/lookup.cpp
new file mode 100644
index 0000000..fcd3055
--- /dev/null
+++ b/JavaScriptCore/kjs/lookup.cpp
@@ -0,0 +1,145 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "lookup.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+using namespace KJS;
+
+int Lookup::find(const struct HashTable *table,
+		 const UChar *c, unsigned int len)
+{
+  // we only know about version 1 so far
+  if (table->type != 1) {
+    fprintf(stderr, "Unknown hash table version.\n");
+    return -1;
+  }
+
+  int h = hash(c, len) % table->hashSize;
+  const HashEntry *e = &table->entries[h];
+
+  // empty bucket ?
+  if (!e->c)
+    return -1;
+
+  do {
+    // compare strings
+#ifdef KJS_SWAPPED_CHAR
+    /* TODO: not exactly as optimized as the other version ... */
+    if (len == e->len) {
+	const UChar *u = (const UChar*)e->c;
+	const UChar *c2 = c;
+	unsigned int i;
+	for (i = 0; i < len; i++, u++, c2++)
+	    if (!(*c2 == UChar(u->low(), u->high()))) // reverse byte order
+		goto next;
+        return e->value;
+    }
+next:
+#else
+    if ((len == e->len) && (memcmp(c, e->c, len * sizeof(UChar)) == 0))
+	return e->value;
+#endif
+    // try next bucket
+    e = e->next;
+  } while (e);
+
+  return -1;
+}
+
+int Lookup::find(const struct HashTable *table, const UString &s)
+{
+  return find(table, s.data(), s.size());
+}
+
+int Lookup::find(const struct HashTable2 *table,
+		 const UChar *c, unsigned int len)
+{
+  if (table->type != 2) {
+    fprintf(stderr, "Unknown hash table version.\n");
+    return -1;
+  }
+
+  char *ascii = new char[len+1];
+  unsigned int i;
+  for(i = 0; i < len; i++, c++) {
+    if (!c->high())
+      ascii[i] = c->low();
+    else
+      break;
+  }
+  ascii[i] = '\0';
+
+  int h = hash(ascii) % table->hashSize;
+  const HashEntry2 *e = &table->entries[h];
+
+  // empty bucket ?
+  if (!e->s) {
+    delete [] ascii;
+    return -1;
+  }
+
+  do {
+    // compare strings
+    if (strcmp(ascii, e->s) == 0) {
+      delete [] ascii;
+      return e->value;
+    }
+    // try next bucket
+    e = e->next;
+  } while (e);
+
+  delete [] ascii;
+  return -1;
+}
+
+int Lookup::find(const struct HashTable2 *table, const UString &s)
+{
+  return find(table, s.data(), s.size());
+}
+
+unsigned int Lookup::hash(const UChar *c, unsigned int len)
+{
+  unsigned int val = 0;
+  // ignoring higher byte
+  for (unsigned int i = 0; i < len; i++, c++)
+    val += c->low();
+
+  return val;
+}
+
+unsigned int Lookup::hash(const UString &key)
+{
+  return hash(key.data(), key.size());
+}
+
+unsigned int Lookup::hash(const char *s)
+{
+  unsigned int val = 0;
+  while (*s)
+    val += *s++;
+
+  return val;
+}
diff --git a/JavaScriptCore/kjs/lookup.h b/JavaScriptCore/kjs/lookup.h
new file mode 100644
index 0000000..9301ad6
--- /dev/null
+++ b/JavaScriptCore/kjs/lookup.h
@@ -0,0 +1,80 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _KJSLOOKUP_H_
+#define _KJSLOOKUP_H_
+
+#include "ustring.h"
+
+namespace KJS {
+
+#if 1  // obsolete version 1
+  struct HashEntry {
+    unsigned int len;
+    const void *c; // unicode data
+    int value;
+    const HashEntry *next;
+  };
+
+  struct HashTable {
+    int type;
+    int size;
+    const HashEntry *entries;
+    int hashSize;
+  };
+#endif
+
+  // version 2
+  struct HashEntry2 {
+    const char *s;
+    int value;
+    int attr;
+    const HashEntry2 *next;
+  };
+
+  struct HashTable2 {
+    int type;
+    int size;
+    const HashEntry2 *entries;
+    int hashSize;
+  };
+
+  /**
+   * @short Fast keyword lookup.
+   */
+  class Lookup {
+  public:
+#if 1 // obsolete
+    static int find(const struct HashTable *table, const UString &s);
+    static int find(const struct HashTable *table,
+		    const UChar *c, unsigned int len);
+#endif
+    static int find(const struct HashTable2 *table, const UString &s);
+    static int find(const struct HashTable2 *table,
+		    const UChar *c, unsigned int len);
+    static unsigned int hash(const UChar *c, unsigned int len);
+    static unsigned int hash(const UString &key);
+    static unsigned int hash(const char *s);
+  private:
+    HashTable *table;
+  };
+
+}; // namespace
+
+#endif
diff --git a/JavaScriptCore/kjs/math_object.cpp b/JavaScriptCore/kjs/math_object.cpp
new file mode 100644
index 0000000..c9ebb79
--- /dev/null
+++ b/JavaScriptCore/kjs/math_object.cpp
@@ -0,0 +1,163 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <math.h>
+#include <stdlib.h>
+
+#include "kjs.h"
+#include "types.h"
+#include "operations.h"
+#include "math_object.h"
+#include "lookup.h"
+
+#include "math_object.lut.h"
+
+using namespace KJS;
+
+KJSO Math::get(const UString &p) const
+{
+  int token = Lookup::find(&mathTable, p);
+
+  if (token < 0)
+    return Imp::get(p);
+
+  double d;
+  int len = 1;
+  switch (token) {
+  case Math::Euler:
+    d = exp(1.0);
+    break;
+  case Math::Ln2:
+    d = log(2.0);
+    break;
+  case Math::Ln10:
+    d = log(10.0);
+    break;
+  case Math::Log2E:
+    d = 1.0/log(2.0);
+    break;
+  case Math::Log10E:
+    d = 1.0/log(10.0);
+    break;
+  case Math::Pi:
+    d = 2.0 * asin(1.0);
+    break;
+  case Math::Sqrt1_2:
+    d = sqrt(0.5);
+    break;
+  case Math::Sqrt2:
+    d = sqrt(2.0);
+    break;
+  default:
+    if (token == Math::Min || token == Math::Max || token == Math::Pow)
+      len = 2;
+    return Function(new MathFunc(token, len));
+  };
+
+  return Number(d);
+}
+
+bool Math::hasProperty(const UString &p, bool recursive) const
+{
+  return (Lookup::find(&mathTable, p) >= 0 ||
+	  (recursive && Imp::hasProperty(p, recursive)));
+}
+
+Completion MathFunc::execute(const List &args)
+{
+  KJSO v = args[0];
+  Number n = v.toNumber();
+  double arg = n.value();
+
+  KJSO v2 = args[1];
+  Number n2 = v2.toNumber();
+  double arg2 = n2.value();
+  double result;
+
+  switch (id) {
+  case Math::Abs:
+    result = ( arg < 0 ) ? (-arg) : arg;
+    break;
+  case Math::ACos:
+    result = ::acos(arg);
+    break;
+  case Math::ASin:
+    result = ::asin(arg);
+    break;
+  case Math::ATan:
+    result = ::atan(arg);
+    break;
+  case Math::ATan2:
+    result = ::atan2(arg, arg2);
+    break;
+  case Math::Ceil:
+    result = ::ceil(arg);
+    break;
+  case Math::Cos:
+    result = ::cos(arg);
+    break;
+  case Math::Exp:
+    result = ::exp(arg);
+    break;
+  case Math::Floor:
+    result = ::floor(arg);
+    break;
+  case Math::Log:
+    result = ::log(arg);
+    break;
+  case Math::Max:
+    result = ( arg > arg2 ) ? arg : arg2;
+    break;
+  case Math::Min:
+    result = ( arg < arg2 ) ? arg : arg2;
+    break;
+  case Math::Pow:
+    result = ::pow(arg, arg2);
+    break;
+  case Math::Random:
+    result = ::rand();
+    result = result / RAND_MAX;
+    break;
+  case Math::Round:
+    if (isNaN(arg))
+      result = arg;
+    if (isInf(arg) || isInf(-arg))
+      result = arg;
+    else if (arg == -0.5)
+      result = 0;
+    else
+      result = (double)(arg >= 0.0 ? int(arg + 0.5) : int(arg - 0.5));
+    break;
+  case Math::Sin:
+    result = ::sin(arg);
+    break;
+  case Math::Sqrt:
+    result = ::sqrt(arg);
+    break;
+  case Math::Tan:
+    result = ::tan(arg);
+    break;
+
+  default:
+    result = 0.0;
+    assert(0);
+  }
+
+  return Completion(ReturnValue, Number(result));
+}
diff --git a/JavaScriptCore/kjs/math_object.h b/JavaScriptCore/kjs/math_object.h
new file mode 100644
index 0000000..a04cfc1
--- /dev/null
+++ b/JavaScriptCore/kjs/math_object.h
@@ -0,0 +1,48 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _MATH_OBJECT_H_
+#define _MATH_OBJECT_H_
+
+#include "object.h"
+#include "function.h"
+
+namespace KJS {
+
+  class Math : public ObjectImp {
+  public:
+    Math() : ObjectImp(BooleanClass) { }
+    virtual KJSO get(const UString &p) const;
+    virtual bool hasProperty(const UString &p, bool recursive = true) const;
+    enum { Euler, Ln2, Ln10, Log2E, Log10E, Pi, Sqrt1_2, Sqrt2,
+	   Abs, ACos, ASin, ATan, ATan2, Ceil, Cos, Pow,
+	   Exp, Floor, Log, Max, Min, Random, Round, Sin, Sqrt, Tan };
+  };
+
+  class MathFunc : public InternalFunctionImp {
+  public:
+    MathFunc(int i, int l) : InternalFunctionImp(l), id(i) { }
+    Completion execute(const List &);
+  private:
+    int id;
+  };
+
+}; // namespace
+
+#endif
diff --git a/JavaScriptCore/kjs/math_object.lut.h b/JavaScriptCore/kjs/math_object.lut.h
new file mode 100644
index 0000000..e422d18
--- /dev/null
+++ b/JavaScriptCore/kjs/math_object.lut.h
@@ -0,0 +1,42 @@
+/* automatically generated from math.table. DO NOT EDIT ! */
+
+namespace KJS {
+
+const struct HashEntry2 mathTableEntries[] = {
+   { "atan", Math::ATan, DontEnum|ReadOnly, &mathTableEntries[25] },
+   { 0, 0, 0, 0 },
+   { "SQRT2", Math::Sqrt2, DontEnum|ReadOnly, &mathTableEntries[23] },
+   { 0, 0, 0, 0 },
+   { 0, 0, 0, 0 },
+   { 0, 0, 0, 0 },
+   { "E", Math::Euler, DontEnum|ReadOnly, &mathTableEntries[21] },
+   { "asin", Math::ASin, DontEnum|ReadOnly, &mathTableEntries[26] },
+   { "atan2", Math::ATan2, DontEnum|ReadOnly, &mathTableEntries[31] },
+   { "LOG2E", Math::Log2E, DontEnum|ReadOnly, &mathTableEntries[27] },
+   { "cos", Math::Cos, DontEnum|ReadOnly, 0 },
+   { "max", Math::Max, DontEnum|ReadOnly, &mathTableEntries[28] },
+   { 0, 0, 0, 0 },
+   { 0, 0, 0, 0 },
+   { "LOG10E", Math::Log10E, DontEnum|ReadOnly, &mathTableEntries[24] },
+   { "LN2", Math::Ln2, DontEnum|ReadOnly, &mathTableEntries[30] },
+   { "abs", Math::Abs, DontEnum|ReadOnly, 0 },
+   { "sqrt", Math::Sqrt, DontEnum|ReadOnly, 0 },
+   { "exp", Math::Exp, DontEnum|ReadOnly, 0 },
+   { 0, 0, 0, 0 },
+   { "LN10", Math::Ln10, DontEnum|ReadOnly, &mathTableEntries[22] },
+   { "PI", Math::Pi, DontEnum|ReadOnly, &mathTableEntries[29] },
+   { "SQRT1_2", Math::Sqrt1_2, DontEnum|ReadOnly, 0 },
+   { "acos", Math::ACos, DontEnum|ReadOnly, 0 },
+   { "ceil", Math::Ceil, DontEnum|ReadOnly, 0 },
+   { "floor", Math::Floor, DontEnum|ReadOnly, 0 },
+   { "log", Math::Log, DontEnum|ReadOnly, 0 },
+   { "min", Math::Min, DontEnum|ReadOnly, 0 },
+   { "random", Math::Random, DontEnum|ReadOnly, 0 },
+   { "round", Math::Round, DontEnum|ReadOnly, 0 },
+   { "sin", Math::Sin, DontEnum|ReadOnly, 0 },
+   { "tan", Math::Tan, DontEnum|ReadOnly, 0 }
+};
+
+const struct HashTable2 mathTable = { 2, 32, mathTableEntries, 21 };
+
+}; // namespace
diff --git a/JavaScriptCore/kjs/nodes.cpp b/JavaScriptCore/kjs/nodes.cpp
new file mode 100644
index 0000000..ab20d3b
--- /dev/null
+++ b/JavaScriptCore/kjs/nodes.cpp
@@ -0,0 +1,1487 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2001 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#include "nodes.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <math.h>
+
+#include "kjs.h"
+#include "ustring.h"
+#include "lexer.h"
+#include "types.h"
+#include "internal.h"
+#include "operations.h"
+#include "regexp_object.h"
+#include "debugger.h"
+
+using namespace KJS;
+
+#ifdef KJS_DEBUGGER
+#define KJS_BREAKPOINT if (!hitStatement()) return Completion(Normal);
+#define KJS_ABORTPOINT if (abortStatement()) return Completion(Normal);
+#else
+#define KJS_BREAKPOINT
+#define KJS_ABORTPOINT
+#endif
+
+int   Node::nodeCount = 0;
+Node* Node::first = 0;
+
+Node::Node()
+{
+  assert(Lexer::curr());
+  line = Lexer::curr()->lineNo();
+  nodeCount++;
+  //  cout << "Node()" << endl;
+
+  // create a list of allocated objects. Makes
+  // deleting (even after a parse error) quite easy
+  next = first;
+  prev = 0L;
+  if (first)
+    first->prev = this;
+  first = this;
+}
+
+Node::~Node()
+{
+  //  cout << "~Node()" << endl;
+  if (next)
+    next->prev = prev;
+  if (prev)
+    prev->next = next;
+  nodeCount--;
+}
+
+void Node::deleteAllNodes()
+{
+  Node *tmp, *n = first;
+
+  while ((tmp = n)) {
+    n = n->next;
+    delete tmp;
+  }
+  first = 0L;
+  //  assert(nodeCount == 0);
+}
+
+KJSO Node::throwError(ErrorType e, const char *msg)
+{
+  return Error::create(e, msg, lineNo());
+}
+
+#ifdef KJS_DEBUGGER
+void StatementNode::setLoc(int line0, int line1)
+{
+    l0 = line0;
+    l1 = line1;
+    sid = KJScriptImp::current()->sourceId();
+}
+
+bool StatementNode::hitStatement()
+{
+  if (KJScriptImp::current()->debugger())
+    return KJScriptImp::current()->debugger()->hit(firstLine(), breakPoint);
+  else
+    return true;
+}
+
+// return true if the debugger wants us to stop at this point
+bool StatementNode::abortStatement()
+{
+  if (KJScriptImp::current()->debugger() &&
+      KJScriptImp::current()->debugger()->mode() == Debugger::Stop)
+      return true;
+
+  return false;
+}
+
+bool Node::setBreakpoint(Node *firstNode, int id, int line, bool set)
+{
+  while (firstNode) {
+    if (firstNode->setBreakpoint(id, line, set) && line >= 0) // line<0 for all
+      return true;
+    firstNode = firstNode->next;
+  }
+  return false;
+}
+
+/**
+ * Try to set or delete a breakpoint depending on the value of set.
+ * The call will return true if successful, i.e. if line is inside
+ * of the statement's range. Additionally, a breakpoint had to
+ * be set already if you tried to delete with set=false.
+ */
+bool StatementNode::setBreakpoint(int id, int line, bool set)
+{
+  // in our source unit and line range ?
+  if (id != sid || ((line < l0 || line > l1) && line >= 0))
+    return false;
+
+  if (!set && !breakPoint)
+    return false;
+
+  breakPoint = set;
+  return true;
+}
+#endif
+
+KJSO NullNode::evaluate()
+{
+  return Null();
+}
+
+KJSO BooleanNode::evaluate()
+{
+  return Boolean(value);
+}
+
+KJSO NumberNode::evaluate()
+{
+  return Number(value);
+}
+
+KJSO StringNode::evaluate()
+{
+  return String(value);
+}
+
+KJSO RegExpNode::evaluate()
+{
+  List list;
+  String p(pattern);
+  String f(flags);
+  list.append(p);
+  list.append(f);
+
+  // very ugly
+  KJSO r = Global::current().get("RegExp");
+  RegExpObject *r2 = (RegExpObject*)r.imp();
+  return r2->construct(list);
+}
+
+// ECMA 11.1.1
+KJSO ThisNode::evaluate()
+{
+  return Context::current()->thisValue();
+}
+
+// ECMA 11.1.2 & 10.1.4
+KJSO ResolveNode::evaluate()
+{
+  assert(Context::current());
+  const List *chain = Context::current()->pScopeChain();
+  assert(chain);
+  ListIterator scope = chain->begin();
+
+  while (scope != chain->end()) {
+    if (scope->hasProperty(ident)) {
+//        cout << "Resolve: found '" << ident.ascii() << "'"
+// 	    << " type " << scope->get(ident).imp()->typeInfo()->name << endl;
+      return Reference(*scope, ident);
+    }
+    scope++;
+  }
+
+  // identifier not found
+//  cout << "Resolve: didn't find '" << ident.ascii() << "'" << endl;
+  return Reference(Null(), ident);
+}
+
+// ECMA 11.1.4
+KJSO ArrayNode::evaluate()
+{
+  KJSO array;
+  int length;
+  int elisionLen = elision ? elision->evaluate().toInt32() : 0;
+
+  if (element) {
+    array = element->evaluate();
+    length = opt ? array.get("length").toInt32() : 0;
+  } else {
+    array = Object::create(ArrayClass);
+    length = 0;
+  }
+
+  if (opt)
+    array.put("length", Number(elisionLen + length), DontEnum | DontDelete);
+
+  return array;
+}
+
+// ECMA 11.1.4
+KJSO ElementNode::evaluate()
+{
+  KJSO array, val;
+  int length = 0;
+  int elisionLen = elision ? elision->evaluate().toInt32() : 0;
+
+  if (list) {
+    array = list->evaluate();
+    val = node->evaluate().getValue();
+    length = array.get("length").toInt32();
+  } else {
+    array = Object::create(ArrayClass);
+    val = node->evaluate().getValue();
+  }
+
+  array.putArrayElement(UString::from(elisionLen + length), val);
+
+  return array;
+}
+
+// ECMA 11.1.4
+KJSO ElisionNode::evaluate()
+{
+  if (elision)
+    return Number(elision->evaluate().toNumber().value() + 1);
+  else
+    return Number(1);
+}
+
+// ECMA 11.1.5
+KJSO ObjectLiteralNode::evaluate()
+{
+  if (list)
+    return list->evaluate();
+
+  return Object::create(ObjectClass);
+}
+
+// ECMA 11.1.5
+KJSO PropertyValueNode::evaluate()
+{
+  KJSO obj;
+  if (list)
+    obj = list->evaluate();
+  else
+    obj = Object::create(ObjectClass);
+  KJSO n = name->evaluate();
+  KJSO a = assign->evaluate();
+  KJSO v = a.getValue();
+
+  obj.put(n.toString().value(), v);
+
+  return obj;
+}
+
+// ECMA 11.1.5
+KJSO PropertyNode::evaluate()
+{
+  KJSO s;
+
+  if (str.isNull()) {
+    s = String(UString::from(numeric));
+  } else
+    s = String(str);
+
+  return s;
+}
+
+// ECMA 11.1.6
+KJSO GroupNode::evaluate()
+{
+  return group->evaluate();
+}
+
+// ECMA 11.2.1a
+KJSO AccessorNode1::evaluate()
+{
+  KJSO e1 = expr1->evaluate();
+  KJSO v1 = e1.getValue();
+  KJSO e2 = expr2->evaluate();
+  KJSO v2 = e2.getValue();
+  Object o = v1.toObject();
+  String s = v2.toString();
+  return Reference(o, s.value());
+}
+
+// ECMA 11.2.1b
+KJSO AccessorNode2::evaluate()
+{
+  KJSO e = expr->evaluate();
+  KJSO v = e.getValue();
+  KJSO o = v.toObject();
+  return Reference(o, ident);
+}
+
+// ECMA 11.2.2
+KJSO NewExprNode::evaluate()
+{
+  KJSO e = expr->evaluate();
+  KJSO v = e.getValue();
+
+  List *argList = args ? args->evaluateList() : 0;
+
+  if (!v.isObject()) {
+    delete argList;
+    return throwError(TypeError, "Expression is no object. Cannot be new'ed");
+  }
+
+  Constructor constr = Constructor::dynamicCast(v);
+  if (constr.isNull()) {
+    delete argList;
+    return throwError(TypeError, "Expression is no constructor.");
+  }
+
+  if (!argList)
+    argList = new List;
+
+  KJSO res = constr.construct(*argList);
+
+  delete argList;
+
+  return res;
+}
+
+// ECMA 11.2.3
+KJSO FunctionCallNode::evaluate()
+{
+  KJSO e = expr->evaluate();
+
+  List *argList = args->evaluateList();
+
+  KJSO v = e.getValue();
+
+  if (!v.isObject()) {
+#ifndef NDEBUG
+    printInfo("Failed function call attempt on", e);
+#endif
+    delete argList;
+    return throwError(TypeError, "Expression is no object. Cannot be called.");
+  }
+
+  if (!v.implementsCall()) {
+#ifndef NDEBUG
+    printInfo("Failed function call attempt on", e);
+#endif
+    delete argList;
+    return throwError(TypeError, "Expression does not allow calls.");
+  }
+
+  KJSO o;
+  if (e.isA(ReferenceType))
+    o = e.getBase();
+  else
+    o = Null();
+
+  if (o.isA(ActivationType))
+    o = Null();
+
+#ifdef KJS_DEBUGGER
+  steppingInto(true);
+#endif
+
+  KJSO result = v.executeCall(o, argList);
+
+#ifdef KJS_DEBUGGER
+  steppingInto(false);
+#endif
+
+  delete argList;
+
+  return result;
+}
+
+#ifdef KJS_DEBUGGER
+void FunctionCallNode::steppingInto(bool in)
+{
+  Debugger *dbg = KJScriptImp::current()->debugger();
+  if (!dbg)
+    return;
+  if (in) {
+    // before entering function. Don't step inside if 'Next' is chosen.
+    previousMode = dbg->mode();
+    if (previousMode == Debugger::Next)
+      dbg->setMode(Debugger::Continue);
+  } else {
+    // restore mode after leaving function
+    dbg->setMode(previousMode);
+  }
+}
+#endif
+
+KJSO ArgumentsNode::evaluate()
+{
+  assert(0);
+  return KJSO(); // dummy, see evaluateList()
+}
+
+// ECMA 11.2.4
+List* ArgumentsNode::evaluateList()
+{
+  if (!list)
+    return new List();
+
+  return list->evaluateList();
+}
+
+KJSO ArgumentListNode::evaluate()
+{
+  assert(0);
+  return KJSO(); // dummy, see evaluateList()
+}
+
+// ECMA 11.2.4
+List* ArgumentListNode::evaluateList()
+{
+  KJSO e = expr->evaluate();
+  KJSO v = e.getValue();
+
+  if (!list) {
+    List *l = new List();
+    l->append(v);
+    return l;
+  }
+
+  List *l = list->evaluateList();
+  l->append(v);
+
+  return l;
+}
+
+// ECMA 11.8
+KJSO RelationalNode::evaluate()
+{
+  KJSO e1 = expr1->evaluate();
+  KJSO v1 = e1.getValue();
+  KJSO e2 = expr2->evaluate();
+  KJSO v2 = e2.getValue();
+
+  bool b;
+  if (oper == OpLess || oper == OpGreaterEq) {
+    int r = relation(v1, v2);
+    if (r < 0)
+      b = false;
+    else
+      b = (oper == OpLess) ? (r == 1) : (r == 0);
+  } else if (oper == OpGreater || oper == OpLessEq) {
+    int r = relation(v2, v1);
+    if (r < 0)
+      b = false;
+    else
+      b = (oper == OpGreater) ? (r == 1) : (r == 0);
+  } else if (oper == OpIn) {
+      /* Is all of this OK for host objects? */
+      if (!v2.isObject())
+          return throwError( TypeError,
+                             "Shift expression not an object into IN expression." );
+      b = v2.hasProperty(v1.toString().value());
+  } else {
+    /* TODO: should apply to Function _objects_ only */
+    if (!v2.derivedFrom("Function"))
+      return throwError(TypeError,
+			"Called instanceof operator on non-function object." );
+    return hasInstance(v2, v1);	/* TODO: make object member function */
+  }
+
+  return Boolean(b);
+}
+
+// ECMA 11.9
+KJSO EqualNode::evaluate()
+{
+  KJSO e1 = expr1->evaluate();
+  KJSO e2 = expr2->evaluate();
+  KJSO v1 = e1.getValue();
+  KJSO v2 = e2.getValue();
+
+  bool result;
+  if (oper == OpEqEq || oper == OpNotEq) {
+    // == and !=
+    bool eq = equal(v1, v2);
+    result = oper == OpEqEq ? eq : !eq;
+  } else {
+    // === and !==
+    bool eq = strictEqual(v1, v2);
+    result = oper == OpStrEq ? eq : !eq;
+  }
+  return Boolean(result);
+}
+
+// ECMA 11.10
+KJSO BitOperNode::evaluate()
+{
+  KJSO e1 = expr1->evaluate();
+  KJSO v1 = e1.getValue();
+  KJSO e2 = expr2->evaluate();
+  KJSO v2 = e2.getValue();
+  int i1 = v1.toInt32();
+  int i2 = v2.toInt32();
+  int result;
+  if (oper == OpBitAnd)
+    result = i1 & i2;
+  else if (oper == OpBitXOr)
+    result = i1 ^ i2;
+  else
+    result = i1 | i2;
+
+  return Number(result);
+}
+
+// ECMA 11.11
+KJSO BinaryLogicalNode::evaluate()
+{
+  KJSO e1 = expr1->evaluate();
+  KJSO v1 = e1.getValue();
+  Boolean b1 = v1.toBoolean();
+  if ((!b1.value() && oper == OpAnd) || (b1.value() && oper == OpOr))
+    return v1;
+
+  KJSO e2 = expr2->evaluate();
+  KJSO v2 = e2.getValue();
+
+  return v2;
+}
+
+// ECMA 11.12
+KJSO ConditionalNode::evaluate()
+{
+  KJSO e = logical->evaluate();
+  KJSO v = e.getValue();
+  Boolean b = v.toBoolean();
+
+  if (b.value())
+    e = expr1->evaluate();
+  else
+    e = expr2->evaluate();
+
+  return e.getValue();
+}
+
+// ECMA 11.13
+KJSO AssignNode::evaluate()
+{
+  KJSO l, e, v;
+  ErrorType err;
+  if (oper == OpEqual) {
+    l = left->evaluate();
+    e = expr->evaluate();
+    v = e.getValue();
+  } else {
+    l = left->evaluate();
+    KJSO v1 = l.getValue();
+    e = expr->evaluate();
+    KJSO v2 = e.getValue();
+    int i1 = v1.toInt32();
+    int i2 = v2.toInt32();
+    switch (oper) {
+    case OpMultEq:
+      v = mult(v1, v2, '*');
+      break;
+    case OpDivEq:
+      v = mult(v1, v2, '/');
+      break;
+    case OpPlusEq:
+      v = add(v1, v2, '+');
+      break;
+    case OpMinusEq:
+      v = add(v1, v2, '-');
+      break;
+    case OpLShift:
+      v = Number(i1 <<= i2);
+      break;
+    case OpRShift:
+      v = Number(i1 >>= i2);
+      break;
+    case OpURShift:
+      i1 = v1.toUInt32();
+      v = Number(i1 >>= i2);
+      break;
+    case OpAndEq:
+      v = Number(i1 &= i2);
+      break;
+    case OpXOrEq:
+      v = Number(i1 ^= i2);
+      break;
+    case OpOrEq:
+      v = Number(i1 |= i2);
+      break;
+    case OpModEq:
+      v = Number(i1 %= i2);
+      break;
+    default:
+      v = Undefined();
+    }
+    err = l.putValue(v);
+  };
+
+  err = l.putValue(v);
+  if (err == NoError)
+    return v;
+  else
+    return throwError(err, "Invalid reference.");
+}
+
+// ECMA 11.3
+KJSO PostfixNode::evaluate()
+{
+  KJSO e = expr->evaluate();
+  KJSO v = e.getValue();
+  Number n = v.toNumber();
+
+  double newValue = (oper == OpPlusPlus) ? n.value() + 1 : n.value() - 1;
+  KJSO n2 = Number(newValue);
+
+  e.putValue(n2);
+
+  return n;
+}
+
+// ECMA 11.4.1
+KJSO DeleteNode::evaluate()
+{
+  KJSO e = expr->evaluate();
+  if (!e.isA(ReferenceType))
+    return Boolean(true);
+  KJSO b = e.getBase();
+  UString n = e.getPropertyName();
+  bool ret = b.deleteProperty(n);
+
+  return Boolean(ret);
+}
+
+// ECMA 11.4.2
+KJSO VoidNode::evaluate()
+{
+  KJSO dummy1 = expr->evaluate();
+  KJSO dummy2 = dummy1.getValue();
+
+  return Undefined();
+}
+
+// ECMA 11.4.3
+KJSO TypeOfNode::evaluate()
+{
+  const char *s = 0L;
+  KJSO e = expr->evaluate();
+  if (e.isA(ReferenceType)) {
+    KJSO b = e.getBase();
+    if (b.isA(NullType))
+      return String("undefined");
+  }
+  KJSO v = e.getValue();
+  switch (v.type())
+    {
+    case UndefinedType:
+      s = "undefined";
+      break;
+    case NullType:
+      s = "object";
+      break;
+    case BooleanType:
+      s = "boolean";
+      break;
+    case NumberType:
+      s = "number";
+      break;
+    case StringType:
+      s = "string";
+      break;
+    default:
+      if (v.implementsCall())
+	s = "function";
+      else
+	s = "object";
+      break;
+    }
+
+  return String(s);
+}
+
+// ECMA 11.4.4 and 11.4.5
+KJSO PrefixNode::evaluate()
+{
+  KJSO e = expr->evaluate();
+  KJSO v = e.getValue();
+  Number n = v.toNumber();
+
+  double newValue = (oper == OpPlusPlus) ? n.value() + 1 : n.value() - 1;
+  KJSO n2 = Number(newValue);
+
+  e.putValue(n2);
+
+  return n2;
+}
+
+// ECMA 11.4.6
+KJSO UnaryPlusNode::evaluate()
+{
+  KJSO e = expr->evaluate();
+  KJSO v = e.getValue();
+
+  return v.toNumber();
+}
+
+// ECMA 11.4.7
+KJSO NegateNode::evaluate()
+{
+  KJSO e = expr->evaluate();
+  KJSO v = e.getValue();
+  Number n = v.toNumber();
+
+  double d = -n.value();
+
+  return Number(d);
+}
+
+// ECMA 11.4.8
+KJSO BitwiseNotNode::evaluate()
+{
+  KJSO e = expr->evaluate();
+  KJSO v = e.getValue();
+  int i32 = v.toInt32();
+
+  return Number(~i32);
+}
+
+// ECMA 11.4.9
+KJSO LogicalNotNode::evaluate()
+{
+  KJSO e = expr->evaluate();
+  KJSO v = e.getValue();
+  Boolean b = v.toBoolean();
+
+  return Boolean(!b.value());
+}
+
+// ECMA 11.5
+KJSO MultNode::evaluate()
+{
+  KJSO t1 = term1->evaluate();
+  KJSO v1 = t1.getValue();
+
+  KJSO t2 = term2->evaluate();
+  KJSO v2 = t2.getValue();
+
+  return mult(v1, v2, oper);
+}
+
+// ECMA 11.7
+KJSO ShiftNode::evaluate()
+{
+  KJSO t1 = term1->evaluate();
+  KJSO v1 = t1.getValue();
+  KJSO t2 = term2->evaluate();
+  KJSO v2 = t2.getValue();
+  unsigned int i2 = v2.toUInt32();
+  i2 &= 0x1f;
+
+  long result;
+  switch (oper) {
+  case OpLShift:
+    result = v1.toInt32() << i2;
+    break;
+  case OpRShift:
+    result = v1.toInt32() >> i2;
+    break;
+  case OpURShift:
+    result = v1.toUInt32() >> i2;
+    break;
+  default:
+    assert(!"ShiftNode: unhandled switch case");
+    result = 0L;
+  }
+
+  return Number(static_cast<double>(result));
+}
+
+// ECMA 11.6
+KJSO AddNode::evaluate()
+{
+  KJSO t1 = term1->evaluate();
+  KJSO v1 = t1.getValue();
+
+  KJSO t2 = term2->evaluate();
+  KJSO v2 = t2.getValue();
+
+  return add(v1, v2, oper);
+}
+
+// ECMA 11.14
+KJSO CommaNode::evaluate()
+{
+  KJSO e = expr1->evaluate();
+  KJSO dummy = e.getValue(); // ignore return value
+  e = expr2->evaluate();
+
+  return e.getValue();
+}
+
+// ECMA 12.1
+Completion BlockNode::execute()
+{
+  if (!statlist)
+    return Completion(Normal);
+
+  return statlist->execute();
+}
+
+// ECMA 12.1
+Completion StatListNode::execute()
+{
+  if (!list) {
+    Completion c = statement->execute();
+    KJS_ABORTPOINT
+    if (KJScriptImp::hadException()) {
+      KJSO ex = KJScriptImp::exception();
+      KJScriptImp::clearException();
+      return Completion(Throw, ex);
+    } else
+      return c;
+  }
+
+  Completion l = list->execute();
+  KJS_ABORTPOINT
+  if (l.complType() != Normal)
+    return l;
+  Completion e = statement->execute();
+  KJS_ABORTPOINT;
+  if (KJScriptImp::hadException()) {
+    KJSO ex = KJScriptImp::exception();
+    KJScriptImp::clearException();
+    return Completion(Throw, ex);
+  }
+
+  KJSO v = e.isValueCompletion() ? e.value() : l.value();
+
+  return Completion(e.complType(), v, e.target() );
+}
+
+// ECMA 12.2
+Completion VarStatementNode::execute()
+{
+  KJS_BREAKPOINT;
+
+  (void) list->evaluate(); // returns 0L
+
+  return Completion(Normal);
+}
+
+// ECMA 12.2
+KJSO VarDeclNode::evaluate()
+{
+  KJSO variable = Context::current()->variableObject();
+
+  KJSO val, tmp;
+  if (init) {
+      tmp = init->evaluate();
+      val = tmp.getValue();
+  } else {
+      if ( variable.hasProperty( ident ) ) // already declared ?
+          return KJSO();
+      val = Undefined();
+  }
+  variable.put(ident, val, DontDelete);
+
+  // spec wants to return ident. But what for ? Will be ignored above.
+  return KJSO();
+}
+
+// ECMA 12.2
+KJSO VarDeclListNode::evaluate()
+{
+  if (list)
+    (void) list->evaluate();
+
+  (void) var->evaluate();
+
+  return KJSO();
+}
+
+// ECMA 12.2
+KJSO AssignExprNode::evaluate()
+{
+  return expr->evaluate();
+}
+
+// ECMA 12.3
+Completion EmptyStatementNode::execute()
+{
+  return Completion(Normal);
+}
+
+// ECMA 12.6.3
+Completion ForNode::execute()
+{
+  KJSO e, v, cval;
+  Boolean b;
+
+  if (expr1) {
+    e = expr1->evaluate();
+    v = e.getValue();
+  }
+  while (1) {
+    if (expr2) {
+      e = expr2->evaluate();
+      v = e.getValue();
+      b = v.toBoolean();
+      if (b.value() == false)
+	return Completion(Normal, cval);
+    }
+    // bail out on error
+    if (KJScriptImp::hadException())
+      return Completion(Throw, KJScriptImp::exception());
+
+    Completion c = stat->execute();
+    if (c.isValueCompletion())
+      cval = c.value();
+    if (!((c.complType() == Continue) && ls.contains(c.target()))) {
+      if ((c.complType() == Break) && ls.contains(c.target()))
+        return Completion(Normal, cval);
+      if (c.complType() != Normal)
+      return c;
+    }
+    if (expr3) {
+      e = expr3->evaluate();
+      v = e.getValue();
+    }
+  }
+}
+
+// ECMA 12.6.4
+Completion ForInNode::execute()
+{
+  KJSO e, v, retval;
+  Completion c;
+  VarDeclNode *vd = 0;
+  const PropList *lst, *curr;
+
+  // This should be done in the constructor
+  if (!lexpr) { // for( var foo = bar in baz )
+    vd = new VarDeclNode(&ident, init);
+    vd->evaluate();
+
+    lexpr = new ResolveNode(&ident);
+  }
+
+  e = expr->evaluate();
+  v = e.getValue().toObject();
+  curr = lst = v.imp()->propList();
+
+  while (curr) {
+    if (!v.hasProperty(curr->name)) {
+      curr = curr->next;
+      continue;
+    }
+
+    e = lexpr->evaluate();
+    e.putValue(String(curr->name));
+
+    c = stat->execute();
+    if (c.isValueCompletion())
+      retval = c.value();
+
+    if (!((c.complType() == Continue) && ls.contains(c.target()))) {
+      if ((c.complType() == Break) && ls.contains(c.target()))
+        break;
+      if (c.complType() != Normal) {
+        delete lst;
+        return c;
+      }
+    }
+
+    curr = curr->next;
+  }
+
+  delete lst;
+  return Completion(Normal, retval);
+}
+
+// ECMA 12.4
+Completion ExprStatementNode::execute()
+{
+  KJS_BREAKPOINT;
+
+  KJSO e = expr->evaluate();
+  KJSO v = e.getValue();
+
+  return Completion(Normal, v);
+}
+
+// ECMA 12.5
+Completion IfNode::execute()
+{
+  KJS_BREAKPOINT;
+
+  KJSO e = expr->evaluate();
+  KJSO v = e.getValue();
+  Boolean b = v.toBoolean();
+
+  // if ... then
+  if (b.value())
+    return statement1->execute();
+
+  // no else
+  if (!statement2)
+    return Completion(Normal);
+
+  // else
+  return statement2->execute();
+}
+
+// ECMA 12.6.1
+Completion DoWhileNode::execute()
+{
+  KJS_BREAKPOINT;
+
+  KJSO be, bv;
+  Completion c;
+  KJSO value;
+
+  do {
+    // bail out on error
+    if (KJScriptImp::hadException())
+      return Completion(Throw, KJScriptImp::exception());
+
+    c = statement->execute();
+    if (!((c.complType() == Continue) && ls.contains(c.target()))) {
+      if ((c.complType() == Break) && ls.contains(c.target()))
+        return Completion(Normal, value);
+      if (c.complType() != Normal)
+        return c;
+    }
+    be = expr->evaluate();
+    bv = be.getValue();
+  } while (bv.toBoolean().value());
+
+  return Completion(Normal, value);
+}
+
+// ECMA 12.6.2
+Completion WhileNode::execute()
+{
+  KJS_BREAKPOINT;
+
+  KJSO be, bv;
+  Completion c;
+  Boolean b(false);
+  KJSO value;
+
+  while (1) {
+    be = expr->evaluate();
+    bv = be.getValue();
+    b = bv.toBoolean();
+
+    // bail out on error
+    if (KJScriptImp::hadException())
+      return Completion(Throw, KJScriptImp::exception());
+
+    if (!b.value())
+      return Completion(Normal, value);
+
+    c = statement->execute();
+    if (c.isValueCompletion())
+      value = c.value();
+
+    if ((c.complType() == Continue) && ls.contains(c.target()))
+      continue;
+    if ((c.complType() == Break) && ls.contains(c.target()))
+      return Completion(Normal, value);
+    if (c.complType() != Normal)
+      return c;
+  }
+}
+
+// ECMA 12.7
+Completion ContinueNode::execute()
+{
+  KJS_BREAKPOINT;
+
+  KJSO dummy;
+  return Context::current()->seenLabels()->contains(ident) ?
+    Completion(Continue, dummy, ident) :
+    Completion(Throw,
+	       throwError(SyntaxError, "Label not found in containing block"));
+}
+
+// ECMA 12.8
+Completion BreakNode::execute()
+{
+  KJS_BREAKPOINT;
+
+  KJSO dummy;
+  return Context::current()->seenLabels()->contains(ident) ?
+    Completion(Break, dummy, ident) :
+    Completion(Throw,
+	       throwError(SyntaxError, "Label not found in containing block"));
+}
+
+// ECMA 12.9
+Completion ReturnNode::execute()
+{
+  KJS_BREAKPOINT;
+
+  if (!value)
+    return Completion(ReturnValue, Undefined());
+
+  KJSO e = value->evaluate();
+  KJSO v = e.getValue();
+
+  return Completion(ReturnValue, v);
+}
+
+// ECMA 12.10
+Completion WithNode::execute()
+{
+  KJS_BREAKPOINT;
+
+  KJSO e = expr->evaluate();
+  KJSO v = e.getValue();
+  Object o = v.toObject();
+  Context::current()->pushScope(o);
+  Completion res = stat->execute();
+  Context::current()->popScope();
+
+  return res;
+}
+
+// ECMA 12.11
+ClauseListNode* ClauseListNode::append(CaseClauseNode *c)
+{
+  ClauseListNode *l = this;
+  while (l->nx)
+    l = l->nx;
+  l->nx = new ClauseListNode(c);
+
+  return this;
+}
+
+// ECMA 12.11
+Completion SwitchNode::execute()
+{
+  KJS_BREAKPOINT;
+
+  KJSO e = expr->evaluate();
+  KJSO v = e.getValue();
+  Completion res = block->evalBlock(v);
+
+  if ((res.complType() == Break) && ls.contains(res.target()))
+    return Completion(Normal, res.value());
+  else
+    return res;
+}
+
+// ECMA 12.11
+Completion CaseBlockNode::evalBlock(const KJSO& input)
+{
+  KJSO v;
+  Completion res;
+  ClauseListNode *a = list1, *b = list2;
+  CaseClauseNode *clause;
+
+  if (a) {
+    while (a) {
+      clause = a->clause();
+      a = a->next();
+      v = clause->evaluate();
+      if (strictEqual(input, v)) {
+	res = clause->evalStatements();
+	if (res.complType() != Normal)
+	  return res;
+	while (a) {
+	  res = a->clause()->evalStatements();
+	  if (res.complType() != Normal)
+	    return res;
+	  a = a->next();
+	}
+	break;
+      }
+    }
+  }
+
+  while (b) {
+    clause = b->clause();
+    b = b->next();
+    v = clause->evaluate();
+    if (strictEqual(input, v)) {
+      res = clause->evalStatements();
+      if (res.complType() != Normal)
+	return res;
+      goto step18;
+    }
+  }
+
+  // default clause
+  if (def) {
+    res = def->evalStatements();
+    if (res.complType() != Normal)
+      return res;
+  }
+  b = list2;
+ step18:
+  while (b) {
+    clause = b->clause();
+    res = clause->evalStatements();
+    if (res.complType() != Normal)
+      return res;
+    b = b->next();
+  }
+
+  return Completion(Normal);
+}
+
+// ECMA 12.11
+KJSO CaseClauseNode::evaluate()
+{
+  KJSO e = expr->evaluate();
+  KJSO v = e.getValue();
+
+  return v;
+}
+
+// ECMA 12.11
+Completion CaseClauseNode::evalStatements()
+{
+  if (list)
+    return list->execute();
+  else
+    return Completion(Normal, Undefined());
+}
+
+// ECMA 12.12
+Completion LabelNode::execute()
+{
+  Completion e;
+
+  if (!Context::current()->seenLabels()->push(label)) {
+    return Completion( Throw,
+		       throwError(SyntaxError, "Duplicated label found" ));
+  };
+  e = stat->execute();
+  Context::current()->seenLabels()->pop();
+
+  if ((e.complType() == Break) && (e.target() == label))
+    return Completion(Normal, e.value());
+  else
+    return e;
+}
+
+// ECMA 12.13
+Completion ThrowNode::execute()
+{
+  KJS_BREAKPOINT;
+
+  KJSO v = expr->evaluate().getValue();
+
+  return Completion(Throw, v);
+}
+
+// ECMA 12.14
+Completion TryNode::execute()
+{
+  KJS_BREAKPOINT;
+
+  Completion c, c2;
+
+  c = block->execute();
+
+  if (!_final) {
+    if (c.complType() != Throw)
+      return c;
+    return _catch->execute(c.value());
+  }
+
+  if (!_catch) {
+    c2 = _final->execute();
+    return (c2.complType() == Normal) ? c : c2;
+  }
+
+  if (c.complType() == Throw)
+    c = _catch->execute(c.value());
+
+  c2 = _final->execute();
+  return (c2.complType() == Normal) ? c : c2;
+}
+
+Completion CatchNode::execute()
+{
+  // should never be reached. execute(const KJS &arg) is used instead
+  assert(0L);
+  return Completion();
+}
+
+// ECMA 12.14
+Completion CatchNode::execute(const KJSO &arg)
+{
+  /* TODO: correct ? Not part of the spec */
+  KJScriptImp::clearException();
+
+  Object obj;
+  obj.put(ident, arg, DontDelete);
+  Context::current()->pushScope(obj);
+  Completion c = block->execute();
+  Context::current()->popScope();
+
+  return c;
+}
+
+// ECMA 12.14
+Completion FinallyNode::execute()
+{
+  return block->execute();
+}
+
+FunctionBodyNode::FunctionBodyNode(SourceElementsNode *s)
+  : source(s)
+{
+#ifdef KJS_DEBUGGER
+  setLoc(-1, -1);
+#endif
+}
+
+// ECMA 13 + 14 for ProgramNode
+Completion FunctionBodyNode::execute()
+{
+  /* TODO: workaround for empty body which I don't see covered by the spec */
+  if (!source)
+    return Completion(ReturnValue, Undefined());
+
+  source->processFuncDecl();
+
+  return source->execute();
+}
+
+// ECMA 13
+void FuncDeclNode::processFuncDecl()
+{
+  const List *sc = Context::current()->pScopeChain();
+  /* TODO: let this be an object with [[Class]] property "Function" */
+  FunctionImp *fimp = new DeclaredFunctionImp(ident, body, sc);
+  Function func(fimp); // protect from GC
+  fimp->put("prototype", Object::create(ObjectClass), DontDelete);
+
+  int plen = 0;
+  for(ParameterNode *p = param; p != 0L; p = p->nextParam(), plen++)
+    fimp->addParameter(p->ident());
+
+  fimp->setLength(plen);
+
+  Context::current()->variableObject().put(ident, func);
+}
+
+// ECMA 13
+KJSO FuncExprNode::evaluate()
+{
+  const List *sc = Context::current()->pScopeChain();
+  FunctionImp *fimp = new DeclaredFunctionImp(UString::null, body, sc->copy());
+  Function ret(fimp);
+
+  int plen = 0;
+  for(ParameterNode *p = param; p != 0L; p = p->nextParam(), plen++)
+    fimp->addParameter(p->ident());
+  fimp->setLength(plen);
+
+  return ret;
+}
+
+ParameterNode* ParameterNode::append(const UString *i)
+{
+  ParameterNode *p = this;
+  while (p->next)
+    p = p->next;
+
+  p->next = new ParameterNode(i);
+
+  return this;
+}
+
+// ECMA 13
+KJSO ParameterNode::evaluate()
+{
+  return Undefined();
+}
+
+void ProgramNode::deleteGlobalStatements()
+{
+  source->deleteStatements();
+}
+
+// ECMA 14
+Completion SourceElementsNode::execute()
+{
+  if (KJScriptImp::hadException())
+    return Completion(Throw, KJScriptImp::exception());
+
+  if (!elements)
+    return element->execute();
+
+  Completion c1 = elements->execute();
+  if (KJScriptImp::hadException())
+    return Completion(Throw, KJScriptImp::exception());
+  if (c1.complType() != Normal)
+    return c1;
+
+  Completion c2 = element->execute();
+  if (KJScriptImp::hadException())
+    return Completion(Throw, KJScriptImp::exception());
+
+  return c2;
+}
+
+// ECMA 14
+void SourceElementsNode::processFuncDecl()
+{
+  if (elements)
+    elements->processFuncDecl();
+
+  element->processFuncDecl();
+}
+
+void SourceElementsNode::deleteStatements()
+{
+  element->deleteStatements();
+
+  if (elements)
+    elements->deleteStatements();
+}
+
+// ECMA 14
+Completion SourceElementNode::execute()
+{
+  if (statement)
+    return statement->execute();
+
+  return Completion(Normal);
+}
+
+// ECMA 14
+void SourceElementNode::processFuncDecl()
+{
+  if (function)
+    function->processFuncDecl();
+}
+
+void SourceElementNode::deleteStatements()
+{
+  delete statement;
+}
+
+ArgumentListNode::ArgumentListNode(Node *e) : list(0L), expr(e) {}
+
+VarDeclNode::VarDeclNode(const UString *id, AssignExprNode *in)
+    : ident(*id), init(in) { }
+
+ArgumentListNode::ArgumentListNode(ArgumentListNode *l, Node *e) :
+    list(l), expr(e) {}
+
+ArgumentsNode::ArgumentsNode(ArgumentListNode *l) : list(l) {}
diff --git a/JavaScriptCore/kjs/nodes.h b/JavaScriptCore/kjs/nodes.h
new file mode 100644
index 0000000..223109a
--- /dev/null
+++ b/JavaScriptCore/kjs/nodes.h
@@ -0,0 +1,789 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _NODES_H_
+#define _NODES_H_
+
+#include "internal.h"
+#include "ustring.h"
+#include "object.h"
+#include "types.h"
+#include "debugger.h"
+
+namespace KJS {
+
+  class KJSO;
+  class RegExp;
+  class SourceElementsNode;
+  class ProgramNode;
+
+  enum Operator { OpEqual,
+		  OpEqEq,
+		  OpNotEq,
+		  OpStrEq,
+		  OpStrNEq,
+		  OpPlusEq,
+		  OpMinusEq,
+		  OpMultEq,
+		  OpDivEq,
+                  OpPlusPlus,
+		  OpMinusMinus,
+		  OpLess,
+		  OpLessEq,
+		  OpGreater,
+		  OpGreaterEq,
+		  OpAndEq,
+		  OpXOrEq,
+		  OpOrEq,
+		  OpModEq,
+                  OpAnd,
+                  OpOr,
+		  OpBitAnd,
+		  OpBitXOr,
+		  OpBitOr,
+		  OpLShift,
+		  OpRShift,
+		  OpURShift,
+		  OpIn,
+		  OpInstanceOf
+  };
+
+  class Node {
+  public:
+    Node();
+    virtual ~Node();
+    virtual KJSO evaluate() = 0;
+    int lineNo() const { return line; }
+    static Node *firstNode() { return first; }
+    static void setFirstNode(Node *n) { first = n; }
+    static void deleteAllNodes();
+#ifdef KJS_DEBUGGER
+    static bool setBreakpoint(Node *firstNode, int id, int line, bool set);
+    virtual bool setBreakpoint(int, int, bool) { return false; }
+#endif
+  protected:
+    KJSO throwError(ErrorType e, const char *msg);
+  private:
+    // disallow assignment and copy-construction
+    Node(const Node &);
+    Node& operator=(const Node&);
+    int line;
+    static  int nodeCount;
+    static Node *first;
+    Node *next, *prev;
+  };
+
+  class StatementNode : public Node {
+  public:
+#ifdef KJS_DEBUGGER
+    StatementNode() : l0(-1), l1(-1), sid(-1), breakPoint(false) { }
+    void setLoc(int line0, int line1);
+    int firstLine() const { return l0; }
+    int lastLine() const { return l1; }
+    int sourceId() const { return sid; }
+    bool hitStatement();
+    bool abortStatement();
+    virtual bool setBreakpoint(int id, int line, bool set);
+#endif
+    virtual Completion execute() = 0;
+    void pushLabel(const UString *id) {
+      if (id) ls.push(*id);
+    }
+  protected:
+    LabelStack ls;
+  private:
+    KJSO evaluate() { return Undefined(); }
+#ifdef KJS_DEBUGGER
+    int l0, l1;
+    int sid;
+    bool breakPoint;
+#endif
+  };
+
+  class NullNode : public Node {
+  public:
+    KJSO evaluate();
+  };
+
+  class BooleanNode : public Node {
+  public:
+    BooleanNode(bool v) : value(v) {}
+    KJSO evaluate();
+  private:
+    bool value;
+  };
+
+  class NumberNode : public Node {
+  public:
+    NumberNode(double v) : value(v) { }
+    KJSO evaluate();
+  private:
+    double value;
+  };
+
+  class StringNode : public Node {
+  public:
+    StringNode(const UString *v) { value = *v; }
+    KJSO evaluate();
+  private:
+    UString value;
+  };
+
+  class RegExpNode : public Node {
+  public:
+    RegExpNode(const UString &p, const UString &f)
+      : pattern(p), flags(f) { }
+    KJSO evaluate();
+  private:
+    UString pattern, flags;
+  };
+
+  class ThisNode : public Node {
+  public:
+    KJSO evaluate();
+  };
+
+  class ResolveNode : public Node {
+  public:
+    ResolveNode(const UString *s) : ident(*s) { }
+    KJSO evaluate();
+  private:
+    UString ident;
+  };
+
+  class GroupNode : public Node {
+  public:
+    GroupNode(Node *g) : group(g) { }
+    KJSO evaluate();
+  private:
+    Node *group;
+  };
+
+  class ElisionNode : public Node {
+  public:
+    ElisionNode(ElisionNode *e) : elision(e) { }
+    KJSO evaluate();
+  private:
+    ElisionNode *elision;
+  };
+
+  class ElementNode : public Node {
+  public:
+    ElementNode(ElisionNode *e, Node *n) : list(0l), elision(e), node(n) { }
+    ElementNode(ElementNode *l, ElisionNode *e, Node *n)
+      : list(l), elision(e), node(n) { }
+    KJSO evaluate();
+  private:
+    ElementNode *list;
+    ElisionNode *elision;
+    Node *node;
+  };
+
+  class ArrayNode : public Node {
+  public:
+    ArrayNode(ElisionNode *e) : element(0L), elision(e), opt(true) { }
+    ArrayNode(ElementNode *ele)
+      : element(ele), elision(0), opt(false) { }
+    ArrayNode(ElisionNode *eli, ElementNode *ele)
+      : element(ele), elision(eli), opt(true) { }
+    KJSO evaluate();
+  private:
+    ElementNode *element;
+    ElisionNode *elision;
+    bool opt;
+  };
+
+  class ObjectLiteralNode : public Node {
+  public:
+    ObjectLiteralNode(Node *l) : list(l) { }
+    KJSO evaluate();
+  private:
+    Node *list;
+  };
+
+  class PropertyValueNode : public Node {
+  public:
+    PropertyValueNode(Node *n, Node *a, Node *l = 0L)
+      : name(n), assign(a), list(l) { }
+    KJSO evaluate();
+  private:
+    Node *name, *assign, *list;
+  };
+
+  class PropertyNode : public Node {
+  public:
+    PropertyNode(double d) : numeric(d) { }
+    PropertyNode(const UString *s) : str(*s) { }
+    KJSO evaluate();
+  private:
+    double numeric;
+    UString str;
+  };
+
+  class AccessorNode1 : public Node {
+  public:
+    AccessorNode1(Node *e1, Node *e2) : expr1(e1), expr2(e2) {}
+    KJSO evaluate();
+  private:
+    Node *expr1;
+    Node *expr2;
+  };
+
+  class AccessorNode2 : public Node {
+  public:
+    AccessorNode2(Node *e, const UString *s) : expr(e), ident(*s) { }
+    KJSO evaluate();
+  private:
+    Node *expr;
+    UString ident;
+  };
+
+  class ArgumentListNode : public Node {
+  public:
+    ArgumentListNode(Node *e);
+    ArgumentListNode(ArgumentListNode *l, Node *e);
+    KJSO evaluate();
+    List *evaluateList();
+  private:
+    ArgumentListNode *list;
+    Node *expr;
+  };
+
+  class ArgumentsNode : public Node {
+  public:
+    ArgumentsNode(ArgumentListNode *l);
+    KJSO evaluate();
+    List *evaluateList();
+  private:
+    ArgumentListNode *list;
+  };
+
+  class NewExprNode : public Node {
+  public:
+    NewExprNode(Node *e) : expr(e), args(0L) {}
+    NewExprNode(Node *e, ArgumentsNode *a) : expr(e), args(a) {}
+    KJSO evaluate();
+  private:
+    Node *expr;
+    ArgumentsNode *args;
+  };
+
+  class FunctionCallNode : public Node {
+  public:
+    FunctionCallNode(Node *e, ArgumentsNode *a) : expr(e), args(a) {}
+    KJSO evaluate();
+#ifdef KJS_DEBUGGER
+    void steppingInto(bool in);
+    Debugger::Mode previousMode;
+#endif
+  private:
+    Node *expr;
+    ArgumentsNode *args;
+  };
+
+  class PostfixNode : public Node {
+  public:
+    PostfixNode(Node *e, Operator o) : expr(e), oper(o) {}
+    KJSO evaluate();
+  private:
+    Node *expr;
+    Operator oper;
+  };
+
+  class DeleteNode : public Node {
+  public:
+    DeleteNode(Node *e) : expr(e) {}
+    KJSO evaluate();
+  private:
+    Node *expr;
+  };
+
+  class VoidNode : public Node {
+  public:
+    VoidNode(Node *e) : expr(e) {}
+    KJSO evaluate();
+  private:
+    Node *expr;
+  };
+
+  class TypeOfNode : public Node {
+  public:
+    TypeOfNode(Node *e) : expr(e) {}
+    KJSO evaluate();
+  private:
+    Node *expr;
+  };
+
+  class PrefixNode : public Node {
+  public:
+    PrefixNode(Operator o, Node *e) : oper(o), expr(e) {}
+    KJSO evaluate();
+  private:
+    Operator oper;
+    Node *expr;
+  };
+
+  class UnaryPlusNode : public Node {
+  public:
+    UnaryPlusNode(Node *e) : expr(e) {}
+    KJSO evaluate();
+  private:
+    Node *expr;
+  };
+
+  class NegateNode : public Node {
+  public:
+    NegateNode(Node *e) : expr(e) {}
+    KJSO evaluate();
+  private:
+    Node *expr;
+  };
+
+  class BitwiseNotNode : public Node {
+  public:
+    BitwiseNotNode(Node *e) : expr(e) {}
+    KJSO evaluate();
+  private:
+    Node *expr;
+  };
+
+  class LogicalNotNode : public Node {
+  public:
+    LogicalNotNode(Node *e) : expr(e) {}
+    KJSO evaluate();
+  private:
+    Node *expr;
+  };
+
+  class MultNode : public Node {
+  public:
+    MultNode(Node *t1, Node *t2, char op) : term1(t1), term2(t2), oper(op) {}
+    KJSO evaluate();
+  private:
+    Node *term1, *term2;
+    char oper;
+  };
+
+  class AddNode : public Node {
+  public:
+    AddNode(Node *t1, Node *t2, char op) : term1(t1), term2(t2), oper(op) {}
+    KJSO evaluate();
+  private:
+    Node *term1, *term2;
+    char oper;
+  };
+
+  class ShiftNode : public Node {
+  public:
+    ShiftNode(Node *t1, Operator o, Node *t2)
+      : term1(t1), term2(t2), oper(o) {}
+    KJSO evaluate();
+  private:
+    Node *term1, *term2;
+    Operator oper;
+  };
+
+  class RelationalNode : public Node {
+  public:
+    RelationalNode(Node *e1, Operator o, Node *e2) :
+      expr1(e1), expr2(e2), oper(o) {}
+    KJSO evaluate();
+  private:
+    Node *expr1, *expr2;
+    Operator oper;
+  };
+
+  class EqualNode : public Node {
+  public:
+    EqualNode(Node *e1, Operator o, Node *e2)
+      : expr1(e1), expr2(e2), oper(o) {}
+    KJSO evaluate();
+  private:
+    Node *expr1, *expr2;
+    Operator oper;
+  };
+
+  class BitOperNode : public Node {
+  public:
+    BitOperNode(Node *e1, Operator o, Node *e2) :
+      expr1(e1), expr2(e2), oper(o) {}
+    KJSO evaluate();
+  private:
+    Node *expr1, *expr2;
+    Operator oper;
+  };
+
+  class BinaryLogicalNode : public Node {
+  public:
+    BinaryLogicalNode(Node *e1, Operator o, Node *e2) :
+      expr1(e1), expr2(e2), oper(o) {}
+    KJSO evaluate();
+  private:
+    Node *expr1, *expr2;
+    Operator oper;
+  };
+
+  class ConditionalNode : public Node {
+  public:
+    ConditionalNode(Node *l, Node *e1, Node *e2) :
+      logical(l), expr1(e1), expr2(e2) {}
+    KJSO evaluate();
+  private:
+    Node *logical, *expr1, *expr2;
+  };
+
+  class AssignNode : public Node {
+  public:
+    AssignNode(Node *l, Operator o, Node *e) : left(l), oper(o), expr(e) {}
+    KJSO evaluate();
+  private:
+    Node *left;
+    Operator oper;
+    Node *expr;
+  };
+
+  class CommaNode : public Node {
+  public:
+    CommaNode(Node *e1, Node *e2) : expr1(e1), expr2(e2) {}
+    KJSO evaluate();
+  private:
+    Node *expr1, *expr2;
+  };
+
+  class StatListNode : public StatementNode {
+  public:
+    StatListNode(StatementNode *s) : statement(s), list(0L) { }
+    StatListNode(StatListNode *l, StatementNode *s) : statement(s), list(l) { }
+    Completion execute();
+  private:
+    StatementNode *statement;
+    StatListNode *list;
+  };
+
+  class AssignExprNode : public Node {
+  public:
+    AssignExprNode(Node *e) : expr(e) {}
+    KJSO evaluate();
+  private:
+    Node *expr;
+  };
+
+  class VarDeclNode : public Node {
+  public:
+    VarDeclNode(const UString *id, AssignExprNode *in);
+    KJSO evaluate();
+  private:
+    UString ident;
+    AssignExprNode *init;
+  };
+
+  class VarDeclListNode : public Node {
+  public:
+    VarDeclListNode(VarDeclNode *v) : list(0L), var(v) {}
+    VarDeclListNode(Node *l, VarDeclNode *v) : list(l), var(v) {}
+    KJSO evaluate();
+  private:
+    Node *list;
+    VarDeclNode *var;
+  };
+
+  class VarStatementNode : public StatementNode {
+  public:
+    VarStatementNode(VarDeclListNode *l) : list(l) {}
+    Completion execute();
+  private:
+    VarDeclListNode *list;
+  };
+
+  class BlockNode : public StatementNode {
+  public:
+    BlockNode(StatListNode *s) : statlist(s) {}
+    Completion execute();
+  private:
+    StatListNode *statlist;
+  };
+
+  class EmptyStatementNode : public StatementNode {
+  public:
+    EmptyStatementNode() { } // debug
+    Completion execute();
+  };
+
+  class ExprStatementNode : public StatementNode {
+  public:
+    ExprStatementNode(Node *e) : expr(e) { }
+    Completion execute();
+  private:
+    Node *expr;
+  };
+
+  class IfNode : public StatementNode {
+  public:
+    IfNode(Node *e, StatementNode *s1, StatementNode *s2)
+      : expr(e), statement1(s1), statement2(s2) {}
+    Completion execute();
+  private:
+    Node *expr;
+    StatementNode *statement1, *statement2;
+  };
+
+  class DoWhileNode : public StatementNode {
+  public:
+    DoWhileNode(StatementNode *s, Node *e) : statement(s), expr(e) {}
+    Completion execute();
+  private:
+    StatementNode *statement;
+    Node *expr;
+  };
+
+  class WhileNode : public StatementNode {
+  public:
+    WhileNode(Node *e, StatementNode *s) : expr(e), statement(s) {}
+    Completion execute();
+  private:
+    Node *expr;
+    StatementNode *statement;
+  };
+
+  class ForNode : public StatementNode {
+  public:
+    ForNode(Node *e1, Node *e2, Node *e3, StatementNode *s) :
+      expr1(e1), expr2(e2), expr3(e3), stat(s) {}
+    Completion execute();
+  private:
+    Node *expr1, *expr2, *expr3;
+    StatementNode *stat;
+  };
+
+  class ForInNode : public StatementNode {
+  public:
+    ForInNode(Node *l, Node *e, StatementNode *s) :
+      init(0L), lexpr(l), expr(e), stat(s) {}
+    ForInNode(const UString *i, AssignExprNode *in, Node *e, StatementNode *s)
+      : ident(*i), init(in), lexpr(0L), expr(e), stat(s) {}
+    Completion execute();
+  private:
+    UString ident;
+    AssignExprNode *init;
+    Node *lexpr, *expr;
+    StatementNode *stat;
+  };
+
+  class ContinueNode : public StatementNode {
+  public:
+    ContinueNode() { }
+    ContinueNode(const UString *i) : ident(*i) { }
+    Completion execute();
+  private:
+    UString ident;
+  };
+
+  class BreakNode : public StatementNode {
+  public:
+    BreakNode() { }
+    BreakNode(const UString *i) : ident(*i) { }
+    Completion execute();
+  private:
+    UString ident;
+  };
+
+  class ReturnNode : public StatementNode {
+  public:
+    ReturnNode(Node *v) : value(v) {}
+    Completion execute();
+  private:
+    Node *value;
+  };
+
+  class WithNode : public StatementNode {
+  public:
+    WithNode(Node *e, StatementNode *s) : expr(e), stat(s) {}
+    Completion execute();
+  private:
+    Node *expr;
+    StatementNode *stat;
+  };
+
+  class CaseClauseNode: public Node {
+  public:
+    CaseClauseNode(Node *e, StatListNode *l) : expr(e), list(l) { }
+    KJSO evaluate();
+    Completion evalStatements();
+  private:
+    Node *expr;
+    StatListNode *list;
+  };
+
+  class ClauseListNode : public Node {
+  public:
+    ClauseListNode(CaseClauseNode *c) : cl(c), nx(0L) { }
+    ClauseListNode* append(CaseClauseNode *c);
+    KJSO evaluate() { /* should never be called */ return KJSO(); }
+    CaseClauseNode *clause() const { return cl; }
+    ClauseListNode *next() const { return nx; }
+  private:
+    CaseClauseNode *cl;
+    ClauseListNode *nx;
+  };
+
+  class CaseBlockNode: public Node {
+  public:
+    CaseBlockNode(ClauseListNode *l1, CaseClauseNode *d, ClauseListNode *l2)
+      : list1(l1), def(d), list2(l2) { }
+    KJSO evaluate() { /* should never be called */ return KJSO(); }
+    Completion evalBlock(const KJSO& input);
+  private:
+    ClauseListNode *list1;
+    CaseClauseNode *def;
+    ClauseListNode *list2;
+  };
+
+  class SwitchNode : public StatementNode {
+  public:
+    SwitchNode(Node *e, CaseBlockNode *b) : expr(e), block(b) { }
+    Completion execute();
+  private:
+    Node *expr;
+    CaseBlockNode *block;
+  };
+
+  class LabelNode : public StatementNode {
+  public:
+    LabelNode(const UString *l, StatementNode *s) : label(*l), stat(s) { }
+    Completion execute();
+  private:
+    UString label;
+    StatementNode *stat;
+  };
+
+  class ThrowNode : public StatementNode {
+  public:
+    ThrowNode(Node *e) : expr(e) {}
+    Completion execute();
+  private:
+    Node *expr;
+  };
+
+  class CatchNode : public StatementNode {
+  public:
+    CatchNode(UString *i, StatementNode *b) : ident(*i), block(b) {}
+    Completion execute();
+    Completion execute(const KJSO &arg);
+  private:
+    UString ident;
+    StatementNode *block;
+  };
+
+  class FinallyNode : public StatementNode {
+  public:
+    FinallyNode(StatementNode *b) : block(b) {}
+    Completion execute();
+  private:
+    StatementNode *block;
+  };
+
+  class TryNode : public StatementNode {
+  public:
+    TryNode(StatementNode *b, Node *c = 0L, Node *f = 0L)
+      : block(b), _catch((CatchNode*)c), _final((FinallyNode*)f) {}
+    Completion execute();
+  private:
+    StatementNode *block;
+    CatchNode *_catch;
+    FinallyNode *_final;
+  };
+
+  class ParameterNode : public Node {
+  public:
+    ParameterNode(const UString *i) : id(*i), next(0L) { }
+    ParameterNode *append(const UString *i);
+    KJSO evaluate();
+    UString ident() { return id; }
+    ParameterNode *nextParam() { return next; }
+  private:
+    UString id;
+    ParameterNode *next;
+  };
+
+  // inherited by ProgramNode
+  class FunctionBodyNode : public StatementNode {
+  public:
+      FunctionBodyNode(SourceElementsNode *s);
+      Completion execute();
+  protected:
+      SourceElementsNode *source;
+  };
+
+  class FuncDeclNode : public StatementNode {
+  public:
+    FuncDeclNode(const UString *i, ParameterNode *p, FunctionBodyNode *b)
+      : ident(*i), param(p), body(b) { }
+    Completion execute() { /* empty */ return Completion(); }
+    void processFuncDecl();
+  private:
+    UString ident;
+    ParameterNode *param;
+    FunctionBodyNode *body;
+  };
+
+  class FuncExprNode : public Node {
+  public:
+    FuncExprNode(ParameterNode *p, FunctionBodyNode *b)
+	: param(p), body(b) { }
+    KJSO evaluate();
+  private:
+    ParameterNode *param;
+    FunctionBodyNode *body;
+  };
+
+  class SourceElementNode : public StatementNode {
+  public:
+    SourceElementNode(StatementNode *s) { statement = s; function = 0L; }
+    SourceElementNode(FuncDeclNode *f) { function = f; statement = 0L;}
+    Completion execute();
+    virtual void processFuncDecl();
+    void deleteStatements();
+  private:
+    StatementNode *statement;
+    FuncDeclNode *function;
+  };
+
+  class SourceElementsNode : public StatementNode {
+  public:
+    SourceElementsNode(SourceElementNode *s1) { element = s1; elements = 0L; }
+    SourceElementsNode(SourceElementsNode *s1, SourceElementNode *s2)
+      { elements = s1; element = s2; }
+    Completion execute();
+    virtual void processFuncDecl();
+    void deleteStatements();
+  private:
+    SourceElementNode *element;
+    SourceElementsNode *elements;
+  };
+
+  class ProgramNode : public FunctionBodyNode {
+  public:
+    ProgramNode(SourceElementsNode *s) : FunctionBodyNode(s) { }
+    void deleteGlobalStatements();
+  };
+
+}; // namespace
+
+#endif
diff --git a/JavaScriptCore/kjs/number_object.cpp b/JavaScriptCore/kjs/number_object.cpp
new file mode 100644
index 0000000..af37d48
--- /dev/null
+++ b/JavaScriptCore/kjs/number_object.cpp
@@ -0,0 +1,131 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "kjs.h"
+#include "operations.h"
+#include "number_object.h"
+
+using namespace KJS;
+
+NumberObject::NumberObject(const Object& funcProto, const Object &numProto)
+  : ConstructorImp(funcProto, 1)
+{
+  // Number.Prototype
+  setPrototypeProperty(numProto);
+}
+
+// ECMA 15.7.3
+KJSO NumberObject::get(const UString &p) const
+{
+  double d;
+
+  if (p == "NaN")
+    d = NaN;
+  else if (p == "NEGATIVE_INFINITY")
+    d = -Inf;
+  else if (p == "POSITIVE_INFINITY")
+    d = Inf;
+  else
+    return Imp::get(p);
+
+  return Number(d);
+}
+
+// ECMA 15.7.1
+Completion NumberObject::execute(const List &args)
+{
+  Number n;
+  if (args.isEmpty())
+    n = Number(0);
+  else
+    n = args[0].toNumber();
+
+  return Completion(ReturnValue, n);
+}
+
+// ECMA 15.7.2
+Object NumberObject::construct(const List &args)
+{
+  Number n;
+  if (args.isEmpty())
+    n = Number(0);
+  else
+    n = args[0].toNumber();
+
+  return Object::create(NumberClass, n);
+}
+
+class NumberProtoFunc : public InternalFunctionImp {
+public:
+  NumberProtoFunc(int i) : id (i) { }
+  Completion execute(const List &);
+  enum { ToString, ToLocaleString, ValueOf };
+private:
+  int id;
+};
+
+// ECMA 15.7.4.2 - 15.7.4.7
+Completion NumberProtoFunc::execute(const List &)
+{
+  KJSO result;
+
+  Object thisObj = Object::dynamicCast(thisValue());
+
+  // no generic function. "this" has to be a Number object
+  if (thisObj.isNull() || thisObj.getClass() != NumberClass) {
+    result = Error::create(TypeError);
+    return Completion(ReturnValue, result);
+  }
+
+  // execute "toString()" or "valueOf()", respectively
+  KJSO v = thisObj.internalValue();
+  switch (id) {
+  case ToString:
+  case ToLocaleString: /* TODO */
+    result = v.toString();
+    break;
+  case ValueOf:
+    result = v.toNumber();
+    break;
+  }
+
+  return Completion(ReturnValue, result);
+}
+
+// ECMA 15.7.4
+NumberPrototype::NumberPrototype(const Object& proto)
+  : ObjectImp(NumberClass, Number(0), proto)
+{
+  // The constructor will be added later in NumberObject's constructor
+}
+
+KJSO NumberPrototype::get(const UString &p) const
+{
+  int t;
+  if (p == "toString")
+    t = NumberProtoFunc::ToString;
+  else if (p == "toLocaleString")
+    t = NumberProtoFunc::ToLocaleString;
+  else if (p == "valueOf")
+    t = NumberProtoFunc::ValueOf;
+  else
+    return Imp::get(p);
+
+  return Function(new NumberProtoFunc(t));
+}
diff --git a/JavaScriptCore/kjs/number_object.h b/JavaScriptCore/kjs/number_object.h
new file mode 100644
index 0000000..3addbdf
--- /dev/null
+++ b/JavaScriptCore/kjs/number_object.h
@@ -0,0 +1,44 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _NUMBER_OBJECT_H_
+#define _NUMBER_OBJECT_H_
+
+#include "object.h"
+#include "function.h"
+
+namespace KJS {
+
+  class NumberObject : public ConstructorImp {
+  public:
+    NumberObject(const Object& funcProto, const Object &numProto);
+    virtual KJSO get(const UString &p) const;
+    Completion execute(const List &);
+    Object construct(const List &);
+  };
+
+  class NumberPrototype : public ObjectImp {
+  public:
+    NumberPrototype(const Object& proto);
+    virtual KJSO get(const UString &p) const;
+  };
+
+}; // namespace
+
+#endif
diff --git a/JavaScriptCore/kjs/object.cpp b/JavaScriptCore/kjs/object.cpp
new file mode 100644
index 0000000..adcc0fb
--- /dev/null
+++ b/JavaScriptCore/kjs/object.cpp
@@ -0,0 +1,1062 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#include "object.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#include "kjs.h"
+#include "types.h"
+#include "internal.h"
+#include "operations.h"
+#include "collector.h"
+#include "error_object.h"
+
+namespace KJS {
+
+#ifdef WORDS_BIGENDIAN
+  unsigned char NaN_Bytes[] = { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 };
+  unsigned char Inf_Bytes[] = { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 };
+#elif defined(arm)
+  unsigned char NaN_Bytes[] = { 0, 0, 0xf8, 0x7f, 0, 0, 0, 0 };
+  unsigned char Inf_Bytes[] = { 0, 0, 0xf0, 0x7f, 0, 0, 0, 0 };
+#else
+  unsigned char NaN_Bytes[] = { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f };
+  unsigned char Inf_Bytes[] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f };
+#endif
+
+  const double NaN = *(const double*) NaN_Bytes;
+  const double Inf = *(const double*) Inf_Bytes;
+  const double D16 = 65536.0;
+  const double D31 = 2147483648.0; 	/* TODO: remove in next version */
+  const double D32 = 4294967296.0;
+
+  // TODO: -0
+};
+
+using namespace KJS;
+
+const TypeInfo Imp::info = { "Imp", AbstractType, 0, 0, 0 };
+
+namespace KJS {
+  struct Property {
+    UString name;
+    Imp *object;
+    int attribute;
+    Property *next;
+  };
+}
+
+KJSO::KJSO()
+  : rep(0)
+{
+#ifdef KJS_DEBUG_MEM
+  count++;
+#endif
+}
+
+KJSO::KJSO(Imp *d)
+  : rep(d)
+{
+#ifdef KJS_DEBUG_MEM
+  count++;
+#endif
+
+  if (rep) {
+    rep->ref();
+    rep->setGcAllowed(true);
+  }
+}
+
+KJSO::KJSO(const KJSO &o)
+{
+#ifdef KJS_DEBUG_MEM
+  count++;
+#endif
+
+  rep = o.rep;
+  if (rep) {
+    rep->ref();
+    rep->setGcAllowed(true);
+  }
+}
+
+KJSO& KJSO::operator=(const KJSO &o)
+{
+  if (rep)
+    rep->deref();
+  rep = o.rep;
+  if (rep) {
+    rep->ref();
+    rep->setGcAllowed(true);
+  }
+
+  return *this;
+}
+
+KJSO::~KJSO()
+{
+#ifdef KJS_DEBUG_MEM
+  count--;
+#endif
+
+  if (rep)
+    rep->deref();
+}
+
+bool KJSO::isDefined() const
+{
+  return !isA(UndefinedType);
+}
+
+bool KJSO::isNull() const
+{
+  return !rep;
+}
+
+Type KJSO::type() const
+{
+#ifdef KJS_VERBOSE
+  if (!rep)
+    fprintf(stderr, "requesting type of null object\n");
+#endif
+
+  return rep ? rep->typeInfo()->type : UndefinedType;
+}
+
+bool KJSO::isObject() const
+{
+  return (type() >= ObjectType);
+}
+
+bool KJSO::isA(const char *s) const
+{
+  assert(rep);
+  const TypeInfo *info = rep->typeInfo();
+
+  if (!s || !info || !info->name)
+    return false;
+
+  if (info->type == HostType && strcmp(s, "HostObject") == 0)
+    return true;
+
+  return (strcmp(s, info->name) == 0);
+}
+
+bool KJSO::derivedFrom(const char *s) const
+{
+  if (!s)
+    return false;
+
+  assert(rep);
+  const TypeInfo *info = rep->typeInfo();
+  while (info) {
+    if (info->name && strcmp(s, info->name) == 0)
+      return true;
+    info = info->base;
+  }
+
+  return false;
+}
+
+KJSO KJSO::toPrimitive(Type preferred) const
+{
+  assert(rep);
+  return rep->toPrimitive(preferred);
+}
+
+Boolean KJSO::toBoolean() const
+{
+  assert(rep);
+  return rep->toBoolean();
+}
+
+Number KJSO::toNumber() const
+{
+  assert(rep);
+  return rep->toNumber();
+}
+
+// helper function for toInteger, toInt32, toUInt32 and toUInt16
+double KJSO::round() const
+{
+  if (isA(UndefinedType)) /* TODO: see below */
+    return 0.0;
+  Number n = toNumber();
+  if (n.value() == 0.0)   /* TODO: -0, NaN, Inf */
+    return 0.0;
+  double d = floor(fabs(n.value()));
+  if (n.value() < 0)
+    d *= -1;
+
+  return d;
+}
+
+// ECMA 9.4
+Number KJSO::toInteger() const
+{
+  return Number(round());
+}
+
+// ECMA 9.5
+int KJSO::toInt32() const
+{
+  double d = round();
+  double d32 = fmod(d, D32);
+
+  if (d32 >= D32 / 2.0)
+    d32 -= D32;
+
+  return static_cast<int>(d32);
+}
+
+// ECMA 9.6
+unsigned int KJSO::toUInt32() const
+{
+  double d = round();
+  double d32 = fmod(d, D32);
+
+  return static_cast<unsigned int>(d32);
+}
+
+// ECMA 9.7
+unsigned short KJSO::toUInt16() const
+{
+  double d = round();
+  double d16 = fmod(d, D16);
+
+  return static_cast<unsigned short>(d16);
+}
+
+String KJSO::toString() const
+{
+  assert(rep);
+  return rep->toString();
+}
+
+Object KJSO::toObject() const
+{
+  assert(rep);
+  if (isObject())
+    return Object(rep);
+
+  return rep->toObject();
+}
+
+bool KJSO::implementsCall() const
+{
+  return (type() == FunctionType ||
+	  type() == InternalFunctionType ||
+	  type() == ConstructorType ||
+	  type() == DeclaredFunctionType ||
+	  type() == AnonymousFunctionType);
+}
+
+// [[call]]
+KJSO KJSO::executeCall(const KJSO &thisV, const List *args)
+{
+  assert(rep);
+  assert(implementsCall());
+  return (static_cast<FunctionImp*>(rep))->executeCall(thisV.imp(), args);
+}
+
+KJSO KJSO::executeCall(const KJSO &thisV, const List *args, const List *extraScope) const
+{
+  assert(rep);
+  assert(implementsCall());
+  return (static_cast<FunctionImp*>(rep))->executeCall(thisV.imp(), args, extraScope);
+}
+
+void KJSO::setConstructor(KJSO c)
+{
+  put("constructor", c, DontEnum | DontDelete | ReadOnly);
+}
+
+// ECMA 8.7.1
+KJSO KJSO::getBase() const
+{
+  if (!isA(ReferenceType))
+    return Error::create(ReferenceError, I18N_NOOP("Invalid reference base"));
+
+  return ((ReferenceImp*)rep)->getBase();
+}
+
+// ECMA 8.7.2
+UString KJSO::getPropertyName() const
+{
+  if (!isA(ReferenceType))
+    // the spec wants a runtime error here. But getValue() and putValue()
+    // will catch this case on their own earlier. When returning a Null
+    // string we should be on the safe side.
+    return UString();
+
+  return ((ReferenceImp*)rep)->getPropertyName();
+}
+
+// ECMA 8.7.1
+KJSO KJSO::getValue() const
+{
+  if (!isA(ReferenceType)) {
+    return *this;
+  }
+  KJSO o = getBase();
+  if (o.isNull() || o.isA(NullType)) {
+    UString m = I18N_NOOP("Can't find variable: ") + getPropertyName();
+    return Error::create(ReferenceError, m.ascii());
+  }
+
+  return o.get(getPropertyName());
+}
+
+/* TODO: remove in next version */
+KJSO KJSO::getValue()
+{
+    return const_cast<const KJSO*>(this)->getValue();
+}
+
+// ECMA 8.7.2
+ErrorType KJSO::putValue(const KJSO& v)
+{
+  if (!isA(ReferenceType))
+    return ReferenceError;
+
+  KJSO o = getBase();
+  if (o.isA(NullType))
+    Global::current().put(getPropertyName(), v);
+  else {
+    // are we writing into an array ?
+    if (o.isA(ObjectType) && (o.toObject().getClass() == ArrayClass))
+      o.putArrayElement(getPropertyName(), v);
+    else
+      o.put(getPropertyName(), v);
+  }
+
+  return NoError;
+}
+
+void KJSO::setPrototype(const KJSO& p)
+{
+  assert(rep);
+  rep->setPrototype(p);
+}
+
+void KJSO::setPrototypeProperty(const KJSO& p)
+{
+  assert(rep);
+  put("prototype", p, DontEnum | DontDelete | ReadOnly);
+}
+
+KJSO KJSO::prototype() const
+{
+  if (rep)
+    return KJSO(rep->proto);
+  else
+    return KJSO();
+}
+
+// ECMA 8.6.2.1
+KJSO KJSO::get(const UString &p) const
+{
+  assert(rep);
+  return rep->get(p);
+}
+
+// ECMA 8.6.2.2
+void KJSO::put(const UString &p, const KJSO& v)
+{
+  assert(rep);
+  rep->put(p, v);
+}
+
+// ECMA 8.6.2.2
+void KJSO::put(const UString &p, const KJSO& v, int attr)
+{
+  static_cast<Imp*>(rep)->put(p, v, attr);
+}
+
+// provided for convenience.
+void KJSO::put(const UString &p, double d, int attr)
+{
+  put(p, Number(d), attr);
+}
+
+// provided for convenience.
+void KJSO::put(const UString &p, int i, int attr)
+{
+  put(p, Number(i), attr);
+}
+
+// provided for convenience.
+void KJSO::put(const UString &p, unsigned int u, int attr)
+{
+  put(p, Number(u), attr);
+}
+
+// ECMA 15.4.5.1
+void KJSO::putArrayElement(const UString &p, const KJSO& v)
+{
+  assert(rep);
+  rep->putArrayElement(p, v);
+}
+
+// ECMA 8.6.2.3
+bool KJSO::canPut(const UString &p) const
+{
+  assert(rep);
+  return rep->canPut(p);
+}
+
+// ECMA 8.6.2.4
+bool KJSO::hasProperty(const UString &p, bool recursive) const
+{
+  assert(rep);
+  return rep->hasProperty(p, recursive);
+}
+
+// ECMA 8.6.2.5
+bool KJSO::deleteProperty(const UString &p)
+{
+  assert(rep);
+  return rep->deleteProperty(p);
+}
+
+Object::Object(Imp *d) : KJSO(d) { }
+
+Object::Object(Class c) : KJSO(new ObjectImp(c)) { }
+
+Object::Object(Class c, const KJSO& v) : KJSO(new ObjectImp(c, v)) { }
+
+Object::Object(Class c, const KJSO& v, const Object& p)
+  : KJSO(new ObjectImp(c, v))
+{
+  setPrototype(p);
+}
+
+Object::~Object() { }
+
+void Object::setClass(Class c)
+{
+  static_cast<ObjectImp*>(rep)->cl = c;
+}
+
+Class Object::getClass() const
+{
+  assert(rep);
+  return static_cast<ObjectImp*>(rep)->cl;
+}
+
+void Object::setInternalValue(const KJSO& v)
+{
+  assert(rep);
+  static_cast<ObjectImp*>(rep)->val = v.imp();
+}
+
+KJSO Object::internalValue()
+{
+  assert(rep);
+  return KJSO(static_cast<ObjectImp*>(rep)->val);
+}
+
+Object Object::create(Class c)
+{
+  return Object::create(c, KJSO());
+}
+
+// factory
+Object Object::create(Class c, const KJSO& val)
+{
+  Global global(Global::current());
+  Object obj = Object();
+  obj.setClass(c);
+  obj.setInternalValue(val);
+
+  UString p = "[[";
+  switch (c) {
+  case UndefClass:
+  case ObjectClass:
+    p += "Object";
+    break;
+  case FunctionClass:
+    p += "Function";
+    break;
+  case ArrayClass:
+    p += "Array";
+    obj.put("length", Number(0), DontEnum | DontDelete);
+    break;
+  case StringClass:
+    p += "String";
+    obj.put("length", val.toString().value().size());
+    break;
+  case BooleanClass:
+    p += "Boolean";
+    break;
+  case NumberClass:
+    p += "Number";
+    break;
+  case DateClass:
+    p += "Date";
+    break;
+  case RegExpClass:
+    p += "RegExp";
+    break;
+  case ErrorClass:
+    p += "Error";
+    break;
+  }
+  p += ".prototype]]";
+
+  //  KJSO prot = global.get(p).get("prototype");
+  KJSO prot = global.get(p);
+  assert(prot.isDefined());
+
+  obj.setPrototype(prot);
+  return obj;
+}
+
+Object Object::create(Class c, const KJSO& val, const Object& p)
+{
+  Global global(Global::current());
+  Object obj = Object();
+  Object prot;
+  obj.setClass(c);
+  obj.setInternalValue(val);
+
+  prot = p;
+  obj.setPrototype(prot);
+  return obj;
+}
+
+Object Object::dynamicCast(const KJSO &obj)
+{
+  // return null object on type mismatch
+  if (!obj.isA(ObjectType))
+    return Object(0L);
+
+  return Object(obj.imp());
+
+}
+
+#ifdef KJS_DEBUG_MEM
+int KJSO::count = 0;
+int Imp::count = 0;
+int List::count = 0;
+#endif
+
+Imp::Imp()
+  : refcount(0), prop(0), proto(0)
+{
+  setCreated(true);
+#ifdef KJS_DEBUG_MEM
+  count++;
+#endif
+}
+
+Imp::~Imp()
+{
+#ifdef KJS_DEBUG_MEM
+  assert(Collector::collecting);
+  count--;
+#endif
+
+// dangling pointer during garbage collection !
+//   if (proto)
+//     proto->deref();
+
+  // delete attached properties
+  Property *tmp, *p = prop;
+  while (p) {
+    tmp = p;
+    p = p->next;
+    delete tmp;
+  }
+}
+
+KJSO Imp::toPrimitive(Type preferred) const
+{
+  return defaultValue(preferred);
+  /* TODO: is there still any need to throw a runtime error _here_ ? */
+}
+
+Boolean Imp::toBoolean() const
+{
+  return Boolean();
+}
+
+Number Imp::toNumber() const
+{
+  return Number();
+}
+
+String Imp::toString() const
+{
+  return String();
+}
+
+Object Imp::toObject() const
+{
+  return Object(Error::create(TypeError).imp());
+}
+
+
+PropList* Imp::propList(PropList *first, PropList *last, bool recursive) const
+{
+  Property *pr = prop;
+  while(pr) {
+    if (!(pr->attribute & DontEnum) && !first->contains(pr->name)) {
+      if(last) {
+        last->next = new PropList();
+	last = last->next;
+      } else {
+        first = new PropList();
+	last = first;
+      }
+      last->name = pr->name;
+    }
+    pr = pr->next;
+  }
+  if (proto && recursive)
+    proto->propList(first, last);
+
+  return first;
+}
+
+KJSO Imp::get(const UString &p) const
+{
+  Property *pr = prop;
+  while (pr) {
+    if (pr->name == p) {
+      return pr->object;
+    }
+    pr = pr->next;
+  }
+
+  if (!proto)
+    return Undefined();
+
+  return proto->get(p);
+}
+
+// may be overriden
+void Imp::put(const UString &p, const KJSO& v)
+{
+  put(p, v, None);
+}
+
+// ECMA 8.6.2.2
+void Imp::put(const UString &p, const KJSO& v, int attr)
+{
+  /* TODO: check for write permissions directly w/o this call */
+  // putValue() is used for JS assignemnts. It passes no attribute.
+  // Assume that a C++ implementation knows what it is doing
+  // and let it override the canPut() check.
+  if (attr == None && !canPut(p))
+    return;
+
+  Property *pr;
+
+  if (prop) {
+    pr = prop;
+    while (pr) {
+      if (pr->name == p) {
+	// replace old value
+	pr->object = v.imp();
+	pr->attribute = attr;
+	return;
+      }
+      pr = pr->next;
+    }
+  }
+
+  // add new property
+  pr = new Property;
+  pr->name = p;
+  pr->object = v.imp();
+  pr->attribute = attr;
+  pr->next = prop;
+  prop = pr;
+}
+
+// ECMA 8.6.2.3
+bool Imp::canPut(const UString &p) const
+{
+  if (prop) {
+    const Property *pr = prop;
+    while (pr) {
+      if (pr->name == p)
+	return !(pr->attribute & ReadOnly);
+      pr = pr->next;
+    }
+  }
+  if (!proto)
+    return true;
+
+  return proto->canPut(p);
+}
+
+// ECMA 8.6.2.4
+bool Imp::hasProperty(const UString &p, bool recursive) const
+{
+  const Property *pr = prop;
+  while (pr) {
+    if (pr->name == p)
+      return true;
+    pr = pr->next;
+  }
+
+  if (!proto || !recursive)
+    return false;
+
+  return proto->hasProperty(p);
+}
+
+// ECMA 8.6.2.5
+bool Imp::deleteProperty(const UString &p)
+{
+  Property *pr = prop;
+  Property **prev = &prop;
+  while (pr) {
+    if (pr->name == p) {
+      if ((pr->attribute & DontDelete))
+	return false;
+      *prev = pr->next;
+      delete pr;
+      return true;
+    }
+    prev = &(pr->next);
+    pr = pr->next;
+  }
+  return true;
+}
+
+// ECMA 15.4.5.1
+void Imp::putArrayElement(const UString &p, const KJSO& v)
+{
+  if (!canPut(p))
+    return;
+
+  if (hasProperty(p)) {
+    if (p == "length") {
+      KJSO len = get("length");
+      unsigned int oldLen = len.toUInt32();
+      unsigned int newLen = v.toUInt32();
+      // shrink array
+      for (unsigned int u = newLen; u < oldLen; u++) {
+	UString p = UString::from(u);
+	if (hasProperty(p, false))
+	  deleteProperty(p);
+      }
+      put("length", Number(newLen), DontEnum | DontDelete);
+      return;
+    }
+    //    put(p, v);
+    } //  } else
+    put(p, v);
+
+  // array index ?
+  unsigned int idx;
+  if (!sscanf(p.cstring().c_str(), "%u", &idx)) /* TODO */
+    return;
+
+  // do we need to update/create the length property ?
+  if (hasProperty("length", false)) {
+    KJSO len = get("length");
+    if (idx < len.toUInt32())
+      return;
+  }
+
+  put("length", Number(idx+1), DontDelete | DontEnum);
+}
+
+bool Imp::implementsCall() const
+{
+  return (type() == FunctionType ||
+	  type() == InternalFunctionType ||
+	  type() == ConstructorType ||
+	  type() == DeclaredFunctionType ||
+	  type() == AnonymousFunctionType);
+}
+
+// ECMA 8.6.2.6 (new draft)
+KJSO Imp::defaultValue(Type hint) const
+{
+  KJSO o;
+
+  /* TODO String on Date object */
+  if (hint != StringType && hint != NumberType)
+    hint = NumberType;
+
+  if (hint == StringType)
+    o = get("toString");
+  else
+    o = get("valueOf");
+
+  Imp *that = const_cast<Imp*>(this);
+  if (o.implementsCall()) { // spec says "not primitive type" but ...
+    FunctionImp *f = static_cast<FunctionImp*>(o.imp());
+    KJSO s = f->executeCall(that, 0L);
+    if (!s.isObject())
+      return s;
+  }
+
+  if (hint == StringType)
+    o = get("valueOf");
+  else
+    o = get("toString");
+
+  if (o.implementsCall()) {
+    FunctionImp *f = static_cast<FunctionImp*>(o.imp());
+    KJSO s = f->executeCall(that, 0L);
+    if (!s.isObject())
+      return s;
+  }
+
+  return Error::create(TypeError, I18N_NOOP("No default value"));
+}
+
+void Imp::mark(Imp*)
+{
+  setMarked(true);
+
+  if (proto && !proto->marked())
+    proto->mark();
+
+  struct Property *p = prop;
+  while (p) {
+    if (p->object && !p->object->marked())
+      p->object->mark();
+    p = p->next;
+  }
+}
+
+bool Imp::marked() const
+{
+  return prev;
+}
+
+void Imp::setPrototype(const KJSO& p)
+{
+  if (proto)
+    proto->deref();
+  proto = p.imp();
+  if (proto)
+    proto->ref();
+}
+
+void Imp::setPrototypeProperty(const KJSO &p)
+{
+  put("prototype", p, DontEnum | DontDelete | ReadOnly);
+}
+
+void Imp::setConstructor(const KJSO& c)
+{
+  put("constructor", c, DontEnum | DontDelete | ReadOnly);
+}
+
+void* Imp::operator new(size_t s)
+{
+  return Collector::allocate(s);
+}
+
+void Imp::operator delete(void*, size_t)
+{
+  // deprecated. a mistake.
+}
+
+void Imp::operator delete(void*)
+{
+  // Do nothing. So far.
+}
+
+void Imp::setMarked(bool m)
+{
+  prev = m ? this : 0L;
+}
+
+void Imp::setGcAllowed(bool a)
+{
+  next = this;
+  if (a)
+    next++;
+}
+
+bool Imp::gcAllowed() const
+{
+  return (next && next != this);
+}
+
+void Imp::setCreated(bool c)
+{
+  next = c ? this : 0L;
+}
+
+bool Imp::created() const
+{
+  return next;
+}
+
+ObjectImp::ObjectImp(Class c) : cl(c), val(0L) { }
+
+ObjectImp::ObjectImp(Class c, const KJSO &v) : cl(c), val(v.imp()) { }
+
+ObjectImp::ObjectImp(Class c, const KJSO &v, const KJSO &p)
+  : cl(c), val(v.imp())
+{
+  setPrototype(p);
+}
+
+ObjectImp::~ObjectImp() { }
+
+Boolean ObjectImp::toBoolean() const
+{
+  return Boolean(true);
+}
+
+Number ObjectImp::toNumber() const
+{
+  return toPrimitive(NumberType).toNumber();
+}
+
+String ObjectImp::toString() const
+{
+  KJSO tmp;
+  String res;
+
+  if (hasProperty("toString") && (tmp = get("toString")).implementsCall()) {
+    // TODO live w/o hack
+    res = tmp.executeCall(KJSO(const_cast<ObjectImp*>(this)), 0L).toString();
+  } else {
+    tmp = toPrimitive(StringType);
+    res = tmp.toString();
+  }
+
+  return res;
+}
+
+const TypeInfo ObjectImp::info = { "Object", ObjectType, 0, 0, 0 };
+
+Object ObjectImp::toObject() const
+{
+  return Object(const_cast<ObjectImp*>(this));
+}
+
+KJSO ObjectImp::toPrimitive(Type preferred) const
+{
+  // ### Imp already does that now. Remove in KDE 3.0.
+  return defaultValue(preferred);
+  /* TODO: is there still any need to throw a runtime error _here_ ? */
+}
+
+void ObjectImp::mark(Imp*)
+{
+  // mark objects from the base
+  Imp::mark();
+
+  // mark internal value, if any and it has not been visited yet
+  if (val && !val->marked())
+    val->mark();
+}
+
+HostImp::HostImp()
+{
+    setPrototype(Global::current().objectPrototype());
+    //printf("HostImp::HostImp() %p\n",this);
+}
+
+HostImp::~HostImp() { }
+
+Boolean HostImp::toBoolean() const
+{
+  return Boolean(true);
+}
+
+String HostImp::toString() const
+{
+  // Exact copy of ObjectImp::toString....
+  KJSO tmp;
+  String res;
+
+  if (hasProperty("toString") && (tmp = get("toString")).implementsCall()) {
+    // TODO live w/o hack
+    res = tmp.executeCall(KJSO(const_cast<HostImp*>(this)), 0L).toString();
+  } else {
+    tmp = toPrimitive(StringType);
+    res = tmp.toString();
+  }
+
+  return res;
+}
+
+const TypeInfo HostImp::info = { "HostObject", HostType, 0, 0, 0 };
+
+Object Error::createObject(ErrorType e, const char *m, int l)
+{
+  Context *context = Context::current();
+  if (!context)
+    return Object();
+
+  Object err = ErrorObject::create(e, m, l);
+
+  if (!KJScriptImp::hadException())
+    KJScriptImp::setException(err.imp());
+
+  const struct ErrorStruct {
+      ErrorType e;
+      const char *s;
+  } errtab[] = {
+      { GeneralError, I18N_NOOP("General error") },
+      { EvalError, I18N_NOOP("Evaluation error") },
+      { RangeError, I18N_NOOP("Range error") },
+      { ReferenceError, I18N_NOOP("Reference error") },
+      { SyntaxError, I18N_NOOP("Syntax error") },
+      { TypeError, I18N_NOOP("Type error") },
+      { URIError, I18N_NOOP("URI error") },
+      { (ErrorType)0, 0 }
+  };
+
+  const char *estr = I18N_NOOP("Unknown error");
+  const ErrorStruct *estruct = errtab;
+  while (estruct->e) {
+      if (estruct->e == e) {
+	  estr = estruct->s;
+	  break;
+      }
+      estruct++;
+  }
+
+#ifndef NDEBUG
+  const char *msg = err.get("message").toString().value().ascii();
+  if (l >= 0)
+      fprintf(stderr, "JS: %s at line %d. %s\n", estr, l, msg);
+  else
+      fprintf(stderr, "JS: %s. %s\n", estr, msg);
+#endif
+
+  return err;
+}
+
+KJSO Error::create(ErrorType e, const char *m, int l)
+{
+  return KJSO(createObject(e, m, l).imp());
+}
diff --git a/JavaScriptCore/kjs/object.h b/JavaScriptCore/kjs/object.h
new file mode 100644
index 0000000..7daee7e
--- /dev/null
+++ b/JavaScriptCore/kjs/object.h
@@ -0,0 +1,640 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2001 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _KJS_OBJECT_H_
+#define _KJS_OBJECT_H_
+
+#include <stdlib.h>
+
+#include "ustring.h"
+
+/**
+ * @short Main namespace
+ */
+namespace KJS {
+
+  /**
+   * Types of classes derived from KJSO
+   */
+  enum Type { // main types
+              AbstractType = 1,
+              UndefinedType,
+	      NullType,
+	      BooleanType,
+	      NumberType,
+	      StringType,
+	      ObjectType,
+	      HostType,
+	      ReferenceType,
+              CompletionType,
+	      // extended types
+	      FunctionType,
+	      InternalFunctionType,
+	      DeclaredFunctionType,
+	      AnonymousFunctionType,
+	      ConstructorType,
+	      ActivationType
+  };
+
+  /**
+   * Property attributes.
+   */
+  enum Attribute { None       = 0,
+		   ReadOnly   = 1 << 1,
+		   DontEnum   = 1 << 2,
+		   DontDelete = 1 << 3,
+		   Internal   = 1 << 4 };
+
+  /**
+   * Types of classes derived from @ref Object.
+   */
+  enum Class { UndefClass,
+	       ArrayClass,
+	       StringClass,
+	       BooleanClass,
+	       NumberClass,
+	       ObjectClass,
+	       DateClass,
+	       RegExpClass,
+	       ErrorClass,
+	       FunctionClass };
+
+  /**
+   * Completion types.
+   */
+  enum Compl { Normal, Break, Continue, ReturnValue, Throw };
+
+  /**
+   * Error codes.
+   */
+  enum ErrorType { NoError = 0,
+		   GeneralError,
+		   EvalError,
+		   RangeError,
+		   ReferenceError,
+		   SyntaxError,
+		   TypeError,
+		   URIError };
+
+  extern const double NaN;
+  extern const double Inf;
+
+  // forward declarations
+  class Imp;
+  class Boolean;
+  class Number;
+  class String;
+  class Object;
+  struct Property;
+  class PropList;
+  class List;
+
+  /**
+   * @short Type information.
+   */
+  struct TypeInfo {
+    /**
+     * A string denoting the type name. Example: "Number".
+     */
+    const char *name;
+    /**
+     * One of the @ref KJS::Type enums.
+     */
+    Type type;
+    /**
+     * Pointer to the type information of the base class.
+     * NULL if there is none.
+     */
+    const TypeInfo *base;
+    /**
+     * Additional specifier for your own use.
+     */
+    int extra;
+    /**
+     * Reserved for future extensions (internal).
+     */
+    void *dummy;
+  };
+
+  /**
+   * @short Main base class for every KJS object.
+   */
+  class KJSO {
+    friend class ElementNode;
+  public:
+    /**
+     * Constructor.
+     */
+    KJSO();
+    /**
+     * @internal
+     */
+    KJSO(Imp *d);
+    /**
+     * Copy constructor.
+     */
+    KJSO(const KJSO &);
+    /*
+     * Assignment operator
+     */
+    KJSO& operator=(const KJSO &);
+    /**
+     * Destructor.
+     */
+    virtual ~KJSO();
+    /**
+     * @return True if this object is null, i.e. if there is no data attached
+     * to this object. Don't confuse this with the Null object.
+     */
+    bool isNull() const;
+    /**
+     * @return True if this objects is of any other value than Undefined.
+     */
+    bool isDefined() const;
+    /**
+     * @return the type of the object. One of the @ref KJS::Type enums.
+     */
+    Type type() const;
+    /**
+     * Check whether object is of a certain type
+     * @param t type to check for
+     */
+    bool isA(Type t) const { return (type() == t); }
+    /**
+     * Check whether object is of a certain type. Allows checking of
+     * host objects, too.
+     * @param type name (Number, Boolean etc.)
+     */
+    bool isA(const char *s) const;
+    /**
+     * Use this method when checking for objects. It's safer than checking
+     * for a single object type with @ref isA().
+     */
+    bool isObject() const;
+    /**
+     * Examine the inheritance structure of this object.
+     * @param t Name of the base class.
+     * @return True if object is of type t or a derived from such a type.
+     */
+    bool derivedFrom(const char *s) const;
+
+    /**
+     * @return Conversion to primitive type (Undefined, Boolean, Number
+     * or String)
+     * @param preferred Optional hint. Either StringType or NumberType.
+     */
+    KJSO toPrimitive(Type preferred = UndefinedType) const; // ECMA 9.1
+    /**
+     * @return Conversion to Boolean type.
+     */
+    Boolean toBoolean() const; // ECMA 9.2
+    /**
+     * @return Conversion to Number type.
+     */
+    Number toNumber() const; // ECMA 9.3
+    /**
+     * @return Conversion to double. 0.0 if conversion failed.
+     */
+    double round() const;
+    /**
+     * @return Conversion to Number type containing an integer value.
+     */
+    Number toInteger() const; // ECMA 9.4
+    /**
+     * @return Conversion to signed integer value.
+     */
+    int toInt32() const; // ECMA 9.5
+    /**
+     * @return Conversion to unsigned integer value.
+     */
+    unsigned int toUInt32() const; // ECMA 9.6
+    /**
+     * @return Conversion to unsigned short value.
+     */
+    unsigned short toUInt16() const; // ECMA 9.7
+    /**
+     * @return Conversion to String type.
+     */
+    String toString() const; // ECMA 9.8
+    /**
+     * @return Conversion to Object type.
+     */
+    Object toObject() const; // ECMA 9.9
+
+    // Properties
+    /**
+     * Set the internal [[Prototype]] property of this object.
+     * @param p A prototype object.
+     */
+    void setPrototype(const KJSO &p);
+    /**
+     * Set the "prototype" property of this object. Different from
+     * the internal [[Prototype]] property.
+     * @param p A prototype object.
+     */
+    void setPrototypeProperty(const KJSO &p);
+    /**
+     * @return The internal [[prototype]] property.
+     */
+    KJSO prototype() const;
+    /**
+     * The internal [[Get]] method.
+     * @return The value of property p.
+     */
+    KJSO get(const UString &p) const;
+    /**
+     * The internal [[HasProperty]] method.
+     * @param p Property name.
+     * @param recursive Indicates whether prototypes are searched as well.
+     * @return Boolean value indicating whether the object already has a
+     * member with the given name p.
+     */
+    bool hasProperty(const UString &p, bool recursive = true) const;
+    /**
+     * The internal [[Put]] method. Sets the specified property to the value v.
+     * @param p Property name.
+     * @param v Value.
+     */
+    void put(const UString &p, const KJSO& v);
+    /**
+     * The internal [[CanPut]] method.
+     * @param p Property name.
+     * @return A boolean value indicating whether a [[Put]] operation with
+     * p succeed.
+     */
+    bool canPut(const UString &p) const;
+    /**
+     * The internal [[Delete]] method. Removes the specified property from
+     * the object.
+     * @param p Property name.
+     * @return True if the property was deleted successfully or didn't exist
+     * in the first place. False if the DontDelete attribute was set.
+     */
+    bool deleteProperty(const UString &p);
+    /**
+     * Same as above put() method except the additional attribute. Right now,
+     * this only works with native types as Host Objects don't reimplement
+     * this method.
+     * @param attr One of @ref KJS::Attribute.
+     */
+    void put(const UString &p, const KJSO& v, int attr);
+    /**
+     * Convenience function for adding a Number property constructed from
+     * a double value.
+     */
+    void put(const UString &p, double d, int attr = None);
+    /**
+     * Convenience function for adding a Number property constructed from
+     * an integer value.
+     */
+    void put(const UString &p, int i, int attr = None);
+    /**
+     * Convenience function for adding a Number property constructed from
+     * an unsigned integer value.
+     */
+    void put(const UString &p, unsigned int u, int attr = None);
+
+    /**
+     * Reference method.
+     * @return Reference base if object is a reference. Throws
+     * a ReferenceError otherwise.
+     */
+    KJSO getBase() const;
+    /**
+     * Reference method.
+     * @return Property name of a reference. Null string if object is not
+     * a reference.
+     */
+    UString getPropertyName() const;
+    /**
+     * Reference method.
+     * @return Referenced value. This object if no reference.
+     */
+    KJSO getValue() const;
+    KJSO getValue();  	/* TODO: remove in next version */
+    /**
+     * Reference method. Set referenced value to v.
+     */
+    ErrorType putValue(const KJSO& v);
+
+    /**
+     * @return True if object supports @ref executeCall() method. That's the
+     * case for all objects derived from FunctionType.
+     */
+    bool implementsCall() const;
+    /**
+     * Execute function implemented via the @ref Function::execute() method.
+     *
+     * Note: check availability via @ref implementsCall() beforehand.
+     * @param thisV Object serving as the 'this' value.
+     * @param args Pointer to the list of arguments or null.
+     * @return Result of the function call.
+     */
+    KJSO executeCall(const KJSO &thisV, const List *args);
+    KJSO executeCall(const KJSO &thisV, const List *args, const List *extraScope) const;
+
+    /**
+     * Set this object's constructor.
+     */
+    void setConstructor(KJSO c);
+
+    /**
+     * @return A Pointer to the internal implementation.
+     */
+    Imp *imp() const { return rep; }
+
+#ifdef KJS_DEBUG_MEM
+    /**
+     * @internal
+     */
+    static int count;
+#endif
+  protected:
+    /**
+     * Pointer to the internal implementation.
+     */
+    Imp *rep;
+
+  private:
+    void putArrayElement(const UString &p, const KJSO &v);
+  }; // end of KJSO
+
+  /**
+   * @short Base for all implementation classes.
+   */
+  class Imp {
+    friend class KJSO;
+    friend class Collector;
+    friend class ForInNode;
+    friend class Debugger;
+  public:
+    Imp();
+  public:
+    virtual KJSO toPrimitive(Type preferred = UndefinedType) const; // ECMA 9.1
+    virtual Boolean toBoolean() const; // ECMA 9.2
+    virtual Number toNumber() const; // ECMA 9.3
+    virtual String toString() const; // ECMA 9.8
+    virtual Object toObject() const; // ECMA 9.9
+
+    // properties
+    virtual KJSO get(const UString &p) const;
+    virtual bool hasProperty(const UString &p, bool recursive = true) const;
+    virtual void put(const UString &p, const KJSO& v);
+    void put(const UString &p, const KJSO& v, int attr);
+    virtual bool canPut(const UString &p) const;
+    virtual bool deleteProperty(const UString &p);
+    virtual KJSO defaultValue(Type hint) const;
+
+    bool implementsCall() const;
+
+    /**
+     * @internal Reserved for mark & sweep garbage collection
+     */
+    virtual void mark(Imp *imp = 0L);
+    bool marked() const;
+
+    Type type() const { return typeInfo()->type; }
+    /**
+     * @return The TypeInfo struct describing this object.
+     */
+    virtual const TypeInfo* typeInfo() const { return &info; }
+
+    void setPrototype(const KJSO& p);
+    Imp* prototype() const { return proto; }
+    void setPrototypeProperty(const KJSO &p);
+    void setConstructor(const KJSO& c);
+
+    void* operator new(size_t);
+    void operator delete(void*);
+    /**
+     * @deprecated
+     */
+    void operator delete(void*, size_t);
+
+#ifdef KJS_DEBUG_MEM
+    /**
+     * @internal
+     */
+    static int count;
+#endif
+  protected:
+    virtual ~Imp();
+  private:
+    Imp(const Imp&);
+    Imp& operator=(const Imp&);
+    void putArrayElement(const UString &p, const KJSO& v);
+
+    /**
+     * Get the property names for this object. To be used by for .. in loops
+     * @return The (pointer to the) first element of a PropList, to be deleted
+     * by the caller, or 0 if there are no enumerable properties
+     */
+    PropList *propList(PropList *first = 0L, PropList *last = 0L,
+		       bool recursive = true) const;
+
+  public:
+    // reference counting mechanism
+    inline Imp* ref() { refcount++; return this; }
+    inline bool deref() { return (!--refcount); }
+    unsigned int refcount;
+
+  private:
+    Property *prop;
+    Imp *proto;
+    static const TypeInfo info;
+
+    // reserved for memory managment - currently used as flags for garbage collection
+    // (prev != 0) = marked, (next != 0) = created, (next != this) = created and gc allowed
+    Imp *prev, *next;
+    // for future extensions
+    class ImpInternal;
+    ImpInternal *internal;
+
+    void setMarked(bool m);
+    void setGcAllowed(bool a);
+    bool gcAllowed() const;
+    void setCreated(bool c);
+    bool created() const;
+  };
+
+  /**
+   * @short General implementation class for Objects
+   */
+  class ObjectImp : public Imp {
+    friend class Object;
+  public:
+    ObjectImp(Class c);
+    ObjectImp(Class c, const KJSO &v);
+    ObjectImp(Class c, const KJSO &v, const KJSO &p);
+    virtual ~ObjectImp();
+    virtual KJSO toPrimitive(Type preferred = UndefinedType) const;
+    virtual Boolean toBoolean() const;
+    virtual Number toNumber() const;
+    virtual String toString() const;
+    virtual Object toObject() const;
+
+    virtual const TypeInfo* typeInfo() const { return &info; }
+    static const TypeInfo info;
+    /**
+     * @internal Reimplemenation of @ref Imp::mark().
+     */
+    virtual void mark(Imp *imp = 0L);
+  private:
+    Class cl;
+    Imp *val;
+  };
+
+  /**
+   * @short Object class encapsulating an internal value.
+   */
+  class Object : public KJSO {
+  public:
+    Object(Imp *d);
+    Object(Class c = UndefClass);
+    Object(Class c, const KJSO& v);
+    Object(Class c, const KJSO& v, const Object& p);
+    virtual ~Object();
+    void setClass(Class c);
+    Class getClass() const;
+    void setInternalValue(const KJSO& v);
+    KJSO internalValue();
+    static Object create(Class c);
+    static Object create(Class c, const KJSO& val);
+    static Object create(Class c, const KJSO& val, const Object &p);
+    static Object dynamicCast(const KJSO &obj);
+  };
+
+  /**
+   * @short Implementation base class for Host Objects.
+   */
+  class HostImp : public Imp {
+  public:
+    HostImp();
+    virtual ~HostImp();
+    virtual const TypeInfo* typeInfo() const { return &info; }
+
+    virtual Boolean toBoolean() const;
+    virtual String toString() const;
+
+    static const TypeInfo info;
+  };
+
+  class KJScriptImp;
+  /**
+   * The Global object represents the global namespace. It holds the native
+   * objects like String and functions like eval().
+   *
+   * It also serves as a container for variables created by the user, i.e.
+   * the statement
+   * <pre>
+   *   var i = 2;
+   * </pre>
+   * will basically perform a Global::current().put("i", Number(2)); operation.
+   *
+   * @short Unique global object containing initial native properties.
+   */
+  class Global : public Object {
+    friend class KJScriptImp;
+  public:
+    /**
+     * Constructs a Global object. This is done by the interpreter once and
+     * there should be no need to create an instance on your own. Usually,
+     * you'll just want to access the current instance.
+     * For example like this:
+     * <pre>
+     * Global global(Global::current());
+     * KJSO proto = global.objectPrototype();
+     * </pre>
+     */
+    Global();
+    /**
+     * Destruct the Global object.
+     */
+    virtual ~Global();
+    /**
+     * @return A reference to the Global object belonging to the current
+     * interpreter instance.
+     */
+    static Global current();
+    /**
+     * @return A handle to Object.prototype.
+     */
+    KJSO objectPrototype() const;
+    /**
+     * @return A handle to Function.prototype.
+     */
+    KJSO functionPrototype() const;
+    /**
+     * Set a filter object that will intercept all put() and get() calls
+     * to the global object. If this object returns Undefined on get() the
+     * request will be passed on the global object.
+     * @deprecated
+     */
+    void setFilter(const KJSO &f);
+    /**
+     * Return a handle to the filter object (see @ref setFilter()).
+     * Null if no filter has been installed.
+     * @deprecated
+     */
+    KJSO filter() const;
+    /**
+     * Returns the extra user data set for this global object. Null by default.
+     * Typical usage if you need to query any info related to the currently
+     * running interpreter:
+     *
+     *    MyMainWindow *m = (MyMainWindow*)Global::current().extra();
+     */
+    void *extra() const;
+    /**
+     * Set the extra user data for this global object. It's not used by the
+     * interpreter itself and can therefore be used to bind arbitrary data
+     * to each interpreter instance.
+     */
+    void setExtra(void *e);
+  private:
+    Global(void *);
+    void init();
+    void clear();
+  };
+
+  /**
+   * @short Factory methods for error objects.
+   */
+  class Error {
+  public:
+    /**
+     * Factory method for error objects. The error will be registered globally
+     * and the execution will continue as if a "throw" statement was
+     * encountered.
+     * @param e Type of error.
+     * @param m Optional error message.
+     * @param l Optional line number.
+     */
+    static KJSO create(ErrorType e, const char *m = 0, int l = -1);
+    /**
+     * Same as above except the different return type (which is not casted
+     * here).
+     */
+    static Object createObject(ErrorType e, const char *m = 0, int l = -1);
+  };
+
+}; // namespace
+
+#endif
diff --git a/JavaScriptCore/kjs/object_object.cpp b/JavaScriptCore/kjs/object_object.cpp
new file mode 100644
index 0000000..80f98ed
--- /dev/null
+++ b/JavaScriptCore/kjs/object_object.cpp
@@ -0,0 +1,152 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "kjs.h"
+#include "operations.h"
+#include "object_object.h"
+#include "types.h"
+#include <stdio.h>
+
+using namespace KJS;
+
+ObjectObject::ObjectObject(const Object &funcProto, const Object &objProto)
+    : ConstructorImp(funcProto, 1)
+{
+  // ECMA 15.2.3.1
+  setPrototypeProperty(objProto);
+}
+
+Completion ObjectObject::execute(const List &args)
+{
+  KJSO result;
+
+  List argList;
+  if (args.isEmpty()) {
+    result = construct(argList);
+  } else {
+    KJSO arg = args[0];
+    if (arg.isA(NullType) || arg.isA(UndefinedType)) {
+      argList.append(arg);
+      result = construct(argList);
+    } else
+      result = arg.toObject();
+  }
+  return Completion(ReturnValue, result);
+}
+
+// ECMA 15.2.2
+Object ObjectObject::construct(const List &args)
+{
+  // if no arguments have been passed ...
+  if (args.isEmpty())
+    return Object::create(ObjectClass);
+
+  KJSO arg = *args.begin();
+  Object obj = Object::dynamicCast(arg);
+  if (!obj.isNull()) {
+    /* TODO: handle host objects */
+    return obj;
+  }
+
+  switch (arg.type()) {
+  case StringType:
+  case BooleanType:
+  case NumberType:
+    return arg.toObject();
+  default:
+    assert(!"unhandled switch case in ObjectConstructor");
+  case NullType:
+  case UndefinedType:
+    return Object::create(ObjectClass);
+  }
+}
+
+ObjectPrototype::ObjectPrototype()
+  : ObjectImp(ObjectClass)
+{
+  // the spec says that [[Property]] should be `null'.
+  // Not sure if Null or C's NULL is needed.
+}
+
+bool ObjectPrototype::hasProperty(const UString &p, bool recursive) const
+{
+    if ( p == "toString" || p == "valueOf" )
+        return true;
+    return /*recursive &&*/ ObjectImp::hasProperty(p, recursive);
+}
+
+KJSO ObjectPrototype::get(const UString &p) const
+{
+  if (p == "toString")
+    return Function(new ObjectProtoFunc(ToString));
+  else if (p == "valueOf")
+    return Function(new ObjectProtoFunc(ValueOf));
+  else
+    return Imp::get(p);
+}
+
+ObjectProtoFunc::ObjectProtoFunc(int i)
+  : id(i)
+{
+}
+
+// ECMA 15.2.4.2 + 15.2.4.3
+Completion ObjectProtoFunc::execute(const List &)
+{
+  Object thisObj = Object::dynamicCast(thisValue());
+
+  /* TODO: what to do with non-objects. Is this possible at all ? */
+  // Yes, this happens with Host Object at least (David)
+  if (thisObj.isNull()) {
+    UString str = "[object ";
+    str += thisValue().isNull() ? "null" : thisValue().imp()->typeInfo()->name;
+    str += "]";
+    return Completion(ReturnValue, String(str));
+  }
+
+  // valueOf()
+  if (id == ObjectPrototype::ValueOf)
+    /* TODO: host objects*/
+    return Completion(ReturnValue, thisObj);
+
+  // toString()
+  UString str;
+  switch(thisObj.getClass()) {
+  case StringClass:
+    str = "[object String]";
+    break;
+  case BooleanClass:
+    str = "[object Boolean]";
+    break;
+  case NumberClass:
+    str = "[object Number]";
+    break;
+  case ObjectClass:
+  {
+    str = "[object ";
+    str += thisValue().isNull() ? "Object" : thisValue().imp()->typeInfo()->name;
+    str += "]";
+    break;
+  }
+  default:
+    str = "[undefined object]";
+  }
+
+  return Completion(ReturnValue, String(str));
+}
diff --git a/JavaScriptCore/kjs/object_object.h b/JavaScriptCore/kjs/object_object.h
new file mode 100644
index 0000000..7f8703e
--- /dev/null
+++ b/JavaScriptCore/kjs/object_object.h
@@ -0,0 +1,53 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _OBJECT_OBJECT_H_
+#define _OBJECT_OBJECT_H_
+
+#include "object.h"
+#include "function.h"
+
+namespace KJS {
+
+  class ObjectObject : public ConstructorImp {
+  public:
+    ObjectObject(const Object &funcProto, const Object &objProto);
+    Completion execute(const List &);
+    Object construct(const List &);
+  };
+
+  class ObjectPrototype : public ObjectImp {
+  public:
+    ObjectPrototype();
+    bool hasProperty(const UString &p, bool recursive) const;
+    KJSO get(const UString &p) const;
+    enum { ToString, ValueOf };
+  };
+
+  class ObjectProtoFunc : public InternalFunctionImp {
+  public:
+    ObjectProtoFunc(int i);
+    Completion execute(const List &);
+  private:
+    int id;
+  };
+
+}; // namespace
+
+#endif
diff --git a/JavaScriptCore/kjs/operations.cpp b/JavaScriptCore/kjs/operations.cpp
new file mode 100644
index 0000000..95e6022
--- /dev/null
+++ b/JavaScriptCore/kjs/operations.cpp
@@ -0,0 +1,224 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#ifndef HAVE_FLOAT_H   /* just for !Windows */
+#define HAVE_FLOAT_H 0
+#define HAVE_FUNC__FINITE 0
+#endif
+
+#include <stdio.h>
+#include <assert.h>
+#include <math.h>
+#include <stdlib.h>
+
+#ifndef HAVE_FUNC_ISINF
+#ifdef HAVE_IEEEFP_H
+#include <ieeefp.h>
+#endif
+#endif /* HAVE_FUNC_ISINF */
+
+#if HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+#include "object.h"
+#include "types.h"
+#include "operations.h"
+
+using namespace KJS;
+
+bool KJS::isNaN(double d)
+{
+#ifdef HAVE_FUNC_ISNAN
+  return isnan(d);
+#elif defined HAVE_FLOAT_H
+  return _isnan(d) != 0;
+#else
+  return !(d == d);
+#endif
+}
+
+bool KJS::isInf(double d)
+{
+#if defined(HAVE_FUNC_ISINF)
+  return isinf(d);
+#elif HAVE_FUNC_FINITE
+  return finite(d) == 0 && d == d;
+#elif HAVE_FUNC__FINITE
+  return _finite(d) == 0 && d == d;
+#else
+  return false;
+#endif
+}
+
+// ECMA 11.9.3
+bool KJS::equal(const KJSO& v1, const KJSO& v2)
+{
+  Type t1 = v1.type();
+  Type t2 = v2.type();
+
+  if (t1 == t2) {
+    if (t1 == UndefinedType || t1 == NullType)
+      return true;
+    if (t1 == NumberType)
+      return (v1.toNumber().value() == v2.toNumber().value()); /* TODO: NaN, -0 ? */
+    if (t1 == StringType)
+      return (v1.toString().value() == v2.toString().value());
+    if (t1 == BooleanType)
+      return (v1.toBoolean().value() == v2.toBoolean().value());
+    if (t1 == HostType) {
+	KJSO h1 = v1.get("[[==]]");
+	KJSO h2 = v2.get("[[==]]");
+	if (!h1.isA(UndefinedType) && !h2.isA(UndefinedType))
+	    return equal(h1, h2);
+    }
+    return (v1.imp() == v2.imp());
+  }
+
+  // different types
+  if ((t1 == NullType && t2 == UndefinedType) || (t1 == UndefinedType && t2 == NullType))
+    return true;
+  if (t1 == NumberType && t2 == StringType) {
+    Number n2 = v2.toNumber();
+    return equal(v1, n2);
+  }
+  if ((t1 == StringType && t2 == NumberType) || t1 == BooleanType) {
+    Number n1 = v1.toNumber();
+    return equal(n1, v2);
+  }
+  if (t2 == BooleanType) {
+    Number n2 = v2.toNumber();
+    return equal(v1, n2);
+  }
+  if ((t1 == StringType || t1 == NumberType) && t2 >= ObjectType) {
+    KJSO p2 = v2.toPrimitive();
+    return equal(v1, p2);
+  }
+  if (t1 >= ObjectType && (t2 == StringType || t2 == NumberType)) {
+    KJSO p1 = v1.toPrimitive();
+    return equal(p1, v2);
+  }
+
+  return false;
+}
+
+bool KJS::strictEqual(const KJSO &v1, const KJSO &v2)
+{
+  Type t1 = v1.type();
+  Type t2 = v2.type();
+
+  if (t1 != t2)
+    return false;
+  if (t1 == UndefinedType || t1 == NullType)
+    return true;
+  if (t1 == NumberType) {
+    double n1 = v1.toNumber().value();
+    double n2 = v2.toNumber().value();
+    if (isNaN(n1) || isNaN(n2))
+      return false;
+    if (n1 == n2)
+      return true;
+    /* TODO: +0 and -0 */
+    return false;
+  } else if (t1 == StringType) {
+    return v1.toString().value() == v2.toString().value();
+  } else if (t2 == BooleanType) {
+    return v1.toBoolean().value() == v2.toBoolean().value();
+  }
+  if (v1.imp() == v2.imp())
+    return true;
+  /* TODO: joined objects */
+
+  return false;
+}
+
+int KJS::relation(const KJSO& v1, const KJSO& v2)
+{
+  KJSO p1 = v1.toPrimitive(NumberType);
+  KJSO p2 = v2.toPrimitive(NumberType);
+
+  if (p1.isA(StringType) && p2.isA(StringType))
+    return p1.toString().value() < p2.toString().value() ? 1 : 0;
+
+  Number n1 = p1.toNumber();
+  Number n2 = p2.toNumber();
+  /* TODO: check for NaN */
+  if (n1.value() == n2.value())
+    return 0;
+  /* TODO: +0, -0 and Infinity */
+  return (n1.value() < n2.value());
+}
+
+double KJS::max(double d1, double d2)
+{
+  /* TODO: check for NaN */
+  return (d1 > d2) ? d1 : d2;
+}
+
+double KJS::min(double d1, double d2)
+{
+  /* TODO: check for NaN */
+  return (d1 < d2) ? d1 : d2;
+}
+
+// ECMA 11.6
+KJSO KJS::add(const KJSO &v1, const KJSO &v2, char oper)
+{
+  KJSO p1 = v1.toPrimitive();
+  KJSO p2 = v2.toPrimitive();
+
+  if ((p1.isA(StringType) || p2.isA(StringType)) && oper == '+') {
+    String s1 = p1.toString();
+    String s2 = p2.toString();
+
+    UString s = s1.value() + s2.value();
+
+    return String(s);
+  }
+
+  Number n1 = p1.toNumber();
+  Number n2 = p2.toNumber();
+
+  if (oper == '+')
+    return Number(n1.value() + n2.value());
+  else
+    return Number(n1.value() - n2.value());
+}
+
+// ECMA 11.5
+KJSO KJS::mult(const KJSO &v1, const KJSO &v2, char oper)
+{
+  Number n1 = v1.toNumber();
+  Number n2 = v2.toNumber();
+
+  double result;
+
+  if (oper == '*')
+    result = n1.value() * n2.value();
+  else if (oper == '/')
+    result = n1.value() / n2.value();
+  else
+    result = fmod(n1.value(), n2.value());
+
+  return Number(result);
+}
diff --git a/JavaScriptCore/kjs/operations.h b/JavaScriptCore/kjs/operations.h
new file mode 100644
index 0000000..d3b0246
--- /dev/null
+++ b/JavaScriptCore/kjs/operations.h
@@ -0,0 +1,67 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _KJS_OPERATIONS_H_
+#define _KJS_OPERATIONS_H_
+
+#include "object.h"
+
+namespace KJS {
+
+  /**
+   * @return True if d is not a number (platform support required).
+   */
+  bool isNaN(double d);
+  /**
+   * @return True if d is infinite (platform support required).
+   */
+  bool isInf(double d);
+  bool equal(const KJSO& v1, const KJSO& v2);
+  bool strictEqual(const KJSO &v1, const KJSO &v2);
+  /**
+   * This operator performs an abstract relational comparision of the two
+   * arguments that can be of arbitrary type. If possible, conversions to the
+   * string or number type will take place before the comparison.
+   *
+   * @return 1 if v1 is "less-than" v2, 0 if the relation is "greater-than-or-
+   * equal". -1 if the result is undefined.
+   */
+  int relation(const KJSO& v1, const KJSO& v2);
+  double max(double d1, double d2);
+  double min(double d1, double d2);
+  /**
+   * Additive operator. Either performs an addition or substraction of v1
+   * and v2.
+   * @param oper '+' or '-' for an addition or substraction, respectively.
+   * @return The result of the operation.
+   */
+  KJSO add(const KJSO &v1, const KJSO &v2, char oper);
+  /**
+   * Multiplicative operator. Either multiplies/divides v1 and v2 or
+   * calculates the remainder from an division.
+   * @param oper '*', '/' or '%' for a multiplication, division or
+   * modulo operation.
+   * @return The result of the operation.
+   */
+  KJSO mult(const KJSO &v1, const KJSO &v2, char oper);
+
+};
+
+#endif
diff --git a/JavaScriptCore/kjs/regexp.cpp b/JavaScriptCore/kjs/regexp.cpp
new file mode 100644
index 0000000..84368e7
--- /dev/null
+++ b/JavaScriptCore/kjs/regexp.cpp
@@ -0,0 +1,68 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2001 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdio.h>
+
+#include "object.h"
+#include "regexp.h"
+
+using namespace KJS;
+
+RegExp::RegExp(const UString &p, int f)
+ : pattern(p), flags(f)
+{
+#ifdef REG_EXTENDED    
+  regcomp(&preg, p.ascii(), REG_EXTENDED);
+#else
+  regcomp(&preg, p.ascii(), 0);  
+#endif  
+  /* TODO use flags, check for errors */
+}
+
+RegExp::~RegExp()
+{
+  /* TODO: is this really okay after an error ? */
+  regfree(&preg);
+}
+
+UString RegExp::match(const UString &s, int i, int *pos)
+{
+  regmatch_t rmatch[10];
+
+  if (i < 0)
+    i = 0;
+
+  if (i > s.size() || s.isNull() ||
+      regexec(&preg, s.ascii() + i, 10, rmatch, 0)) {
+    if (pos)
+      *pos = -1;
+    return UString::null;
+  }
+
+  if (pos)
+    *pos = rmatch[0].rm_so + i;
+  return s.substr(rmatch[0].rm_so + i, rmatch[0].rm_eo - rmatch[0].rm_so);
+}
+
+bool RegExp::test(const UString &s, int)
+{
+  int r = regexec(&preg, s.ascii(), 0, 0, 0);
+
+  return r == 0;
+}
diff --git a/JavaScriptCore/kjs/regexp.h b/JavaScriptCore/kjs/regexp.h
new file mode 100644
index 0000000..9a4b2b2
--- /dev/null
+++ b/JavaScriptCore/kjs/regexp.h
@@ -0,0 +1,56 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _KJS_REGEXP_H_
+#define _KJS_REGEXP_H_
+
+#include <sys/types.h>
+
+#include "config.h"
+
+#ifdef HAVE_PCREPOSIX
+#include <pcreposix.h>
+#else  // POSIX regex - not so good...
+extern "C" { // bug with some libc5 distributions
+#include <regex.h>
+}
+#endif //HAVE_PCREPOSIX
+
+#include "ustring.h"
+
+namespace KJS {
+
+  class RegExp {
+  public:
+    enum { None, Global, IgnoreCase, Multiline };
+    RegExp(const UString &p, int f = None);
+    ~RegExp();
+    UString match(const UString &s, int i = -1, int *pos = 0L);
+    bool test(const UString &s, int i = -1);
+  private:
+    const UString &pattern;
+    int flags;
+    regex_t preg;
+
+    RegExp();
+  };
+
+}; // namespace
+
+#endif
diff --git a/JavaScriptCore/kjs/regexp_object.cpp b/JavaScriptCore/kjs/regexp_object.cpp
new file mode 100644
index 0000000..b7e6b12
--- /dev/null
+++ b/JavaScriptCore/kjs/regexp_object.cpp
@@ -0,0 +1,146 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdio.h>
+
+#include "kjs.h"
+#include "operations.h"
+#include "types.h"
+#include "internal.h"
+#include "regexp.h"
+#include "regexp_object.h"
+
+using namespace KJS;
+
+RegExpObject::RegExpObject(const Object& funcProto, const Object &regProto)
+    : ConstructorImp(funcProto, 2)
+{
+  // ECMA 15.10.5.1 RegExp.prototype
+  setPrototypeProperty(regProto);
+}
+
+// ECMA 15.9.2
+Completion RegExpObject::execute(const List &)
+{
+  return Completion(ReturnValue, Undefined());
+}
+
+// ECMA 15.9.3
+Object RegExpObject::construct(const List &args)
+{
+  /* TODO: regexp arguments */
+  String p = args[0].toString();
+  String f = args[1].toString();
+  UString flags = f.value();
+
+  RegExpImp *dat = new RegExpImp();
+  Object obj(dat); // protect from GC
+
+  bool global = (flags.find("g") >= 0);
+  bool ignoreCase = (flags.find("i") >= 0);
+  bool multiline = (flags.find("m") >= 0);
+  /* TODO: throw an error on invalid flags */
+
+  dat->put("global", Boolean(global));
+  dat->put("ignoreCase", Boolean(ignoreCase));
+  dat->put("multiline", Boolean(multiline));
+
+  dat->put("source", String(p.value()));
+  dat->put("lastIndex", 0, DontDelete | DontEnum);
+
+  dat->setRegExp(new RegExp(p.value() /* TODO flags */));
+  obj.setClass(RegExpClass);
+  obj.setPrototype(Global::current().get("[[RegExp.prototype]]"));
+
+  return obj;
+}
+
+// ECMA 15.9.4
+RegExpPrototype::RegExpPrototype(const Object& proto)
+  : ObjectImp(RegExpClass, String(""), proto)
+{
+  // The constructor will be added later in RegExpObject's constructor
+}
+
+KJSO RegExpPrototype::get(const UString &p) const
+{
+  int id = -1;
+  if (p == "exec")
+    id = RegExpProtoFunc::Exec;
+  else if (p == "test")
+    id = RegExpProtoFunc::Test;
+  else if (p == "toString")
+    id = RegExpProtoFunc::ToString;
+
+  if (id >= 0)
+    return Function(new RegExpProtoFunc(id));
+  else
+    return Imp::get(p);
+}
+
+Completion RegExpProtoFunc::execute(const List &args)
+{
+  KJSO result;
+
+  Object thisObj = Object::dynamicCast(thisValue());
+
+  if (thisObj.getClass() != RegExpClass) {
+    result = Error::create(TypeError);
+    return Completion(ReturnValue, result);
+  }
+
+  RegExp *re = static_cast<RegExpImp*>(thisObj.imp())->regExp();
+  String s;
+  KJSO lastIndex, tmp;
+  UString str;
+  int length, i;
+  switch (id) {
+  case Exec:
+  case Test:
+    s = args[0].toString();
+    length = s.value().size();
+    lastIndex = thisObj.get("lastIndex");
+    i = lastIndex.toInt32();
+    tmp = thisObj.get("global");
+    if (tmp.toBoolean().value() == false)
+      i = 0;
+    if (i < 0 || i > length) {
+      thisObj.put("lastIndex", 0);
+      result = Null();
+      break;
+    }
+    str = re->match(s.value(), i);
+    if (id == Test) {
+      result = Boolean(str.size() != 0);
+      break;
+    }
+    /* TODO complete */
+    result = String(str);
+    break;
+  case ToString:
+    s = thisObj.get("source").toString();
+    str = "/";
+    str += s.value();
+    str += "/";
+    result = String(str);
+    break;
+  }
+
+  return Completion(ReturnValue, result);
+}
diff --git a/JavaScriptCore/kjs/regexp_object.h b/JavaScriptCore/kjs/regexp_object.h
new file mode 100644
index 0000000..a5af288
--- /dev/null
+++ b/JavaScriptCore/kjs/regexp_object.h
@@ -0,0 +1,52 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _REGEXP_OBJECT_H_
+#define _REGEXP_OBJECT_H_
+
+#include "object.h"
+#include "function.h"
+
+namespace KJS {
+
+  class RegExpObject : public ConstructorImp {
+  public:
+    RegExpObject(const Object& funcProto, const Object &regProto);
+    Completion execute(const List &);
+    Object construct(const List &);
+  };
+
+  class RegExpPrototype : public ObjectImp {
+  public:
+    RegExpPrototype(const Object& proto);
+    KJSO get(const UString &p) const;
+  };
+
+  class RegExpProtoFunc : public InternalFunctionImp {
+  public:
+    RegExpProtoFunc(int i) : id(i) { }
+    Completion execute(const List &);
+    enum { Exec, Test, ToString };
+  private:
+    int id;
+  };
+
+}; // namespace
+
+#endif
diff --git a/JavaScriptCore/kjs/string_object.cpp b/JavaScriptCore/kjs/string_object.cpp
new file mode 100644
index 0000000..8e088bc
--- /dev/null
+++ b/JavaScriptCore/kjs/string_object.cpp
@@ -0,0 +1,419 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2001 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "kjs.h"
+#include "operations.h"
+#include "types.h"
+#include "regexp.h"
+#include "string_object.h"
+#include <stdio.h>
+
+using namespace KJS;
+
+StringObject::StringObject(const Object &funcProto, const Object &stringProto)
+  : ConstructorImp(funcProto, 1)
+{
+  // ECMA 15.5.3.1 String.prototype
+  setPrototypeProperty(stringProto);
+}
+
+KJSO StringObject::get(const UString &p) const
+{
+  if (p == "fromCharCode")
+    return Function(new StringObjectFunc());
+  else
+    return Imp::get(p);
+}
+
+// ECMA 15.5.1
+Completion StringObject::execute(const List &args)
+{
+  KJSO v;
+  String s;
+
+  if (args.isEmpty())
+    s = String("");
+  else {
+    v = args[0];
+    s = v.toString();
+  }
+
+  return Completion(ReturnValue, s);
+}
+
+// ECMA 15.5.2
+Object StringObject::construct(const List &args)
+{
+  String s;
+  if (args.size() > 0)
+    s = args.begin()->toString();
+  else
+    s = String("");
+
+  return Object::create(StringClass, s);
+}
+
+// ECMA 15.5.3.2 fromCharCode()
+Completion StringObjectFunc::execute(const List &args)
+{
+  UString s;
+  if (args.size()) {
+    UChar *buf = new UChar[args.size()];
+    UChar *p = buf;
+    ListIterator it = args.begin();
+    while (it != args.end()) {
+      unsigned short u = it->toUInt16();
+      *p++ = UChar(u);
+      it++;
+    }
+    s = UString(buf, args.size(), false);
+  } else
+    s = "";
+
+  return Completion(ReturnValue, String(s));
+}
+
+// ECMA 15.5.4
+StringPrototype::StringPrototype(const Object& proto)
+  : ObjectImp(StringClass, String(""), proto)
+{
+  // The constructor will be added later in StringObject's constructor
+}
+
+KJSO StringPrototype::get(const UString &p) const
+{
+  int id;
+
+  if (p == "toString")
+    id = StringProtoFunc::ToString;
+  else if (p == "valueOf")
+    id = StringProtoFunc::ValueOf;
+  else if (p == "charAt")
+    id = StringProtoFunc::CharAt;
+  else if (p == "charCodeAt")
+    id = StringProtoFunc::CharCodeAt;
+  else if (p == "indexOf")
+    id = StringProtoFunc::IndexOf;
+  else if (p == "lastIndexOf")
+    id = StringProtoFunc::LastIndexOf;
+  else if (p == "match")
+    id = StringProtoFunc::Match;
+  else if (p == "replace")
+    id = StringProtoFunc::Replace;
+  else if (p == "search")
+    id = StringProtoFunc::Search;
+  else if (p == "split")
+    id = StringProtoFunc::Split;
+  else if (p == "substr")
+    id = StringProtoFunc::Substr;
+  else if (p == "substring")
+    id = StringProtoFunc::Substring;
+  else if (p == "toLowerCase")
+    id = StringProtoFunc::ToLowerCase;
+  else if (p == "toUpperCase")
+    id = StringProtoFunc::ToUpperCase;
+#ifndef KJS_PURE_ECMA
+  else if (p == "big")
+    id = StringProtoFunc::Big;
+  else if (p == "small")
+    id = StringProtoFunc::Small;
+  else if (p == "blink")
+    id = StringProtoFunc::Blink;
+  else if (p == "bold")
+    id = StringProtoFunc::Bold;
+  else if (p == "fixed")
+    id = StringProtoFunc::Fixed;
+  else if (p == "italics")
+    id = StringProtoFunc::Italics;
+  else if (p == "strike")
+    id = StringProtoFunc::Strike;
+  else if (p == "sub")
+    id = StringProtoFunc::Sub;
+  else if (p == "sup")
+    id = StringProtoFunc::Sup;
+  else if (p == "fontcolor")
+    id = StringProtoFunc::Fontcolor;
+  else if (p == "fontsize")
+    id = StringProtoFunc::Fontsize;
+  else if (p == "anchor")
+    id = StringProtoFunc::Anchor;
+  else if (p == "link")
+    id = StringProtoFunc::Link;
+#endif
+  else
+    return Imp::get(p);
+
+  return Function(new StringProtoFunc(id));
+}
+
+StringProtoFunc::StringProtoFunc(int i)
+  : id(i)
+{
+}
+
+// ECMA 15.5.4.2 - 15.5.4.20
+Completion StringProtoFunc::execute(const List &args)
+{
+  KJSO result;
+
+  Object thisObj = Object::dynamicCast(thisValue());
+
+  // toString and valueOf are no generic function.
+  if (id == ToString || id == ValueOf) {
+    if (thisObj.isNull() || thisObj.getClass() != StringClass) {
+      result = Error::create(TypeError);
+      return Completion(ReturnValue, result);
+    }
+  }
+
+  String s2;
+  Number n, m;
+  UString u, u2, u3;
+  int pos, p0, i;
+  double d, d2;
+  KJSO v = thisObj.internalValue();
+  String s = v.toString();
+  int len = s.value().size();
+  KJSO a0 = args[0];
+  KJSO a1 = args[1];
+
+  switch (id) {
+  case ToString:
+  case ValueOf:
+    result = v.toString();
+    break;
+  case CharAt:
+    n = a0.toInteger();
+    pos = (int) n.value();
+    if (pos < 0 || pos >= len)
+      u = "";
+    else
+      u = s.value().substr(pos, 1);
+    result = String(u);
+    break;
+  case CharCodeAt:
+    n = a0.toInteger();
+    pos = (int) n.value();
+    if (pos < 0 || pos >= len)
+      d = NaN;
+    else {
+      UChar c = s.value()[pos];
+      d = (c.high() << 8) + c.low();
+    }
+    result = Number(d);
+    break;
+  case IndexOf:
+    s2 = a0.toString();
+    if (a1.isA(UndefinedType))
+      pos = 0;
+    else
+      pos = a1.toInteger().intValue();
+    d = s.value().find(s2.value(), pos);
+    result = Number(d);
+    break;
+  case LastIndexOf:
+    s2 = a0.toString();
+    if (a1.isA(UndefinedType))
+      pos = len;
+    else
+      pos = a1.toInteger().intValue();
+    d = s.value().rfind(s2.value(), pos);
+    result = Number(d);
+    break;
+  case Match:
+  case Search:
+    u = s.value();
+    if (a0.isA(ObjectType) && a0.toObject().getClass() == RegExpClass) {
+      s2 = a0.get("source").toString();
+      RegExp reg(s2.value());
+      UString mstr = reg.match(u, -1, &pos);
+      if (id == Search) {
+        result = Number(pos);
+        break;
+      }
+      if (mstr.isNull()) {
+	result = Null();
+	break;
+      }
+      /* TODO return an array, with the matches, etc. */
+      result = String(mstr);
+    } else
+    {
+      printf("Match/Search. Argument is not a RegExp - returning Undefined\n");
+      result = Undefined(); // No idea what to do here
+    }
+    break;
+  case Replace:
+    /* TODO: this is just a hack to get the most common cases going */
+    u = s.value();
+    if (a0.isA(ObjectType) && a0.toObject().getClass() == RegExpClass) {
+      s2 = a0.get("source").toString();
+      RegExp reg(s2.value());
+      UString mstr = reg.match(u, -1, &pos);
+      len = mstr.size();
+    } else {
+      s2 = a0.toString();
+      u2 = s2.value();
+      pos = u.find(u2);
+      len = u2.size();
+    }
+    if (pos == -1)
+	result = s;
+    else {
+	u3 = u.substr(0, pos) + a1.toString().value() +
+	     u.substr(pos + len);
+	result = String(u3);
+    }
+    break;
+  case Split:
+    result = Object::create(ArrayClass);
+    u = s.value();
+    i = p0 = 0;
+    d = a1.isDefined() ? a1.toInteger().intValue() : -1; // optional max number
+    if (a0.isA(ObjectType) && Object(a0.imp()).getClass() == RegExpClass) {
+      RegExp reg(a0.get("source").toString().value());
+      if (u.isEmpty() && !reg.match(u, 0).isNull()) {
+	// empty string matched by regexp -> empty array
+	result.put("length", 0);
+	break;
+      }
+      int mpos;
+      pos = 0;
+      while (1) {
+	/* TODO: back references */
+	UString mstr = reg.match(u, pos, &mpos);
+	if (mpos < 0)
+	  break;
+	pos = mpos + (mstr.isEmpty() ? 1 : mstr.size());
+	if (mpos != p0 || !mstr.isEmpty()) {
+	  result.put(UString::from(i), String(u.substr(p0, mpos-p0)));
+	  p0 = mpos + mstr.size();
+	  i++;
+	}
+      }
+    } else if (a0.isDefined()) {
+      u2 = a0.toString().value();
+      if (u2.isEmpty()) {
+	if (u.isEmpty()) {
+	  // empty separator matches empty string -> empty array
+	  put("length", 0);
+	  break;
+	} else {
+	  while (i != d && i < u.size())
+	    result.put(UString::from(i++), String(u.substr(p0++, 1)));
+	}
+      } else {
+	while (i != d && (pos = u.find(u2, p0)) >= 0) {
+	  result.put(UString::from(i), String(u.substr(p0, pos-p0)));
+	  p0 = pos + u2.size();
+	  i++;
+	}
+      }
+    }
+    // add remaining string, if any
+    if (i != d && (p0 < len || i == 0))
+      result.put(UString::from(i++), String(u.substr(p0)));
+    result.put("length", i);
+    break;
+  case Substr:
+    n = a0.toInteger();
+    m = a1.toInteger();
+    if (n.value() >= 0)
+      d = n.value();
+    else
+      d = max(len + n.value(), 0);
+    if (a1.isA(UndefinedType))
+      d2 = len - d;
+    else
+      d2 = min(max(m.value(), 0), len - d);
+    result = String(s.value().substr((int)d, (int)d2));
+    break;
+  case Substring:
+    n = a0.toInteger();
+    m = a1.toInteger();
+    d = min(max(n.value(), 0), len);
+    if (a1.isA(UndefinedType))
+      d2 = len - d;
+    else {
+      d2 = min(max(m.value(), 0), len);
+      d2 = max(d2-d, 0);
+    }
+    result = String(s.value().substr((int)d, (int)d2));
+    break;
+  case ToLowerCase:
+    u = UString(s.value());
+    for (i = 0; i < len; i++)
+      u[i] = u[i].toLower();
+    result = String(u);
+    break;
+  case ToUpperCase:
+    u = UString(s.value());
+    for (i = 0; i < len; i++)
+      u[i] = u[i].toUpper();
+    result = String(u);
+    break;
+#ifndef KJS_PURE_ECMA
+  case Big:
+    result = String("<BIG>" + s.value() + "</BIG>");
+    break;
+  case Small:
+    result = String("<SMALL>" + s.value() + "</SMALL>");
+    break;
+  case Blink:
+    result = String("<BLINK>" + s.value() + "</BLINK>");
+    break;
+  case Bold:
+    result = String("<B>" + s.value() + "</B>");
+    break;
+  case Fixed:
+    result = String("<TT>" + s.value() + "</TT>");
+    break;
+  case Italics:
+    result = String("<I>" + s.value() + "</I>");
+    break;
+  case Strike:
+    result = String("<STRIKE>" + s.value() + "</STRIKE>");
+    break;
+  case Sub:
+    result = String("<SUB>" + s.value() + "</SUB>");
+    break;
+  case Sup:
+    result = String("<SUP>" + s.value() + "</SUP>");
+    break;
+  case Fontcolor:
+    result = String("<FONT COLOR=" + a0.toString().value() + ">"
+		    + s.value() + "</FONT>");
+    break;
+  case Fontsize:
+    result = String("<FONT SIZE=" + a0.toString().value() + ">"
+		    + s.value() + "</FONT>");
+    break;
+  case Anchor:
+    result = String("<a name=" + a0.toString().value() + ">"
+		    + s.value() + "</a>");
+    break;
+  case Link:
+    result = String("<a href=" + a0.toString().value() + ">"
+		    + s.value() + "</a>");
+    break;
+#endif
+  }
+
+  return Completion(ReturnValue, result);
+}
diff --git a/JavaScriptCore/kjs/string_object.h b/JavaScriptCore/kjs/string_object.h
new file mode 100644
index 0000000..5396750
--- /dev/null
+++ b/JavaScriptCore/kjs/string_object.h
@@ -0,0 +1,66 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _STRING_OBJECT_H_
+#define _STRING_OBJECT_H_
+
+#include "object.h"
+#include "function.h"
+
+namespace KJS {
+
+  class StringObject : public ConstructorImp {
+  public:
+    StringObject(const Object &funcProto, const Object &stringProto);
+    KJSO get(const UString &p) const;
+    Completion execute(const List &);
+    Object construct(const List &);
+  };
+
+  class StringObjectFunc : public InternalFunctionImp {
+  public:
+    Completion execute(const List &);
+  };
+
+  class StringPrototype : public ObjectImp {
+  public:
+    StringPrototype(const Object& proto);
+    KJSO get(const UString &p) const;
+  };
+
+  class StringProtoFunc : public InternalFunctionImp {
+  public:
+    StringProtoFunc(int i);
+    Completion execute(const List &);
+
+    enum { ToString, ValueOf, CharAt, CharCodeAt, IndexOf, LastIndexOf,
+	   Match, Replace, Search, Slice, Split,
+	   Substr, Substring, FromCharCode, ToLowerCase, ToUpperCase
+#ifndef KJS_PURE_ECMA
+	   , Big, Small, Blink, Bold, Fixed, Italics, Strike, Sub, Sup,
+	   Fontcolor, Fontsize, Anchor, Link
+#endif
+    };
+  private:
+    int id;
+  };
+
+}; // namespace
+
+#endif
diff --git a/JavaScriptCore/kjs/test.js b/JavaScriptCore/kjs/test.js
new file mode 100644
index 0000000..f5bbf5b
--- /dev/null
+++ b/JavaScriptCore/kjs/test.js
@@ -0,0 +1,29 @@
+var i = 0;
+
+function sum(a, b)
+{
+ debug("inside test()");
+ i = i + 1;
+ debug(a);
+ debug(b);
+ return a + b;
+}
+
+s = sum(10, sum(20, 30));
+debug("s = " + s);
+debug("i = " + i);
+
+var a = new Array(11, 22, 33, 44);
+a.length = 2;
+a[4] = 'apple';
+
+for(i = 0; i != a.length; i++)
+  debug("a[" + i + "] = " + a[i]);
+
+var b = new Boolean(1==1);
+b.toString=Object.prototype.toString;
+debug("b = " + b.toString());
+
+// regular expression
+rx = /b*c/;
+debug(rx.exec("abbbcd"));
diff --git a/JavaScriptCore/kjs/testkjs.cpp b/JavaScriptCore/kjs/testkjs.cpp
new file mode 100644
index 0000000..afb04b0
--- /dev/null
+++ b/JavaScriptCore/kjs/testkjs.cpp
@@ -0,0 +1,80 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+
+#include "kjs.h"
+
+#include "object.h"
+#include "types.h"
+#include "internal.h"
+
+int main(int argc, char **argv)
+{
+  // expecting a filename
+  if (argc < 2) {
+    fprintf(stderr, "You have to specify at least one filename\n");
+    return -1;
+  }
+
+  // create interpreter
+  KJScript *kjs = new KJScript();
+
+  // add debug() function
+  kjs->enableDebug();
+
+  const int BufferSize = 100000;
+  char code[BufferSize];
+
+  bool ret = true;
+  for (int i = 1; i < argc; i++) {
+    const char *file = argv[i];
+    FILE *f = fopen(file, "r");
+    if (!f) {
+      fprintf(stderr, "Error opening %s.\n", file);
+      return -1;
+    }
+    int num = fread(code, 1, BufferSize, f);
+    code[num] = '\0';
+    if(num >= BufferSize)
+      fprintf(stderr, "Warning: File may have been too long.\n");
+
+    // run
+    ret = ret && kjs->evaluate(code);
+    if (kjs->errorType() != 0)
+      printf("%s returned: %s\n", file, kjs->errorMsg());
+    else if (kjs->returnValue())
+      printf("returned a value\n");
+
+    fclose(f);
+  }
+
+  delete kjs;
+
+#ifdef KJS_DEBUG_MEM
+  printf("List::count = %d\n", KJS::List::count);
+  assert(KJS::List::count == 0);
+  printf("Imp::count = %d\n", KJS::Imp::count);
+  assert(KJS::Imp::count == 0);
+#endif
+
+  fprintf(stderr, "OK.\n");
+  return ret;
+}
diff --git a/JavaScriptCore/kjs/types.cpp b/JavaScriptCore/kjs/types.cpp
new file mode 100644
index 0000000..682e607
--- /dev/null
+++ b/JavaScriptCore/kjs/types.cpp
@@ -0,0 +1,299 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+
+#include "kjs.h"
+#include "object.h"
+#include "types.h"
+#include "internal.h"
+#include "operations.h"
+#include "nodes.h"
+
+using namespace KJS;
+
+Undefined::Undefined() : KJSO(UndefinedImp::staticUndefined) { }
+
+Undefined::~Undefined() { }
+
+Null::Null() : KJSO(NullImp::staticNull) { }
+
+Null::~Null() { }
+
+Boolean::Boolean(bool b)
+  : KJSO(b ? BooleanImp::staticTrue : BooleanImp::staticFalse)
+{
+}
+
+Boolean::Boolean(BooleanImp *i) : KJSO(i) { }
+
+Boolean::~Boolean() { }
+
+bool Boolean::value() const
+{
+  assert(rep);
+  return ((BooleanImp*)rep)->value();
+}
+
+Number::Number(int i)
+  : KJSO(new NumberImp(static_cast<double>(i))) { }
+
+Number::Number(unsigned int u)
+  : KJSO(new NumberImp(static_cast<double>(u))) { }
+
+Number::Number(double d)
+  : KJSO(new NumberImp(d)) { }
+
+Number::Number(long int l)
+  : KJSO(new NumberImp(static_cast<double>(l))) { }
+
+Number::Number(long unsigned int l)
+  : KJSO(new NumberImp(static_cast<double>(l))) { }
+
+Number::Number(NumberImp *i)
+  : KJSO(i) { }
+
+Number::~Number() { }
+
+double Number::value() const
+{
+  assert(rep);
+  return ((NumberImp*)rep)->value();
+}
+
+int Number::intValue() const
+{
+  assert(rep);
+  return (int)((NumberImp*)rep)->value();
+}
+
+bool Number::isNaN() const
+{
+  return KJS::isNaN(((NumberImp*)rep)->value());
+}
+
+bool Number::isInf() const
+{
+  return KJS::isInf(((NumberImp*)rep)->value());
+}
+
+String::String(const UString &s) : KJSO(new StringImp(UString(s))) { }
+
+String::String(StringImp *i) : KJSO(i) { }
+
+String::~String() { }
+
+UString String::value() const
+{
+  assert(rep);
+  return ((StringImp*)rep)->value();
+}
+
+Reference::Reference(const KJSO& b, const UString &p)
+  : KJSO(new ReferenceImp(b, p))
+{
+}
+
+Reference::~Reference()
+{
+}
+
+Completion::Completion(Imp *d) : KJSO(d) { }
+
+Completion::Completion(Compl c)
+  : KJSO(new CompletionImp(c, KJSO(), UString::null))
+{
+  if (c == Throw)
+    KJScriptImp::setException(new UndefinedImp());
+}
+
+Completion::Completion(Compl c, const KJSO& v, const UString &t)
+  : KJSO(new CompletionImp(c, v, t))
+{
+  if (c == Throw)
+    KJScriptImp::setException(v.imp());
+}
+
+Completion::~Completion() { }
+
+Compl Completion::complType() const
+{
+  assert(rep);
+  return ((CompletionImp*)rep)->completion();
+}
+
+bool Completion::isValueCompletion() const
+{
+  assert(rep);
+  return !((CompletionImp*)rep)->value().isNull();
+}
+
+KJSO Completion::value() const
+{
+  assert(isA(CompletionType));
+  return ((CompletionImp*)rep)->value();
+}
+
+UString Completion::target() const
+{
+  assert(rep);
+  return ((CompletionImp*)rep)->target();
+}
+
+ListIterator::ListIterator(const List &l)
+  : node(l.hook->next)
+{
+}
+
+List::List()
+{
+#ifdef KJS_DEBUG_MEM
+  count++;
+#endif
+
+  static KJSO *null = 0;
+  if (!null)
+     null = new KJSO();
+
+  hook = new ListNode(*null, 0L, 0L);
+  hook->next = hook;
+  hook->prev = hook;
+}
+
+List::~List()
+{
+#ifdef KJS_DEBUG_MEM
+  count--;
+#endif
+
+  clear();
+  delete hook;
+}
+
+void List::append(const KJSO& obj)
+{
+  ListNode *n = new ListNode(obj, hook->prev, hook);
+  hook->prev->next = n;
+  hook->prev = n;
+}
+
+void List::prepend(const KJSO& obj)
+{
+  ListNode *n = new ListNode(obj, hook, hook->next);
+  hook->next->prev = n;
+  hook->next = n;
+}
+
+void List::removeFirst()
+{
+  erase(hook->next);
+}
+
+void List::removeLast()
+{
+  erase(hook->prev);
+}
+
+void List::remove(const KJSO &obj)
+{
+  if (obj.isNull())
+    return;
+  ListNode *n = hook->next;
+  while (n != hook) {
+    if (n->member.imp() == obj.imp()) {
+      erase(n);
+      return;
+    }
+    n = n->next;
+  }
+}
+
+void List::clear()
+{
+  ListNode *n = hook->next;
+  while (n != hook) {
+    n = n->next;
+    delete n->prev;
+  }
+
+  hook->next = hook;
+  hook->prev = hook;
+}
+
+List *List::copy() const
+{
+  List *newList = new List();
+  ListIterator e = end();
+  ListIterator it = begin();
+
+  while(it != e) {
+    newList->append(*it);
+    ++it;
+  }
+
+  return newList;
+}
+
+void List::erase(ListNode *n)
+{
+  if (n != hook) {
+    n->next->prev = n->prev;
+    n->prev->next = n->next;
+    delete n;
+  }
+}
+
+int List::size() const
+{
+  int s = 0;
+  ListNode *node = hook;
+  while ((node = node->next) != hook)
+    s++;
+
+  return s;
+}
+
+KJSO List::at(int i) const
+{
+  if (i < 0 || i >= size())
+    return Undefined();
+
+  ListIterator it = begin();
+  int j = 0;
+  while ((j++ < i))
+    it++;
+
+  return *it;
+}
+
+List *List::emptyList = 0L;
+
+const List *List::empty()
+{
+  if (!emptyList)
+    emptyList = new List;
+#ifdef KJS_DEBUG_MEM
+  else
+    count++;
+#endif
+
+
+  return emptyList;
+}
diff --git a/JavaScriptCore/kjs/types.h b/JavaScriptCore/kjs/types.h
new file mode 100644
index 0000000..c1bfac6
--- /dev/null
+++ b/JavaScriptCore/kjs/types.h
@@ -0,0 +1,355 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _TYPES_H_
+#define _TYPES_H_
+
+#include "object.h"
+
+namespace KJS {
+
+  /**
+   * @short Handle for an Undefined type.
+   */
+  class Undefined : public KJSO {
+  public:
+    Undefined();
+    virtual ~Undefined();
+  };
+
+  /**
+   * @short Handle for a Null type.
+   */
+  class Null : public KJSO {
+  public:
+    Null();
+    virtual ~Null();
+  };
+
+  class BooleanImp;
+  class NumberImp;
+  class StringImp;
+
+  /**
+   * @short Handle for a Boolean type.
+   */
+  class Boolean : public KJSO {
+    friend class BooleanImp;
+  public:
+    Boolean(bool b = false);
+    virtual ~Boolean();
+    bool value() const;
+  private:
+    Boolean(BooleanImp *i);
+  };
+
+  /**
+   * @short Handle for a Number type.
+   *
+   * Number is a handle for a number value. @ref KJSO::toPrimitive(),
+   * @ref KJSO::toBoolean(), @ref KJSO::toNumber(), @ref KJSO::toString() and
+   * @ref KJSO::toString() are re-implemented internally according to the
+   * specification.
+   *
+   * Example usage:
+   * <pre>
+   * Number a(2), b(3.0), c; // c defaults to 0.0
+   *
+   * c = a.value() * b.value(); // c will be 6.0 now
+   *
+   * String s = c.toString(); // s holds "6"
+   * </pre>
+   *
+   * Note the following implementation detail: Internally, the value is stored
+   * as a double and will be casted from and to other types when needed.
+   * This won't be noticable within a certain range of values but might produce
+   * unpredictable results when crossing these limits. In case this turns out
+   * to be a real problem for an application we might have to extend this class
+   * to behave more intelligently.
+   */
+  class Number : public KJSO {
+    friend class NumberImp;
+  public:
+    /**
+     * Construct a Number type from an integer.
+     */
+    Number(int i);
+    /**
+     * Construct a Number type from an unsigned integer.
+     */
+    Number(unsigned int u);
+    /**
+     * Construct a Number type from a double.
+     */
+    Number(double d = 0.0);
+    /**
+     * Construct a Number type from a long int.
+     */
+    Number(long int l);
+    /**
+     * Construct a Number type from a long unsigned int.
+     */
+    Number(long unsigned int l);
+    /**
+     * Destructor.
+     */
+    virtual ~Number();
+    /**
+     * @return The internally stored value.
+     */
+    double value() const;
+    /**
+     * Convenience function.
+     * @return The internally stored value converted to an int.
+     */
+    int intValue() const;
+    /**
+     * @return True is this is not a number (NaN).
+     */
+    bool isNaN() const;
+    /**
+     * @return True if Number is either +Infinity or -Infinity.
+     */
+    bool isInf() const;
+  private:
+    Number(NumberImp *i);
+  };
+
+  /**
+   * @short Handle for a String type.
+   */
+  class String : public KJSO {
+    friend class StringImp;
+  public:
+    String(const UString &s = "");
+    virtual ~String();
+    UString value() const;
+  private:
+    String(StringImp *i);
+  };
+
+  /**
+   * Completion objects are used to convey the return status and value
+   * from functions.
+   *
+   * See @ref FunctionImp::execute()
+   *
+   * @see FunctionImp
+   *
+   * @short Handle for a Completion type.
+   */
+  class Completion : public KJSO {
+  public:
+    Completion(Imp *d = 0L);
+    Completion(Compl c);
+    Completion(Compl c, const KJSO& v, const UString &t = UString::null);
+    virtual ~Completion();
+    Compl complType() const;
+    bool isValueCompletion() const;
+    KJSO value() const;
+    UString target() const;
+  };
+
+  class List;
+  class ListIterator;
+
+  /**
+   * @internal
+   */
+  class ListNode {
+    friend class List;
+    friend class ListIterator;
+    ListNode(KJSO obj, ListNode *p, ListNode *n)
+      : member(obj), prev(p), next(n) {};
+    KJSO member;
+    ListNode *prev, *next;
+  };
+
+  /**
+   * @short Iterator for @ref KJS::List objects.
+   */
+  class ListIterator {
+    friend class List;
+    ListIterator();
+    ListIterator(ListNode *n) : node(n) { }
+  public:
+    /**
+     * Construct an iterator that points to the first element of the list.
+     * @param l The list the iterator will operate on.
+     */
+    ListIterator(const List &list);
+    /**
+     * Assignment constructor.
+     */
+    ListIterator& operator=(const ListIterator &iterator)
+      { node=iterator.node; return *this; }
+    /**
+     * Copy constructor.
+     */
+    ListIterator(const ListIterator &i) : node(i.node) { }
+    /**
+     * Dereference the iterator.
+     * @return A pointer to the element the iterator operates on.
+     */
+    KJSO* operator->() const { return &node->member; }
+    //    operator KJSO* () const { return node->member; }
+    KJSO operator*() const { return node->member; }
+    /**
+     * Conversion to @ref KJS::KJSO*
+     * @return A pointer to the element the iterator operates on.
+     */
+    //    operator KJSO*() const { return node->member; }
+    /**
+     * Postfix increment operator.
+     * @return The element after the increment.
+     */
+    KJSO operator++() { node = node->next; return node->member; }
+    /**
+     * Prefix increment operator.
+     */
+    KJSO operator++(int) { const ListNode *n = node; ++*this; return n->member; }
+    /**
+     * Postfix decrement operator.
+     */
+    KJSO operator--() { node = node->prev; return node->member; }
+    /**
+     * Prefix decrement operator.
+     */
+    KJSO operator--(int) { const ListNode *n = node; --*this; return n->member; }
+    /**
+     * Compare the iterator with another one.
+     * @return True if the two iterators operate on the same list element.
+     * False otherwise.
+     */
+    bool operator==(const ListIterator &it) const { return (node==it.node); }
+    /**
+     * Check for inequality with another iterator.
+     * @return True if the two iterators operate on different list elements.
+     */
+    bool operator!=(const ListIterator &it) const { return (node!=it.node); }
+  private:
+    ListNode *node;
+  };
+
+  /**
+   * @short Native list type.
+   *
+   * List is a native ECMAScript type. List values are only used for
+   * intermediate results of expression evaluation and cannot be stored
+   * as properties of objects.
+   *
+   * The list is explicitly shared. Note that while copy() returns a deep
+   * copy of the list the referenced objects are still shared.
+   */
+  class List {
+    friend class ListIterator;
+  public:
+    /**
+     * Constructor.
+     */
+    List();
+    /**
+     * Destructor.
+     */
+    ~List();
+    /**
+     * Append an object to the end of the list.
+     *
+     * @param obj Pointer to object.
+     */
+    void append(const KJSO& obj);
+    /**
+     * Insert an object at the beginning of the list.
+     *
+     * @param obj Pointer to object.
+     */
+    void prepend(const KJSO& obj);
+    /**
+     * Remove the element at the beginning of the list.
+     */
+    void removeFirst();
+    /**
+     * Remove the element at the end of the list.
+     */
+    void removeLast();
+    /*
+     * Remove obj from list.
+     */
+    void remove(const KJSO &obj);
+    /**
+     * Remove all elements from the list.
+     */
+    void clear();
+    /**
+     * Returns a deep copy of the list. Ownership is passed to the user
+     * who is responsible for deleting the list then.
+     */
+    List *copy() const;
+    /**
+     * @return A @ref KJS::ListIterator pointing to the first element.
+     */
+    ListIterator begin() const { return ListIterator(hook->next); }
+    /**
+     * @return A @ref KJS::ListIterator pointing to the last element.
+     */
+    ListIterator end() const { return ListIterator(hook); }
+    /**
+     * @return true if the list is empty. false otherwise.
+     */
+    bool isEmpty() const { return (hook->prev == hook); }
+    /**
+     * @return the current size of the list.
+     */
+    int size() const;
+    /**
+     * Retrieve an element at an indexed position. If you want to iterate
+     * trough the whole list using @ref KJS::ListIterator will be faster.
+     *
+     * @param i List index.
+     * @return Return the element at position i. @ref KJS::Undefined if the
+     * index is out of range.
+     */
+    KJSO at(int i) const;
+    /**
+     * Equivalent to @ref at.
+     */
+    KJSO operator[](int i) const { return at(i); }
+    /**
+     * Returns a pointer to a static instance of an empty list. Useful if a
+     * function has a @ref KJS::List parameter.
+     */
+    static const List *empty();
+
+#ifdef KJS_DEBUG_MEM
+    /**
+     * @internal
+     */
+    static int count;
+#endif
+  private:
+    void erase(ListNode *n);
+    ListNode *hook;
+    static List *emptyList;
+  };
+
+}; // namespace
+
+
+#endif
diff --git a/JavaScriptCore/kjs/ustring.cpp b/JavaScriptCore/kjs/ustring.cpp
new file mode 100644
index 0000000..d547a04
--- /dev/null
+++ b/JavaScriptCore/kjs/ustring.cpp
@@ -0,0 +1,539 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
+#include "ustring.h"
+#include "operations.h"
+
+namespace KJS {
+  extern const double NaN;
+  extern const double Inf;
+};
+
+using namespace KJS;
+
+CString::CString(const char *c)
+{
+  data = new char[strlen(c)+1];
+  strcpy(data, c);
+}
+
+CString::CString(const CString &b)
+{
+  data = new char[b.size()+1];
+  strcpy(data, b.c_str());
+}
+
+CString::~CString()
+{
+  delete [] data;
+}
+
+CString &CString::append(const CString &t)
+{
+  char *n;
+  if (data) {
+    n = new char[strlen(data)+t.size()+1];
+    strcpy(n, data);
+  } else {
+    n = new char[t.size()+1];
+    n[0] = '\0';
+  }
+  strcat(n, t.c_str());
+
+  delete [] data;
+  data = n;
+
+  return *this;
+}
+
+CString &CString::operator=(const char *c)
+{
+  if (data)
+    delete [] data;
+  data = new char[strlen(c)+1];
+  strcpy(data, c);
+
+  return *this;
+}
+
+CString &CString::operator=(const CString &str)
+{
+  if (this == &str)
+    return *this;
+
+  if (data)
+    delete [] data;
+  data = new char[str.size()+1];
+  strcpy(data, str.c_str());
+
+  return *this;
+}
+
+CString &CString::operator+=(const CString &str)
+{
+  return append(str.c_str());
+}
+
+int CString::size() const
+{
+  return strlen(data);
+}
+
+bool KJS::operator==(const KJS::CString& c1, const KJS::CString& c2)
+{
+  return (strcmp(c1.c_str(), c2.c_str()) == 0);
+}
+
+UChar UChar::null;
+UString::Rep UString::Rep::null = { 0, 0, 1 };
+UString UString::null;
+static char *statBuffer = 0L;
+
+UChar::UChar(const UCharReference &c)
+#ifdef KJS_SWAPPED_CHAR
+  : lo(c.low()), hi(c.high())
+#else
+  : hi(c.high()), lo(c.low())
+#endif
+{
+}
+
+UChar UChar::toLower() const
+{
+  if (islower(lo) && hi == 0)
+    return *this;
+
+  return UChar(0, tolower(lo));
+}
+
+UChar UChar::toUpper() const
+{
+  if (isupper(lo) && hi == 0)
+    return *this;
+
+  return UChar(0, toupper(lo));
+}
+
+UCharReference& UCharReference::operator=(UChar c)
+{
+  str->detach();
+  if (offset < str->rep->len)
+    *(str->rep->dat + offset) = c;
+  /* TODO: lengthen string ? */
+  return *this;
+}
+
+UChar& UCharReference::ref() const
+{
+  if (offset < str->rep->len)
+    return *(str->rep->dat + offset);
+  else
+    return UChar::null;
+}
+
+UString::Rep *UString::Rep::create(UChar *d, int l)
+{
+  Rep *r = new Rep;
+  r->dat = d;
+  r->len = l;
+  r->rc = 1;
+
+  return r;
+}
+
+UString::UString()
+{
+  null.rep = &Rep::null;
+  attach(&Rep::null);
+}
+
+UString::UString(char c)
+{
+  rep = Rep::create(new UChar(0, c), 1);
+}
+
+UString::UString(const char *c)
+{
+  attach(&Rep::null);
+  operator=(c);
+}
+
+UString::UString(const UChar *c, int length)
+{
+  UChar *d = new UChar[length];
+  memcpy(d, c, length * sizeof(UChar));
+  rep = Rep::create(d, length);
+}
+
+UString::UString(UChar *c, int length, bool copy)
+{
+  UChar *d;
+  if (copy) {
+    d = new UChar[length];
+    memcpy(d, c, length * sizeof(UChar));
+  } else
+    d = c;
+  rep = Rep::create(d, length);
+}
+
+UString::UString(const UString &b)
+{
+  attach(b.rep);
+}
+
+UString::~UString()
+{
+  release();
+}
+
+UString UString::from(int i)
+{
+  char buf[40];
+  sprintf(buf, "%d", i);
+
+  return UString(buf);
+}
+
+UString UString::from(unsigned int u)
+{
+  char buf[40];
+  sprintf(buf, "%u", u);
+
+  return UString(buf);
+}
+
+UString UString::from(double d)
+{
+  char buf[40];
+  sprintf(buf, "%.16g", d);	// does the right thing
+  return UString(buf);
+}
+
+UString &UString::append(const UString &t)
+{
+  int l = size();
+  UChar *n = new UChar[l+t.size()];
+  memcpy(n, data(), l * sizeof(UChar));
+  memcpy(n+l, t.data(), t.size() * sizeof(UChar));
+  release();
+  rep = Rep::create(n, l + t.size());
+
+  return *this;
+}
+
+CString UString::cstring() const
+{
+  return CString(ascii());
+}
+
+char *UString::ascii() const
+{
+  if (statBuffer)
+    delete [] statBuffer;
+
+  statBuffer = new char[size()+1];
+  for(int i = 0; i < size(); i++)
+    statBuffer[i] = data()[i].lo;
+  statBuffer[size()] = '\0';
+
+  return statBuffer;
+}
+
+UString &UString::operator=(const char *c)
+{
+  release();
+  int l = c ? strlen(c) : 0;
+  UChar *d = new UChar[l];
+  for (int i = 0; i < l; i++)
+    d[i].lo = c[i];
+  rep = Rep::create(d, l);
+
+  return *this;
+}
+
+UString &UString::operator=(const UString &str)
+{
+  str.rep->ref();
+  release();
+  rep = str.rep;  
+
+  return *this;
+}
+
+UString &UString::operator+=(const UString &s)
+{
+  return append(s);
+}
+
+bool UString::is8Bit() const
+{
+  const UChar *u = data();
+  for(int i = 0; i < size(); i++, u++)
+    if (u->hi)
+      return false;
+
+  return true;
+}
+
+UChar UString::operator[](int pos) const
+{
+  if (pos >= size())
+    return UChar::null;
+
+  return ((UChar *)data())[pos];
+}
+
+UCharReference UString::operator[](int pos)
+{
+  /* TODO: boundary check */
+  return UCharReference(this, pos);
+}
+
+double UString::toDouble() const
+{
+  double d;
+
+  if (!is8Bit())
+    return NaN;
+
+  CString str = cstring();
+  const char *c = str.c_str();
+
+  // skip leading white space
+  while (isspace(*c))
+    c++;
+
+  // empty string ?
+  if (*c == '\0')
+    return 0.0;
+
+  // hex number ?
+  if (*c == '0' && (*(c+1) == 'x' || *(c+1) == 'X')) {
+    c++;
+    d = 0.0;
+    while (*(++c)) {
+      if (*c >= '0' && *c <= '9')
+	d = d * 16.0 + *c - '0';
+      else if ((*c >= 'A' && *c <= 'F') || (*c >= 'a' && *c <= 'f'))
+	d = d * 16.0 + (*c & 0xdf) - 'A' + 10.0;
+      else
+	break;
+    }
+  } else {
+    // regular number ?
+    char *end;
+    d = strtod(c, &end);
+    if (d != 0.0 || end != c) {
+      c = end;
+    } else {
+      // infinity ?
+      d = 1.0;
+      if (*c == '+')
+	c++;
+      else if (*c == '-') {
+	d = -1.0;
+	c++;
+      }
+      if (strncmp(c, "Infinity", 8) != 0)
+	return NaN;
+      d = d * Inf;
+      c += 8;
+    }
+  }
+
+  // allow trailing white space
+  while (isspace(*c))
+    c++;
+  if (*c != '\0')
+    d = NaN;
+
+  return d;
+}
+
+unsigned long UString::toULong(bool *ok) const
+{
+  double d = toDouble();
+  bool b = true;
+
+  if (isNaN(d) || d != static_cast<unsigned long>(d)) {
+    b = false;
+    d = 0;
+  }
+
+  if (ok)
+    *ok = b;
+
+  return static_cast<unsigned long>(d);
+}
+
+int UString::find(const UString &f, int pos) const
+{
+  if (isNull())
+    return -1;
+  long fsize = f.size() * sizeof(UChar);
+  if (pos < 0)
+    pos = 0;
+  const UChar *end = data() + size() - f.size();
+  for (const UChar *c = data() + pos; c <= end; c++)
+    if (!memcmp((void*)c, (void*)f.data(), fsize))
+      return (c-data());
+
+  return -1;
+}
+
+int UString::rfind(const UString &f, int pos) const
+{
+  if (isNull())
+    return -1;
+  if (pos + f.size() >= size())
+    pos = size() - f.size();
+  long fsize = f.size() * sizeof(UChar);
+  for (const UChar *c = data() + pos; c >= data(); c--) {
+    if (!memcmp((void*)c, (void*)f.data(), fsize))
+      return (c-data());
+  }
+
+  return -1;
+}
+
+UString UString::substr(int pos, int len) const
+{
+  if (isNull())
+    return UString();
+  if (pos < 0)
+    pos = 0;
+  else if (pos >= (int) size())
+    pos = size();
+  if (len < 0)
+    len = size();
+  if (pos + len >= (int) size())
+    len = size() - pos;
+
+  UChar *tmp = new UChar[len];
+  memcpy(tmp, data()+pos, len * sizeof(UChar));
+  UString result(tmp, len);
+  delete [] tmp;
+
+  return result;
+}
+
+void UString::attach(Rep *r)
+{
+  rep = r;
+  rep->ref();
+}
+
+void UString::detach()
+{
+  if (rep->rc > 1) {
+    int l = size();
+    UChar *n = new UChar[l];
+    memcpy(n, data(), l * sizeof(UChar));
+    release();
+    rep = Rep::create(n, l);
+  }
+}
+
+void UString::release()
+{
+  if (!rep->deref()) {
+    delete [] rep->dat;
+    delete rep;
+  }
+}
+
+bool KJS::operator==(const UChar &c1, const UChar &c2)
+{
+  return ((c1.lo == c2.lo) & (c1.hi == c2.hi));
+}
+
+bool KJS::operator==(const UString& s1, const UString& s2)
+{
+  if (s1.rep->len != s2.rep->len)
+    return false;
+
+  return (memcmp(s1.rep->dat, s2.rep->dat,
+		 s1.rep->len * sizeof(UChar)) == 0);
+}
+
+bool KJS::operator==(const UString& s1, const char *s2)
+{
+  if (s2 == 0L && s1.isNull())
+    return true;
+
+  if (s1.size() != (int) strlen(s2))
+    return false;
+
+  const UChar *u = s1.data();
+  while (*s2) {
+    if (u->lo != *s2 || u->hi != 0)
+      return false;
+    s2++;
+    u++;
+  }
+
+  return true;
+}
+
+bool KJS::operator==(const char *s1, const UString& s2)
+{
+  return operator==(s2, s1);
+}
+
+bool KJS::operator<(const UString& s1, const UString& s2)
+{
+  int l1 = s1.size();
+  int l2 = s2.size();
+  const UChar *c1 = s1.data();
+  const UChar *c2 = s2.data();
+  int l = 0;
+  int le = l1 < l2 ? l1 : l2;
+  while (l < le && *c1 == *c2) {
+    c1++;
+    c2++;
+    l++;
+  }
+  if (l != le)
+    return (c1->unicode() < c2->unicode());
+
+  return (l1 < l2 && !(*c1 == *c2));
+}
+
+UString KJS::operator+(const UString& s1, const UString& s2)
+{
+  UString tmp(s1);
+  tmp.append(s2);
+
+  return tmp;
+}
diff --git a/JavaScriptCore/kjs/ustring.h b/JavaScriptCore/kjs/ustring.h
new file mode 100644
index 0000000..e897a34
--- /dev/null
+++ b/JavaScriptCore/kjs/ustring.h
@@ -0,0 +1,419 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _KJS_STRING_H_
+#define _KJS_STRING_H_
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/**
+ * @internal
+ */
+namespace DOM {
+  class DOMString;
+};
+class KJScript;
+class QString;
+class QConstString;
+
+#if defined(__GNUC__)
+#define KJS_PACKED __attribute__((__packed__))
+#else
+#define KJS_PACKED
+#endif
+
+namespace KJS {
+
+  class UCharReference;
+  class UString;
+
+  /**
+   * @short Unicode character.
+   *
+   * UChar represents a 16 bit Unicode character. It's internal data
+   * representation is compatible to XChar2b and QChar. It's therefore
+   * possible to exchange data with X and Qt with shallow copies.
+   */
+  struct UChar {
+    /**
+     * Construct a character with value 0.
+     */
+    UChar();
+    /**
+     * Construct a character with the value denoted by the arguments.
+     * @param h higher byte
+     * @param l lower byte
+     */
+    UChar(unsigned char h , unsigned char l);
+    /**
+     * Construct a character with the given value.
+     * @param u 16 bit Unicode value
+     */
+    UChar(unsigned short u);
+    UChar(const UCharReference &c);
+    /**
+     * @return The higher byte of the character.
+     */
+    unsigned char high() const { return hi; }
+    /**
+     * @return The lower byte of the character.
+     */
+    unsigned char low() const { return lo; }
+    /**
+     * @return the 16 bit Unicode value of the character
+     */
+    unsigned short unicode() const { return hi << 8 | lo; }
+  public:
+    /**
+     * @return The character converted to lower case.
+     */
+    UChar toLower() const;
+    /**
+     * @return The character converted to upper case.
+     */
+    UChar toUpper() const;
+    /**
+     * A static instance of UChar(0).
+     */
+    static UChar null;
+  private:
+    friend class UCharReference;
+    friend class UString;
+    friend bool operator==(const UChar &c1, const UChar &c2);
+    friend bool operator==(const UString& s1, const char *s2);
+    friend bool operator<(const UString& s1, const UString& s2);
+#ifdef KJS_SWAPPED_CHAR
+    unsigned char lo;
+    unsigned char hi;
+#else
+    unsigned char hi;
+    unsigned char lo;
+#endif
+  } KJS_PACKED;
+
+
+#ifdef KJS_SWAPPED_CHAR // to avoid reorder warnings
+  inline UChar::UChar() : lo(0), hi(0) { }
+  inline UChar::UChar(unsigned char h , unsigned char l) : lo(l), hi(h) { }
+  inline UChar::UChar(unsigned short u) : lo(u & 0x00ff), hi(u >> 8) { }
+#else
+  inline UChar::UChar() : hi(0), lo(0) { }
+  inline UChar::UChar(unsigned char h , unsigned char l) : hi(h), lo(l) { }
+  inline UChar::UChar(unsigned short u) : hi(u >> 8), lo(u & 0x00ff) { }
+#endif
+
+  /**
+   * @short Dynamic reference to a string character.
+   *
+   * UCharReference is the dynamic counterpart of @ref UChar. It's used when
+   * characters retrieved via index from a @ref UString are used in an
+   * assignment expression (and therefore can't be treated as being const):
+   * <pre>
+   * UString s("hello world");
+   * s[0] = 'H';
+   * </pre>
+   *
+   * If that sounds confusing your best bet is to simply forget about the
+   * existance of this class and treat is as being identical to @ref UChar.
+   */
+  class UCharReference {
+    friend class UString;
+    UCharReference(UString *s, unsigned int off) : str(s), offset(off) { }
+  public:
+    /**
+     * Set the referenced character to c.
+     */
+    UCharReference& operator=(UChar c);
+    /**
+     * Same operator as above except the argument that it takes.
+     */
+    UCharReference& operator=(char c) { return operator=(UChar(c)); }
+    /**
+     * @return Unicode value.
+     */
+    unsigned short unicode() const { return ref().unicode(); }
+    /**
+     * @return Lower byte.
+     */
+    unsigned char& low() const { return ref().lo; }
+    /**
+     * @return Higher byte.
+     */
+    unsigned char& high() const { return ref().hi; }
+    /**
+     * @return Character converted to lower case.
+     */
+    UChar toLower() const { return ref().toLower(); }
+    /**
+     * @return Character converted to upper case.
+     */
+    UChar toUpper() const  { return ref().toUpper(); }
+  private:
+    // not implemented, can only be constructed from UString
+    UCharReference();
+
+    UChar& ref() const;
+    UString *str;
+    int offset;
+  };
+
+  /**
+   * @short 8 bit char based string class
+   */
+  class CString {
+  public:
+    CString() : data(0L) { }
+    CString(const char *c);
+    CString(const CString &);
+
+    ~CString();
+
+    CString &append(const CString &);
+    CString &operator=(const char *c);
+    CString &operator=(const CString &);
+    CString &operator+=(const CString &);
+
+    int size() const;
+    const char *c_str() const { return data; }
+  private:
+    char *data;
+  };
+
+  /**
+   * @short Unicode string class
+   */
+  class UString {
+    friend bool operator==(const UString&, const UString&);
+    friend class UCharReference;
+    /**
+     * @internal
+     */
+    struct Rep {
+      friend class UString;
+      friend bool operator==(const UString&, const UString&);
+      static Rep *create(UChar *d, int l);
+      inline UChar *data() const { return dat; }
+      inline int size() const { return len; }
+
+      inline void ref() { rc++; }
+      inline int deref() { return --rc; }
+
+      UChar *dat;
+      int len;
+      int rc;
+      static Rep null;
+    };
+
+  public:
+    /**
+     * Constructs a null string.
+     */
+    UString();
+    /**
+     * Constructs a string from the single character c.
+     */
+    UString(char c);
+    /**
+     * Constructs a string from a classical zero determined char string.
+     */
+    UString(const char *c);
+    /**
+     * Constructs a string from an array of Unicode characters of the specified
+     * length.
+     */
+    UString(const UChar *c, int length);
+    /**
+     * If copy is false a shallow copy of the string will be created. That
+     * means that the data will NOT be copied and you'll have to guarantee that
+     * it doesn't get deleted during the lifetime of the UString object.
+     * Behaviour defaults to a deep copy if copy is true.
+     */
+    UString(UChar *c, int length, bool copy);
+    /**
+     * Copy constructor. Makes a shallow copy only.
+     */
+    UString(const UString &);
+    /**
+     * Convenience declaration only ! You'll be on your own to write the
+     * implementation for a construction from QString.
+     *
+     * Note: feel free to contact me if you want to see a dummy header for
+     * your favourite FooString class here !
+     */
+    UString(const QString &);
+    /**
+     * Convenience declaration only ! See @ref UString(const QString&).
+     */
+    UString(const DOM::DOMString &);
+    /**
+     * Destructor. If this handle was the only one holding a reference to the
+     * string the data will be freed.
+     */
+    ~UString();
+
+    /**
+     * Constructs a string from an int.
+     */
+    static UString from(int i);
+    /**
+     * Constructs a string from an unsigned int.
+     */
+    static UString from(unsigned int u);
+    /**
+     * Constructs a string from a double.
+     */
+    static UString from(double d);
+
+    /**
+     * Append another string.
+     */
+    UString &append(const UString &);
+
+    /**
+     * @return The string converted to the 8-bit string type @ref CString().
+     */
+    CString cstring() const;
+    /**
+     * Convert the Unicode string to plain ASCII chars chopping of any higher
+     * bytes. This method should only be used for *debugging* purposes as it
+     * is neither Unicode safe nor free from side effects. In order not to
+     * waste any memory the char buffer is static and *shared* by all UString
+     * instances.
+     */
+    char *ascii() const;
+    /**
+     * @see UString(const QString&).
+     */
+    DOM::DOMString string() const;
+    /**
+     * @see UString(const QString&).
+     */
+    QString qstring() const;
+    /**
+     * @see UString(const QString&).
+     */
+    QConstString qconststring() const;
+
+    /**
+     * Assignment operator.
+     */
+    UString &operator=(const char *c);
+    /**
+     * Assignment operator.
+     */
+    UString &operator=(const UString &);
+    /**
+     * Appends the specified string.
+     */
+    UString &operator+=(const UString &s);
+
+    /**
+     * @return A pointer to the internal Unicode data.
+     */
+    const UChar* data() const { return rep->data(); }
+    /**
+     * @return True if null.
+     */
+    bool isNull() const { return (rep == &Rep::null); }
+    /**
+     * @return True if null or zero length.
+     */
+    bool isEmpty() const { return (!rep->len); }
+    /**
+     * Use this if you want to make sure that this string is a plain ASCII
+     * string. For example, if you don't want to lose any information when
+     * using @ref cstring() or @ref ascii().
+     *
+     * @return True if the string doesn't contain any non-ASCII characters.
+     */
+    bool is8Bit() const;
+    /**
+     * @return The length of the string.
+     */
+    int size() const { return rep->size(); }
+    /**
+     * Const character at specified position.
+     */
+    UChar operator[](int pos) const;
+    /**
+     * Writable reference to character at specified position.
+     */
+    UCharReference operator[](int pos);
+
+    /**
+     * Attempts an conversion to a number. Apart from floating point numbers,
+     * the algorithm will recognize hexadecimal representations (as
+     * indicated by a 0x or 0X prefix) and +/- Infinity.
+     * Returns NaN if the conversion failed.
+     */
+    double toDouble() const;
+    /**
+     * Attempts an conversion to an unsigned long integer. ok will be set
+     * according to the success.
+     */
+    unsigned long toULong(bool *ok = 0L) const;
+    /**
+     * @return Position of first occurence of f starting at position pos.
+     * -1 if the search was not successful.
+     */
+    int find(const UString &f, int pos = 0) const;
+    /**
+     * @return Position of first occurence of f searching backwards from
+     * position pos.
+     * -1 if the search was not successful.
+     */
+    int rfind(const UString &f, int pos) const;
+    /**
+     * @return The sub string starting at position pos and length len.
+     */
+    UString substr(int pos = 0, int len = -1) const;
+    /**
+     * Static instance of a null string.
+     */
+    static UString null;
+  private:
+    void attach(Rep *r);
+    void detach();
+    void release();
+    Rep *rep;
+  };
+
+  bool operator==(const UChar &c1, const UChar &c2);
+  bool operator==(const UString& s1, const UString& s2);
+  inline bool operator!=(const UString& s1, const UString& s2) {
+    return !KJS::operator==(s1, s2);
+  }
+  bool operator<(const UString& s1, const UString& s2);
+  bool operator==(const UString& s1, const char *s2);
+  inline bool operator!=(const UString& s1, const char *s2) {
+    return !KJS::operator==(s1, s2);
+  }
+  bool operator==(const char *s1, const UString& s2);
+  inline bool operator!=(const char *s1, const UString& s2) {
+    return !KJS::operator==(s1, s2);
+  }
+  bool operator==(const CString& s1, const CString& s2);
+  UString operator+(const UString& s1, const UString& s2);
+
+}; // namespace
+
+#endif
diff --git a/WebCore/src/kdelibs/kjs/.cvsignore b/WebCore/src/kdelibs/kjs/.cvsignore
new file mode 100644
index 0000000..e2a42ee
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/.cvsignore
@@ -0,0 +1,5 @@
+Makefile
+Makefile.in
+testkjs
+libkjs_la.all_cpp.cpp
+SunWS_cache
diff --git a/WebCore/src/kdelibs/kjs/ChangeLog b/WebCore/src/kdelibs/kjs/ChangeLog
new file mode 100644
index 0000000..8176cf4
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/ChangeLog
@@ -0,0 +1,24 @@
+2001-01-04  Harri Porten  <harri at trolltech.com>
+
+	* ustring.h: pack bytes to avoid alignment problems (ARM) reported
+	by Stefan Hanske <sh990154 at mail.uni-greifswald.de>
+	* nodes.cpp: typeof fix by Emmeran Seehuber <the_emmy at gmx.de>
+	* nodes.cpp: fixed order of function declaration proccessing
+
+2000-12-18  Harri Porten  <harri at trolltech.com>
+
+	* string_object.cpp: fixed out-of-bounds error in fromCharCode()
+
+2000-12-11  Harri Porten  <harri at trolltech.com>
+
+	* regexp.h: compile fix for buggy libc
+	* ustring.cpp: format string conversion of numbers with %g
+
+2000-12-10  Harri Porten  <harri at trolltech.com>
+
+	* lexer.cpp: parsing != was broken, added \v escape in strings,
+		fixed "\u" and "\x" and \x with non hex chars following.
+	* nodes.cpp: implemented <<=, >>=, >>>=, &=, ^=, |= and %=
+	* internal.cpp: create error message including line no on parse errors
+
+
diff --git a/WebCore/src/kdelibs/kjs/Makefile.am b/WebCore/src/kdelibs/kjs/Makefile.am
new file mode 100644
index 0000000..1cd1be0
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/Makefile.am
@@ -0,0 +1,66 @@
+#    This file is part of the KDE libraries
+#    Copyright (C) 1999 Harri Porten (porten at kde.org)
+
+#    This library is free software; you can redistribute it and/or
+#    modify it under the terms of the GNU Library General Public
+#    License as published by the Free Software Foundation; either
+#    version 2 of the License, or (at your option) any later version.
+
+#    This library is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#    Library General Public License for more details.
+
+#    You should have received a copy of the GNU Library General Public License
+#    along with this library; see the file COPYING.LIB.  If not, write to
+#    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+#    Boston, MA 02111-1307, USA.
+
+YACC = bison
+INCLUDES = $(all_includes)
+
+lib_LTLIBRARIES = libkjs.la
+
+libkjs_la_SOURCES =  kjs.cpp grammar.cpp lexer.cpp nodes.cpp object.cpp \
+	operations.cpp ustring.cpp function.cpp types.cpp lookup.cpp \
+	internal.cpp regexp.cpp global_object.cpp math_object.cpp \
+	bool_object.cpp object_object.cpp error_object.cpp \
+	array_object.cpp string_object.cpp number_object.cpp \
+	date_object.cpp regexp_object.cpp collector.cpp function_object.cpp \
+	debugger.cpp
+
+kjsincludedir = $(includedir)/kjs
+kjsinclude_HEADERS = kjs.h object.h operations.h ustring.h \
+	function.h lookup.h types.h
+
+noinst_HEADERS = nodes.h lexer.h regexp.h internal.h collector.h \
+	grammar.h object_object.h function_object.h function_object.h \
+	bool_object.h math_object.h array_object.h string_object.h \
+	number_object.h date_object.h regexp_object.h error_object.h \
+	debugger.h
+
+libkjs_la_LDFLAGS = -version-info 1:0 -no-undefined $(USER_LDFLAGS)
+libkjs_la_LIBADD = -lm $(LIBPCRE)
+
+parser: $(srcdir)/grammar.y
+	cd $(srcdir); \
+	$(YACC) -d -p kjsyy grammar.y && mv grammar.tab.c grammar.cpp; \
+	if test -f grammar.tab.h; then \
+	if cmp -s grammar.tab.h grammar.h; then rm -f grammar.tab.h; \
+	else mv grammar.tab.h grammar.h; fi \
+	else :; fi
+
+## with debugger interface
+debugger: $(libkjs_la_SOURCES) $(kjsinclude_HEADERS) $(noinst_HEADERS)
+	$(MAKE) DEFS="-DKJS_DEBUGGER $(DEFS)" libkjs.la
+
+## test program (in one program for easier profiling/memory debugging)
+EXTRA_PROGRAMS = testkjs_static
+testkjs_static_SOURCES = testkjs.cpp  $(libkjs_la_SOURCES)
+testkjs_static_LDADD = $(LIBPCRE)
+
+## test program (linked to libkjs)
+check_PROGRAMS = testkjs
+testkjs_SOURCES = testkjs.cpp
+testkjs_LDADD = libkjs.la
+
diff --git a/WebCore/src/kdelibs/kjs/Makefile.in b/WebCore/src/kdelibs/kjs/Makefile.in
new file mode 100644
index 0000000..dd601f3
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/Makefile.in
@@ -0,0 +1,738 @@
+# KDE tags expanded automatically by am_edit - $Revision$ 
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+#    This file is part of the KDE libraries
+#    Copyright (C) 1999 Harri Porten (porten at kde.org)
+
+#    This library is free software; you can redistribute it and/or
+#    modify it under the terms of the GNU Library General Public
+#    License as published by the Free Software Foundation; either
+#    version 2 of the License, or (at your option) any later version.
+
+#    This library is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#    Library General Public License for more details.
+
+#    You should have received a copy of the GNU Library General Public License
+#    along with this library; see the file COPYING.LIB.  If not, write to
+#    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+#    Boston, MA 02111-1307, USA.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+#>- 
+bindir = @bindir@
+#>+ 3
+DEPDIR = .deps
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_alias = @build_alias@
+build_triplet = @build@
+host_alias = @host_alias@
+host_triplet = @host@
+target_alias = @target_alias@
+target_triplet = @target@
+ARTSCCONFIG = @ARTSCCONFIG@
+ARTS_BUILD_GMCOP = @ARTS_BUILD_GMCOP@
+ARTS_BUILD_KDE = @ARTS_BUILD_KDE@
+ARTS_MAJOR_VERSION = @ARTS_MAJOR_VERSION@
+ARTS_MICRO_VERSION = @ARTS_MICRO_VERSION@
+ARTS_MINOR_VERSION = @ARTS_MINOR_VERSION@
+ARTS_VERSION = @ARTS_VERSION@
+AS = @AS@
+AUTODIRS = @AUTODIRS@
+BZIP2DIR = @BZIP2DIR@
+BZIP2_FILTER = @BZIP2_FILTER@
+CC = @CC@
+CONF_FILES = @CONF_FILES@
+CPP = @CPP@
+CUPSSUBDIR = @CUPSSUBDIR@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+DCOPIDL = @DCOPIDL@
+DCOPIDL2CPP = @DCOPIDL2CPP@
+DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@
+DLLTOOL = @DLLTOOL@
+DPMSINC = @DPMSINC@
+DPMSLIB = @DPMSLIB@
+EXEEXT = @EXEEXT@
+EXTRA_SUBDIRS = @EXTRA_SUBDIRS@
+GCJ = @GCJ@
+GCJFLAGS = @GCJFLAGS@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_DEPLIBS = @GLIB_DEPLIBS@
+GLIB_LIBS = @GLIB_LIBS@
+GLINC = @GLINC@
+GLLIB = @GLLIB@
+GMSGFMT = @GMSGFMT@
+HAVE_MITSHM = @HAVE_MITSHM@
+HELP_SUBDIR = @HELP_SUBDIR@
+ICE_RLIB = @ICE_RLIB@
+ICE_SUBDIR = @ICE_SUBDIR@
+IDL = @IDL@
+IDL_DEPENDENCIES = @IDL_DEPENDENCIES@
+JAR = @JAR@
+JAVAC = @JAVAC@
+JAVAH = @JAVAH@
+JVMLIBS = @JVMLIBS@
+KDECONFIG = @KDECONFIG@
+KDE_CXXFLAGS = @KDE_CXXFLAGS@
+KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@
+KDE_INCLUDES = @KDE_INCLUDES@
+KDE_LDFLAGS = @KDE_LDFLAGS@
+KDE_PLUGIN = @KDE_PLUGIN@
+KDE_RPATH = @KDE_RPATH@
+KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@
+KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@
+KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@
+KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@
+KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@
+LIBASOUND = @LIBASOUND@
+LIBAUDIOFILE = @LIBAUDIOFILE@
+LIBAUDIOIO = @LIBAUDIOIO@
+LIBAUDIONAS = @LIBAUDIONAS@
+LIBBZ2 = @LIBBZ2@
+LIBCOMPAT = @LIBCOMPAT@
+LIBCRYPT = @LIBCRYPT@
+LIBDL = @LIBDL@
+LIBFAM = @LIBFAM@
+LIBGEN = @LIBGEN@
+LIBICE = @LIBICE@
+LIBJPEG = @LIBJPEG@
+LIBMICO = @LIBMICO@
+LIBOBJS = @LIBOBJS@
+LIBOSSAUDIO = @LIBOSSAUDIO@
+LIBPCRE = @LIBPCRE@
+LIBPNG = @LIBPNG@
+LIBPOSIX1E = @LIBPOSIX1E@
+LIBPTHREAD = @LIBPTHREAD@
+LIBPYTHON = @LIBPYTHON@
+LIBQIMGIO = @LIBQIMGIO@
+LIBRESOLV = @LIBRESOLV@
+LIBSHADOW = @LIBSHADOW@
+LIBSM = @LIBSM@
+LIBSOCKET = @LIBSOCKET@
+LIBSSL = @LIBSSL@
+LIBTIFF = @LIBTIFF@
+LIBTOOL = @LIBTOOL@
+LIBUCB = @LIBUCB@
+LIBUTIL = @LIBUTIL@
+LIBVOLMGT = @LIBVOLMGT@
+LIBXINERAMA = @LIBXINERAMA@
+LIBXML_CFLAGS = @LIBXML_CFLAGS@
+LIBXML_LIBS = @LIBXML_LIBS@
+LIBXML_RPATH = @LIBXML_RPATH@
+LIBXSLT_MAJOR_VERSION = @LIBXSLT_MAJOR_VERSION@
+LIBXSLT_MICRO_VERSION = @LIBXSLT_MICRO_VERSION@
+LIBXSLT_MINOR_VERSION = @LIBXSLT_MINOR_VERSION@
+LIBXSLT_VERSION = @LIBXSLT_VERSION@
+LIBXSLT_VERSION_INFO = @LIBXSLT_VERSION_INFO@
+LIBXSLT_VERSION_NUMBER = @LIBXSLT_VERSION_NUMBER@
+LIBZ = @LIBZ@
+LIB_CUPS = @LIB_CUPS@
+LIB_DCOP = @LIB_DCOP@
+LIB_DMALLOC = @LIB_DMALLOC@
+LIB_KAB = @LIB_KAB@
+LIB_KDECORE = @LIB_KDECORE@
+LIB_KDEUI = @LIB_KDEUI@
+LIB_KFILE = @LIB_KFILE@
+LIB_KFM = @LIB_KFM@
+LIB_KFORMULA = @LIB_KFORMULA@
+LIB_KHTML = @LIB_KHTML@
+LIB_KIMGIO = @LIB_KIMGIO@
+LIB_KIO = @LIB_KIO@
+LIB_KPARTS = @LIB_KPARTS@
+LIB_KSPELL = @LIB_KSPELL@
+LIB_KSSL = @LIB_KSSL@
+LIB_KSYCOCA = @LIB_KSYCOCA@
+LIB_KWRITE = @LIB_KWRITE@
+LIB_QT = @LIB_QT@
+LIB_SMB = @LIB_SMB@
+LIB_X11 = @LIB_X11@
+LN_S = @LN_S@
+MAKEINFO = @MAKEINFO@
+MCOPIDL = @MCOPIDL@
+MEINPROC = @MEINPROC@
+MICO_INCLUDES = @MICO_INCLUDES@
+MICO_LDFLAGS = @MICO_LDFLAGS@
+MOC = @MOC@
+MSGFMT = @MSGFMT@
+M_LIBS = @M_LIBS@
+NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@
+NOREPO = @NOREPO@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PAMLIBS = @PAMLIBS@
+PASSWDLIBS = @PASSWDLIBS@
+PKG_CONFIG = @PKG_CONFIG@
+PYTHONINC = @PYTHONINC@
+PYTHONLIB = @PYTHONLIB@
+PYTHONMODDIR = @PYTHONMODDIR@
+QNAMESPACE_H = @QNAMESPACE_H@
+QTDOCDIR = @QTDOCDIR@
+QT_INCLUDES = @QT_INCLUDES@
+QT_LDFLAGS = @QT_LDFLAGS@
+RANLIB = @RANLIB@
+REPO = @REPO@
+SETUIDFLAGS = @SETUIDFLAGS@
+SSL_INCLUDES = @SSL_INCLUDES@
+SSL_LDFLAGS = @SSL_LDFLAGS@
+STRIP = @STRIP@
+TOPSUBDIRS = @TOPSUBDIRS@
+UIC = @UIC@
+USER_INCLUDES = @USER_INCLUDES@
+USER_LDFLAGS = @USER_LDFLAGS@
+USE_EXCEPTIONS = @USE_EXCEPTIONS@
+USE_RTTI = @USE_RTTI@
+USE_THREADS = @USE_THREADS@
+VERSION = @VERSION@
+WITH_MEM_DEBUG = @WITH_MEM_DEBUG@
+WITH_XSLT_DEBUG = @WITH_XSLT_DEBUG@
+XGETTEXT = @XGETTEXT@
+XPMINC = @XPMINC@
+XPMLIB = @XPMLIB@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_INCLUDES = @X_INCLUDES@
+X_LDFLAGS = @X_LDFLAGS@
+X_PRE_LIBS = @X_PRE_LIBS@
+all_includes = @all_includes@
+all_libraries = @all_libraries@
+idldir = @idldir@
+jni_includes = @jni_includes@
+kde_appsdir = @kde_appsdir@
+kde_bindir = @kde_bindir@
+kde_confdir = @kde_confdir@
+kde_datadir = @kde_datadir@
+kde_htmldir = @kde_htmldir@
+kde_icondir = @kde_icondir@
+kde_includes = @kde_includes@
+kde_libraries = @kde_libraries@
+kde_libs_htmldir = @kde_libs_htmldir@
+kde_libs_prefix = @kde_libs_prefix@
+kde_locale = @kde_locale@
+kde_mimedir = @kde_mimedir@
+kde_moduledir = @kde_moduledir@
+kde_servicesdir = @kde_servicesdir@
+kde_servicetypesdir = @kde_servicetypesdir@
+kde_sounddir = @kde_sounddir@
+kde_templatesdir = @kde_templatesdir@
+kde_wallpaperdir = @kde_wallpaperdir@
+micodir = @micodir@
+path_su = @path_su@
+qt_includes = @qt_includes@
+qt_libraries = @qt_libraries@
+x_includes = @x_includes@
+x_libraries = @x_libraries@
+
+YACC = bison
+INCLUDES = $(all_includes)
+
+lib_LTLIBRARIES = libkjs.la
+
+libkjs_la_SOURCES = kjs.cpp grammar.cpp lexer.cpp nodes.cpp object.cpp 	operations.cpp ustring.cpp function.cpp types.cpp lookup.cpp 	internal.cpp regexp.cpp global_object.cpp math_object.cpp 	bool_object.cpp object_object.cpp error_object.cpp 	array_object.cpp string_object.cpp number_object.cpp 	date_object.cpp regexp_object.cpp collector.cpp function_object.cpp 	debugger.cpp
+
+
+kjsincludedir = $(includedir)/kjs
+kjsinclude_HEADERS = kjs.h object.h operations.h ustring.h 	function.h lookup.h types.h
+
+
+noinst_HEADERS = nodes.h lexer.h regexp.h internal.h collector.h 	grammar.h object_object.h function_object.h function_object.h 	bool_object.h math_object.h array_object.h string_object.h 	number_object.h date_object.h regexp_object.h error_object.h 	debugger.h
+
+
+libkjs_la_LDFLAGS = -version-info 1:0 -no-undefined $(USER_LDFLAGS)
+libkjs_la_LIBADD = -lm $(LIBPCRE)
+
+EXTRA_PROGRAMS = testkjs_static
+testkjs_static_SOURCES = testkjs.cpp  $(libkjs_la_SOURCES)
+testkjs_static_LDADD = $(LIBPCRE)
+
+check_PROGRAMS = testkjs
+testkjs_SOURCES = testkjs.cpp
+testkjs_LDADD = libkjs.la
+mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs
+CONFIG_HEADER = ../config.h
+CONFIG_CLEAN_FILES = 
+LTLIBRARIES =  $(lib_LTLIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I..
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+libkjs_la_DEPENDENCIES = 
+#>- libkjs_la_OBJECTS =  kjs.lo grammar.lo lexer.lo nodes.lo object.lo \
+#>- operations.lo ustring.lo function.lo types.lo lookup.lo internal.lo \
+#>- regexp.lo global_object.lo math_object.lo bool_object.lo \
+#>- object_object.lo error_object.lo array_object.lo string_object.lo \
+#>- number_object.lo date_object.lo regexp_object.lo collector.lo \
+#>- function_object.lo debugger.lo
+#>+ 9
+libkjs_la_final_OBJECTS = libkjs_la.all_cpp.lo 
+libkjs_la_nofinal_OBJECTS = kjs.lo grammar.lo lexer.lo nodes.lo object.lo \
+operations.lo ustring.lo function.lo types.lo lookup.lo internal.lo \
+regexp.lo global_object.lo math_object.lo bool_object.lo \
+object_object.lo error_object.lo array_object.lo string_object.lo \
+number_object.lo date_object.lo regexp_object.lo collector.lo \
+function_object.lo debugger.lo
+ at KDE_USE_FINAL_FALSE@libkjs_la_OBJECTS = $(libkjs_la_nofinal_OBJECTS)
+ at KDE_USE_FINAL_TRUE@libkjs_la_OBJECTS = $(libkjs_la_final_OBJECTS)
+check_PROGRAMS =  testkjs$(EXEEXT)
+#>- testkjs_static_OBJECTS =  testkjs.$(OBJEXT) kjs.$(OBJEXT) \
+#>- grammar.$(OBJEXT) lexer.$(OBJEXT) nodes.$(OBJEXT) object.$(OBJEXT) \
+#>- operations.$(OBJEXT) ustring.$(OBJEXT) function.$(OBJEXT) \
+#>- types.$(OBJEXT) lookup.$(OBJEXT) internal.$(OBJEXT) regexp.$(OBJEXT) \
+#>- global_object.$(OBJEXT) math_object.$(OBJEXT) bool_object.$(OBJEXT) \
+#>- object_object.$(OBJEXT) error_object.$(OBJEXT) array_object.$(OBJEXT) \
+#>- string_object.$(OBJEXT) number_object.$(OBJEXT) date_object.$(OBJEXT) \
+#>- regexp_object.$(OBJEXT) collector.$(OBJEXT) function_object.$(OBJEXT) \
+#>- debugger.$(OBJEXT)
+#>+ 9
+testkjs_static_OBJECTS = testkjs.$(OBJEXT) kjs.$(OBJEXT) \
+grammar.$(OBJEXT) lexer.$(OBJEXT) nodes.$(OBJEXT) object.$(OBJEXT) \
+operations.$(OBJEXT) ustring.$(OBJEXT) function.$(OBJEXT) \
+types.$(OBJEXT) lookup.$(OBJEXT) internal.$(OBJEXT) regexp.$(OBJEXT) \
+global_object.$(OBJEXT) math_object.$(OBJEXT) bool_object.$(OBJEXT) \
+object_object.$(OBJEXT) error_object.$(OBJEXT) array_object.$(OBJEXT) \
+string_object.$(OBJEXT) number_object.$(OBJEXT) date_object.$(OBJEXT) \
+regexp_object.$(OBJEXT) collector.$(OBJEXT) function_object.$(OBJEXT) \
+debugger.$(OBJEXT)
+testkjs_static_DEPENDENCIES = 
+testkjs_static_LDFLAGS = 
+#>- testkjs_OBJECTS =  testkjs.$(OBJEXT)
+#>+ 1
+testkjs_OBJECTS = testkjs.$(OBJEXT)
+testkjs_DEPENDENCIES =  libkjs.la
+testkjs_LDFLAGS = 
+CXXFLAGS = @CXXFLAGS@
+#>- CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+#>+ 1
+CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS)
+#>- LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+#>+ 1
+LTCXXCOMPILE = $(LIBTOOL) --mode=compile --tag=CXX $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS)
+CXXLD = $(CXX)
+#>- CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@
+#>+ 1
+CXXLINK = $(LIBTOOL) --mode=link --tag=CXX $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) $(LDFLAGS) -o $@
+HEADERS =  $(kjsinclude_HEADERS) $(noinst_HEADERS)
+
+DIST_COMMON =  README ChangeLog Makefile.am Makefile.in THANKS
+
+
+#>- DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+#>+ 4
+KDE_DIST=configure.in.in grammar.y keywords.table math_object.lut.h test.js create_hash_table lexer.lut.h 
+
+DISTFILES= $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) $(KDE_DIST)
+
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(libkjs_la_SOURCES) $(testkjs_static_SOURCES) $(testkjs_SOURCES)
+OBJECTS = $(libkjs_la_OBJECTS) $(testkjs_static_OBJECTS) $(testkjs_OBJECTS)
+
+#>- all: all-redirect
+#>+ 1
+all: docs-am  all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .cpp .lo .o .obj .s
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
+#>- 	cd $(top_srcdir) && $(AUTOMAKE) --foreign --include-deps kjs/Makefile
+#>+ 2
+	cd $(top_srcdir) && $(AUTOMAKE) --foreign --include-deps kjs/Makefile
+	cd $(top_srcdir) && perl admin/am_edit kjs/Makefile.in
+
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+	cd $(top_builddir) \
+	  && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-libLTLIBRARIES:
+
+clean-libLTLIBRARIES:
+	-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+
+distclean-libLTLIBRARIES:
+
+maintainer-clean-libLTLIBRARIES:
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+	@$(NORMAL_INSTALL)
+	$(mkinstalldirs) $(DESTDIR)$(libdir)
+	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+	  if test -f $$p; then \
+	    echo "$(LIBTOOL)  --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \
+	    $(LIBTOOL)  --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \
+	  else :; fi; \
+	done
+
+uninstall-libLTLIBRARIES:
+	@$(NORMAL_UNINSTALL)
+	list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+	  $(LIBTOOL)  --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
+	done
+
+.c.o:
+	$(COMPILE) -c $<
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+	$(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+	$(COMPILE) -c $<
+
+.S.o:
+	$(COMPILE) -c $<
+
+mostlyclean-compile:
+	-rm -f *.o core *.core
+	-rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+	-rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+	$(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+	$(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+	$(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+#>- libkjs.la: $(libkjs_la_OBJECTS) $(libkjs_la_DEPENDENCIES)
+#>+ 2
+ at KDE_USE_CLOSURE_TRUE@libkjs.la: libkjs.la.closure $(libkjs_la_OBJECTS) $(libkjs_la_DEPENDENCIES)
+ at KDE_USE_CLOSURE_FALSE@libkjs.la: $(libkjs_la_OBJECTS) $(libkjs_la_DEPENDENCIES)
+	$(CXXLINK) -rpath $(libdir) $(libkjs_la_LDFLAGS) $(libkjs_la_OBJECTS) $(libkjs_la_LIBADD) $(LIBS)
+
+mostlyclean-checkPROGRAMS:
+
+clean-checkPROGRAMS:
+	-test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS)
+
+distclean-checkPROGRAMS:
+
+maintainer-clean-checkPROGRAMS:
+
+testkjs_static$(EXEEXT): $(testkjs_static_OBJECTS) $(testkjs_static_DEPENDENCIES)
+	@rm -f testkjs_static$(EXEEXT)
+	$(CXXLINK) $(testkjs_static_LDFLAGS) $(testkjs_static_OBJECTS) $(testkjs_static_LDADD) $(LIBS)
+
+testkjs$(EXEEXT): $(testkjs_OBJECTS) $(testkjs_DEPENDENCIES)
+	@rm -f testkjs$(EXEEXT)
+	$(CXXLINK) $(testkjs_LDFLAGS) $(testkjs_OBJECTS) $(testkjs_LDADD) $(LIBS)
+.cpp.o:
+	$(CXXCOMPILE) -c $<
+.cpp.obj:
+	$(CXXCOMPILE) -c `cygpath -w $<`
+.cpp.lo:
+	$(LTCXXCOMPILE) -c $<
+
+install-kjsincludeHEADERS: $(kjsinclude_HEADERS)
+	@$(NORMAL_INSTALL)
+	$(mkinstalldirs) $(DESTDIR)$(kjsincludedir)
+	@list='$(kjsinclude_HEADERS)'; for p in $$list; do \
+	  if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
+	  echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(kjsincludedir)/$$p"; \
+	  $(INSTALL_DATA) $$d$$p $(DESTDIR)$(kjsincludedir)/$$p; \
+	done
+
+uninstall-kjsincludeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	list='$(kjsinclude_HEADERS)'; for p in $$list; do \
+	  rm -f $(DESTDIR)$(kjsincludedir)/$$p; \
+	done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+	list='$(SOURCES) $(HEADERS)'; \
+	unique=`for i in $$list; do echo $$i; done | \
+	  awk '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	here=`pwd` && cd $(srcdir) \
+	  && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)'; \
+	unique=`for i in $$list; do echo $$i; done | \
+	  awk '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+	  || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags  $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+	-rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = kjs
+
+distdir: $(DISTFILES)
+#>- 	@for file in $(DISTFILES); do \
+#>- 	  d=$(srcdir); \
+#>- 	  if test -d $$d/$$file; then \
+#>- 	    cp -pr $$/$$file $(distdir)/$$file; \
+#>- 	  else \
+#>- 	    test -f $(distdir)/$$file \
+#>- 	    || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+#>- 	    || cp -p $$d/$$file $(distdir)/$$file || :; \
+#>- 	  fi; \
+#>- 	done
+#>+ 10
+	@for file in $(DISTFILES); do \
+	  d=$(srcdir); \
+	  if test -d $$d/$$file; then \
+	    cp -pr $$d/$$file $(distdir)/$$file; \
+	  else \
+	    test -f $(distdir)/$$file \
+	    || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+	    || cp -p $$d/$$file $(distdir)/$$file || :; \
+	  fi; \
+	done
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+	$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-libLTLIBRARIES
+install-exec: install-exec-am
+
+install-data-am: install-kjsincludeHEADERS
+install-data: install-data-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-libLTLIBRARIES uninstall-kjsincludeHEADERS
+uninstall: uninstall-am
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
+all-redirect: all-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+	$(mkinstalldirs)  $(DESTDIR)$(libdir) $(DESTDIR)$(kjsincludedir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-rm -f Makefile $(CONFIG_CLEAN_FILES)
+	-rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am:  mostlyclean-libLTLIBRARIES mostlyclean-compile \
+		mostlyclean-libtool mostlyclean-checkPROGRAMS \
+		mostlyclean-tags mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+#>- clean-am:  clean-libLTLIBRARIES clean-compile clean-libtool \
+#>- 		clean-checkPROGRAMS clean-tags clean-generic \
+#>- 		mostlyclean-am
+#>+ 3
+clean-am: clean-closures clean-final   clean-libLTLIBRARIES clean-compile clean-libtool \
+		clean-checkPROGRAMS clean-tags clean-generic \
+		mostlyclean-am
+
+#>- clean: clean-am
+#>+ 1
+clean: kde-rpo-clean  clean-am
+
+distclean-am:  distclean-libLTLIBRARIES distclean-compile \
+		distclean-libtool distclean-checkPROGRAMS \
+		distclean-tags distclean-generic clean-am
+	-rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am:  maintainer-clean-libLTLIBRARIES \
+		maintainer-clean-compile maintainer-clean-libtool \
+		maintainer-clean-checkPROGRAMS maintainer-clean-tags \
+		maintainer-clean-generic distclean-am
+	@echo "This command is intended for maintainers to use;"
+	@echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-libLTLIBRARIES distclean-libLTLIBRARIES \
+clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \
+uninstall-libLTLIBRARIES install-libLTLIBRARIES mostlyclean-compile \
+distclean-compile clean-compile maintainer-clean-compile \
+mostlyclean-libtool distclean-libtool clean-libtool \
+maintainer-clean-libtool mostlyclean-checkPROGRAMS \
+distclean-checkPROGRAMS clean-checkPROGRAMS \
+maintainer-clean-checkPROGRAMS uninstall-kjsincludeHEADERS \
+install-kjsincludeHEADERS tags mostlyclean-tags distclean-tags \
+clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \
+check-am installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+parser: $(srcdir)/grammar.y
+	cd $(srcdir); \
+	$(YACC) -d -p kjsyy grammar.y && mv grammar.tab.c grammar.cpp; \
+	if test -f grammar.tab.h; then \
+	if cmp -s grammar.tab.h grammar.h; then rm -f grammar.tab.h; \
+	else mv grammar.tab.h grammar.h; fi \
+	else :; fi
+
+debugger: $(libkjs_la_SOURCES) $(kjsinclude_HEADERS) $(noinst_HEADERS)
+	$(MAKE) DEFS="-DKJS_DEBUGGER $(DEFS)" libkjs.la
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
+
+#>+ 8
+libkjs.la.closure: $(libkjs_la_OBJECTS) $(libkjs_la_DEPENDENCIES)
+	@echo "int main() {return 0;}" > libkjs_la_closure.cpp
+	@$(LTCXXCOMPILE) -c libkjs_la_closure.cpp
+	@$(CXXLINK) libkjs_la_closure.lo $(libkjs_la_LDFLAGS) $(libkjs_la_OBJECTS) $(libkjs_la_LIBADD) $(LIBS)
+	@rm -f libkjs_la_closure.* libkjs.la.closure
+	@echo "timestamp" > libkjs.la.closure
+
+
+#>+ 3
+clean-closures:
+	-rm -f  libkjs.la.closure
+
+#>+ 2
+docs-am:
+
+#>+ 5
+force-reedit:
+		cd $(top_srcdir) && $(AUTOMAKE) --foreign --include-deps kjs/Makefile
+	cd $(top_srcdir) && perl admin/am_edit kjs/Makefile.in
+
+
+#>+ 11
+libkjs_la.all_cpp.cpp: $(srcdir)/Makefile.in $(srcdir)/kjs.cpp $(srcdir)/grammar.cpp $(srcdir)/lexer.cpp $(srcdir)/nodes.cpp $(srcdir)/object.cpp $(srcdir)/operations.cpp $(srcdir)/ustring.cpp $(srcdir)/function.cpp $(srcdir)/types.cpp $(srcdir)/lookup.cpp $(srcdir)/internal.cpp $(srcdir)/regexp.cpp $(srcdir)/global_object.cpp $(srcdir)/math_object.cpp $(srcdir)/bool_object.cpp $(srcdir)/object_object.cpp $(srcdir)/error_object.cpp $(srcdir)/array_object.cpp $(srcdir)/string_object.cpp $(srcdir)/number_object.cpp $(srcdir)/date_object.cpp $(srcdir)/regexp_object.cpp $(srcdir)/collector.cpp $(srcdir)/function_object.cpp $(srcdir)/debugger.cpp  
+	@echo 'creating libkjs_la.all_cpp.cpp ...'; \
+	rm -f libkjs_la.all_cpp.files libkjs_la.all_cpp.final; \
+	echo "#define KDE_USE_FINAL 1" >> libkjs_la.all_cpp.final; \
+	for file in kjs.cpp grammar.cpp lexer.cpp nodes.cpp object.cpp operations.cpp ustring.cpp function.cpp types.cpp lookup.cpp internal.cpp regexp.cpp global_object.cpp math_object.cpp bool_object.cpp object_object.cpp error_object.cpp array_object.cpp string_object.cpp number_object.cpp date_object.cpp regexp_object.cpp collector.cpp function_object.cpp debugger.cpp ; do \
+	  echo "#include \"$$file\"" >> libkjs_la.all_cpp.files; \
+	  test ! -f $(srcdir)/$$file || egrep '^#pragma +implementation' $(srcdir)/$$file >> libkjs_la.all_cpp.final; \
+	done; \
+	cat libkjs_la.all_cpp.final libkjs_la.all_cpp.files  > libkjs_la.all_cpp.cpp; \
+	rm -f libkjs_la.all_cpp.final libkjs_la.all_cpp.files
+
+#>+ 11
+testkjs.all_cpp.cpp: $(srcdir)/Makefile.in $(srcdir)/testkjs.cpp  
+	@echo 'creating testkjs.all_cpp.cpp ...'; \
+	rm -f testkjs.all_cpp.files testkjs.all_cpp.final; \
+	echo "#define KDE_USE_FINAL 1" >> testkjs.all_cpp.final; \
+	for file in testkjs.cpp ; do \
+	  echo "#include \"$$file\"" >> testkjs.all_cpp.files; \
+	  test ! -f $(srcdir)/$$file || egrep '^#pragma +implementation' $(srcdir)/$$file >> testkjs.all_cpp.final; \
+	done; \
+	cat testkjs.all_cpp.final testkjs.all_cpp.files  > testkjs.all_cpp.cpp; \
+	rm -f testkjs.all_cpp.final testkjs.all_cpp.files
+
+#>+ 3
+clean-final:
+	-rm -f libkjs_la.all_cpp.cpp testkjs.all_cpp.cpp
+
+#>+ 2
+final:
+	$(MAKE) libkjs_la_OBJECTS="$(libkjs_la_final_OBJECTS)" all-am
+#>+ 2
+no-final:
+	$(MAKE) libkjs_la_OBJECTS="$(libkjs_la_nofinal_OBJECTS)" all-am
+#>+ 3
+cvs-clean:
+	$(MAKE) -f $(top_srcdir)/admin/Makefile.common cvs-clean
+
+#>+ 3
+kde-rpo-clean:
+	-rm -f *.rpo
diff --git a/WebCore/src/kdelibs/kjs/README b/WebCore/src/kdelibs/kjs/README
new file mode 100644
index 0000000..b4a0fcc
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/README
@@ -0,0 +1,25 @@
+This library provides an ECMAScript compatible interpreter. The ECMA standard
+is based on well known scripting languages such as Netscape's JavaScript and
+Microsoft's JScript.
+
+I'm currently pursuing to be compliant with Edition 3 of ECMA-262. Postscript
+and pdf versions of the standard are avaiable at:
+
+http://www.ecma.ch
+
+About 90% of the required features should be covered by now. Note that this
+number covers the core language elements only. Features like the famous
+roll-over buttons on the www are NOT part of the standard. Those extensions
+are added via a module loaded dynamically by the KHTML Widget.
+
+I'll provide some examples of how to extend this library for various needs at
+a later point in time. Feel free to contact me via mail if you have any
+questions on how to provide scripting capabilites for your application.
+
+A debugger is being worked on. To compile it, add -DKJS_DEBUGGER to the CXXFLAGS
+section in the Makefile.am of kdelibs/kjs and kdelibs/khtml/ecma.
+
+Bug reports, patches or feedback of any kind is very welcome.
+
+Harri Porten <porten at kde.org>
+
diff --git a/WebCore/src/kdelibs/kjs/THANKS b/WebCore/src/kdelibs/kjs/THANKS
new file mode 100644
index 0000000..036e5e7
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/THANKS
@@ -0,0 +1,7 @@
+I would like to thank the following people for their help:
+
+Richard Moore <rich at kde.org> - for filling the Math object with some life
+Daegeun Lee <realking at mizi.com> - for pointing out some bugs and providing
+                                  much code for the String and Date object.
+Marco Pinelli <pinmc at libero.it> - for his patches
+Christian Kirsch <ck at held.mind.de> - for his contribution to the Date object
diff --git a/WebCore/src/kdelibs/kjs/array_object.cpp b/WebCore/src/kdelibs/kjs/array_object.cpp
new file mode 100644
index 0000000..cc97dff
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/array_object.cpp
@@ -0,0 +1,341 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "kjs.h"
+#include "operations.h"
+#include "types.h"
+#include "array_object.h"
+#include <stdio.h>
+
+using namespace KJS;
+
+ArrayObject::ArrayObject(const Object &funcProto,
+			 const Object &arrayProto)
+    : ConstructorImp(funcProto, 1)
+{
+  // ECMA 15.4.3.1 Array.prototype
+  setPrototypeProperty(arrayProto);
+}
+
+// ECMA 15.6.1
+Completion ArrayObject::execute(const List &args)
+{
+  // equivalent to 'new Array(....)'
+  KJSO result = construct(args);
+
+  return Completion(ReturnValue, result);
+}
+
+// ECMA 15.6.2
+Object ArrayObject::construct(const List &args)
+{
+  Object result = Object::create(ArrayClass);
+
+  unsigned int len;
+  ListIterator it = args.begin();
+  // a single argument might denote the array size
+  if (args.size() == 1 && it->isA(NumberType))
+    len = it->toUInt32();
+  else {
+    // initialize array
+    len = args.size();
+    for (unsigned int u = 0; it != args.end(); it++, u++)
+      result.put(UString::from(u), *it);
+  }
+
+  // array size
+  result.put("length", len, DontEnum | DontDelete);
+
+  return result;
+}
+
+// ECMA 15.6.4
+ArrayPrototype::ArrayPrototype(const Object& proto)
+  : ObjectImp(ArrayClass, Null(), proto)
+{
+  // The constructor will be added later in ArrayObject's constructor
+
+  put("length", 0u, DontEnum | DontDelete);
+}
+
+KJSO ArrayPrototype::get(const UString &p) const
+{
+  int id;
+  if(p == "toString")
+    id = ArrayProtoFunc::ToString;
+  else if(p == "toLocaleString")
+    id = ArrayProtoFunc::ToLocaleString;
+  else if(p == "concat")
+    id = ArrayProtoFunc::Concat;
+  else if (p == "join")
+    id = ArrayProtoFunc::Join;
+  else if(p == "pop")
+    id = ArrayProtoFunc::Pop;
+  else if(p == "push")
+    id = ArrayProtoFunc::Push;
+  else if(p == "reverse")
+    id = ArrayProtoFunc::Reverse;
+  else if(p == "shift")
+    id = ArrayProtoFunc::Shift;
+  else if(p == "slice")
+    id = ArrayProtoFunc::Slice;
+  else if(p == "sort")
+    id = ArrayProtoFunc::Sort;
+  else if(p == "splice")
+    id = ArrayProtoFunc::Splice;
+  else if(p == "unshift")
+    id = ArrayProtoFunc::UnShift;
+  else
+    return Imp::get(p);
+
+  return Function(new ArrayProtoFunc(id));
+}
+
+// ECMA 15.4.4
+Completion ArrayProtoFunc::execute(const List &args)
+{
+  KJSO result, obj, obj2;
+  Object thisObj = Object::dynamicCast(thisValue());
+  unsigned int length = thisObj.get("length").toUInt32();
+  unsigned int middle;
+  UString str = "", str2;
+  UString separator = ",";
+
+  switch (id) {
+  case ToLocaleString:
+    /* TODO */
+    // fall trough
+  case ToString:
+    if (!thisObj.getClass() == ArrayClass) {
+      result = Error::create(TypeError);
+      break;
+    }
+    // fall trough
+  case Join:
+    {
+      if (!args[0].isA(UndefinedType))
+	separator = args[0].toString().value();
+      for (unsigned int k = 0; k < length; k++) {
+	if (k >= 1)
+	  str += separator;
+	obj = thisObj.get(UString::from(k));
+	if (!obj.isA(UndefinedType) && !obj.isA(NullType))
+	  str += obj.toString().value();
+      }
+    }
+    result = String(str);
+    break;
+  case Concat: {
+    result = Object::create(ArrayClass);
+    int n = 0;
+    obj = thisObj;
+    ListIterator it = args.begin();
+    for (;;) {
+      if (obj.isA(ObjectType) &&
+	  static_cast<Object&>(obj).getClass() == ArrayClass) {
+	unsigned int k = 0;
+	if (n > 0)
+	  length = obj.get("length").toUInt32();
+	while (k < length) {
+	  UString p = UString::from(k);
+	  if (obj.hasProperty(p))
+	    result.put(UString::from(n), obj.get(p));
+	  n++;
+	  k++;
+	}
+      } else {
+	result.put(UString::from(n), obj);
+	n++;      
+      }
+      if (it == args.end())
+	break;
+      obj = it++;
+    }
+    result.put("length", Number(n), DontEnum | DontDelete);
+  }
+    break;
+  case Pop:
+    if (length == 0) {
+      thisObj.put("length", Number(length), DontEnum | DontDelete);
+      result = Undefined();
+    } else {
+      str = UString::from(length - 1);
+      result = thisObj.get(str);
+      thisObj.deleteProperty(str);
+      thisObj.put("length", length - 1, DontEnum | DontDelete);
+    }
+    break;
+  case Push:
+    {
+      for (int n = 0; n < args.size(); n++)
+	thisObj.put(UString::from(length + n), args[n]);
+      length += args.size();
+      thisObj.put("length", length, DontEnum | DontDelete);
+      result = Number(length);
+    }
+    break;
+  case Reverse:
+    {
+      middle = length / 2;
+      for (unsigned int k = 0; k < middle; k++) {
+	str = UString::from(k);
+	str2 = UString::from(length - k - 1);
+	obj = thisObj.get(str);
+	obj2 = thisObj.get(str2);
+	if (thisObj.hasProperty(str2)) {
+	  if (thisObj.hasProperty(str)) {
+	    thisObj.put(str, obj2);
+	    thisObj.put(str2, obj);
+	  } else {
+	    thisObj.put(str, obj2);
+	    thisObj.deleteProperty(str2);
+	  }
+	} else {
+	  if (thisObj.hasProperty(str)) {
+	    thisObj.deleteProperty(str);
+	    thisObj.put(str2, obj);
+	  } else {
+	    // why delete something that's not there ? Strange.
+	    thisObj.deleteProperty(str);
+	    thisObj.deleteProperty(str2);
+	  }
+	}
+      }
+    }
+    result = thisObj;
+    break;
+  case Shift:
+    if (length == 0) {
+      thisObj.put("length", Number(length), DontEnum | DontDelete);
+      result = Undefined();
+    } else {
+      result = thisObj.get("0");
+      for(unsigned int k = 1; k < length; k++) {
+	str = UString::from(k);
+	str2 = UString::from(k-1);
+	if (thisObj.hasProperty(str)) {
+	  obj = thisObj.get(str);
+	  thisObj.put(str2, obj);
+	} else
+	  thisObj.deleteProperty(str2);
+      }
+      thisObj.deleteProperty(UString::from(length - 1));
+      thisObj.put("length", length - 1, DontEnum | DontDelete);
+    }
+    break;
+  case Slice: // http://developer.netscape.com/docs/manuals/js/client/jsref/array.htm#1193713
+    {
+        result = Object::create(ArrayClass); // We return a new array
+        int begin = args[0].toUInt32();
+        int end = length;
+        if (!args[1].isA(UndefinedType))
+        {
+          end = args[1].toUInt32();
+          if ( end < 0 )
+            end += length;
+        }
+        // safety tests
+        if ( begin < 0 || end < 0 || begin >= end ) {
+            result.put("length", Number(0), DontEnum | DontDelete);
+            break;
+        }
+        //printf( "Slicing from %d to %d \n", begin, end );
+        for(unsigned int k = 0; k < (unsigned int) end-begin; k++) {
+            str = UString::from(k+begin);
+            str2 = UString::from(k);
+            if (thisObj.hasProperty(str)) {
+                obj = thisObj.get(str);
+                result.put(str2, obj);
+            }
+        }
+        result.put("length", end - begin, DontEnum | DontDelete);
+        break;
+    }
+  case Sort:
+    {
+#if 0
+        printf("KJS Array::Sort length=%d\n", length);
+        for ( unsigned int i = 0 ; i<length ; ++i )
+            printf("KJS Array::Sort: %d: %s\n", i, thisObj.get(UString::from(i)).toString().value().ascii() );
+#endif
+        Object sortFunction;
+        bool useSortFunction = !args[0].isA(UndefinedType);
+        if (useSortFunction)
+        {
+            sortFunction = args[0].toObject();
+            if (!sortFunction.implementsCall())
+                useSortFunction = false;
+        }
+
+        if (length == 0) {
+            thisObj.put("length", Number(0), DontEnum | DontDelete);
+            result = Undefined();
+            break;
+        }
+
+        // "Min" sort. Not the fastest, but definitely less code than heapsort
+        // or quicksort, and much less swapping than bubblesort/insertionsort.
+        for ( unsigned int i = 0 ; i<length-1 ; ++i )
+        {
+            KJSO iObj = thisObj.get(UString::from(i));
+            unsigned int themin = i;
+            KJSO minObj = iObj;
+            for ( unsigned int j = i+1 ; j<length ; ++j )
+            {
+                KJSO jObj = thisObj.get(UString::from(j));
+                int cmp;
+                if ( useSortFunction )
+                {
+                    List l;
+                    l.append(jObj);
+                    l.append(minObj);
+                    cmp = sortFunction.executeCall( Global::current(), &l ).toInt32();
+                }
+                else
+                    cmp = ( jObj.toString().value() < minObj.toString().value() ) ? -1 : 1;
+                if ( cmp < 0 )
+                {
+                    themin = j;
+                    minObj = jObj;
+                }
+            }
+            // Swap themin and i
+            if ( themin > i )
+            {
+                //printf("KJS Array::Sort: swapping %d and %d\n", i, themin );
+                thisObj.put( UString::from(i), minObj );
+                thisObj.put( UString::from(themin), iObj );
+            }
+        }
+#if 0
+        printf("KJS Array::Sort -- Resulting array:\n");
+        for ( unsigned int i = 0 ; i<length ; ++i )
+            printf("KJS Array::Sort: %d: %s\n", i, thisObj.get(UString::from(i)).toString().value().ascii() );
+#endif
+        result = thisObj;
+        break;
+    }
+  // TODO Splice
+  // TODO Unshift
+  default:
+    result = Undefined();
+  }
+
+  return Completion(ReturnValue, result);
+}
diff --git a/WebCore/src/kdelibs/kjs/array_object.h b/WebCore/src/kdelibs/kjs/array_object.h
new file mode 100644
index 0000000..f4d56e4
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/array_object.h
@@ -0,0 +1,53 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _ARRAY_OBJECT_H_
+#define _ARRAY_OBJECT_H_
+
+#include "object.h"
+#include "function.h"
+
+namespace KJS {
+
+  class ArrayObject : public ConstructorImp {
+  public:
+    ArrayObject(const Object &funcProto, const Object &arrayProto);
+    Completion execute(const List &);
+    Object construct(const List &);
+  };
+
+  class ArrayPrototype : public ObjectImp {
+  public:
+    ArrayPrototype(const Object& proto);
+    virtual KJSO get(const UString &p) const;
+  };
+
+  class ArrayProtoFunc : public InternalFunctionImp {
+  public:
+    ArrayProtoFunc(int i) : id(i) { }
+    Completion execute(const List &);
+    enum { ToString, ToLocaleString, Concat, Join, Pop, Push,
+	   Reverse, Shift, Slice, Sort, Splice, UnShift };
+  private:
+    int id;
+  };
+
+}; // namespace
+
+#endif
diff --git a/WebCore/src/kdelibs/kjs/bool_object.cpp b/WebCore/src/kdelibs/kjs/bool_object.cpp
new file mode 100644
index 0000000..08fcc5c
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/bool_object.cpp
@@ -0,0 +1,103 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "kjs.h"
+#include "operations.h"
+#include "types.h"
+#include "bool_object.h"
+#include "error_object.h"
+
+using namespace KJS;
+
+BooleanObject::BooleanObject(const KJSO& funcProto, const KJSO &booleanProto)
+  : ConstructorImp(funcProto, 1)
+{
+  // Boolean.prototype
+  setPrototypeProperty(booleanProto);
+}
+
+// ECMA 15.6.1
+Completion BooleanObject::execute(const List &args)
+{
+  Boolean b;
+
+  if (args.isEmpty())
+    b = Boolean(false);
+  else
+    b = args[0].toBoolean();
+
+  return Completion(ReturnValue, b);
+}
+
+// ECMA 15.6.2
+Object BooleanObject::construct(const List &args)
+{
+  Boolean b;
+  if (args.size() > 0)
+    b = args.begin()->toBoolean();
+  else
+    b = Boolean(false);
+
+  return Object::create(BooleanClass, b);
+}
+
+// ECMA 15.6.4
+BooleanPrototype::BooleanPrototype(const Object& proto)
+  : ObjectImp(BooleanClass, Boolean(false), proto)
+{
+  // The constructor will be added later in BooleanObject's constructor
+}
+
+KJSO BooleanPrototype::get(const UString &p) const
+{
+  if (p == "toString")
+    return Function(new BooleanProtoFunc(ToString));
+  else if (p == "valueOf")
+    return Function(new BooleanProtoFunc(ValueOf));
+  else
+    return Imp::get(p);
+}
+
+BooleanProtoFunc::BooleanProtoFunc(int i)
+  : id(i)
+{
+}
+
+// ECMA 15.6.4.2 + 15.6.4.3
+Completion BooleanProtoFunc::execute(const List &)
+{
+  KJSO result;
+
+  Object thisObj = Object::dynamicCast(thisValue());
+
+  // no generic function. "this" has to be a Boolean object
+  if (thisObj.isNull() || thisObj.getClass() != BooleanClass) {
+    result = Error::create(TypeError);
+    return Completion(ReturnValue, result);
+  }
+
+  // execute "toString()" or "valueOf()", respectively
+  KJSO v = thisObj.internalValue();
+  if (id == BooleanPrototype::ToString)
+    result = v.toString();
+  else
+    result = v.toBoolean();
+
+  return Completion(ReturnValue, result);
+}
diff --git a/WebCore/src/kdelibs/kjs/bool_object.h b/WebCore/src/kdelibs/kjs/bool_object.h
new file mode 100644
index 0000000..89dc451
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/bool_object.h
@@ -0,0 +1,52 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _BOOL_OBJECT_H_
+#define _BOOL_OBJECT_H_
+
+#include "object.h"
+#include "function.h"
+
+namespace KJS {
+
+  class BooleanObject : public ConstructorImp {
+  public:
+    BooleanObject(const KJSO& funcProto, const KJSO &booleanProto);
+    Completion execute(const List &);
+    Object construct(const List &);
+  };
+
+  class BooleanPrototype : public ObjectImp {
+  public:
+    BooleanPrototype(const Object& proto);
+    virtual KJSO get(const UString &p) const;
+    enum { ToString, ValueOf };
+  };
+
+  class BooleanProtoFunc : public InternalFunctionImp {
+  public:
+    BooleanProtoFunc(int i);
+    Completion execute(const List &);
+  private:
+    int id;
+  };
+
+}; // namespace
+
+#endif
diff --git a/WebCore/src/kdelibs/kjs/collector.cpp b/WebCore/src/kdelibs/kjs/collector.cpp
new file mode 100644
index 0000000..df79038
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/collector.cpp
@@ -0,0 +1,211 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "collector.h"
+#include "object.h"
+#include "internal.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+namespace KJS {
+
+  class CollectorBlock {
+  public:
+    CollectorBlock(int s);
+    ~CollectorBlock();
+    int size;
+    int filled;
+    void** mem;
+    CollectorBlock *prev, *next;
+  };
+
+}; // namespace
+
+using namespace KJS;
+
+CollectorBlock::CollectorBlock(int s)
+  : size(s),
+    filled(0),
+    prev(0L),
+    next(0L)
+{
+  mem = new void*[size];
+  memset(mem, 0, size * sizeof(void*));
+}
+
+CollectorBlock::~CollectorBlock()
+{
+  delete [] mem;
+  mem = 0L;
+}
+
+CollectorBlock* Collector::root = 0L;
+CollectorBlock* Collector::currentBlock = 0L;
+unsigned long Collector::filled = 0;
+unsigned long Collector::softLimit = KJS_MEM_INCREMENT;
+#ifdef KJS_DEBUG_MEM
+bool Collector::collecting = false;
+#endif
+
+void* Collector::allocate(size_t s)
+{
+  if (s == 0)
+    return 0L;
+
+  if (filled >= softLimit) {
+    collect();
+    if (filled >= softLimit && softLimit < KJS_MEM_LIMIT) // we are actually using all this memory
+      softLimit *= 2;
+  }
+
+  void *m = malloc(s);
+
+  // hack to ensure obj is protected from GC before any constructors are run
+  // (prev = marked, next = gcallowed)
+  static_cast<Imp*>(m)->prev = 0;
+  static_cast<Imp*>(m)->next = 0;
+
+  if (!root) {
+    root = new CollectorBlock(BlockSize);
+    currentBlock = root;
+  }
+
+  CollectorBlock *block = currentBlock;
+  if (!block)
+    block = root;
+
+  // search for a block with space left
+  while (block->next && block->filled == block->size)
+    block = block->next;
+
+  if (block->filled >= block->size) {
+#ifdef KJS_DEBUG_MEM
+    printf("allocating new block of size %d\n", block->size);
+#endif
+    CollectorBlock *tmp = new CollectorBlock(BlockSize);
+    block->next = tmp;
+    tmp->prev = block;
+    block = tmp;
+  }
+  currentBlock = block;
+  // look for a free spot in the block
+  void **r = block->mem;
+  while (*r)
+    r++;
+  *r = m;
+  filled++;
+  block->filled++;
+
+  if (softLimit >= KJS_MEM_LIMIT) {
+      KJScriptImp::setException("Out of memory");
+  }
+
+  return m;
+}
+
+/**
+ * Mark-sweep garbage collection.
+ */
+void Collector::collect()
+{
+#ifdef KJS_DEBUG_MEM
+  printf("collecting %d objects total\n", Imp::count);
+  collecting = true;
+#endif
+
+  // MARK: first set all ref counts to 0 ....
+  CollectorBlock *block = root;
+  while (block) {
+#ifdef KJS_DEBUG_MEM
+    printf("cleaning block filled %d out of %d\n", block->filled, block->size);
+#endif
+    Imp **r = (Imp**)block->mem;
+    assert(r);
+    for (int i = 0; i < block->size; i++, r++)
+      if (*r) {
+        (*r)->setMarked(false);
+      }
+    block = block->next;
+  }
+
+  // ... increase counter for all referenced objects recursively
+  // starting out from the set of root objects
+  if (KJScriptImp::hook) {
+    KJScriptImp *scr = KJScriptImp::hook;
+    do {
+      scr->mark();
+      scr = scr->next;
+    } while (scr != KJScriptImp::hook);
+  }
+
+  // mark any other objects that we wouldn't delete anyway
+  block = root;
+  while (block) {
+    Imp **r = (Imp**)block->mem;
+    assert(r);
+    for (int i = 0; i < block->size; i++, r++)
+      if (*r && (*r)->created() && ((*r)->refcount || !(*r)->gcAllowed()) && !(*r)->marked())
+        (*r)->mark();
+    block = block->next;
+  }
+
+  // SWEEP: delete everything with a zero refcount (garbage)
+  block = root;
+  while (block) {
+    Imp **r = (Imp**)block->mem;
+    int del = 0;
+    for (int i = 0; i < block->size; i++, r++) {
+      if (*r && ((*r)->refcount == 0) && !(*r)->marked() && (*r)->gcAllowed()) {
+	// emulate destructing part of 'operator delete()'
+	(*r)->~Imp();
+	free(*r);
+	*r = 0L;
+	del++;
+      }
+    }
+    filled -= del;
+    block->filled -= del;
+    block = block->next;
+  }
+
+  // delete the emtpy containers
+  block = root;
+  while (block) {
+    CollectorBlock *next = block->next;
+    if (block->filled == 0) {
+      if (block->prev)
+	block->prev->next = next;
+      if (block == root)
+	root = next;
+      if (next)
+	next->prev = block->prev;
+      if (block == currentBlock) // we don't want a dangling pointer
+	currentBlock = 0L;
+      assert(block != root);
+      delete block;
+    }
+    block = next;
+  }
+
+#ifdef KJS_DEBUG_MEM
+  collecting = false;
+#endif
+}
diff --git a/WebCore/src/kdelibs/kjs/collector.h b/WebCore/src/kdelibs/kjs/collector.h
new file mode 100644
index 0000000..7e88e7f
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/collector.h
@@ -0,0 +1,91 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _KJSCOLLECTOR_H_
+#define _KJSCOLLECTOR_H_
+
+// KJS_MEM_LIMIT and KJS_MEM_INCREMENT can be tweaked to adjust how the
+// garbage collector allocates memory. KJS_MEM_LIMIT is the largest # of objects
+// the collector will allow to be present in memory. Once this limit is reached,
+// a running script will get an "out of memory" exception.
+//
+// KJS_MEM_INCREMENT specifies the amount by which the "soft limit" on memory is
+// increased when the memory gets filled up. The soft limit is the amount after
+// which the GC will run and delete unused objects.
+//
+// If you are debugging seemingly random crashes where an object has been deleted,
+// try setting KJS_MEM_INCREMENT to something small, e.g. 300, to force garbage
+// collection to happen more often, and disable the softLimit increase &
+// out-of-memory testing code in Collector::allocate()
+
+#define KJS_MEM_LIMIT 500000
+#define KJS_MEM_INCREMENT 1000
+
+#include <stdlib.h>
+
+namespace KJS {
+
+  class Imp;
+  class CollectorBlock;
+
+  /**
+   * @short Garbage collector.
+   */
+  class Collector {
+    // disallow direct construction/destruction
+    Collector();
+  public:
+    /**
+     * Register an object with the collector. The following assumptions are
+     * made:
+     * @li the operator new() of the object class is overloaded.
+     * @li operator delete() has been overloaded as well and does not free
+     * the memory on its own.
+     *
+     * @param s Size of the memory to be registered.
+     * @return A pointer to the allocated memory.
+     */
+    static void* allocate(size_t s);
+    /**
+     * Run the garbage collection. This involves calling the delete operator
+     * on each object and freeing the used memory.
+     * In the current implemenation this will basically free all registered
+     * object regardless whether they are still references by others or not.
+     * 
+     */
+    static void collect();
+    static int size() { return filled; }
+
+#ifdef KJS_DEBUG_MEM
+    /**
+     * @internal
+     */
+    static bool collecting;
+#endif
+  private:
+    static CollectorBlock* root;
+    static CollectorBlock* currentBlock;
+    static unsigned long filled;
+    static unsigned long softLimit;
+    enum { BlockSize = 100 };
+  };
+
+};
+
+#endif
diff --git a/WebCore/src/kdelibs/kjs/configure.in.in b/WebCore/src/kdelibs/kjs/configure.in.in
new file mode 100644
index 0000000..d789ce3
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/configure.in.in
@@ -0,0 +1,51 @@
+dnl KDE JavaScript specific configure tests
+
+AC_CHECK_HEADERS(ieeefp.h float.h)
+AC_CHECK_LIB(m, isinf, [
+  AC_DEFINE_UNQUOTED(HAVE_FUNC_ISINF, 1, [Define if you have isinf])
+])
+AC_CHECK_LIB(m, finite, [
+  AC_DEFINE_UNQUOTED(HAVE_FUNC_FINITE, 1, [Define if you have finite])
+])
+AC_CHECK_LIB(m, _finite, [
+  AC_DEFINE_UNQUOTED(HAVE_FUNC__FINITE, 1, [Define if you have _finite])
+])
+AC_CHECK_LIB(m, isnan, [
+  AC_DEFINE_UNQUOTED(HAVE_FUNC_ISNAN, 1, [Define if you have isnan])
+])
+
+AC_DEFUN(AC_CHECK_PCREPOSIX,
+[
+  AC_MSG_CHECKING([for pcreposix])
+  AC_CACHE_VAL(ac_cv_have_pcreposix,
+  [
+    ac_save_libs="$LIBS"
+    KDE_FIND_PATH(pcre-config, PCRE_CONFIG, [${prefix}/bin /usr/local/bin /opt/local/bin], [PCRE_CONFIG="" ])
+    if test -n "$PCRE_CONFIG" && $PCRE_CONFIG --libs >/dev/null 2>&1; then
+        LIBS=`$PCRE_CONFIG --libs --libs-posix`
+        CPPFLAGS="$CPPFLAGS `$PCRE_CONFIG --cflags`"
+    else
+        LIBS="-lpcre -lpcreposix"
+    fi
+    ac_CPPFLAGS_save="$CPPFLAGS"
+    CPPFLAGS="$CPPFLAGS $all_includes"
+    ac_LDFLAGS_save="$LDFLAGS"
+    LDFLAGS="$LDFLAGS $all_libraries"
+    AC_TRY_LINK(
+      [#include <pcreposix.h>],
+      [regfree(0);],
+      [ac_cv_have_pcreposix="yes"],
+      [ac_cv_have_pcreposix="no"]
+    )
+    LIBS="$ac_save_libs"
+    LDFLAGS="$ac_LDFLAGS_save"
+    CPPFLAGS="$ac_CPPFLAGS_save"
+  ])
+  AC_MSG_RESULT($ac_cv_have_pcreposix)
+  if test "$ac_cv_have_pcreposix" = "yes"; then
+    LIBPCRE="-lpcre -lpcreposix"
+    AC_DEFINE(HAVE_PCREPOSIX, 1, [Define if you have pcreposix libraries and header files.])
+  fi
+])
+AC_CHECK_PCREPOSIX
+AC_SUBST(LIBPCRE)
diff --git a/WebCore/src/kdelibs/kjs/create_hash_table b/WebCore/src/kdelibs/kjs/create_hash_table
new file mode 100755
index 0000000..85c6744
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/create_hash_table
@@ -0,0 +1,116 @@
+#! /usr/bin/perl
+
+$file = $ARGV[0];
+open(IN, $file) or die "No such file $file";
+
+ at keys = ();
+ at values = ();
+ at attrs = ();
+
+my $inside = 0;
+my $name;
+my $size;
+my $hashsize;
+my $banner = 0;
+
+while (<IN>) {
+  chop; 
+  s/^\s*//g; 
+  if (/^\#|^$/) {
+      # comment. do nothing
+    } elsif (/^\@begin\s*(\w+)\s*(\d+)\s*$/ && !$inside) {
+      $inside = 1;
+      $name = $1;
+      $hashsize = $2;
+    } elsif (/^\@end\s*$/ && $inside) {
+      calcTable();
+      output();
+      @keys = ();
+      @values = ();
+      @attrs = ();
+      $inside = 0;
+    } elsif (/^(\w+)\s*([\w\:]+)\s*([\w\|]*)\s*$/ && $inside) {
+      push(@keys, $1);
+      push(@values, $2);
+      push(@attrs, length($3) > 0 ? $3 : "0");
+    } else {
+      die "invalid data";
+    }
+}
+
+die "missing closing \@end" if ($inside);
+
+sub calcTable() {
+  @table = ();
+  @links = ();
+  $size = $hashsize;
+  my $collisions = 0;
+  my $i = 0;
+  foreach $key (@keys) {
+    my $h = hashValue($key) % $hashsize;
+    while (defined($table[$h])) {
+      if (defined($links[$h])) {
+	$h = $links[$h];
+      } else {
+	$collisions++;
+	$links[$h] = $size;
+	$h = $size;
+	$size++;
+      }
+    }
+    $table[$h] = $i;
+    $i++;
+  }
+
+# print "// Number of collisions: $collisions\n";
+#  printf "total size: $size\n";
+#  my $i = 0;
+#  foreach $entry (@table) {
+#    print "$i " . $entry;
+#    print " -> " . $links[$i] if (defined($links[$i]));
+#    print "\n";
+#    $i++;
+#  }
+}
+
+sub hashValue {
+  @chars = split(/ */, @_[0]);
+  my $val = 0;
+  foreach $c (@chars) {
+    $val += ord($c);
+  }
+  return $val;
+}
+
+sub output {
+  if (!$banner) {
+    $banner = 1;
+    print "/* automatically generated from $file. DO NOT EDIT ! */\n";
+  }
+
+  print "\nnamespace KJS {\n";
+  print "\nconst struct HashEntry2 ${name}Entries[] = {\n";
+  my $i = 0;
+  foreach $entry (@table) {
+    if (defined($entry)) {
+      my $key = $keys[$entry];
+      print "   \{ \"" . $key . "\"";
+      print ", " . $values[$entry];
+      print ", " . $attrs[$entry] . ", ";
+      if (defined($links[$i])) {
+	print "&${name}Entries[$links[$i]]" . " \}";
+      } else {
+	print "0 \}"
+      }
+    } else {
+      print "   \{ 0, 0, 0, 0 \}";
+    }
+    print "," unless ($i == $size - 1);
+    print "\n";
+    $i++;
+  }
+  print "};\n";
+  print "\nconst struct HashTable2 $name = ";
+  print "\{ 2, $size, ${name}Entries, $hashsize \};\n\n";
+  print "}; // namespace\n";
+}
diff --git a/WebCore/src/kdelibs/kjs/date_object.cpp b/WebCore/src/kdelibs/kjs/date_object.cpp
new file mode 100644
index 0000000..ab81504
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/date_object.cpp
@@ -0,0 +1,466 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#ifndef HAVE_SYS_TIMEB_H
+#define HAVE_SYS_TIMEB_H 0
+#endif
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+#if HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#  include <time.h>
+# endif
+#endif
+#if HAVE_SYS_TIMEB_H
+#include <sys/timeb.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#  include <sys/param.h>
+#endif // HAVE_SYS_PARAM_H
+
+#include <math.h>
+#include <string.h>
+#include <stdio.h>
+#include <locale.h>
+
+#include "kjs.h"
+#include "date_object.h"
+
+namespace KJS {
+
+  class DateObjectFunc : public InternalFunctionImp {
+  public:
+    DateObjectFunc(int i) : id(i) { };
+    Completion execute(const List &);
+    enum { Parse, UTC };
+  private:
+    int id;
+  };
+
+  class DateProtoFunc : public InternalFunctionImp {
+  public:
+    DateProtoFunc(int i, bool u);
+    Completion execute(const List &);
+    enum { ToString, ToDateString, ToTimeString, ToLocaleString,
+	   ToLocaleDateString, ToLocaleTimeString, ValueOf, GetTime,
+	   GetFullYear, GetMonth, GetDate, GetDay, GetHours, GetMinutes,
+	   GetSeconds, GetMilliSeconds, GetTimezoneOffset, SetTime,
+	   SetMilliSeconds, SetSeconds, SetMinutes, SetHours, SetDate,
+	   SetMonth, SetFullYear, ToUTCString,
+	   // non-normative properties (Appendix B)
+	   GetYear, SetYear, ToGMTString };
+  private:
+    int id;
+    bool utc;
+  };
+
+  // helper functions
+  KJSO parseDate(const String &s);
+  KJSO timeClip(const KJSO &t);
+};
+
+using namespace KJS;
+
+KJSO KJS::parseDate(const String &s)
+{
+  UString u = s.value();
+  int firstSlash = u.find('/');
+  if ( firstSlash == -1 )
+  {
+    /* TODO parse dates like "December 25, 1995 23:15:00"*/
+    fprintf(stderr,"KJS::parseDate parsing for this format isn't implemented\n%s", u.ascii());
+    return Number(0);
+  }
+  else
+  {
+    // Found 12/31/2099 on some website -> obviously MM/DD/YYYY
+    int month = u.substr(0,firstSlash).toULong();
+    int secondSlash = u.find('/',firstSlash+1);
+    //fprintf(stdout,"KJS::parseDate firstSlash=%d, secondSlash=%d\n", firstSlash, secondSlash);
+    if ( secondSlash == -1 )
+    {
+      fprintf(stderr,"KJS::parseDate parsing for this format isn't implemented\n%s", u.ascii());
+      return Number(0);
+    }
+    int day = u.substr(firstSlash+1,secondSlash-firstSlash-1).toULong();
+    int year = u.substr(secondSlash+1).toULong();
+    //fprintf(stdout,"KJS::parseDate day=%d, month=%d, year=%d\n", day, month, year);
+    struct tm t;
+    memset( &t, 0, sizeof(t) );
+    year = (year > 2037) ? 2037 : year; // mktime is limited to 2037 !!!
+    t.tm_year = (year >= 0 && year <= 99) ? year : year - 1900;
+    t.tm_mon = month-1; // mktime wants 0-11 for some reason
+    t.tm_mday = day;
+    time_t seconds = mktime(&t);
+    if ( seconds == -1 )
+    {
+      fprintf(stderr,"KJS::parseDate mktime returned -1.\n%s", u.ascii());
+      return Undefined();
+    }
+    else
+      return Number(seconds * 1000.0);
+  }
+}
+
+KJSO KJS::timeClip(const KJSO &t)
+{
+  /* TODO */
+  return t;
+}
+
+DateObject::DateObject(const Object& funcProto, const Object &dateProto)
+    : ConstructorImp(funcProto, 7)
+{
+  // ECMA 15.9.4.1 Date.prototype
+  setPrototypeProperty(dateProto);
+}
+
+// ECMA 15.9.2
+Completion DateObject::execute(const List &)
+{
+  time_t t = time(0L);
+  UString s(ctime(&t));
+
+  // return formatted string minus trailing \n
+  return Completion(ReturnValue, String(s.substr(0, s.size() - 1)));
+}
+
+// ECMA 15.9.3
+Object DateObject::construct(const List &args)
+{
+  KJSO value;
+
+  int numArgs = args.size();
+
+  if (numArgs == 0) { // new Date() ECMA 15.9.3.3
+#if HAVE_SYS_TIMEB_H
+#  if defined(__BORLANDC__)
+    struct timeb timebuffer;
+    ftime(&timebuffer);
+#  else
+    struct _timeb timebuffer;
+    _ftime(&timebuffer);
+#  endif
+    double utc = floor((double)timebuffer.time * 1000.0 + (double)timebuffer.millitm);
+#else
+    struct timeval tv;
+    gettimeofday(&tv, 0L);
+    double utc = floor((double)tv.tv_sec * 1000.0 + (double)tv.tv_usec / 1000.0);
+#endif
+    value = Number(utc);
+  } else if (numArgs == 1) {
+    KJSO p = args[0].toPrimitive();
+    if (p.isA(StringType))
+      value = parseDate(p.toString());
+    else
+      value = p.toNumber();
+  } else {
+    struct tm t;
+    memset(&t, 0, sizeof(t));
+    Number y = args[0].toNumber();
+    /* TODO: check for NaN */
+    int year = y.toInt32();
+    t.tm_year = (year >= 0 && year <= 99) ? year : year - 1900;
+    t.tm_mon = args[1].toInt32();
+    t.tm_mday = (numArgs >= 3) ? args[2].toInt32() : 1;
+    t.tm_hour = (numArgs >= 4) ? args[3].toInt32() : 0;
+    t.tm_min = (numArgs >= 5) ? args[4].toInt32() : 0;
+    t.tm_sec = (numArgs >= 6) ? args[5].toInt32() : 0;
+    t.tm_isdst = -1;
+    int ms = (numArgs >= 7) ? args[6].toInt32() : 0;
+    value = Number(mktime(&t) * 1000.0 + ms);
+  }
+
+  return Object::create(DateClass, timeClip(value));
+}
+
+KJSO DateObject::get(const UString &p) const
+{
+  int id;
+
+  if (p == "parse")
+    id = DateObjectFunc::Parse;
+  else if (p == "UTC")
+    id = DateObjectFunc::UTC;
+  else
+    return Imp::get(p);
+
+  return Function(new DateObjectFunc(id));
+}
+
+// ECMA 15.9.4.2 - 3
+Completion DateObjectFunc::execute(const List &args)
+{
+  KJSO result;
+
+  if (id == Parse)
+    if (args[0].isA(StringType))
+      result = parseDate(args[0].toString());
+    else
+      result = Undefined();
+  else {
+    struct tm t;
+    memset(&t, 0, sizeof(t));
+    int n = args.size();
+    Number y = args[0].toNumber();
+    /* TODO: check for NaN */
+    int year = y.toInt32();
+    t.tm_year = (year >= 0 && year <= 99) ? year : year - 1900;
+    t.tm_mon = args[1].toInt32();
+    t.tm_mday = (n >= 3) ? args[2].toInt32() : 1;
+    t.tm_hour = (n >= 4) ? args[3].toInt32() : 0;
+    t.tm_min = (n >= 5) ? args[4].toInt32() : 0;
+    t.tm_sec = (n >= 6) ? args[5].toInt32() : 0;
+    int ms = (n >= 7) ? args[6].toInt32() : 0;
+    result = Number(mktime(&t) * 1000.0 + ms);
+  }
+
+  return Completion(ReturnValue, result);
+}
+
+// ECMA 15.9.4
+DatePrototype::DatePrototype(const Object& proto)
+  : ObjectImp(DateClass, Number(NaN), proto)
+{
+  // The constructor will be added later in DateObject's constructor
+}
+
+KJSO DatePrototype::get(const UString &p) const
+{
+  int id;
+
+  if (p == "toString" || p == "toUTCString")
+    id = DateProtoFunc::ToString;
+  else if (p == "toDateString")
+    id = DateProtoFunc::ToDateString;
+  else if (p == "toTimeString")
+    id = DateProtoFunc::ToTimeString;
+  else if (p == "toLocaleString")
+    id = DateProtoFunc::ToLocaleString;
+  else if (p == "toLocaleDateString")
+    id = DateProtoFunc::ToLocaleDateString;
+  else if (p == "toLocaleTimeString")
+    id = DateProtoFunc::ToLocaleTimeString;
+  else if (p == "valueOf")
+    id = DateProtoFunc::ValueOf;
+  else if (p == "getTime")
+    id = DateProtoFunc::GetTime;
+  else if (p == "getFullYear" || p == "getUTCFullYear")
+    id = DateProtoFunc::GetFullYear;
+  else if (p == "toGMTString")
+    id = DateProtoFunc::ToGMTString;
+  else if (p == "getMonth" || p == "getUTCMonth")
+    id = DateProtoFunc::GetMonth;
+  else if (p == "getDate" || p == "getUTCDate")
+    id = DateProtoFunc::GetDate;
+  else if (p == "getDay" || p == "getUTCDay")
+    id = DateProtoFunc::GetDay;
+  else if (p == "getHours" || p == "getUTCHours")
+    id = DateProtoFunc::GetHours;
+  else if (p == "getMinutes" || p == "getUTCMinutes")
+    id = DateProtoFunc::GetMinutes;
+  else if (p == "getSeconds" || p == "getUTCSeconds")
+    id = DateProtoFunc::GetSeconds;
+  else if (p == "getMilliseconds" || p == "getUTCMilliseconds")
+    id = DateProtoFunc::GetMilliSeconds;
+  else if (p == "getTimezoneOffset")
+    id = DateProtoFunc::GetTimezoneOffset;
+  else if (p == "setTime")
+    id = DateProtoFunc::SetTime;
+  else if (p == "setMilliseconds" || p == "setUTCMilliseconds")
+    id = DateProtoFunc::SetMilliSeconds;
+  else if (p == "setSeconds" || p == "setUTCSeconds")
+    id = DateProtoFunc::SetSeconds;
+  else if (p == "setMinutes" || p == "setUTCMinutes")
+    id = DateProtoFunc::SetMinutes;
+  else if (p == "setHours" || p == "setUTCHours")
+    id = DateProtoFunc::SetHours;
+  else if (p == "setDate" || p == "setUTCDate")
+    id = DateProtoFunc::SetDate;
+  else if (p == "setMonth" || p == "setUTCMonth")
+    id = DateProtoFunc::SetMonth;
+  else if (p == "setFullYear" || p == "setUTCFullYear")
+    id = DateProtoFunc::SetFullYear;
+  else if (p == "setYear" )
+    id = DateProtoFunc::SetYear;
+  // non-normative
+  else if (p == "getYear")
+    id = DateProtoFunc::GetYear;
+  else if (p == "toGMTString")
+    id = DateProtoFunc::ToGMTString;
+  else
+    return Undefined();
+
+  bool utc = (p.find("UTC") >= 0) ? true : false;
+  return Function(new DateProtoFunc(id, utc));
+}
+
+DateProtoFunc::DateProtoFunc(int i, bool u) : id(i), utc(u)
+{
+}
+
+Completion DateProtoFunc::execute(const List &args)
+{
+  KJSO result;
+  UString s;
+  const int bufsize=100;
+  char timebuffer[bufsize];
+  char *oldlocale = setlocale(LC_TIME,NULL);
+  if (!oldlocale)
+    oldlocale = setlocale(LC_ALL, NULL);
+  Object thisObj = Object::dynamicCast(thisValue());
+  KJSO v = thisObj.internalValue();
+  double milli = v.toNumber().value();
+  time_t tv = (time_t) floor(milli / 1000.0);
+  int ms = int(milli - tv * 1000.0);
+
+  struct tm *t;
+  if (utc)
+    t = gmtime(&tv);
+  else
+    t = localtime(&tv);
+
+  switch (id) {
+  case ToString:
+    s = ctime(&tv);
+    result = String(s.substr(0, s.size() - 1));
+    break;
+  case ToDateString:
+  case ToTimeString:
+  case ToGMTString:
+    setlocale(LC_TIME,"C");
+    if (id == DateProtoFunc::ToDateString) {
+      strftime(timebuffer, bufsize, "%x",t);
+    } else if (id == DateProtoFunc::ToTimeString) {
+      strftime(timebuffer, bufsize, "%X",t);
+    } else {
+      t = gmtime(&tv);
+      strftime(timebuffer, bufsize, "%a, %d-%b-%y %H:%M:%S %Z", t);
+    }
+    setlocale(LC_TIME,oldlocale);
+    result = String(timebuffer);
+    break;
+  case ToLocaleString:
+    strftime(timebuffer, bufsize, "%c", t);
+    result = String(timebuffer);
+    break;
+  case ToLocaleDateString:
+    strftime(timebuffer, bufsize, "%x", t);
+    result = String(timebuffer);
+    break;
+  case ToLocaleTimeString:
+    strftime(timebuffer, bufsize, "%X", t);
+    result = String(timebuffer);
+    break;
+  case ValueOf:
+    result = Number(milli);
+    break;
+  case GetTime:
+    if (thisObj.getClass() == DateClass)
+      result = Number(milli);
+    else
+      result = Error::create(TypeError);
+    break;
+  case GetYear:
+    result = Number(t->tm_year);
+    break;
+  case GetFullYear:
+    result = Number(1900 + t->tm_year);
+    break;
+  case GetMonth:
+    result = Number(t->tm_mon);
+    break;
+  case GetDate:
+    result = Number(t->tm_mday);
+    break;
+  case GetDay:
+    result = Number(t->tm_wday);
+    break;
+  case GetHours:
+    result = Number(t->tm_hour);
+    break;
+  case GetMinutes:
+    result = Number(t->tm_min);
+    break;
+  case GetSeconds:
+    result = Number(t->tm_sec);
+    break;
+  case GetMilliSeconds:
+    result = Undefined();
+    break;
+  case GetTimezoneOffset:
+#if defined BSD || defined(__APPLE__)
+    result = Number(-( t->tm_gmtoff / 60 ) + ( t->tm_isdst ? 60 : 0 ));
+#else
+#  if defined(__BORLANDC__)
+#error please add daylight savings offset here!
+    result = Number(_timezone / 60 - (_daylight ? 60 : 0));
+#  else
+    result = Number(( timezone / 60 - ( daylight ? 60 : 0 )));
+#  endif
+#endif
+    break;
+  case SetTime:
+    milli = args[0].round();
+    result = Number(milli);
+    thisObj.setInternalValue(result);
+    break;
+  case SetMilliSeconds:
+    ms = args[0].toInt32();
+    break;
+  case SetSeconds:
+    t->tm_sec = args[0].toInt32();
+    break;
+  case SetMinutes:
+    t->tm_min = args[0].toInt32();
+    break;
+  case SetHours:
+    t->tm_hour = args[0].toInt32();
+    break;
+  case SetDate:
+    t->tm_mday = args[0].toInt32();
+    break;
+  case SetMonth:
+    t->tm_mon = args[0].toInt32();
+    break;
+  case SetFullYear:
+    t->tm_year = args[0].toInt32() - 1900;
+    break;
+  case SetYear:
+    t->tm_year = args[0].toInt32() >= 1900 ? args[0].toInt32() - 1900 : args[0].toInt32();
+    break;
+  }
+
+  if (id == SetYear || id == SetMilliSeconds || id == SetSeconds ||
+      id == SetMinutes || id == SetHours || id == SetDate ||
+      id == SetMonth || id == SetFullYear ) {
+    result = Number(mktime(t) * 1000.0 + ms);
+    thisObj.setInternalValue(result);
+  }
+
+  return Completion(ReturnValue, result);
+}
diff --git a/WebCore/src/kdelibs/kjs/date_object.h b/WebCore/src/kdelibs/kjs/date_object.h
new file mode 100644
index 0000000..5eed675
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/date_object.h
@@ -0,0 +1,44 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _DATE_OBJECT_H_
+#define _DATE_OBJECT_H_
+
+#include "object.h"
+#include "function.h"
+
+namespace KJS {
+
+  class DateObject : public ConstructorImp {
+  public:
+    DateObject(const Object& funcProto, const Object &dateProto);
+    Completion execute(const List &);
+    Object construct(const List &);
+    KJSO get(const UString &p) const;
+  };
+
+  class DatePrototype : public ObjectImp {
+  public:
+    DatePrototype(const Object& proto);
+    virtual KJSO get(const UString &p) const;
+  };
+
+}; // namespace
+
+#endif
diff --git a/WebCore/src/kdelibs/kjs/debugger.cpp b/WebCore/src/kdelibs/kjs/debugger.cpp
new file mode 100644
index 0000000..e0f3859
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/debugger.cpp
@@ -0,0 +1,229 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2001 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef KJS_DEBUGGER
+
+#include "debugger.h"
+#include "kjs.h"
+#include "internal.h"
+#include "ustring.h"
+
+using namespace KJS;
+
+Debugger::Debugger(KJScript *engine)
+  : eng(0L),
+    sid(-1)
+{
+  attach(engine);
+}
+
+Debugger::~Debugger()
+{
+  detach();
+}
+
+void Debugger::attach(KJScript *e)
+{
+  dmode = Disabled;
+  if (e) {
+    if (!eng || e->rep != eng->rep) {
+      eng = e;
+      eng->rep->attachDebugger(this);
+    }
+  } else {
+    eng = 0L;
+  }
+  reset();
+}
+
+KJScript *Debugger::engine() const
+{
+  return eng;
+}
+
+void Debugger::detach()
+{
+  reset();
+  if (!eng)
+    return;
+  eng->rep->attachDebugger(0L);
+  eng = 0L;
+}
+
+void Debugger::setMode(Mode m)
+{
+  dmode = m;
+}
+
+Debugger::Mode Debugger::mode() const
+{
+  return dmode;
+}
+
+// supposed to be overriden by the user
+bool Debugger::stopEvent()
+{
+  return true;
+}
+
+void Debugger::callEvent(const UString &, const UString &)
+{
+}
+
+void Debugger::returnEvent()
+{
+}
+
+void Debugger::reset()
+{
+  l = -1;
+}
+
+int Debugger::freeSourceId() const
+{
+  return eng ? eng->rep->sourceId()+1 : -1;
+}
+
+bool Debugger::setBreakpoint(int id, int line)
+{
+  if (!eng)
+    return false;
+  return eng->rep->setBreakpoint(id, line, true);
+}
+
+bool Debugger::deleteBreakpoint(int id, int line)
+{
+  if (!eng)
+    return false;
+  return eng->rep->setBreakpoint(id, line, false);
+}
+
+void Debugger::clearAllBreakpoints(int id)
+{
+  if (!eng)
+    return;
+  eng->rep->setBreakpoint(id, -1, false);
+}
+
+UString Debugger::varInfo(const UString &ident)
+{
+  if (!eng)
+    return UString();
+
+  int dot = ident.find('.');
+  if (dot < 0)
+      dot = ident.size();
+  UString sub = ident.substr(0, dot);
+  KJSO obj;
+  // resolve base
+  if (sub == "this") {
+      obj = Context::current()->thisValue();
+  } else {
+      const List *chain = Context::current()->pScopeChain();
+      ListIterator scope = chain->begin();
+      while (scope != chain->end()) {
+	  if (scope->hasProperty(ident)) {
+	      obj = scope->get(ident);
+	      break;
+	  }
+	  scope++;
+      }
+      if (scope == chain->end())
+	return UString();
+  }
+  // look up each part of a.b.c.
+  while (dot < ident.size()) {
+    int olddot = dot;
+    dot = ident.find('.', olddot+1);
+    if (dot < 0)
+      dot = ident.size();
+    sub = ident.substr(olddot+1, dot-olddot-1);
+    obj = obj.get(sub);
+    if (!obj.isDefined())
+      break;
+  }
+
+  return sub + "=" + objInfo(obj) + ":" + UString(obj.imp()->typeInfo()->name);
+}
+
+// called by varInfo() and recursively by itself on each properties
+UString Debugger::objInfo(const KJSO &obj) const
+{
+  const char *cnames[] = { "Undefined", "Array", "String", "Boolean",
+			   "Number", "Object", "Date", "RegExp",
+			   "Error", "Function" };
+  PropList *plist = obj.imp()->propList(0, 0, false);
+  if (!plist)
+    return obj.toString().value();
+  else {
+    UString result = "{";
+    while (1) {
+      result += plist->name + "=";
+      KJSO p = obj.get(plist->name);
+      result += objInfo(p) + ":";
+      Object obj = Object::dynamicCast(p);
+      if (obj.isNull())
+	result += p.imp()->typeInfo()->name;
+      else
+	result += cnames[int(obj.getClass())];
+      plist = plist->next;
+      if (!plist)
+	break;
+      result += ",";
+    }
+    result += "}";
+    return result;
+  }
+}
+
+bool Debugger::setVar(const UString &ident, const KJSO &value)
+{
+  if (!eng)
+    return false;
+  const List *chain = Context::current()->pScopeChain();
+  ListIterator scope = chain->begin();
+  while (scope != chain->end()) {
+    if (scope->hasProperty(ident)) {
+      if (!scope->canPut(ident))
+	return false;
+      scope->put(ident, value);
+      return true;
+    }
+    scope++;
+  }
+  // didn't find variable
+  return false;
+}
+
+// called from the scripting engine each time a statement node is hit.
+bool Debugger::hit(int line, bool breakPoint)
+{
+  l = line;
+  if (!eng)
+    return true;
+
+  if (!breakPoint && ( mode() == Continue || mode() == Disabled ) )
+      return true;
+
+  bool ret = stopEvent();
+  eng->init();	// in case somebody used a different interpreter meanwhile
+  return ret;
+}
+
+#endif
diff --git a/WebCore/src/kdelibs/kjs/debugger.h b/WebCore/src/kdelibs/kjs/debugger.h
new file mode 100644
index 0000000..b0e97fe
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/debugger.h
@@ -0,0 +1,150 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2001 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _KJSDEBUGGER_H_
+#define _KJSDEBUGGER_H_
+
+#include "internal.h"
+
+namespace KJS {
+
+  //
+  // NOTE: this interface is not ready, yet. Do not use unless you
+  // don't mind source and binary incompatible changes that may arise
+  // before the final version is released.
+  //
+
+#ifdef KJS_DEBUGGER
+  class Debugger {
+    friend class KJScriptImp;
+    friend class StatementNode;
+    friend class DeclaredFunctionImp;
+    friend class FunctionImp;
+  public:
+    /**
+     * Available modes of the debugger.
+     */
+    enum Mode { Disabled = 0, Next, Step, Continue, Stop };
+    /**
+     * Construct a debugger and attach it to the scripting engine s.
+     */
+    Debugger(KJScript *s);
+    /**
+     * Destruct the debugger and detach from the scripting engine we
+     * might have been attached to.
+     */
+    virtual ~Debugger();
+    /**
+     * Attaches the debugger to specified scripting engine.
+     */
+    void attach(KJScript *e);
+    /**
+     * Returns the engine the interpreter is currently attached to. Null
+     * if there isn't any.
+     */
+    KJScript* engine() const;
+    /**
+     * Detach the debugger from any scripting engine.
+     */
+    void detach();
+    /**
+     * Set debugger into specified mode. This will influence further behaviour
+     * if execution of the programm is started or continued.
+     */
+    virtual void setMode(Mode m);
+    /**
+     * Returns the current operation mode.
+     */
+    Mode mode() const;
+    /**
+     * Returns the line number the debugger currently has stopped at.
+     * -1 if the debugger is not in a break status.
+     */
+    int lineNumber() const { return l; }
+    /**
+     * Returns the source id the debugger currently has stopped at.
+     * -1 if the debugger is not in a break status.
+     */
+    int sourceId() const { return sid; }
+    /**
+     * Sets a breakpoint in the first statement where line lies in between
+     * the statements range. Returns true if sucessfull, false if no
+     * matching statement could be found.
+     */
+    bool setBreakpoint(int id, int line);
+    bool deleteBreakpoint(int id, int line);
+    void clearAllBreakpoints(int id=-1);
+    /**
+     * Returns the value of ident out of the current context in string form
+     */
+    UString varInfo(const UString &ident);
+    /**
+     * Set variable ident to value. Returns true if successful, false if
+     * the specified variable doesn't exist or isn't writable.
+     */
+    bool setVar(const UString &ident, const KJSO &value);
+
+  protected:
+    /**
+     * Invoked in case a breakpoint or the next statement is reached in step
+     * mode. The return value decides whether execution will continue. True
+     * denotes continuation, false an abortion, respectively.
+     *
+     * The default implementation does nothing. Overload this method if
+     * you want to process this event.
+     */
+    virtual bool stopEvent();
+    /**
+     * Returns an integer that will be assigned to the code passed
+     * next to one of the KJScript::evaluate() methods. It's basically
+     * a counter to will only be reset to 0 on KJScript::clear().
+     *
+     * This information is useful in case you evaluate multiple blocks of
+     * code containing some function declarations. Keep a map of source id/
+     * code pairs, query sourceId() in case of a stopEvent() and update
+     * your debugger window with the matching source code.
+     */
+    int freeSourceId() const;
+    /**
+     * Invoked on each function call. Use together with @ref returnEvent
+     * if you want to keep track of the call stack.
+     */
+    virtual void callEvent(const UString &fn = UString::null,
+				    const UString &s = UString::null);
+    /**
+     * Invoked on each function exit.
+     */
+    virtual void returnEvent();
+
+  private:
+    void reset();
+    bool hit(int line, bool breakPoint);
+    void setSourceId(int i) { sid = i; }
+    UString objInfo(const KJSO &obj) const;
+
+    KJScript *eng;
+    Mode dmode;
+    int l;
+    int sid;
+  };
+#endif
+
+};
+
+#endif
diff --git a/WebCore/src/kdelibs/kjs/error_object.cpp b/WebCore/src/kdelibs/kjs/error_object.cpp
new file mode 100644
index 0000000..a5aa6d8
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/error_object.cpp
@@ -0,0 +1,125 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "kjs.h"
+#include "operations.h"
+#include "types.h"
+#include "internal.h"
+#include "error_object.h"
+#include "debugger.h"
+
+using namespace KJS;
+
+const char *ErrorObject::errName[] = {
+  "No Error",
+  "Error",
+  "EvalError",
+  "RangeError",
+  "ReferenceError",
+  "SyntaxError",
+  "TypeError",
+  "URIError"
+};
+
+ErrorObject::ErrorObject(const Object &funcProto, const Object &errProto,
+			 ErrorType t)
+  : ConstructorImp(funcProto, 1), errType(t)
+{
+  // ECMA 15.11.3.1 Error.prototype
+  setPrototypeProperty(errProto);
+  const char *n = errName[errType];
+
+  put("name", String(n));
+}
+
+ErrorObject::ErrorObject(const Object& proto, ErrorType t,
+			 const char *m, int l)
+  : ConstructorImp(proto, 1), errType(t)
+{
+  const char *n = errName[errType];
+
+  put("name", String(n));
+  put("message", String(m));
+  put("line", Number(l));
+#ifdef KJS_DEBUGGER
+  Debugger *dbg = KJScriptImp::current()->debugger();
+  if (dbg)
+    put("sid", Number(dbg->sourceId()));
+#endif
+}
+
+// ECMA 15.9.2
+Completion ErrorObject::execute(const List &args)
+{
+  // "Error()" gives the sames result as "new Error()"
+  return Completion(ReturnValue, construct(args));
+}
+
+// ECMA 15.9.3
+Object ErrorObject::construct(const List &args)
+{
+  if (args.isEmpty() == 1 || !args[0].isDefined())
+    return Object::create(ErrorClass, Undefined());
+
+  String message = args[0].toString();
+  return Object::create(ErrorClass, message);
+}
+
+Object ErrorObject::create(ErrorType e, const char *m, int l)
+{
+  Global global(Global::current());
+  KJSO prot = Global::current().get("[[Error.prototype]]");
+  assert(prot.isObject());
+  Imp *d = new ErrorObject(Object(prot.imp()), e, m, l);
+
+  return Object(d);
+}
+
+// ECMA 15.9.4
+ErrorPrototype::ErrorPrototype(const Object& proto)
+  : ObjectImp(ErrorClass, Undefined(), proto)
+{
+  // The constructor will be added later in ErrorObject's constructor
+}
+
+KJSO ErrorPrototype::get(const UString &p) const
+{
+  const char *s;
+
+  /* TODO: are these properties dynamic, i.e. should we put() them ? */
+  if (p == "name")
+    s = "Error";
+  else if (p == "message")
+    s = "Error message.";
+  else if (p == "toString")
+    return Function(new ErrorProtoFunc());
+  else
+    return Imp::get(p);
+
+  return String(s);
+}
+
+Completion ErrorProtoFunc::execute(const List &)
+{
+  // toString()
+  const char *s = "Error message.";
+
+  return Completion(ReturnValue, String(s));
+}
+
diff --git a/WebCore/src/kdelibs/kjs/error_object.h b/WebCore/src/kdelibs/kjs/error_object.h
new file mode 100644
index 0000000..8e515f0
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/error_object.h
@@ -0,0 +1,55 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _ERROR_OBJECT_H_
+#define _ERROR_OBJECT_H_
+
+#include "object.h"
+#include "function.h"
+
+namespace KJS {
+
+  class ErrorObject : public ConstructorImp {
+  public:
+    ErrorObject(const Object &funcProto, const Object &errProto,
+		ErrorType t = GeneralError);
+    ErrorObject(const Object& proto, ErrorType t, const char *m, int l = -1);
+    Completion execute(const List &);
+    Object construct(const List &);
+    static Object create(ErrorType e, const char *m, int ln);
+  private:
+    ErrorType errType;
+    static const char *errName[];
+  };
+
+  class ErrorPrototype : public ObjectImp {
+  public:
+    ErrorPrototype(const Object& proto);
+    virtual KJSO get(const UString &p) const;
+  };
+
+  class ErrorProtoFunc : public InternalFunctionImp {
+  public:
+    ErrorProtoFunc() { }
+    Completion execute(const List &);
+  };
+
+}; // namespace
+
+#endif
diff --git a/WebCore/src/kdelibs/kjs/function.cpp b/WebCore/src/kdelibs/kjs/function.cpp
new file mode 100644
index 0000000..22db1d2
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/function.cpp
@@ -0,0 +1,355 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#include "function.h"
+
+#include "kjs.h"
+#include "types.h"
+#include "internal.h"
+#include "operations.h"
+#include "nodes.h"
+#ifndef NDEBUG
+#include <stdio.h>
+#endif
+
+using namespace KJS;
+
+const TypeInfo FunctionImp::info = { "Function", FunctionType,
+				      &ObjectImp::info, 0, 0 };
+const TypeInfo InternalFunctionImp::info = { "InternalFunction",
+					      InternalFunctionType,
+					      &FunctionImp::info, 0, 0 };
+const TypeInfo ConstructorImp::info = { "Function", ConstructorType,
+					 &InternalFunctionImp::info, 0, 0 };
+
+namespace KJS {
+
+  class Parameter {
+  public:
+    Parameter(const UString &n) : name(n), next(0L) { }
+    ~Parameter() { delete next; }
+    UString name;
+    Parameter *next;
+  };
+
+};
+
+FunctionImp::FunctionImp()
+  : ObjectImp(/*TODO*/BooleanClass), param(0L)
+{
+}
+
+FunctionImp::FunctionImp(const UString &n)
+  : ObjectImp(/*TODO*/BooleanClass), ident(n), param(0L)
+{
+}
+
+FunctionImp::~FunctionImp()
+{
+  delete param;
+}
+
+KJSO FunctionImp::thisValue() const
+{
+  return KJSO(Context::current()->thisValue());
+}
+
+void FunctionImp::addParameter(const UString &n)
+{
+  Parameter **p = &param;
+  while (*p)
+    p = &(*p)->next;
+
+  *p = new Parameter(n);
+}
+
+void FunctionImp::setLength(int l)
+{
+  put("length", Number(l), ReadOnly|DontDelete|DontEnum);
+}
+
+// ECMA 10.1.3
+void FunctionImp::processParameters(const List *args)
+{
+  KJSO variable = Context::current()->variableObject();
+
+  assert(args);
+
+#ifdef KJS_VERBOSE
+  fprintf(stderr, "---------------------------------------------------\n"
+	  "processing parameters for %s call\n",
+	  name().isEmpty() ? "(internal)" : name().ascii());
+#endif
+
+  if (param) {
+    ListIterator it = args->begin();
+    Parameter **p = &param;
+    while (*p) {
+      if (it != args->end()) {
+#ifdef KJS_VERBOSE
+	fprintf(stderr, "setting parameter %s ", (*p)->name.ascii());
+	printInfo("to", *it);
+#endif
+	variable.put((*p)->name, *it);
+	it++;
+      } else
+	variable.put((*p)->name, Undefined());
+      p = &(*p)->next;
+    }
+  }
+#ifdef KJS_VERBOSE
+  else {
+    for (int i = 0; i < args->size(); i++)
+      printInfo("setting argument", (*args)[i]);
+  }
+#endif
+#ifdef KJS_DEBUGGER
+  if (KJScriptImp::current()->debugger()) {
+    UString argStr;
+    for (int i = 0; i < args->size(); i++) {
+      if (i > 0)
+	argStr += ", ";
+      Imp *a = (*args)[i].imp();
+      argStr += a->toString().value() + " : " +	UString(a->typeInfo()->name);
+    }
+    UString n = name().isEmpty() ? UString( "(internal)" ) : name();
+    KJScriptImp::current()->debugger()->callEvent(n, argStr);
+  }
+#endif
+}
+
+// ECMA 13.2.1
+KJSO FunctionImp::executeCall(Imp *thisV, const List *args)
+{
+  return executeCall(thisV,args,0);
+}
+
+KJSO FunctionImp::executeCall(Imp *thisV, const List *args, const List *extraScope)
+{
+  bool dummyList = false;
+  if (!args) {
+    args = new List();
+    dummyList = true;
+  }
+
+  KJScriptImp *curr = KJScriptImp::current();
+  Context *save = curr->context();
+
+  Context *ctx = new Context(codeType(), save, this, args, thisV);
+  curr->setContext(ctx);
+
+  int numScopes = 0;
+  if (extraScope) {
+    ListIterator scopeIt = extraScope->begin();
+    for (; scopeIt != extraScope->end(); scopeIt++) {
+      KJSO obj(*scopeIt);
+      ctx->pushScope(obj);
+      numScopes++;
+    }
+  }
+
+  // assign user supplied arguments to parameters
+  processParameters(args);
+
+  Completion comp = execute(*args);
+
+  if (dummyList)
+    delete args;
+
+  int i;
+  for (i = 0; i < numScopes; i++)
+    ctx->popScope();
+
+  put("arguments", Null());
+  delete ctx;
+  curr->setContext(save);
+
+#ifdef KJS_VERBOSE
+  if (comp.complType() == Throw)
+    printInfo("throwing", comp.value());
+  else if (comp.complType() == ReturnValue)
+    printInfo("returning", comp.value());
+  else
+    fprintf(stderr, "returning: undefined\n");
+#endif
+#ifdef KJS_DEBUGGER
+  if (KJScriptImp::current()->debugger())
+    KJScriptImp::current()->debugger()->returnEvent();
+#endif
+
+  if (comp.complType() == Throw)
+    return comp.value();
+  else if (comp.complType() == ReturnValue)
+    return comp.value();
+  else
+    return Undefined();
+}
+
+UString FunctionImp::name() const
+{
+  return ident;
+}
+
+InternalFunctionImp::InternalFunctionImp()
+{
+}
+
+InternalFunctionImp::InternalFunctionImp(int l)
+{
+  if (l >= 0)
+    setLength(l);
+}
+
+InternalFunctionImp::InternalFunctionImp(const UString &n)
+  : FunctionImp(n)
+{
+}
+
+String InternalFunctionImp::toString() const
+{
+  if (name().isNull())
+    return UString("(Internal function)");
+  else
+    return UString("function " + name() + "()");
+}
+
+Completion InternalFunctionImp::execute(const List &)
+{
+  return Completion(ReturnValue, Undefined());
+}
+
+ConstructorImp::ConstructorImp() {
+  setPrototype(Global::current().functionPrototype());
+  // TODO ???  put("constructor", this);
+  setLength(1);
+}
+
+ConstructorImp::ConstructorImp(const UString &n)
+  : InternalFunctionImp(n)
+{
+}
+
+ConstructorImp::ConstructorImp(const KJSO &p, int len)
+{
+  setPrototype(p);
+  // TODO ???  put("constructor", *this);
+  setLength(len);
+}
+
+ConstructorImp::ConstructorImp(const UString &n, const KJSO &p, int len)
+  : InternalFunctionImp(n)
+{
+  setPrototype(p);
+  // TODO ???  put("constructor", *this);
+  setLength(len);
+}
+
+ConstructorImp::~ConstructorImp() { }
+
+Completion ConstructorImp::execute(const List &)
+{
+  /* TODO */
+  return Completion(ReturnValue, Null());
+}
+
+Function::Function(Imp *d)
+  : KJSO(d)
+{
+  if (d) {
+    static_cast<FunctionImp*>(rep)->attr = ImplicitNone;
+    assert(Global::current().hasProperty("[[Function.prototype]]"));
+    setPrototype(Global::current().functionPrototype());
+  }
+}
+
+Completion Function::execute(const List &args)
+{
+  assert(rep);
+  return static_cast<FunctionImp*>(rep)->execute(args);
+}
+
+bool Function::hasAttribute(FunctionAttribute a) const
+{
+  assert(rep);
+  return static_cast<FunctionImp*>(rep)->hasAttribute(a);
+}
+
+#if 0
+InternalFunction::InternalFunction(Imp *d)
+  : Function(d)
+{
+  param = 0L;
+}
+
+InternalFunction::~InternalFunction()
+{
+}
+#endif
+
+Constructor::Constructor(Imp *d)
+  : Function(d)
+{
+  if (d) {
+    assert(Global::current().hasProperty("[[Function.prototype]]"));
+    setPrototype(Global::current().get("[[Function.prototype]]"));
+    put("constructor", *this);
+    KJSO tmp(d); // protect from GC
+    ((FunctionImp*)d)->setLength(1);
+  }
+}
+
+#if 0
+Constructor::Constructor(const Object& proto, int len)
+{
+  setPrototype(proto);
+  put("constructor", *this);
+  put("length", len, DontEnum);
+}
+#endif
+
+Constructor::~Constructor()
+{
+}
+
+Completion Constructor::execute(const List &)
+{
+  /* TODO: call construct instead ? */
+  return Completion(ReturnValue, Undefined());
+}
+
+Object Constructor::construct(const List &args)
+{
+  assert(rep && rep->type() == ConstructorType);
+  return ((ConstructorImp*)rep)->construct(args);
+}
+
+Constructor Constructor::dynamicCast(const KJSO &obj)
+{
+  // return null object on type mismatch
+  if (!obj.isA(ConstructorType))
+    return Constructor(0L);
+
+  return Constructor(obj.imp());
+}
+
+KJSO Function::thisValue() const
+{
+  return KJSO(Context::current()->thisValue());
+}
diff --git a/WebCore/src/kdelibs/kjs/function.h b/WebCore/src/kdelibs/kjs/function.h
new file mode 100644
index 0000000..70c1f3a
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/function.h
@@ -0,0 +1,134 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _KJS_FUNCTION_H_
+#define _KJS_FUNCTION_H_
+
+#include <assert.h>
+
+#include "object.h"
+#include "types.h"
+
+namespace KJS {
+
+  enum CodeType { GlobalCode,
+		  EvalCode,
+		  FunctionCode,
+		  AnonymousCode,
+		  HostCode };
+
+  enum FunctionAttribute { ImplicitNone, ImplicitThis, ImplicitParents };
+
+  class Function;
+  class Parameter;
+
+  /**
+   * @short Implementation class for Functions.
+   */
+  class FunctionImp : public ObjectImp {
+    friend class Function;
+  public:
+    FunctionImp();
+    FunctionImp(const UString &n);
+    virtual ~FunctionImp();
+    virtual const TypeInfo* typeInfo() const { return &info; }
+    static const TypeInfo info;
+    virtual Completion execute(const List &) = 0;
+    bool hasAttribute(FunctionAttribute a) const { return (attr & a) != 0; }
+    virtual CodeType codeType() const = 0;
+    KJSO thisValue() const;
+    void addParameter(const UString &n);
+    void setLength(int l);
+    KJSO executeCall(Imp *thisV, const List *args);
+    KJSO executeCall(Imp *thisV, const List *args, const List *extraScope);
+    UString name() const;
+  protected:
+    UString ident;
+    FunctionAttribute attr;
+    Parameter *param;
+  private:
+    void processParameters(const List *);
+  };
+
+  /**
+   * @short Abstract base class for internal functions.
+   */
+  class InternalFunctionImp : public FunctionImp {
+  public:
+    InternalFunctionImp();
+    InternalFunctionImp(int l);
+    InternalFunctionImp(const UString &n);
+    virtual ~InternalFunctionImp() { }
+    virtual String toString() const;
+    virtual KJSO toPrimitive(Type) const { return toString(); }
+    virtual const TypeInfo* typeInfo() const { return &info; }
+    static const TypeInfo info;
+    virtual Completion execute(const List &);
+    virtual CodeType codeType() const { return HostCode; }
+  };
+
+  /**
+   * @short Base class for Function objects.
+   */
+  class Function : public KJSO {
+  public:
+    Function(Imp *);
+    virtual ~Function() { }
+    Completion execute(const List &);
+    bool hasAttribute(FunctionAttribute a) const;
+    CodeType codeType() const { return HostCode; }
+    KJSO thisValue() const;
+  };
+  
+  /**
+   * @short Implementation class for Constructors.
+   */
+  class ConstructorImp : public InternalFunctionImp {
+  public:
+    ConstructorImp();
+    ConstructorImp(const UString &n);	/* TODO: add length */
+    ConstructorImp(const KJSO &, int);
+    ConstructorImp(const UString &n, const KJSO &p, int len);
+    virtual ~ConstructorImp();
+    virtual const TypeInfo* typeInfo() const { return &info; }
+    static const TypeInfo info;
+    virtual Completion execute(const List &);
+    virtual Object construct(const List &) = 0;
+  };
+
+  /**
+    * @short Constructor object for use with the 'new' operator
+    */
+  class Constructor : public Function {
+  public:
+    Constructor(Imp *);
+    virtual ~Constructor();
+    //    Constructor(const Object& proto, int len);
+    /**
+     * @return @ref ConstructorType
+     */
+    Completion execute(const List &);
+    Object construct(const List &args);
+    static Constructor dynamicCast(const KJSO &obj);
+  };
+
+}; // namespace
+
+#endif
diff --git a/WebCore/src/kdelibs/kjs/function_object.cpp b/WebCore/src/kdelibs/kjs/function_object.cpp
new file mode 100644
index 0000000..63b8b63
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/function_object.cpp
@@ -0,0 +1,121 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "function_object.h"
+
+#include "lexer.h"
+#include "nodes.h"
+#include "error_object.h"
+
+extern int kjsyyparse();
+
+using namespace KJS;
+
+FunctionObject::FunctionObject(const Object& funcProto)
+  : ConstructorImp(funcProto, 1)
+{
+  // ECMA 15.3.3.1 Function.prototype
+  setPrototypeProperty(funcProto);
+}
+
+// ECMA 15.3.1 The Function Constructor Called as a Function
+Completion FunctionObject::execute(const List &args)
+{
+  return Completion(ReturnValue, construct(args));
+}
+
+// ECMA 15.3.2 The Function Constructor
+Object FunctionObject::construct(const List &args)
+{
+  UString p("");
+  UString body;
+  int argsSize = args.size();
+  if (argsSize == 0) {
+    body = "";
+  } else if (argsSize == 1) {
+    body = args[0].toString().value();
+  } else {
+    p = args[0].toString().value();
+    for (int k = 1; k < argsSize - 1; k++)
+      p += "," + args[k].toString().value();
+    body = args[argsSize-1].toString().value();
+  }
+
+  Lexer::curr()->setCode(body.data(), body.size());
+
+  KJScriptImp::current()->pushStack();
+  int yp = kjsyyparse();
+  ProgramNode *progNode = KJScriptImp::current()->progNode();
+  KJScriptImp::current()->popStack();
+  if (yp) {
+    /* TODO: free nodes */
+    return ErrorObject::create(SyntaxError,
+			       I18N_NOOP("Syntax error in function body"), -1);
+  }
+
+  List scopeChain;
+  scopeChain.append(Global::current());
+  FunctionBodyNode *bodyNode = progNode;
+  FunctionImp *fimp = new DeclaredFunctionImp(UString::null, bodyNode,
+					      &scopeChain);
+  Object ret(fimp); // protect from GC
+
+  // parse parameter list. throw syntax error on illegal identifiers
+  int len = p.size();
+  const UChar *c = p.data();
+  int i = 0, params = 0;
+  UString param;
+  while (i < len) {
+      while (*c == ' ' && i < len)
+	  c++, i++;
+      if (Lexer::isIdentLetter(c->unicode())) {  // else error
+	  param = UString(c, 1);
+	  c++, i++;
+	  while (i < len && (Lexer::isIdentLetter(c->unicode()) ||
+			     Lexer::isDecimalDigit(c->unicode()))) {
+	      param += UString(c, 1);
+	      c++, i++;
+	  }
+	  while (i < len && *c == ' ')
+	      c++, i++;
+	  if (i == len) {
+	      fimp->addParameter(param);
+	      params++;
+	      break;
+	  } else if (*c == ',') {
+	      fimp->addParameter(param);
+	      params++;
+	      c++, i++;
+	      continue;
+	  } // else error
+      }
+      return ErrorObject::create(SyntaxError,
+				 I18N_NOOP("Syntax error in parameter list"),
+				 -1);
+  }
+
+  fimp->setLength(params);
+  fimp->setPrototypeProperty(Global::current().functionPrototype());
+  return ret;
+}
+
+FunctionPrototype::FunctionPrototype(const Object &p)
+    : ObjectImp(FunctionClass, Null(), p)
+{
+}
diff --git a/WebCore/src/kdelibs/kjs/function_object.h b/WebCore/src/kdelibs/kjs/function_object.h
new file mode 100644
index 0000000..9617ac0
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/function_object.h
@@ -0,0 +1,42 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _FUNCTION_OBJECT_H_
+#define _FUNCTION_OBJECT_H_
+
+#include "object.h"
+#include "function.h"
+
+namespace KJS {
+
+  class FunctionPrototype : public ObjectImp {
+  public:
+    FunctionPrototype(const Object &p);
+  };
+
+  class FunctionObject : public ConstructorImp {
+  public:
+    FunctionObject(const Object &funcProto);
+    Completion execute(const List &);
+    Object construct(const List &);
+  };
+
+}; // namespace
+
+#endif
diff --git a/WebCore/src/kdelibs/kjs/global_object.cpp b/WebCore/src/kdelibs/kjs/global_object.cpp
new file mode 100644
index 0000000..c5bb3ed
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/global_object.cpp
@@ -0,0 +1,373 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2001 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "kjs.h"
+#include "object.h"
+#include "operations.h"
+#include "internal.h"
+#include "types.h"
+#include "lexer.h"
+#include "nodes.h"
+#include "lexer.h"
+
+#include "object_object.h"
+#include "function_object.h"
+#include "array_object.h"
+#include "bool_object.h"
+#include "string_object.h"
+#include "number_object.h"
+#include "math_object.h"
+#include "date_object.h"
+#include "regexp_object.h"
+#include "error_object.h"
+
+extern int kjsyyparse();
+
+namespace KJS {
+
+  class GlobalImp : public ObjectImp {
+  public:
+    GlobalImp();
+    virtual ~GlobalImp();
+    virtual void mark(Imp*);
+    void init();
+    virtual KJSO get(const UString &p) const;
+    virtual void put(const UString &p, const KJSO& v);
+    virtual bool hasProperty(const UString &p, bool recursive = true) const;
+    Imp *filter;
+    void *extraData;
+  private:
+    class GlobalInternal;
+    GlobalInternal *internal;
+  };
+
+};
+
+using namespace KJS;
+
+class GlobalFunc : public InternalFunctionImp {
+public:
+  GlobalFunc(int i) : id(i) { }
+  Completion execute(const List &c);
+  virtual CodeType codeType() const;
+  enum { Eval, ParseInt, ParseFloat, IsNaN, IsFinite, Escape, UnEscape };
+private:
+  int id;
+};
+
+Global::Global()
+  : Object(0L)
+{
+  rep = 0;
+  init();
+}
+
+Global::Global(void *)
+  : Object(0L)
+{
+}
+
+Global::~Global()
+{
+}
+
+void Global::init()
+{
+  if (rep)
+    rep->deref();
+  GlobalImp *g = new GlobalImp();
+  rep = g;
+  rep->ref();
+  g->init();
+}
+
+void Global::clear()
+{
+//   if (rep && rep->deref())
+//     delete rep;
+//   rep = 0L;
+}
+
+Global Global::current()
+{
+  assert(KJScriptImp::current());
+  return KJScriptImp::current()->glob;
+}
+
+KJSO Global::objectPrototype() const
+{
+  return get("[[Object.prototype]]");
+}
+
+KJSO Global::functionPrototype() const
+{
+  return get("[[Function.prototype]]");
+}
+
+void Global::setFilter(const KJSO &f)
+{
+  static_cast<GlobalImp*>(rep)->filter = f.imp();
+}
+
+KJSO Global::filter() const
+{
+  Imp *f = static_cast<GlobalImp*>(rep)->filter;
+  return f ? KJSO(f) : KJSO(Null());
+}
+
+void *Global::extra() const
+{
+  return static_cast<GlobalImp*>(rep)->extraData;
+}
+
+void Global::setExtra(void *e)
+{
+  static_cast<GlobalImp*>(rep)->extraData = e;
+}
+
+GlobalImp::GlobalImp()
+  : ObjectImp(ObjectClass),
+    filter(0L),
+    extraData(0L)
+{
+  // constructor properties. prototypes as Global's member variables first.
+  Object objProto(new ObjectPrototype());
+  Object funcProto(new FunctionPrototype(objProto));
+  Object arrayProto(new ArrayPrototype(objProto));
+  Object stringProto(new StringPrototype(objProto));
+  Object booleanProto(new BooleanPrototype(objProto));
+  Object numberProto(new NumberPrototype(objProto));
+  Object dateProto(new DatePrototype(objProto));
+  Object regexpProto(new RegExpPrototype(objProto));
+  Object errorProto(new ErrorPrototype(objProto));
+
+  put("[[Object.prototype]]", objProto);
+  put("[[Function.prototype]]", funcProto);
+  put("[[Array.prototype]]", arrayProto);
+  put("[[String.prototype]]", stringProto);
+  put("[[Boolean.prototype]]", booleanProto);
+  put("[[Number.prototype]]", numberProto);
+  put("[[Date.prototype]]", dateProto);
+  put("[[RegExp.prototype]]", regexpProto);
+  put("[[Error.prototype]]", errorProto);
+
+  Object objectObj(new ObjectObject(funcProto, objProto));
+  Object funcObj(new FunctionObject(funcProto));
+  Object arrayObj(new ArrayObject(funcProto, arrayProto));
+  Object stringObj(new StringObject(funcProto, stringProto));
+  Object boolObj(new BooleanObject(funcProto, booleanProto));
+  Object numObj(new NumberObject(funcProto, numberProto));
+  Object dateObj(new DateObject(funcProto, dateProto));
+  Object regObj(new RegExpObject(funcProto, regexpProto));
+  Object errObj(new ErrorObject(funcProto, errorProto));
+
+  Imp::put("Object", objectObj, DontEnum);
+  Imp::put("Function", funcObj, DontEnum);
+  Imp::put("Array", arrayObj, DontEnum);
+  Imp::put("Boolean", boolObj, DontEnum);
+  Imp::put("String", stringObj, DontEnum);
+  Imp::put("Number", numObj, DontEnum);
+  Imp::put("Date", dateObj, DontEnum);
+  Imp::put("RegExp", regObj, DontEnum);
+  Imp::put("Error", errObj, DontEnum);
+
+  objProto.setConstructor(objectObj);
+  funcProto.setConstructor(funcObj);
+  arrayProto.setConstructor(arrayObj);
+  booleanProto.setConstructor(boolObj);
+  stringProto.setConstructor(stringObj);
+  numberProto.setConstructor(numObj);
+  dateProto.setConstructor(dateObj);
+  regexpProto.setConstructor(regObj);
+  errorProto.setConstructor(errObj);
+};
+
+void GlobalImp::init()
+{
+  Imp::put("eval", Function(new GlobalFunc(GlobalFunc::Eval)));
+  Imp::put("parseInt", Function(new GlobalFunc(GlobalFunc::ParseInt)));
+  Imp::put("parseFloat", Function(new GlobalFunc(GlobalFunc::ParseFloat)));
+  Imp::put("isNaN", Function(new GlobalFunc(GlobalFunc::IsNaN)));
+  Imp::put("isFinite", Function(new GlobalFunc(GlobalFunc::IsFinite)));
+  Imp::put("escape", Function(new GlobalFunc(GlobalFunc::Escape)));
+  Imp::put("unescape", Function(new GlobalFunc(GlobalFunc::UnEscape)));
+
+  // other properties
+  Imp::put("Math", Object(new Math()), DontEnum);
+}
+
+GlobalImp::~GlobalImp() { }
+
+void GlobalImp::mark(Imp*)
+{
+  ObjectImp::mark();
+  /* TODO: remove in next version */
+  if (filter && !filter->marked())
+    filter->mark();
+}
+
+KJSO GlobalImp::get(const UString &p) const
+{
+  if (p == "NaN")
+    return Number(NaN);
+  else if (p == "Infinity")
+    return Number(Inf);
+  else if (p == "undefined")
+    return Undefined();
+
+  return Imp::get(p);
+}
+
+void GlobalImp::put(const UString &p, const KJSO& v)
+{
+  // if we already have this property (added by init() or a variable
+  // declaration) overwrite it. Otherwise pass it to the prototype.
+  // Needed to get something like a browser's window object working.
+  if (!prototype() || hasProperty(p, false) || Imp::hasProperty(p, false))
+    Imp::put(p, v);
+  else
+    prototype()->put(p, v);
+#if 0    
+  if (filter)
+    filter->put(p, v);   /* TODO: remove in next version */
+  else
+    Imp::put(p, v);
+#endif  
+}
+
+bool GlobalImp::hasProperty(const UString &p, bool recursive) const
+{
+    if (p == "NaN" || p == "Infinity" || p == "undefined")
+	return true;
+    return (recursive && Imp::hasProperty(p, recursive));
+}
+
+CodeType GlobalFunc::codeType() const
+{
+  return id == Eval ? EvalCode : InternalFunctionImp::codeType();
+}
+
+Completion GlobalFunc::execute(const List &args)
+{
+  KJSO res;
+
+  static const char non_escape[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+				   "abcdefghijklmnopqrstuvwxyz"
+				   "0123456789@*_+-./";
+
+  if (id == Eval) { // eval()
+    KJSO x = args[0];
+    if (x.type() != StringType)
+      return Completion(ReturnValue, x);
+    else {
+      UString s = x.toString().value();
+      Lexer::curr()->setCode(s.data(), s.size());
+      Node::setFirstNode(KJScriptImp::current()->firstNode());      
+      int yp = kjsyyparse();
+      KJScriptImp::current()->setFirstNode(Node::firstNode());
+      if (yp) {
+	// TODO: stop this from growing (will be deleted at end of global eval)
+	//	KJS::Node::deleteAllNodes();
+	return Completion(ReturnValue, Error::create(SyntaxError));
+      }
+
+      Completion c = KJScriptImp::current()->progNode()->execute();
+      if (c.complType() == ReturnValue)
+	  return c;
+      else if (c.complType() == Normal) {
+	  if (c.isValueCompletion())
+	      return Completion(ReturnValue, c.value());
+	  else
+	      return Completion(ReturnValue, Undefined());
+      } else
+	  return c;
+
+      //      if (KJS::Node::progNode())
+      //	KJS::Node::progNode()->deleteStatements();
+    }
+  } else if (id == ParseInt) {
+    String str = args[0].toString();
+    int radix = args[1].toInt32();
+    if (radix == 0)
+      radix = 10;
+    else if (radix < 2 || radix > 36) {
+      res = Number(NaN);
+      return Completion(ReturnValue, res);
+    }
+    /* TODO: use radix */
+    int i = 0;
+    sscanf(str.value().ascii(), "%d", &i);
+    res = Number(i);
+  } else if (id == ParseFloat) {
+    String str = args[0].toString();
+    double d = 0.0;
+    sscanf(str.value().ascii(), "%lf", &d);
+    res = Number(d);
+  } else if (id == IsNaN) {
+    res = Boolean(args[0].toNumber().isNaN());
+  } else if (id == IsFinite) {
+    Number n = args[0].toNumber();
+    res = Boolean(!n.isNaN() && !n.isInf());
+  } else if (id == Escape) {
+    UString r = "", s, str = args[0].toString().value();
+    const UChar *c = str.data();
+    for (int k = 0; k < str.size(); k++, c++) {
+      int u = c->unicode();
+      if (u > 255) {
+	char tmp[7];
+	sprintf(tmp, "%%u%04x", u);
+	s = UString(tmp);
+      } else if (strchr(non_escape, (char)u)) {
+	s = UString(c, 1);
+      } else {
+	char tmp[4];
+	sprintf(tmp, "%%%02x", u);
+	s = UString(tmp);
+      }
+      r += s;
+    }
+    res = String(r);
+  } else if (id == UnEscape) {
+    UString s, str = args[0].toString().value();
+    int k = 0, len = str.size();
+    while (k < len) {
+      const UChar *c = str.data() + k;
+      UChar u;
+      if (*c == UChar('%') && k <= len - 6 && *(c+1) == UChar('u')) {
+	u = Lexer::convertUnicode((c+2)->unicode(), (c+3)->unicode(),
+				  (c+4)->unicode(), (c+5)->unicode());
+	c = &u;
+	k += 5;
+      } else if (*c == UChar('%') && k <= len - 3) {
+	u = UChar(Lexer::convertHex((c+1)->unicode(), (c+2)->unicode()));
+	c = &u;
+	k += 2;
+      }
+      k++;
+      s += UString(c, 1);
+    }
+    res = String(s);
+  }
+
+  return Completion(ReturnValue, res);
+}
diff --git a/WebCore/src/kdelibs/kjs/grammar.cpp b/WebCore/src/kdelibs/kjs/grammar.cpp
new file mode 100644
index 0000000..9639e01
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/grammar.cpp
@@ -0,0 +1,2220 @@
+
+/*  A Bison parser, made from grammar.y
+    by GNU Bison version 1.28  */
+
+#define YYBISON 1  /* Identify Bison output.  */
+
+#define yyparse kjsyyparse
+#define yylex kjsyylex
+#define yyerror kjsyyerror
+#define yylval kjsyylval
+#define yychar kjsyychar
+#define yydebug kjsyydebug
+#define yynerrs kjsyynerrs
+#define YYLSP_NEEDED
+
+#define	NULLTOKEN	257
+#define	TRUETOKEN	258
+#define	FALSETOKEN	259
+#define	STRING	260
+#define	NUMBER	261
+#define	BREAK	262
+#define	CASE	263
+#define	DEFAULT	264
+#define	FOR	265
+#define	NEW	266
+#define	VAR	267
+#define	CONTINUE	268
+#define	FUNCTION	269
+#define	RETURN	270
+#define	VOID	271
+#define	DELETE	272
+#define	IF	273
+#define	THIS	274
+#define	DO	275
+#define	WHILE	276
+#define	ELSE	277
+#define	IN	278
+#define	INSTANCEOF	279
+#define	TYPEOF	280
+#define	SWITCH	281
+#define	WITH	282
+#define	RESERVED	283
+#define	THROW	284
+#define	TRY	285
+#define	CATCH	286
+#define	FINALLY	287
+#define	EQEQ	288
+#define	NE	289
+#define	STREQ	290
+#define	STRNEQ	291
+#define	LE	292
+#define	GE	293
+#define	OR	294
+#define	AND	295
+#define	PLUSPLUS	296
+#define	MINUSMINUS	297
+#define	LSHIFT	298
+#define	RSHIFT	299
+#define	URSHIFT	300
+#define	PLUSEQUAL	301
+#define	MINUSEQUAL	302
+#define	MULTEQUAL	303
+#define	DIVEQUAL	304
+#define	LSHIFTEQUAL	305
+#define	RSHIFTEQUAL	306
+#define	URSHIFTEQUAL	307
+#define	ANDEQUAL	308
+#define	MODEQUAL	309
+#define	XOREQUAL	310
+#define	OREQUAL	311
+#define	IDENT	312
+#define	AUTO	313
+
+#line 1 "grammar.y"
+
+
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <string.h>
+#include "kjs.h"
+#include "nodes.h"
+#include "lexer.h"
+
+/* default values for bison */
+#define YYDEBUG 0
+#define YYMAXDEPTH 0
+#ifdef KJS_DEBUGGER
+#define YYERROR_VERBOSE
+#define DBG(l, s, e) { l->setLoc(s.first_line, e.last_line); } // location
+#else
+#undef YYLSP_NEEDED
+#define DBG(l, s, e)
+#endif
+
+extern int yylex();
+int yyerror (const char *);
+bool automatic();
+
+using namespace KJS;
+
+
+#line 49 "grammar.y"
+typedef union {
+  int                 ival;
+  double              dval;
+  UString             *ustr;
+  Node                *node;
+  StatementNode       *stat;
+  ParameterNode       *param;
+  FunctionBodyNode    *body;
+  FuncDeclNode        *func;
+  ProgramNode         *prog;
+  AssignExprNode      *init;
+  SourceElementNode   *src;
+  SourceElementsNode  *srcs;
+  StatListNode        *slist;
+  ArgumentsNode       *args;
+  ArgumentListNode    *alist;
+  VarDeclNode         *decl;
+  VarDeclListNode     *vlist;
+  CaseBlockNode       *cblk;
+  ClauseListNode      *clist;
+  CaseClauseNode      *ccl;
+  ElementNode         *elm;
+  ElisionNode         *eli;
+  Operator            op;
+} YYSTYPE;
+
+#ifndef YYLTYPE
+typedef
+  struct yyltype
+    {
+      int timestamp;
+      int first_line;
+      int first_column;
+      int last_line;
+      int last_column;
+      char *text;
+   }
+  yyltype;
+
+#define YYLTYPE yyltype
+#endif
+
+#include <stdio.h>
+
+#ifndef __cplusplus
+#ifndef __STDC__
+#define const
+#endif
+#endif
+
+
+
+#define	YYFINAL		358
+#define	YYFLAG		-32768
+#define	YYNTBASE	84
+
+#define YYTRANSLATE(x) ((unsigned)(x) <= 313 ? yytranslate[x] : 148)
+
+static const char yytranslate[] = {     0,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,    73,     2,     2,     2,    75,    78,     2,    61,
+    62,    74,    70,    67,    71,    69,    60,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,    68,    83,    76,
+    82,    77,    81,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+    65,     2,    66,    79,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,    63,    80,    64,    72,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     1,     3,     4,     5,     6,
+     7,     8,     9,    10,    11,    12,    13,    14,    15,    16,
+    17,    18,    19,    20,    21,    22,    23,    24,    25,    26,
+    27,    28,    29,    30,    31,    32,    33,    34,    35,    36,
+    37,    38,    39,    40,    41,    42,    43,    44,    45,    46,
+    47,    48,    49,    50,    51,    52,    53,    54,    55,    56,
+    57,    58,    59
+};
+
+#if YYDEBUG != 0
+static const short yyprhs[] = {     0,
+     0,     2,     4,     6,     8,    10,    12,    14,    16,    18,
+    20,    24,    27,    31,    35,    39,    45,    48,    53,    54,
+    56,    58,    61,    65,    71,    73,    75,    77,    79,    81,
+    86,    90,    94,    96,    99,   102,   105,   110,   114,   117,
+   121,   123,   127,   129,   131,   133,   136,   139,   141,   144,
+   147,   150,   153,   157,   160,   164,   167,   170,   173,   176,
+   178,   182,   186,   190,   192,   196,   200,   202,   206,   210,
+   214,   216,   220,   224,   228,   232,   236,   240,   242,   246,
+   250,   254,   258,   260,   264,   266,   270,   272,   276,   278,
+   282,   284,   288,   290,   296,   298,   302,   304,   306,   308,
+   310,   312,   314,   316,   318,   320,   322,   324,   326,   328,
+   332,   334,   336,   338,   340,   342,   344,   346,   348,   350,
+   352,   354,   356,   358,   360,   363,   367,   369,   372,   376,
+   380,   382,   386,   388,   391,   394,   396,   399,   402,   408,
+   416,   423,   429,   439,   450,   458,   467,   477,   478,   480,
+   483,   486,   490,   494,   497,   500,   504,   508,   511,   514,
+   518,   522,   528,   534,   538,   544,   545,   547,   549,   552,
+   556,   561,   564,   568,   572,   576,   580,   584,   589,   595,
+   598,   604,   611,   616,   622,   624,   628,   631,   635,   637,
+   639,   642,   644
+};
+
+static const short yyrhs[] = {     3,
+     0,     4,     0,     5,     0,     7,     0,     6,     0,    60,
+     0,    20,     0,    58,     0,    84,     0,    86,     0,    61,
+   113,    62,     0,    63,    64,     0,    63,    90,    64,     0,
+    65,    88,    66,     0,    65,    87,    66,     0,    65,    87,
+    67,    88,    66,     0,    88,   111,     0,    87,    67,    88,
+   111,     0,     0,    89,     0,    67,     0,    89,    67,     0,
+    91,    68,   111,     0,    90,    67,    91,    68,   111,     0,
+    58,     0,     6,     0,     7,     0,    85,     0,   142,     0,
+    92,    65,   113,    66,     0,    92,    69,    58,     0,    12,
+    92,    95,     0,    92,     0,    12,    93,     0,    92,    95,
+     0,    94,    95,     0,    94,    65,   113,    66,     0,    94,
+    69,    58,     0,    61,    62,     0,    61,    96,    62,     0,
+   111,     0,    96,    67,   111,     0,    93,     0,    94,     0,
+    97,     0,    97,    42,     0,    97,    43,     0,    98,     0,
+    18,    99,     0,    17,    99,     0,    26,    99,     0,    42,
+    99,     0,    59,    42,    99,     0,    43,    99,     0,    59,
+    43,    99,     0,    70,    99,     0,    71,    99,     0,    72,
+    99,     0,    73,    99,     0,    99,     0,   100,    74,    99,
+     0,   100,    60,    99,     0,   100,    75,    99,     0,   100,
+     0,   101,    70,   100,     0,   101,    71,   100,     0,   101,
+     0,   102,    44,   101,     0,   102,    45,   101,     0,   102,
+    46,   101,     0,   102,     0,   103,    76,   102,     0,   103,
+    77,   102,     0,   103,    38,   102,     0,   103,    39,   102,
+     0,   103,    25,   102,     0,   103,    24,   102,     0,   103,
+     0,   104,    34,   103,     0,   104,    35,   103,     0,   104,
+    36,   103,     0,   104,    37,   103,     0,   104,     0,   105,
+    78,   104,     0,   105,     0,   106,    79,   104,     0,   106,
+     0,   107,    80,   104,     0,   107,     0,   108,    41,   107,
+     0,   108,     0,   109,    40,   108,     0,   109,     0,   109,
+    81,   111,    68,   111,     0,   110,     0,    97,   112,   111,
+     0,    82,     0,    47,     0,    48,     0,    49,     0,    50,
+     0,    51,     0,    52,     0,    53,     0,    54,     0,    56,
+     0,    57,     0,    55,     0,   111,     0,   113,    67,   111,
+     0,   115,     0,   117,     0,   121,     0,   122,     0,   123,
+     0,   124,     0,   126,     0,   127,     0,   128,     0,   129,
+     0,   130,     0,   136,     0,   137,     0,   138,     0,    63,
+    64,     0,    63,   116,    64,     0,   114,     0,   116,   114,
+     0,    13,   118,    83,     0,    13,   118,     1,     0,   119,
+     0,   118,    67,   119,     0,    58,     0,    58,   120,     0,
+    82,   111,     0,    83,     0,   113,    83,     0,   113,     1,
+     0,    19,    61,   113,    62,   114,     0,    19,    61,   113,
+    62,   114,    23,   114,     0,    21,   114,    22,    61,   113,
+    62,     0,    22,    61,   113,    62,   114,     0,    11,    61,
+   125,    83,   125,    83,   125,    62,   114,     0,    11,    61,
+    13,   118,    83,   125,    83,   125,    62,   114,     0,    11,
+    61,    97,    24,   113,    62,   114,     0,    11,    61,    13,
+    58,    24,   113,    62,   114,     0,    11,    61,    13,    58,
+   120,    24,   113,    62,   114,     0,     0,   113,     0,    14,
+    83,     0,    14,     1,     0,    14,    58,    83,     0,    14,
+    58,     1,     0,     8,    83,     0,     8,     1,     0,     8,
+    58,    83,     0,     8,    58,     1,     0,    16,    83,     0,
+    16,     1,     0,    16,   113,    83,     0,    16,   113,     1,
+     0,    28,    61,   113,    62,   114,     0,    27,    61,   113,
+    62,   131,     0,    63,   132,    64,     0,    63,   132,   135,
+   132,    64,     0,     0,   133,     0,   134,     0,   133,   134,
+     0,     9,   113,    68,     0,     9,   113,    68,   116,     0,
+    10,    68,     0,    10,    68,   116,     0,    58,    68,   114,
+     0,    30,   113,    83,     0,    31,   115,   139,     0,    31,
+   115,   140,     0,    31,   115,   139,   140,     0,    32,    61,
+    58,    62,   115,     0,    33,   115,     0,    15,    58,    61,
+    62,   144,     0,    15,    58,    61,   143,    62,   144,     0,
+    15,    61,    62,   144,     0,    15,    61,   143,    62,   144,
+     0,    58,     0,   143,    67,    58,     0,    63,    64,     0,
+    63,   146,    64,     0,   146,     0,   147,     0,   146,   147,
+     0,   114,     0,   141,     0
+};
+
+#endif
+
+#if YYDEBUG != 0
+static const short yyrline[] = { 0,
+   156,   158,   159,   160,   161,   162,   167,   169,   171,   172,
+   173,   174,   175,   178,   180,   181,   184,   186,   190,   192,
+   195,   197,   200,   202,   206,   209,   210,   213,   215,   216,
+   217,   219,   222,   224,   227,   229,   230,   231,   234,   236,
+   239,   241,   244,   246,   249,   251,   252,   255,   257,   258,
+   259,   260,   261,   262,   263,   264,   265,   266,   267,   270,
+   272,   273,   274,   277,   279,   280,   283,   285,   286,   287,
+   290,   292,   294,   296,   298,   300,   302,   306,   308,   309,
+   310,   311,   314,   316,   319,   321,   324,   326,   329,   331,
+   335,   337,   341,   343,   347,   349,   353,   355,   356,   357,
+   358,   359,   360,   361,   362,   363,   364,   365,   368,   370,
+   373,   375,   376,   377,   378,   379,   380,   381,   382,   383,
+   384,   385,   386,   387,   390,   392,   395,   397,   400,   403,
+   412,   414,   418,   420,   423,   427,   431,   434,   441,   443,
+   447,   449,   450,   453,   456,   459,   463,   469,   471,   474,
+   476,   480,   482,   489,   491,   495,   497,   505,   507,   511,
+   512,   518,   523,   528,   530,   534,   536,   539,   541,   544,
+   546,   549,   551,   554,   560,   564,   566,   567,   570,   574,
+   578,   581,   585,   587,   592,   594,   598,   600,   603,   608,
+   610,   613,   615
+};
+#endif
+
+
+#if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
+
+static const char * const yytname[] = {   "$","error","$undefined.","NULLTOKEN",
+"TRUETOKEN","FALSETOKEN","STRING","NUMBER","BREAK","CASE","DEFAULT","FOR","NEW",
+"VAR","CONTINUE","FUNCTION","RETURN","VOID","DELETE","IF","THIS","DO","WHILE",
+"ELSE","IN","INSTANCEOF","TYPEOF","SWITCH","WITH","RESERVED","THROW","TRY","CATCH",
+"FINALLY","EQEQ","NE","STREQ","STRNEQ","LE","GE","OR","AND","PLUSPLUS","MINUSMINUS",
+"LSHIFT","RSHIFT","URSHIFT","PLUSEQUAL","MINUSEQUAL","MULTEQUAL","DIVEQUAL",
+"LSHIFTEQUAL","RSHIFTEQUAL","URSHIFTEQUAL","ANDEQUAL","MODEQUAL","XOREQUAL",
+"OREQUAL","IDENT","AUTO","'/'","'('","')'","'{'","'}'","'['","']'","','","':'",
+"'.'","'+'","'-'","'~'","'!'","'*'","'%'","'<'","'>'","'&'","'^'","'|'","'?'",
+"'='","';'","Literal","PrimaryExpr","ArrayLiteral","ElementList","ElisionOpt",
+"Elision","PropertyNameAndValueList","PropertyName","MemberExpr","NewExpr","CallExpr",
+"Arguments","ArgumentList","LeftHandSideExpr","PostfixExpr","UnaryExpr","MultiplicativeExpr",
+"AdditiveExpr","ShiftExpr","RelationalExpr","EqualityExpr","BitwiseANDExpr",
+"BitwiseXORExpr","BitwiseORExpr","LogicalANDExpr","LogicalORExpr","ConditionalExpr",
+"AssignmentExpr","AssignmentOperator","Expr","Statement","Block","StatementList",
+"VariableStatement","VariableDeclarationList","VariableDeclaration","Initializer",
+"EmptyStatement","ExprStatement","IfStatement","IterationStatement","ExprOpt",
+"ContinueStatement","BreakStatement","ReturnStatement","WithStatement","SwitchStatement",
+"CaseBlock","CaseClausesOpt","CaseClauses","CaseClause","DefaultClause","LabelledStatement",
+"ThrowStatement","TryStatement","Catch","Finally","FunctionDeclaration","FunctionExpr",
+"FormalParameterList","FunctionBody","Program","SourceElements","SourceElement", NULL
+};
+#endif
+
+static const short yyr1[] = {     0,
+    84,    84,    84,    84,    84,    84,    85,    85,    85,    85,
+    85,    85,    85,    86,    86,    86,    87,    87,    88,    88,
+    89,    89,    90,    90,    91,    91,    91,    92,    92,    92,
+    92,    92,    93,    93,    94,    94,    94,    94,    95,    95,
+    96,    96,    97,    97,    98,    98,    98,    99,    99,    99,
+    99,    99,    99,    99,    99,    99,    99,    99,    99,   100,
+   100,   100,   100,   101,   101,   101,   102,   102,   102,   102,
+   103,   103,   103,   103,   103,   103,   103,   104,   104,   104,
+   104,   104,   105,   105,   106,   106,   107,   107,   108,   108,
+   109,   109,   110,   110,   111,   111,   112,   112,   112,   112,
+   112,   112,   112,   112,   112,   112,   112,   112,   113,   113,
+   114,   114,   114,   114,   114,   114,   114,   114,   114,   114,
+   114,   114,   114,   114,   115,   115,   116,   116,   117,   117,
+   118,   118,   119,   119,   120,   121,   122,   122,   123,   123,
+   124,   124,   124,   124,   124,   124,   124,   125,   125,   126,
+   126,   126,   126,   127,   127,   127,   127,   128,   128,   128,
+   128,   129,   130,   131,   131,   132,   132,   133,   133,   134,
+   134,   135,   135,   136,   137,   138,   138,   138,   139,   140,
+   141,   141,   142,   142,   143,   143,   144,   144,   145,   146,
+   146,   147,   147
+};
+
+static const short yyr2[] = {     0,
+     1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+     3,     2,     3,     3,     3,     5,     2,     4,     0,     1,
+     1,     2,     3,     5,     1,     1,     1,     1,     1,     4,
+     3,     3,     1,     2,     2,     2,     4,     3,     2,     3,
+     1,     3,     1,     1,     1,     2,     2,     1,     2,     2,
+     2,     2,     3,     2,     3,     2,     2,     2,     2,     1,
+     3,     3,     3,     1,     3,     3,     1,     3,     3,     3,
+     1,     3,     3,     3,     3,     3,     3,     1,     3,     3,
+     3,     3,     1,     3,     1,     3,     1,     3,     1,     3,
+     1,     3,     1,     5,     1,     3,     1,     1,     1,     1,
+     1,     1,     1,     1,     1,     1,     1,     1,     1,     3,
+     1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+     1,     1,     1,     1,     2,     3,     1,     2,     3,     3,
+     1,     3,     1,     2,     2,     1,     2,     2,     5,     7,
+     6,     5,     9,    10,     7,     8,     9,     0,     1,     2,
+     2,     3,     3,     2,     2,     3,     3,     2,     2,     3,
+     3,     5,     5,     3,     5,     0,     1,     1,     2,     3,
+     4,     2,     3,     3,     3,     3,     3,     4,     5,     2,
+     5,     6,     4,     5,     1,     3,     2,     3,     1,     1,
+     2,     1,     1
+};
+
+static const short yydefact[] = {     0,
+     1,     2,     3,     5,     4,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     7,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     8,     0,     6,     0,     0,
+    19,     0,     0,     0,     0,   136,     9,    28,    10,    33,
+    43,    44,    45,    48,    60,    64,    67,    71,    78,    83,
+    85,    87,    89,    91,    93,    95,   109,     0,   192,   111,
+   112,   113,   114,   115,   116,   117,   118,   119,   120,   121,
+   122,   123,   124,   193,    29,   189,   190,   155,     0,   154,
+   148,     0,     8,     0,    33,    34,   133,     0,   131,   151,
+     0,   150,     0,     0,   159,   158,     0,    45,    50,    49,
+     0,     0,     0,    51,     0,     0,     0,     0,     0,    52,
+    54,     0,     0,     0,     0,     5,     4,     8,    12,     0,
+     0,   127,     0,    21,     0,     0,    20,    56,    57,    58,
+    59,     0,     0,     0,    35,     0,     0,    36,    46,    47,
+    98,    99,   100,   101,   102,   103,   104,   105,   108,   106,
+   107,    97,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,   138,     0,   137,
+   191,   157,   156,     0,    45,   149,     0,    26,    27,    25,
+    12,    32,     0,   134,   130,     0,   129,   153,   152,     0,
+   185,     0,     0,   161,   160,     0,     0,     0,     0,     0,
+   175,   125,     0,     0,   176,   177,   174,    53,    55,    11,
+    13,     0,     0,   126,   128,    15,    19,    14,    17,    22,
+    39,     0,    41,     0,    31,     0,    38,    96,    62,    61,
+    63,    65,    66,    68,    69,    70,    77,    76,    74,    75,
+    72,    73,    79,    80,    81,    82,    84,    86,    88,    90,
+    92,     0,   110,   133,     0,     0,   148,   135,   132,     0,
+     0,     0,   183,     0,     0,     0,     0,     0,     0,     0,
+     0,   180,   178,     0,    23,     0,    40,     0,    30,    37,
+     0,     0,   134,   148,     0,     0,   181,     0,   187,     0,
+   184,   186,   139,     0,   142,   166,   163,   162,     0,     0,
+    16,    18,    42,    94,     0,     0,     0,     0,   148,   182,
+   188,     0,   141,     0,     0,   167,   168,     0,    24,     0,
+     0,   148,   145,     0,   140,     0,     0,   164,   166,   169,
+   179,   146,     0,     0,     0,   170,   172,     0,   147,     0,
+   143,   171,   173,   165,   144,     0,     0,     0
+};
+
+static const short yydefgoto[] = {    37,
+    38,    39,   125,   126,   127,   120,   121,    40,    41,    42,
+   135,   232,    43,    44,    45,    46,    47,    48,    49,    50,
+    51,    52,    53,    54,    55,    56,    57,   153,    58,    59,
+    60,   123,    61,    88,    89,   194,    62,    63,    64,    65,
+   187,    66,    67,    68,    69,    70,   307,   325,   326,   327,
+   339,    71,    72,    73,   215,   216,    74,    75,   203,   273,
+   356,    76,    77
+};
+
+static const short yypact[] = {   699,
+-32768,-32768,-32768,-32768,-32768,     2,   -29,   121,    34,     4,
+   129,   227,  1171,  1171,    42,-32768,   772,    89,  1171,   107,
+   128,  1171,    -7,  1171,  1171,    62,    -2,-32768,  1171,   334,
+   124,  1171,  1171,  1171,  1171,-32768,-32768,-32768,-32768,    51,
+-32768,    73,   769,-32768,-32768,    69,    90,   210,    72,   201,
+   115,    60,   145,   186,   -13,-32768,-32768,    11,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,   699,-32768,-32768,     5,-32768,
+   887,   168,-32768,   101,    51,-32768,   161,    15,-32768,-32768,
+     6,-32768,   185,    28,-32768,-32768,    16,    27,-32768,-32768,
+  1171,   230,  1171,-32768,  1171,  1171,   -59,   407,   144,-32768,
+-32768,   772,  1171,  1171,    -4,   192,   194,    62,   853,   157,
+   196,-32768,   480,-32768,   153,   958,   215,-32768,-32768,-32768,
+-32768,  1029,  1171,   225,-32768,  1171,   226,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,  1171,  1171,  1171,  1171,  1171,  1171,  1171,  1171,
+  1171,  1171,  1171,  1171,  1171,  1171,  1171,  1171,  1171,  1171,
+  1171,  1171,  1171,  1171,  1171,  1171,  1171,-32768,  1171,-32768,
+-32768,-32768,-32768,   231,    -5,   228,   211,-32768,-32768,-32768,
+-32768,-32768,  1171,-32768,-32768,    34,-32768,-32768,-32768,    61,
+-32768,   233,    17,-32768,-32768,    55,   241,    78,    84,    85,
+-32768,-32768,   242,    -7,   271,-32768,-32768,-32768,-32768,-32768,
+-32768,    23,  1171,-32768,-32768,-32768,   124,-32768,-32768,-32768,
+-32768,    96,-32768,   174,-32768,   191,-32768,-32768,-32768,-32768,
+-32768,    69,    69,    90,    90,    90,   210,   210,   210,   210,
+   210,   210,    72,    72,    72,    72,   201,   201,   201,   145,
+   186,   239,-32768,   -15,   -44,  1171,  1171,-32768,-32768,   233,
+   100,   553,-32768,   233,   250,   772,  1171,   772,   246,   772,
+   253,-32768,-32768,   244,-32768,  1100,-32768,  1171,-32768,-32768,
+  1171,  1171,   290,  1171,   116,   234,-32768,   233,-32768,   626,
+-32768,-32768,   293,   118,-32768,   310,-32768,-32768,   258,  1171,
+-32768,-32768,-32768,-32768,   155,  1171,   238,   772,  1171,-32768,
+-32768,   772,-32768,  1171,    12,   310,-32768,    -7,-32768,   772,
+   156,  1171,-32768,   260,-32768,   200,   256,-32768,   310,-32768,
+-32768,-32768,   772,   263,   772,   772,   772,   268,-32768,   772,
+-32768,   772,   772,-32768,-32768,   327,   343,-32768
+};
+
+static const short yypgoto[] = {-32768,
+-32768,-32768,-32768,   130,-32768,-32768,   122,   326,   350,-32768,
+   -24,-32768,    40,-32768,     1,   117,   112,     8,    80,   105,
+-32768,-32768,   184,   187,-32768,-32768,  -122,-32768,    -1,   -17,
+   -22,   -66,-32768,   182,   171,   104,-32768,-32768,-32768,-32768,
+  -201,-32768,-32768,-32768,-32768,-32768,-32768,    30,-32768,    44,
+-32768,-32768,-32768,-32768,-32768,   158,-32768,-32768,   172,  -161,
+-32768,    99,   -74
+};
+
+
+#define	YYLAST		1244
+
+
+static const short yytable[] = {   102,
+   109,   181,    78,   229,    90,   182,   198,   179,   292,   233,
+    97,   178,   122,    99,   100,   195,   204,   138,   266,   104,
+   107,   337,   196,   211,   110,   111,   176,   115,   188,   189,
+   238,    81,   128,   129,   130,   131,   139,   140,   294,   113,
+   114,   141,   142,   143,   144,   145,   146,   147,   148,   149,
+   150,   151,    98,    98,   262,   108,   263,   220,    98,    79,
+   192,    91,   179,    98,    98,   296,   193,   177,   139,   140,
+   268,    98,    98,    98,    98,   338,   152,   179,   274,   186,
+   190,   196,   179,   275,    80,   201,    92,   183,   199,   202,
+   122,    87,   317,   180,   217,   162,   163,   197,   205,   206,
+   285,   208,   101,   209,   210,   225,   188,   189,   297,   164,
+   165,   132,   301,   218,   219,   133,   276,   334,   201,   134,
+   185,   179,   270,     1,     2,     3,     4,     5,   154,   112,
+   344,   234,     8,   132,   236,    82,   320,   136,   173,   278,
+    16,   137,   155,   156,   179,   279,   280,   166,   167,   103,
+   179,   179,    98,    98,   239,   240,   241,   287,   190,   157,
+   158,   298,   288,   312,   191,   313,   275,   105,   314,   247,
+   248,   249,   250,   251,   252,   213,   214,   318,    83,   323,
+    28,    29,   179,    84,   179,    31,    93,   329,   106,    94,
+   124,   282,   172,    98,    98,    98,    98,    98,    98,    98,
+    98,    98,    98,    98,    98,    98,    98,    98,    98,    98,
+    98,    98,    98,    98,    98,    98,   330,   343,   226,   227,
+   221,   179,   179,   222,   174,   181,   175,    95,    94,     1,
+     2,     3,     4,     5,   168,   169,   170,   171,     8,   289,
+   179,    82,   193,    13,    14,   200,    16,   253,   254,   255,
+   256,   207,    19,   159,   160,   161,   290,   179,   303,   -26,
+   305,   -27,   308,   223,   295,   186,   179,   346,    24,    25,
+   244,   245,   246,   242,   243,   304,   257,   258,   259,   352,
+   353,   230,   235,   237,    83,    27,    28,    29,   264,    84,
+   315,    31,   186,   267,   179,   272,    32,    33,    34,    35,
+   333,   277,   281,   214,   335,   341,   291,   302,   306,    96,
+   309,   310,   342,   316,   331,   322,   319,   186,   324,   328,
+   332,   345,   336,   347,   350,   349,   357,   351,   122,   122,
+   186,   354,   355,    85,   225,   225,     1,     2,     3,   116,
+   117,     6,   358,   284,     7,     8,     9,    10,    82,    12,
+    13,    14,    15,    16,    17,    18,   286,    86,   260,    19,
+    20,    21,   261,    22,    23,   265,   269,   293,   348,   340,
+   300,   271,   283,     0,     0,    24,    25,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,   118,    27,    28,    29,     0,    30,   119,    31,     0,
+     0,     0,     0,    32,    33,    34,    35,     0,     0,     1,
+     2,     3,     4,     5,     6,     0,    36,     7,     8,     9,
+    10,    82,    12,    13,    14,    15,    16,    17,    18,     0,
+     0,     0,    19,    20,    21,     0,    22,    23,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,    24,    25,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,    26,    27,    28,    29,     0,    30,
+   212,    31,     0,     0,     0,     0,    32,    33,    34,    35,
+     0,     0,     1,     2,     3,     4,     5,     6,     0,    36,
+     7,     8,     9,    10,    82,    12,    13,    14,    15,    16,
+    17,    18,     0,     0,     0,    19,    20,    21,     0,    22,
+    23,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,    24,    25,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,    26,    27,    28,
+    29,     0,    30,   224,    31,     0,     0,     0,     0,    32,
+    33,    34,    35,     0,     0,     1,     2,     3,     4,     5,
+     6,     0,    36,     7,     8,     9,    10,    11,    12,    13,
+    14,    15,    16,    17,    18,     0,     0,     0,    19,    20,
+    21,     0,    22,    23,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,    24,    25,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+    26,    27,    28,    29,     0,    30,   299,    31,     0,     0,
+     0,     0,    32,    33,    34,    35,     0,     0,     1,     2,
+     3,     4,     5,     6,     0,    36,     7,     8,     9,    10,
+    11,    12,    13,    14,    15,    16,    17,    18,     0,     0,
+     0,    19,    20,    21,     0,    22,    23,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,    24,    25,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,    26,    27,    28,    29,     0,    30,   321,
+    31,     0,     0,     0,     0,    32,    33,    34,    35,     0,
+     0,     1,     2,     3,     4,     5,     6,     0,    36,     7,
+     8,     9,    10,    11,    12,    13,    14,    15,    16,    17,
+    18,     0,     0,     0,    19,    20,    21,     0,    22,    23,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+    24,    25,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,    26,    27,    28,    29,
+     0,    30,     0,    31,     0,     0,     0,     0,    32,    33,
+    34,    35,     0,     0,     1,     2,     3,     4,     5,     6,
+     0,    36,     7,     8,     9,    10,    82,    12,    13,    14,
+    15,    16,    17,    18,     0,     0,     0,    19,    20,    21,
+     0,    22,    23,     0,     0,     0,     0,     0,     0,     0,
+   139,   140,     0,    24,    25,   141,   142,   143,   144,   145,
+   146,   147,   148,   149,   150,   151,     0,     0,     0,    26,
+    27,    28,    29,     0,    30,     0,    31,     0,     0,     0,
+     0,    32,    33,    34,    35,     0,     0,     0,     0,     0,
+   152,     0,  -125,     0,    36,  -125,  -125,  -125,  -125,  -125,
+  -125,  -125,  -125,  -125,  -125,  -125,  -125,  -125,  -125,  -125,
+  -125,  -125,  -125,  -125,  -125,  -125,     0,     0,  -125,  -125,
+  -125,     0,  -125,  -125,     0,     0,     0,     0,     0,     1,
+     2,     3,     4,     5,     0,     0,     0,     0,     8,   184,
+     0,    82,     0,    13,    14,     0,    16,     0,     0,     0,
+  -125,  -125,    19,     0,     0,  -125,  -125,     0,     0,     0,
+     0,     0,     0,     0,  -125,  -125,     0,     0,    24,    25,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,    83,    27,    28,    29,     0,    84,
+     0,    31,     0,     0,     0,     0,    32,    33,    34,    35,
+     1,     2,     3,     4,     5,     0,     0,     0,     0,     8,
+     0,     0,    82,     0,    13,    14,     0,    16,     0,     0,
+     0,     0,     0,    19,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,    24,
+    25,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,    83,    27,    28,    29,     0,
+    84,     0,    31,   228,     0,     0,     0,    32,    33,    34,
+    35,     1,     2,     3,     4,     5,     0,     0,     0,     0,
+     8,     0,     0,    82,     0,    13,    14,     0,    16,     0,
+     0,     0,     0,     0,    19,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+    24,    25,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,    83,    27,    28,    29,
+   231,    84,     0,    31,     0,     0,     0,     0,    32,    33,
+    34,    35,     1,     2,     3,     4,     5,     0,     0,     0,
+     0,     8,     0,     0,    82,     0,    13,    14,     0,    16,
+     0,     0,     0,     0,     0,    19,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,    24,    25,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,    83,    27,    28,
+    29,     0,    84,     0,    31,   311,     0,     0,     0,    32,
+    33,    34,    35,     1,     2,     3,     4,     5,     0,     0,
+     0,     0,     8,     0,     0,    82,     0,    13,    14,     0,
+    16,     0,     0,     0,     0,     0,    19,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,    24,    25,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,    83,    27,
+    28,    29,     0,    84,     0,    31,     0,     0,     0,     0,
+    32,    33,    34,    35
+};
+
+static const short yycheck[] = {    17,
+    23,    76,     1,   126,     1,     1,     1,    67,    24,   132,
+    12,     1,    30,    13,    14,     1,     1,    42,    24,    19,
+    22,    10,    67,    83,    24,    25,    40,    29,     6,     7,
+   153,    61,    32,    33,    34,    35,    42,    43,    83,    42,
+    43,    47,    48,    49,    50,    51,    52,    53,    54,    55,
+    56,    57,    13,    14,   177,    63,   179,    62,    19,    58,
+    85,    58,    67,    24,    25,   267,    82,    81,    42,    43,
+   193,    32,    33,    34,    35,    64,    82,    67,    62,    81,
+    58,    67,    67,    67,    83,    58,    83,    83,    83,    62,
+   108,    58,   294,    83,   112,    24,    25,    83,    83,   101,
+   223,   103,    61,   105,   106,   123,     6,     7,   270,    38,
+    39,    61,   274,   113,   114,    65,    62,   319,    58,    69,
+    81,    67,    62,     3,     4,     5,     6,     7,    60,    68,
+   332,   133,    12,    61,   136,    15,   298,    65,    79,    62,
+    20,    69,    74,    75,    67,    62,    62,    76,    77,    61,
+    67,    67,   113,   114,   154,   155,   156,    62,    58,    70,
+    71,    62,    67,   286,    64,   288,    67,    61,   291,   162,
+   163,   164,   165,   166,   167,    32,    33,    62,    58,    62,
+    60,    61,    67,    63,    67,    65,    58,   310,    61,    61,
+    67,   214,    78,   154,   155,   156,   157,   158,   159,   160,
+   161,   162,   163,   164,   165,   166,   167,   168,   169,   170,
+   171,   172,   173,   174,   175,   176,    62,    62,    66,    67,
+    64,    67,    67,    67,    80,   300,    41,     1,    61,     3,
+     4,     5,     6,     7,    34,    35,    36,    37,    12,    66,
+    67,    15,    82,    17,    18,    61,    20,   168,   169,   170,
+   171,    22,    26,    44,    45,    46,    66,    67,   276,    68,
+   278,    68,   280,    68,   266,   267,    67,    68,    42,    43,
+   159,   160,   161,   157,   158,   277,   172,   173,   174,   346,
+   347,    67,    58,    58,    58,    59,    60,    61,    58,    63,
+   292,    65,   294,    83,    67,    63,    70,    71,    72,    73,
+   318,    61,    61,    33,   322,   328,    68,    58,    63,    83,
+    58,    68,   330,    24,   316,    23,    83,   319,     9,    62,
+    83,    62,   324,    68,    62,   343,     0,   345,   346,   347,
+   332,    64,   350,     8,   352,   353,     3,     4,     5,     6,
+     7,     8,     0,   222,    11,    12,    13,    14,    15,    16,
+    17,    18,    19,    20,    21,    22,   227,     8,   175,    26,
+    27,    28,   176,    30,    31,   184,   196,   264,   339,   326,
+   272,   200,   215,    -1,    -1,    42,    43,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    58,    59,    60,    61,    -1,    63,    64,    65,    -1,
+    -1,    -1,    -1,    70,    71,    72,    73,    -1,    -1,     3,
+     4,     5,     6,     7,     8,    -1,    83,    11,    12,    13,
+    14,    15,    16,    17,    18,    19,    20,    21,    22,    -1,
+    -1,    -1,    26,    27,    28,    -1,    30,    31,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    42,    43,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    58,    59,    60,    61,    -1,    63,
+    64,    65,    -1,    -1,    -1,    -1,    70,    71,    72,    73,
+    -1,    -1,     3,     4,     5,     6,     7,     8,    -1,    83,
+    11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
+    21,    22,    -1,    -1,    -1,    26,    27,    28,    -1,    30,
+    31,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    42,    43,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    58,    59,    60,
+    61,    -1,    63,    64,    65,    -1,    -1,    -1,    -1,    70,
+    71,    72,    73,    -1,    -1,     3,     4,     5,     6,     7,
+     8,    -1,    83,    11,    12,    13,    14,    15,    16,    17,
+    18,    19,    20,    21,    22,    -1,    -1,    -1,    26,    27,
+    28,    -1,    30,    31,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    42,    43,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    58,    59,    60,    61,    -1,    63,    64,    65,    -1,    -1,
+    -1,    -1,    70,    71,    72,    73,    -1,    -1,     3,     4,
+     5,     6,     7,     8,    -1,    83,    11,    12,    13,    14,
+    15,    16,    17,    18,    19,    20,    21,    22,    -1,    -1,
+    -1,    26,    27,    28,    -1,    30,    31,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    42,    43,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    58,    59,    60,    61,    -1,    63,    64,
+    65,    -1,    -1,    -1,    -1,    70,    71,    72,    73,    -1,
+    -1,     3,     4,     5,     6,     7,     8,    -1,    83,    11,
+    12,    13,    14,    15,    16,    17,    18,    19,    20,    21,
+    22,    -1,    -1,    -1,    26,    27,    28,    -1,    30,    31,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    42,    43,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    58,    59,    60,    61,
+    -1,    63,    -1,    65,    -1,    -1,    -1,    -1,    70,    71,
+    72,    73,    -1,    -1,     3,     4,     5,     6,     7,     8,
+    -1,    83,    11,    12,    13,    14,    15,    16,    17,    18,
+    19,    20,    21,    22,    -1,    -1,    -1,    26,    27,    28,
+    -1,    30,    31,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    42,    43,    -1,    42,    43,    47,    48,    49,    50,    51,
+    52,    53,    54,    55,    56,    57,    -1,    -1,    -1,    58,
+    59,    60,    61,    -1,    63,    -1,    65,    -1,    -1,    -1,
+    -1,    70,    71,    72,    73,    -1,    -1,    -1,    -1,    -1,
+    82,    -1,     0,    -1,    83,     3,     4,     5,     6,     7,
+     8,     9,    10,    11,    12,    13,    14,    15,    16,    17,
+    18,    19,    20,    21,    22,    23,    -1,    -1,    26,    27,
+    28,    -1,    30,    31,    -1,    -1,    -1,    -1,    -1,     3,
+     4,     5,     6,     7,    -1,    -1,    -1,    -1,    12,    13,
+    -1,    15,    -1,    17,    18,    -1,    20,    -1,    -1,    -1,
+    58,    59,    26,    -1,    -1,    63,    64,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    72,    73,    -1,    -1,    42,    43,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    58,    59,    60,    61,    -1,    63,
+    -1,    65,    -1,    -1,    -1,    -1,    70,    71,    72,    73,
+     3,     4,     5,     6,     7,    -1,    -1,    -1,    -1,    12,
+    -1,    -1,    15,    -1,    17,    18,    -1,    20,    -1,    -1,
+    -1,    -1,    -1,    26,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    42,
+    43,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    58,    59,    60,    61,    -1,
+    63,    -1,    65,    66,    -1,    -1,    -1,    70,    71,    72,
+    73,     3,     4,     5,     6,     7,    -1,    -1,    -1,    -1,
+    12,    -1,    -1,    15,    -1,    17,    18,    -1,    20,    -1,
+    -1,    -1,    -1,    -1,    26,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    42,    43,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    58,    59,    60,    61,
+    62,    63,    -1,    65,    -1,    -1,    -1,    -1,    70,    71,
+    72,    73,     3,     4,     5,     6,     7,    -1,    -1,    -1,
+    -1,    12,    -1,    -1,    15,    -1,    17,    18,    -1,    20,
+    -1,    -1,    -1,    -1,    -1,    26,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    42,    43,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    58,    59,    60,
+    61,    -1,    63,    -1,    65,    66,    -1,    -1,    -1,    70,
+    71,    72,    73,     3,     4,     5,     6,     7,    -1,    -1,
+    -1,    -1,    12,    -1,    -1,    15,    -1,    17,    18,    -1,
+    20,    -1,    -1,    -1,    -1,    -1,    26,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    42,    43,    -1,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    58,    59,
+    60,    61,    -1,    63,    -1,    65,    -1,    -1,    -1,    -1,
+    70,    71,    72,    73
+};
+/* -*-C-*-  Note some compilers choke on comments on `#line' lines.  */
+#line 3 "/usr/share/misc/bison.simple"
+/* This file comes from bison-1.28.  */
+
+/* Skeleton output parser for bison,
+   Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, when this file is copied by Bison into a
+   Bison output file, you may use that output file without restriction.
+   This special exception was added by the Free Software Foundation
+   in version 1.24 of Bison.  */
+
+/* This is the parser code that is written into each bison parser
+  when the %semantic_parser declaration is not specified in the grammar.
+  It was written by Richard Stallman by simplifying the hairy parser
+  used when %semantic_parser is specified.  */
+
+#ifndef YYSTACK_USE_ALLOCA
+#ifdef alloca
+#define YYSTACK_USE_ALLOCA
+#else /* alloca not defined */
+#ifdef __GNUC__
+#define YYSTACK_USE_ALLOCA
+#define alloca __builtin_alloca
+#else /* not GNU C.  */
+#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386))
+#define YYSTACK_USE_ALLOCA
+#include <alloca.h>
+#else /* not sparc */
+/* We think this test detects Watcom and Microsoft C.  */
+/* This used to test MSDOS, but that is a bad idea
+   since that symbol is in the user namespace.  */
+#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__)
+#if 0 /* No need for malloc.h, which pollutes the namespace;
+	 instead, just don't use alloca.  */
+#include <malloc.h>
+#endif
+#else /* not MSDOS, or __TURBOC__ */
+#if defined(_AIX)
+/* I don't know what this was needed for, but it pollutes the namespace.
+   So I turned it off.   rms, 2 May 1997.  */
+/* #include <malloc.h>  */
+ #pragma alloca
+#define YYSTACK_USE_ALLOCA
+#else /* not MSDOS, or __TURBOC__, or _AIX */
+#if 0
+#ifdef __hpux /* haible at ilog.fr says this works for HPUX 9.05 and up,
+		 and on HPUX 10.  Eventually we can turn this on.  */
+#define YYSTACK_USE_ALLOCA
+#define alloca __builtin_alloca
+#endif /* __hpux */
+#endif
+#endif /* not _AIX */
+#endif /* not MSDOS, or __TURBOC__ */
+#endif /* not sparc */
+#endif /* not GNU C */
+#endif /* alloca not defined */
+#endif /* YYSTACK_USE_ALLOCA not defined */
+
+#ifdef YYSTACK_USE_ALLOCA
+#define YYSTACK_ALLOC alloca
+#else
+#define YYSTACK_ALLOC malloc
+#endif
+
+/* Note: there must be only one dollar sign in this file.
+   It is replaced by the list of actions, each action
+   as one case of the switch.  */
+
+#define yyerrok		(yyerrstatus = 0)
+#define yyclearin	(yychar = YYEMPTY)
+#define YYEMPTY		-2
+#define YYEOF		0
+#define YYACCEPT	goto yyacceptlab
+#define YYABORT 	goto yyabortlab
+#define YYERROR		goto yyerrlab1
+/* Like YYERROR except do call yyerror.
+   This remains here temporarily to ease the
+   transition to the new meaning of YYERROR, for GCC.
+   Once GCC version 2 has supplanted version 1, this can go.  */
+#define YYFAIL		goto yyerrlab
+#define YYRECOVERING()  (!!yyerrstatus)
+#define YYBACKUP(token, value) \
+do								\
+  if (yychar == YYEMPTY && yylen == 1)				\
+    { yychar = (token), yylval = (value);			\
+      yychar1 = YYTRANSLATE (yychar);				\
+      YYPOPSTACK;						\
+      goto yybackup;						\
+    }								\
+  else								\
+    { yyerror ("syntax error: cannot back up"); YYERROR; }	\
+while (0)
+
+#define YYTERROR	1
+#define YYERRCODE	256
+
+#ifndef YYPURE
+#define YYLEX		yylex()
+#endif
+
+#ifdef YYPURE
+#ifdef YYLSP_NEEDED
+#ifdef YYLEX_PARAM
+#define YYLEX		yylex(&yylval, &yylloc, YYLEX_PARAM)
+#else
+#define YYLEX		yylex(&yylval, &yylloc)
+#endif
+#else /* not YYLSP_NEEDED */
+#ifdef YYLEX_PARAM
+#define YYLEX		yylex(&yylval, YYLEX_PARAM)
+#else
+#define YYLEX		yylex(&yylval)
+#endif
+#endif /* not YYLSP_NEEDED */
+#endif
+
+/* If nonreentrant, generate the variables here */
+
+#ifndef YYPURE
+
+int	yychar;			/*  the lookahead symbol		*/
+YYSTYPE	yylval;			/*  the semantic value of the		*/
+				/*  lookahead symbol			*/
+
+#ifdef YYLSP_NEEDED
+YYLTYPE yylloc;			/*  location data for the lookahead	*/
+				/*  symbol				*/
+#endif
+
+int yynerrs;			/*  number of parse errors so far       */
+#endif  /* not YYPURE */
+
+#if YYDEBUG != 0
+int yydebug;			/*  nonzero means print parse trace	*/
+/* Since this is uninitialized, it does not stop multiple parsers
+   from coexisting.  */
+#endif
+
+/*  YYINITDEPTH indicates the initial size of the parser's stacks	*/
+
+#ifndef	YYINITDEPTH
+#define YYINITDEPTH 200
+#endif
+
+/*  YYMAXDEPTH is the maximum size the stacks can grow to
+    (effective only if the built-in stack extension method is used).  */
+
+#if YYMAXDEPTH == 0
+#undef YYMAXDEPTH
+#endif
+
+#ifndef YYMAXDEPTH
+#define YYMAXDEPTH 10000
+#endif
+
+/* Define __yy_memcpy.  Note that the size argument
+   should be passed with type unsigned int, because that is what the non-GCC
+   definitions require.  With GCC, __builtin_memcpy takes an arg
+   of type size_t, but it can handle unsigned int.  */
+
+#if __GNUC__ > 1		/* GNU C and GNU C++ define this.  */
+#define __yy_memcpy(TO,FROM,COUNT)	__builtin_memcpy(TO,FROM,COUNT)
+#else				/* not GNU C or C++ */
+#ifndef __cplusplus
+
+/* This is the most reliable way to avoid incompatibilities
+   in available built-in functions on various systems.  */
+static void
+__yy_memcpy (to, from, count)
+     char *to;
+     char *from;
+     unsigned int count;
+{
+  register char *f = from;
+  register char *t = to;
+  register int i = count;
+
+  while (i-- > 0)
+    *t++ = *f++;
+}
+
+#else /* __cplusplus */
+
+/* This is the most reliable way to avoid incompatibilities
+   in available built-in functions on various systems.  */
+static void
+__yy_memcpy (char *to, char *from, unsigned int count)
+{
+  register char *t = to;
+  register char *f = from;
+  register int i = count;
+
+  while (i-- > 0)
+    *t++ = *f++;
+}
+
+#endif
+#endif
+
+#line 217 "/usr/share/misc/bison.simple"
+
+/* The user can define YYPARSE_PARAM as the name of an argument to be passed
+   into yyparse.  The argument should have type void *.
+   It should actually point to an object.
+   Grammar actions can access the variable by casting it
+   to the proper pointer type.  */
+
+#ifdef YYPARSE_PARAM
+#ifdef __cplusplus
+#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
+#define YYPARSE_PARAM_DECL
+#else /* not __cplusplus */
+#define YYPARSE_PARAM_ARG YYPARSE_PARAM
+#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
+#endif /* not __cplusplus */
+#else /* not YYPARSE_PARAM */
+#define YYPARSE_PARAM_ARG
+#define YYPARSE_PARAM_DECL
+#endif /* not YYPARSE_PARAM */
+
+/* Prevent warning if -Wstrict-prototypes.  */
+#ifdef __GNUC__
+#ifdef YYPARSE_PARAM
+int yyparse (void *);
+#else
+int yyparse (void);
+#endif
+#endif
+
+int
+yyparse(YYPARSE_PARAM_ARG)
+     YYPARSE_PARAM_DECL
+{
+  register int yystate;
+  register int yyn;
+  register short *yyssp;
+  register YYSTYPE *yyvsp;
+  int yyerrstatus;	/*  number of tokens to shift before error messages enabled */
+  int yychar1 = 0;		/*  lookahead token as an internal (translated) token number */
+
+  short	yyssa[YYINITDEPTH];	/*  the state stack			*/
+  YYSTYPE yyvsa[YYINITDEPTH];	/*  the semantic value stack		*/
+
+  short *yyss = yyssa;		/*  refer to the stacks thru separate pointers */
+  YYSTYPE *yyvs = yyvsa;	/*  to allow yyoverflow to reallocate them elsewhere */
+
+#ifdef YYLSP_NEEDED
+  YYLTYPE yylsa[YYINITDEPTH];	/*  the location stack			*/
+  YYLTYPE *yyls = yylsa;
+  YYLTYPE *yylsp;
+
+#define YYPOPSTACK   (yyvsp--, yyssp--, yylsp--)
+#else
+#define YYPOPSTACK   (yyvsp--, yyssp--)
+#endif
+
+  int yystacksize = YYINITDEPTH;
+  int yyfree_stacks = 0;
+
+#ifdef YYPURE
+  int yychar;
+  YYSTYPE yylval;
+  int yynerrs;
+#ifdef YYLSP_NEEDED
+  YYLTYPE yylloc;
+#endif
+#endif
+
+  YYSTYPE yyval;		/*  the variable used to return		*/
+				/*  semantic values from the action	*/
+				/*  routines				*/
+
+  int yylen;
+
+#if YYDEBUG != 0
+  if (yydebug)
+    fprintf(stderr, "Starting parse\n");
+#endif
+
+  yystate = 0;
+  yyerrstatus = 0;
+  yynerrs = 0;
+  yychar = YYEMPTY;		/* Cause a token to be read.  */
+
+  /* Initialize stack pointers.
+     Waste one element of value and location stack
+     so that they stay on the same level as the state stack.
+     The wasted elements are never initialized.  */
+
+  yyssp = yyss - 1;
+  yyvsp = yyvs;
+#ifdef YYLSP_NEEDED
+  yylsp = yyls;
+#endif
+
+/* Push a new state, which is found in  yystate  .  */
+/* In all cases, when you get here, the value and location stacks
+   have just been pushed. so pushing a state here evens the stacks.  */
+yynewstate:
+
+  *++yyssp = yystate;
+
+  if (yyssp >= yyss + yystacksize - 1)
+    {
+      /* Give user a chance to reallocate the stack */
+      /* Use copies of these so that the &'s don't force the real ones into memory. */
+      YYSTYPE *yyvs1 = yyvs;
+      short *yyss1 = yyss;
+#ifdef YYLSP_NEEDED
+      YYLTYPE *yyls1 = yyls;
+#endif
+
+      /* Get the current used size of the three stacks, in elements.  */
+      int size = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+      /* Each stack pointer address is followed by the size of
+	 the data in use in that stack, in bytes.  */
+#ifdef YYLSP_NEEDED
+      /* This used to be a conditional around just the two extra args,
+	 but that might be undefined if yyoverflow is a macro.  */
+      yyoverflow("parser stack overflow",
+		 &yyss1, size * sizeof (*yyssp),
+		 &yyvs1, size * sizeof (*yyvsp),
+		 &yyls1, size * sizeof (*yylsp),
+		 &yystacksize);
+#else
+      yyoverflow("parser stack overflow",
+		 &yyss1, size * sizeof (*yyssp),
+		 &yyvs1, size * sizeof (*yyvsp),
+		 &yystacksize);
+#endif
+
+      yyss = yyss1; yyvs = yyvs1;
+#ifdef YYLSP_NEEDED
+      yyls = yyls1;
+#endif
+#else /* no yyoverflow */
+      /* Extend the stack our own way.  */
+      if (yystacksize >= YYMAXDEPTH)
+	{
+	  yyerror("parser stack overflow");
+	  if (yyfree_stacks)
+	    {
+	      free (yyss);
+	      free (yyvs);
+#ifdef YYLSP_NEEDED
+	      free (yyls);
+#endif
+	    }
+	  return 2;
+	}
+      yystacksize *= 2;
+      if (yystacksize > YYMAXDEPTH)
+	yystacksize = YYMAXDEPTH;
+#ifndef YYSTACK_USE_ALLOCA
+      yyfree_stacks = 1;
+#endif
+      yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp));
+      __yy_memcpy ((char *)yyss, (char *)yyss1,
+		   size * (unsigned int) sizeof (*yyssp));
+      yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp));
+      __yy_memcpy ((char *)yyvs, (char *)yyvs1,
+		   size * (unsigned int) sizeof (*yyvsp));
+#ifdef YYLSP_NEEDED
+      yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp));
+      __yy_memcpy ((char *)yyls, (char *)yyls1,
+		   size * (unsigned int) sizeof (*yylsp));
+#endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + size - 1;
+      yyvsp = yyvs + size - 1;
+#ifdef YYLSP_NEEDED
+      yylsp = yyls + size - 1;
+#endif
+
+#if YYDEBUG != 0
+      if (yydebug)
+	fprintf(stderr, "Stack size increased to %d\n", yystacksize);
+#endif
+
+      if (yyssp >= yyss + yystacksize - 1)
+	YYABORT;
+    }
+
+#if YYDEBUG != 0
+  if (yydebug)
+    fprintf(stderr, "Entering state %d\n", yystate);
+#endif
+
+  goto yybackup;
+ yybackup:
+
+/* Do appropriate processing given the current state.  */
+/* Read a lookahead token if we need one and don't already have one.  */
+/* yyresume: */
+
+  /* First try to decide what to do without reference to lookahead token.  */
+
+  yyn = yypact[yystate];
+  if (yyn == YYFLAG)
+    goto yydefault;
+
+  /* Not known => get a lookahead token if don't already have one.  */
+
+  /* yychar is either YYEMPTY or YYEOF
+     or a valid token in external form.  */
+
+  if (yychar == YYEMPTY)
+    {
+#if YYDEBUG != 0
+      if (yydebug)
+	fprintf(stderr, "Reading a token: ");
+#endif
+      yychar = YYLEX;
+    }
+
+  /* Convert token to internal form (in yychar1) for indexing tables with */
+
+  if (yychar <= 0)		/* This means end of input. */
+    {
+      yychar1 = 0;
+      yychar = YYEOF;		/* Don't call YYLEX any more */
+
+#if YYDEBUG != 0
+      if (yydebug)
+	fprintf(stderr, "Now at end of input.\n");
+#endif
+    }
+  else
+    {
+      yychar1 = YYTRANSLATE(yychar);
+
+#if YYDEBUG != 0
+      if (yydebug)
+	{
+	  fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
+	  /* Give the individual parser a way to print the precise meaning
+	     of a token, for further debugging info.  */
+#ifdef YYPRINT
+	  YYPRINT (stderr, yychar, yylval);
+#endif
+	  fprintf (stderr, ")\n");
+	}
+#endif
+    }
+
+  yyn += yychar1;
+  if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
+    goto yydefault;
+
+  yyn = yytable[yyn];
+
+  /* yyn is what to do for this token type in this state.
+     Negative => reduce, -yyn is rule number.
+     Positive => shift, yyn is new state.
+       New state is final state => don't bother to shift,
+       just return success.
+     0, or most negative number => error.  */
+
+  if (yyn < 0)
+    {
+      if (yyn == YYFLAG)
+	goto yyerrlab;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+  else if (yyn == 0)
+    goto yyerrlab;
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  /* Shift the lookahead token.  */
+
+#if YYDEBUG != 0
+  if (yydebug)
+    fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
+#endif
+
+  /* Discard the token being shifted unless it is eof.  */
+  if (yychar != YYEOF)
+    yychar = YYEMPTY;
+
+  *++yyvsp = yylval;
+#ifdef YYLSP_NEEDED
+  *++yylsp = yylloc;
+#endif
+
+  /* count tokens shifted since error; after three, turn off error status.  */
+  if (yyerrstatus) yyerrstatus--;
+
+  yystate = yyn;
+  goto yynewstate;
+
+/* Do the default action for the current state.  */
+yydefault:
+
+  yyn = yydefact[yystate];
+  if (yyn == 0)
+    goto yyerrlab;
+
+/* Do a reduction.  yyn is the number of a rule to reduce with.  */
+yyreduce:
+  yylen = yyr2[yyn];
+  if (yylen > 0)
+    yyval = yyvsp[1-yylen]; /* implement default value of the action */
+
+#if YYDEBUG != 0
+  if (yydebug)
+    {
+      int i;
+
+      fprintf (stderr, "Reducing via rule %d (line %d), ",
+	       yyn, yyrline[yyn]);
+
+      /* Print the symbols being reduced, and their result.  */
+      for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
+	fprintf (stderr, "%s ", yytname[yyrhs[i]]);
+      fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
+    }
+#endif
+
+
+  switch (yyn) {
+
+case 1:
+#line 157 "grammar.y"
+{ yyval.node = new NullNode(); ;
+    break;}
+case 2:
+#line 158 "grammar.y"
+{ yyval.node = new BooleanNode(true); ;
+    break;}
+case 3:
+#line 159 "grammar.y"
+{ yyval.node = new BooleanNode(false); ;
+    break;}
+case 4:
+#line 160 "grammar.y"
+{ yyval.node = new NumberNode(yyvsp[0].dval); ;
+    break;}
+case 5:
+#line 161 "grammar.y"
+{ yyval.node = new StringNode(yyvsp[0].ustr); delete yyvsp[0].ustr; ;
+    break;}
+case 6:
+#line 162 "grammar.y"
+{ Lexer *l = Lexer::curr();
+                                     if (!l->scanRegExp()) YYABORT;
+                                     yyval.node = new RegExpNode(l->pattern,l->flags);;
+    break;}
+case 7:
+#line 168 "grammar.y"
+{ yyval.node = new ThisNode(); ;
+    break;}
+case 8:
+#line 169 "grammar.y"
+{ yyval.node = new ResolveNode(yyvsp[0].ustr);
+                                     delete yyvsp[0].ustr; ;
+    break;}
+case 11:
+#line 173 "grammar.y"
+{ yyval.node = new GroupNode(yyvsp[-1].node); ;
+    break;}
+case 12:
+#line 174 "grammar.y"
+{ yyval.node = new ObjectLiteralNode(0L); ;
+    break;}
+case 13:
+#line 175 "grammar.y"
+{ yyval.node = new ObjectLiteralNode(yyvsp[-1].node); ;
+    break;}
+case 14:
+#line 179 "grammar.y"
+{ yyval.node = new ArrayNode(yyvsp[-1].eli); ;
+    break;}
+case 15:
+#line 180 "grammar.y"
+{ yyval.node = new ArrayNode(yyvsp[-1].elm); ;
+    break;}
+case 16:
+#line 181 "grammar.y"
+{ yyval.node = new ArrayNode(yyvsp[-1].eli, yyvsp[-3].elm); ;
+    break;}
+case 17:
+#line 185 "grammar.y"
+{ yyval.elm = new ElementNode(yyvsp[-1].eli, yyvsp[0].node); ;
+    break;}
+case 18:
+#line 187 "grammar.y"
+{ yyval.elm = new ElementNode(yyvsp[-3].elm, yyvsp[-1].eli, yyvsp[0].node); ;
+    break;}
+case 19:
+#line 191 "grammar.y"
+{ yyval.eli = 0L; ;
+    break;}
+case 21:
+#line 196 "grammar.y"
+{ yyval.eli = new ElisionNode(0L); ;
+    break;}
+case 22:
+#line 197 "grammar.y"
+{ yyval.eli = new ElisionNode(yyvsp[-1].eli); ;
+    break;}
+case 23:
+#line 201 "grammar.y"
+{ yyval.node = new PropertyValueNode(yyvsp[-2].node, yyvsp[0].node); ;
+    break;}
+case 24:
+#line 203 "grammar.y"
+{ yyval.node = new PropertyValueNode(yyvsp[-2].node, yyvsp[0].node, yyvsp[-4].node); ;
+    break;}
+case 25:
+#line 207 "grammar.y"
+{ yyval.node = new PropertyNode(yyvsp[0].ustr);
+                                     delete yyvsp[0].ustr; ;
+    break;}
+case 26:
+#line 209 "grammar.y"
+{ yyval.node = new PropertyNode(yyvsp[0].ustr); delete yyvsp[0].ustr; ;
+    break;}
+case 27:
+#line 210 "grammar.y"
+{ yyval.node = new PropertyNode(yyvsp[0].dval); ;
+    break;}
+case 30:
+#line 216 "grammar.y"
+{ yyval.node = new AccessorNode1(yyvsp[-3].node, yyvsp[-1].node); ;
+    break;}
+case 31:
+#line 217 "grammar.y"
+{ yyval.node = new AccessorNode2(yyvsp[-2].node, yyvsp[0].ustr);
+                                     delete yyvsp[0].ustr; ;
+    break;}
+case 32:
+#line 219 "grammar.y"
+{ yyval.node = new NewExprNode(yyvsp[-1].node, yyvsp[0].args); ;
+    break;}
+case 34:
+#line 224 "grammar.y"
+{ yyval.node = new NewExprNode(yyvsp[0].node); ;
+    break;}
+case 35:
+#line 228 "grammar.y"
+{ yyval.node = new FunctionCallNode(yyvsp[-1].node, yyvsp[0].args); ;
+    break;}
+case 36:
+#line 229 "grammar.y"
+{ yyval.node = new FunctionCallNode(yyvsp[-1].node, yyvsp[0].args); ;
+    break;}
+case 37:
+#line 230 "grammar.y"
+{ yyval.node = new AccessorNode1(yyvsp[-3].node, yyvsp[-1].node); ;
+    break;}
+case 38:
+#line 231 "grammar.y"
+{ yyval.node = new AccessorNode2(yyvsp[-2].node, yyvsp[0].ustr); ;
+    break;}
+case 39:
+#line 235 "grammar.y"
+{ yyval.args = new ArgumentsNode(0L); ;
+    break;}
+case 40:
+#line 236 "grammar.y"
+{ yyval.args = new ArgumentsNode(yyvsp[-1].alist); ;
+    break;}
+case 41:
+#line 240 "grammar.y"
+{ yyval.alist = new ArgumentListNode(yyvsp[0].node); ;
+    break;}
+case 42:
+#line 241 "grammar.y"
+{ yyval.alist = new ArgumentListNode(yyvsp[-2].alist, yyvsp[0].node); ;
+    break;}
+case 46:
+#line 251 "grammar.y"
+{ yyval.node = new PostfixNode(yyvsp[-1].node, OpPlusPlus); ;
+    break;}
+case 47:
+#line 252 "grammar.y"
+{ yyval.node = new PostfixNode(yyvsp[-1].node, OpMinusMinus); ;
+    break;}
+case 49:
+#line 257 "grammar.y"
+{ yyval.node = new DeleteNode(yyvsp[0].node); ;
+    break;}
+case 50:
+#line 258 "grammar.y"
+{ yyval.node = new VoidNode(yyvsp[0].node); ;
+    break;}
+case 51:
+#line 259 "grammar.y"
+{ yyval.node = new TypeOfNode(yyvsp[0].node); ;
+    break;}
+case 52:
+#line 260 "grammar.y"
+{ yyval.node = new PrefixNode(OpPlusPlus, yyvsp[0].node); ;
+    break;}
+case 53:
+#line 261 "grammar.y"
+{ yyval.node = new PrefixNode(OpPlusPlus, yyvsp[0].node); ;
+    break;}
+case 54:
+#line 262 "grammar.y"
+{ yyval.node = new PrefixNode(OpMinusMinus, yyvsp[0].node); ;
+    break;}
+case 55:
+#line 263 "grammar.y"
+{ yyval.node = new PrefixNode(OpMinusMinus, yyvsp[0].node); ;
+    break;}
+case 56:
+#line 264 "grammar.y"
+{ yyval.node = new UnaryPlusNode(yyvsp[0].node); ;
+    break;}
+case 57:
+#line 265 "grammar.y"
+{ yyval.node = new NegateNode(yyvsp[0].node); ;
+    break;}
+case 58:
+#line 266 "grammar.y"
+{ yyval.node = new BitwiseNotNode(yyvsp[0].node); ;
+    break;}
+case 59:
+#line 267 "grammar.y"
+{ yyval.node = new LogicalNotNode(yyvsp[0].node); ;
+    break;}
+case 61:
+#line 272 "grammar.y"
+{ yyval.node = new MultNode(yyvsp[-2].node, yyvsp[0].node, '*'); ;
+    break;}
+case 62:
+#line 273 "grammar.y"
+{ yyval.node = new MultNode(yyvsp[-2].node, yyvsp[0].node, '/'); ;
+    break;}
+case 63:
+#line 274 "grammar.y"
+{ yyval.node = new MultNode(yyvsp[-2].node,yyvsp[0].node,'%'); ;
+    break;}
+case 65:
+#line 279 "grammar.y"
+{ yyval.node = new AddNode(yyvsp[-2].node, yyvsp[0].node, '+'); ;
+    break;}
+case 66:
+#line 280 "grammar.y"
+{ yyval.node = new AddNode(yyvsp[-2].node, yyvsp[0].node, '-'); ;
+    break;}
+case 68:
+#line 285 "grammar.y"
+{ yyval.node = new ShiftNode(yyvsp[-2].node, OpLShift, yyvsp[0].node); ;
+    break;}
+case 69:
+#line 286 "grammar.y"
+{ yyval.node = new ShiftNode(yyvsp[-2].node, OpRShift, yyvsp[0].node); ;
+    break;}
+case 70:
+#line 287 "grammar.y"
+{ yyval.node = new ShiftNode(yyvsp[-2].node, OpURShift, yyvsp[0].node); ;
+    break;}
+case 72:
+#line 293 "grammar.y"
+{ yyval.node = new RelationalNode(yyvsp[-2].node, OpLess, yyvsp[0].node); ;
+    break;}
+case 73:
+#line 295 "grammar.y"
+{ yyval.node = new RelationalNode(yyvsp[-2].node, OpGreater, yyvsp[0].node); ;
+    break;}
+case 74:
+#line 297 "grammar.y"
+{ yyval.node = new RelationalNode(yyvsp[-2].node, OpLessEq, yyvsp[0].node); ;
+    break;}
+case 75:
+#line 299 "grammar.y"
+{ yyval.node = new RelationalNode(yyvsp[-2].node, OpGreaterEq, yyvsp[0].node); ;
+    break;}
+case 76:
+#line 301 "grammar.y"
+{ yyval.node = new RelationalNode(yyvsp[-2].node, OpInstanceOf, yyvsp[0].node); ;
+    break;}
+case 77:
+#line 303 "grammar.y"
+{ yyval.node = new RelationalNode(yyvsp[-2].node, OpIn, yyvsp[0].node); ;
+    break;}
+case 79:
+#line 308 "grammar.y"
+{ yyval.node = new EqualNode(yyvsp[-2].node, OpEqEq, yyvsp[0].node); ;
+    break;}
+case 80:
+#line 309 "grammar.y"
+{ yyval.node = new EqualNode(yyvsp[-2].node, OpNotEq, yyvsp[0].node); ;
+    break;}
+case 81:
+#line 310 "grammar.y"
+{ yyval.node = new EqualNode(yyvsp[-2].node, OpStrEq, yyvsp[0].node); ;
+    break;}
+case 82:
+#line 311 "grammar.y"
+{ yyval.node = new EqualNode(yyvsp[-2].node, OpStrNEq, yyvsp[0].node);;
+    break;}
+case 84:
+#line 316 "grammar.y"
+{ yyval.node = new BitOperNode(yyvsp[-2].node, OpBitAnd, yyvsp[0].node); ;
+    break;}
+case 86:
+#line 321 "grammar.y"
+{ yyval.node = new BitOperNode(yyvsp[-2].node, OpBitXOr, yyvsp[0].node); ;
+    break;}
+case 88:
+#line 326 "grammar.y"
+{ yyval.node = new BitOperNode(yyvsp[-2].node, OpBitOr, yyvsp[0].node); ;
+    break;}
+case 90:
+#line 332 "grammar.y"
+{ yyval.node = new BinaryLogicalNode(yyvsp[-2].node, OpAnd, yyvsp[0].node); ;
+    break;}
+case 92:
+#line 338 "grammar.y"
+{ yyval.node = new BinaryLogicalNode(yyvsp[-2].node, OpOr, yyvsp[0].node); ;
+    break;}
+case 94:
+#line 344 "grammar.y"
+{ yyval.node = new ConditionalNode(yyvsp[-4].node, yyvsp[-2].node, yyvsp[0].node); ;
+    break;}
+case 96:
+#line 350 "grammar.y"
+{ yyval.node = new AssignNode(yyvsp[-2].node, yyvsp[-1].op, yyvsp[0].node);;
+    break;}
+case 97:
+#line 354 "grammar.y"
+{ yyval.op = OpEqual; ;
+    break;}
+case 98:
+#line 355 "grammar.y"
+{ yyval.op = OpPlusEq; ;
+    break;}
+case 99:
+#line 356 "grammar.y"
+{ yyval.op = OpMinusEq; ;
+    break;}
+case 100:
+#line 357 "grammar.y"
+{ yyval.op = OpMultEq; ;
+    break;}
+case 101:
+#line 358 "grammar.y"
+{ yyval.op = OpDivEq; ;
+    break;}
+case 102:
+#line 359 "grammar.y"
+{ yyval.op = OpLShift; ;
+    break;}
+case 103:
+#line 360 "grammar.y"
+{ yyval.op = OpRShift; ;
+    break;}
+case 104:
+#line 361 "grammar.y"
+{ yyval.op = OpURShift; ;
+    break;}
+case 105:
+#line 362 "grammar.y"
+{ yyval.op = OpAndEq; ;
+    break;}
+case 106:
+#line 363 "grammar.y"
+{ yyval.op = OpXOrEq; ;
+    break;}
+case 107:
+#line 364 "grammar.y"
+{ yyval.op = OpOrEq; ;
+    break;}
+case 108:
+#line 365 "grammar.y"
+{ yyval.op = OpModEq; ;
+    break;}
+case 110:
+#line 370 "grammar.y"
+{ yyval.node = new CommaNode(yyvsp[-2].node, yyvsp[0].node); ;
+    break;}
+case 125:
+#line 391 "grammar.y"
+{ yyval.stat = new BlockNode(0L); DBG(yyval.stat, yylsp[0], yylsp[0]); ;
+    break;}
+case 126:
+#line 392 "grammar.y"
+{ yyval.stat = new BlockNode(yyvsp[-1].slist); DBG(yyval.stat, yylsp[0], yylsp[0]); ;
+    break;}
+case 127:
+#line 396 "grammar.y"
+{ yyval.slist = new StatListNode(yyvsp[0].stat); ;
+    break;}
+case 128:
+#line 397 "grammar.y"
+{ yyval.slist = new StatListNode(yyvsp[-1].slist, yyvsp[0].stat); ;
+    break;}
+case 129:
+#line 401 "grammar.y"
+{ yyval.stat = new VarStatementNode(yyvsp[-1].vlist);
+                                      DBG(yyval.stat, yylsp[-2], yylsp[0]); ;
+    break;}
+case 130:
+#line 403 "grammar.y"
+{ if (automatic()) {
+                                          yyval.stat = new VarStatementNode(yyvsp[-1].vlist);
+					  DBG(yyval.stat, yylsp[-2], yylsp[-1]);
+                                        } else {
+					  YYABORT;
+					}
+                                      ;
+    break;}
+case 131:
+#line 413 "grammar.y"
+{ yyval.vlist = new VarDeclListNode(yyvsp[0].decl); ;
+    break;}
+case 132:
+#line 415 "grammar.y"
+{ yyval.vlist = new VarDeclListNode(yyvsp[-2].vlist, yyvsp[0].decl); ;
+    break;}
+case 133:
+#line 419 "grammar.y"
+{ yyval.decl = new VarDeclNode(yyvsp[0].ustr, 0); delete yyvsp[0].ustr; ;
+    break;}
+case 134:
+#line 420 "grammar.y"
+{ yyval.decl = new VarDeclNode(yyvsp[-1].ustr, yyvsp[0].init); delete yyvsp[-1].ustr; ;
+    break;}
+case 135:
+#line 424 "grammar.y"
+{ yyval.init = new AssignExprNode(yyvsp[0].node); ;
+    break;}
+case 136:
+#line 428 "grammar.y"
+{ yyval.stat = new EmptyStatementNode(); ;
+    break;}
+case 137:
+#line 432 "grammar.y"
+{ yyval.stat = new ExprStatementNode(yyvsp[-1].node);
+                                     DBG(yyval.stat, yylsp[-1], yylsp[0]); ;
+    break;}
+case 138:
+#line 434 "grammar.y"
+{ if (automatic()) {
+                                       yyval.stat = new ExprStatementNode(yyvsp[-1].node);
+				       DBG(yyval.stat, yylsp[-1], yylsp[-1]);
+                                     } else
+				       YYABORT; ;
+    break;}
+case 139:
+#line 442 "grammar.y"
+{ yyval.stat = new IfNode(yyvsp[-2].node,yyvsp[0].stat,0L);DBG(yyval.stat,yylsp[-4],yylsp[-1]); ;
+    break;}
+case 140:
+#line 444 "grammar.y"
+{ yyval.stat = new IfNode(yyvsp[-4].node,yyvsp[-2].stat,yyvsp[0].stat);DBG(yyval.stat,yylsp[-6],yylsp[-3]); ;
+    break;}
+case 141:
+#line 448 "grammar.y"
+{ yyval.stat=new DoWhileNode(yyvsp[-4].stat,yyvsp[-1].node);DBG(yyval.stat,yylsp[-5],yylsp[-3]);;
+    break;}
+case 142:
+#line 449 "grammar.y"
+{ yyval.stat = new WhileNode(yyvsp[-2].node,yyvsp[0].stat);DBG(yyval.stat,yylsp[-4],yylsp[-1]); ;
+    break;}
+case 143:
+#line 451 "grammar.y"
+{ yyval.stat = new ForNode(yyvsp[-6].node,yyvsp[-4].node,yyvsp[-2].node,yyvsp[0].stat);
+	                             DBG(yyval.stat,yylsp[-8],yylsp[-1]); ;
+    break;}
+case 144:
+#line 454 "grammar.y"
+{ yyval.stat = new ForNode(yyvsp[-6].vlist,yyvsp[-4].node,yyvsp[-2].node,yyvsp[0].stat);
+	                             DBG(yyval.stat,yylsp[-9],yylsp[-1]); ;
+    break;}
+case 145:
+#line 457 "grammar.y"
+{ yyval.stat = new ForInNode(yyvsp[-4].node, yyvsp[-2].node, yyvsp[0].stat);
+	                             DBG(yyval.stat,yylsp[-6],yylsp[-1]); ;
+    break;}
+case 146:
+#line 460 "grammar.y"
+{ yyval.stat = new ForInNode(yyvsp[-4].ustr,0L,yyvsp[-2].node,yyvsp[0].stat);
+	                             DBG(yyval.stat,yylsp[-7],yylsp[-1]);
+                                     delete yyvsp[-4].ustr; ;
+    break;}
+case 147:
+#line 464 "grammar.y"
+{ yyval.stat = new ForInNode(yyvsp[-5].ustr,yyvsp[-4].init,yyvsp[-2].node,yyvsp[0].stat);
+	                             DBG(yyval.stat,yylsp[-8],yylsp[-1]);
+                                     delete yyvsp[-5].ustr; ;
+    break;}
+case 148:
+#line 470 "grammar.y"
+{ yyval.node = 0L; ;
+    break;}
+case 150:
+#line 475 "grammar.y"
+{ yyval.stat = new ContinueNode(); DBG(yyval.stat,yylsp[-1],yylsp[0]); ;
+    break;}
+case 151:
+#line 476 "grammar.y"
+{ if (automatic()) {
+                                       yyval.stat = new ContinueNode(); DBG(yyval.stat,yylsp[-1],yylsp[0]);
+                                     } else
+				       YYABORT; ;
+    break;}
+case 152:
+#line 480 "grammar.y"
+{ yyval.stat = new ContinueNode(yyvsp[-1].ustr); DBG(yyval.stat,yylsp[-2],yylsp[0]);
+                                     delete yyvsp[-1].ustr; ;
+    break;}
+case 153:
+#line 482 "grammar.y"
+{ if (automatic()) {
+                                       yyval.stat = new ContinueNode(yyvsp[-1].ustr);DBG(yyval.stat,yylsp[-2],yylsp[-1]);
+				       delete yyvsp[-1].ustr;
+                                     } else
+				       YYABORT; ;
+    break;}
+case 154:
+#line 490 "grammar.y"
+{ yyval.stat = new BreakNode();DBG(yyval.stat,yylsp[-1],yylsp[0]); ;
+    break;}
+case 155:
+#line 491 "grammar.y"
+{ if (automatic()) {
+                                       yyval.stat = new BreakNode(); DBG(yyval.stat,yylsp[-1],yylsp[-1]);
+                                     } else
+				       YYABORT; ;
+    break;}
+case 156:
+#line 495 "grammar.y"
+{ yyval.stat = new BreakNode(yyvsp[-1].ustr); DBG(yyval.stat,yylsp[-2],yylsp[0]);
+                                     delete yyvsp[-1].ustr; ;
+    break;}
+case 157:
+#line 497 "grammar.y"
+{ if (automatic()) {
+                                       yyval.stat = new BreakNode(yyvsp[-1].ustr); DBG(yyval.stat,yylsp[-2],yylsp[-1]);
+				       delete yyvsp[-1].ustr;
+                                     } else
+				       YYABORT;
+                                   ;
+    break;}
+case 158:
+#line 506 "grammar.y"
+{ yyval.stat = new ReturnNode(0L); DBG(yyval.stat,yylsp[-1],yylsp[0]); ;
+    break;}
+case 159:
+#line 507 "grammar.y"
+{ if (automatic()) {
+                                       yyval.stat = new ReturnNode(0L); DBG(yyval.stat,yylsp[-1],yylsp[-1]);
+                                     } else
+				       YYABORT; ;
+    break;}
+case 160:
+#line 511 "grammar.y"
+{ yyval.stat = new ReturnNode(yyvsp[-1].node); ;
+    break;}
+case 161:
+#line 512 "grammar.y"
+{ if (automatic())
+                                       yyval.stat = new ReturnNode(yyvsp[-1].node);
+                                     else
+				       YYABORT; ;
+    break;}
+case 162:
+#line 519 "grammar.y"
+{ yyval.stat = new WithNode(yyvsp[-2].node,yyvsp[0].stat);
+                                     DBG(yyval.stat, yylsp[-4], yylsp[-1]); ;
+    break;}
+case 163:
+#line 524 "grammar.y"
+{ yyval.stat = new SwitchNode(yyvsp[-2].node, yyvsp[0].cblk);
+                                     DBG(yyval.stat, yylsp[-4], yylsp[-1]); ;
+    break;}
+case 164:
+#line 529 "grammar.y"
+{ yyval.cblk = new CaseBlockNode(yyvsp[-1].clist, 0L, 0L); ;
+    break;}
+case 165:
+#line 531 "grammar.y"
+{ yyval.cblk = new CaseBlockNode(yyvsp[-3].clist, yyvsp[-2].ccl, yyvsp[-1].clist); ;
+    break;}
+case 166:
+#line 535 "grammar.y"
+{ yyval.clist = 0L; ;
+    break;}
+case 168:
+#line 540 "grammar.y"
+{ yyval.clist = new ClauseListNode(yyvsp[0].ccl); ;
+    break;}
+case 169:
+#line 541 "grammar.y"
+{ yyval.clist = yyvsp[-1].clist->append(yyvsp[0].ccl); ;
+    break;}
+case 170:
+#line 545 "grammar.y"
+{ yyval.ccl = new CaseClauseNode(yyvsp[-1].node, 0L); ;
+    break;}
+case 171:
+#line 546 "grammar.y"
+{ yyval.ccl = new CaseClauseNode(yyvsp[-2].node, yyvsp[0].slist); ;
+    break;}
+case 172:
+#line 550 "grammar.y"
+{ yyval.ccl = new CaseClauseNode(0L, 0L);; ;
+    break;}
+case 173:
+#line 551 "grammar.y"
+{ yyval.ccl = new CaseClauseNode(0L, yyvsp[0].slist); ;
+    break;}
+case 174:
+#line 555 "grammar.y"
+{ yyvsp[0].stat->pushLabel(yyvsp[-2].ustr);
+                                     yyval.stat = new LabelNode(yyvsp[-2].ustr, yyvsp[0].stat);
+                                     delete yyvsp[-2].ustr; ;
+    break;}
+case 175:
+#line 561 "grammar.y"
+{ yyval.stat = new ThrowNode(yyvsp[-1].node); ;
+    break;}
+case 176:
+#line 565 "grammar.y"
+{ yyval.stat = new TryNode(yyvsp[-1].stat, yyvsp[0].node); ;
+    break;}
+case 177:
+#line 566 "grammar.y"
+{ yyval.stat = new TryNode(yyvsp[-1].stat, 0L, yyvsp[0].node); ;
+    break;}
+case 178:
+#line 567 "grammar.y"
+{ yyval.stat = new TryNode(yyvsp[-2].stat, yyvsp[-1].node, yyvsp[0].node); ;
+    break;}
+case 179:
+#line 571 "grammar.y"
+{ yyval.node = new CatchNode(yyvsp[-2].ustr, yyvsp[0].stat); delete yyvsp[-2].ustr; ;
+    break;}
+case 180:
+#line 575 "grammar.y"
+{ yyval.node = new FinallyNode(yyvsp[0].stat); ;
+    break;}
+case 181:
+#line 579 "grammar.y"
+{ yyval.func = new FuncDeclNode(yyvsp[-3].ustr, 0L, yyvsp[0].body);
+                                             delete yyvsp[-3].ustr; ;
+    break;}
+case 182:
+#line 582 "grammar.y"
+{ yyval.func = new FuncDeclNode(yyvsp[-4].ustr, yyvsp[-2].param, yyvsp[0].body);
+                                     delete yyvsp[-4].ustr; ;
+    break;}
+case 183:
+#line 586 "grammar.y"
+{ yyval.node = new FuncExprNode(0L, yyvsp[0].body); ;
+    break;}
+case 184:
+#line 588 "grammar.y"
+{ yyval.node = new FuncExprNode(yyvsp[-2].param, yyvsp[0].body); ;
+    break;}
+case 185:
+#line 593 "grammar.y"
+{ yyval.param = new ParameterNode(yyvsp[0].ustr); delete yyvsp[0].ustr; ;
+    break;}
+case 186:
+#line 594 "grammar.y"
+{ yyval.param = yyvsp[-2].param->append(yyvsp[0].ustr);
+	                             delete yyvsp[0].ustr; ;
+    break;}
+case 187:
+#line 599 "grammar.y"
+{ yyval.body = new FunctionBodyNode(0L); ;
+    break;}
+case 188:
+#line 600 "grammar.y"
+{ yyval.body = new FunctionBodyNode(yyvsp[-1].srcs); ;
+    break;}
+case 189:
+#line 604 "grammar.y"
+{ yyval.prog = new ProgramNode(yyvsp[0].srcs);
+                                     KJScriptImp::current()->setProgNode(yyval.prog); ;
+    break;}
+case 190:
+#line 609 "grammar.y"
+{ yyval.srcs = new SourceElementsNode(yyvsp[0].src); ;
+    break;}
+case 191:
+#line 610 "grammar.y"
+{ yyval.srcs = new SourceElementsNode(yyvsp[-1].srcs, yyvsp[0].src); ;
+    break;}
+case 192:
+#line 614 "grammar.y"
+{ yyval.src = new SourceElementNode(yyvsp[0].stat); ;
+    break;}
+case 193:
+#line 615 "grammar.y"
+{ yyval.src = new SourceElementNode(yyvsp[0].func); ;
+    break;}
+}
+   /* the action file gets copied in in place of this dollarsign */
+#line 543 "/usr/share/misc/bison.simple"
+
+  yyvsp -= yylen;
+  yyssp -= yylen;
+#ifdef YYLSP_NEEDED
+  yylsp -= yylen;
+#endif
+
+#if YYDEBUG != 0
+  if (yydebug)
+    {
+      short *ssp1 = yyss - 1;
+      fprintf (stderr, "state stack now");
+      while (ssp1 != yyssp)
+	fprintf (stderr, " %d", *++ssp1);
+      fprintf (stderr, "\n");
+    }
+#endif
+
+  *++yyvsp = yyval;
+
+#ifdef YYLSP_NEEDED
+  yylsp++;
+  if (yylen == 0)
+    {
+      yylsp->first_line = yylloc.first_line;
+      yylsp->first_column = yylloc.first_column;
+      yylsp->last_line = (yylsp-1)->last_line;
+      yylsp->last_column = (yylsp-1)->last_column;
+      yylsp->text = 0;
+    }
+  else
+    {
+      yylsp->last_line = (yylsp+yylen-1)->last_line;
+      yylsp->last_column = (yylsp+yylen-1)->last_column;
+    }
+#endif
+
+  /* Now "shift" the result of the reduction.
+     Determine what state that goes to,
+     based on the state we popped back to
+     and the rule number reduced by.  */
+
+  yyn = yyr1[yyn];
+
+  yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
+  if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+    yystate = yytable[yystate];
+  else
+    yystate = yydefgoto[yyn - YYNTBASE];
+
+  goto yynewstate;
+
+yyerrlab:   /* here on detecting error */
+
+  if (! yyerrstatus)
+    /* If not already recovering from an error, report this error.  */
+    {
+      ++yynerrs;
+
+#ifdef YYERROR_VERBOSE
+      yyn = yypact[yystate];
+
+      if (yyn > YYFLAG && yyn < YYLAST)
+	{
+	  int size = 0;
+	  char *msg;
+	  int x, count;
+
+	  count = 0;
+	  /* Start X at -yyn if nec to avoid negative indexes in yycheck.  */
+	  for (x = (yyn < 0 ? -yyn : 0);
+	       x < (sizeof(yytname) / sizeof(char *)); x++)
+	    if (yycheck[x + yyn] == x)
+	      size += strlen(yytname[x]) + 15, count++;
+	  msg = (char *) malloc(size + 15);
+	  if (msg != 0)
+	    {
+	      strcpy(msg, "parse error");
+
+	      if (count < 5)
+		{
+		  count = 0;
+		  for (x = (yyn < 0 ? -yyn : 0);
+		       x < (sizeof(yytname) / sizeof(char *)); x++)
+		    if (yycheck[x + yyn] == x)
+		      {
+			strcat(msg, count == 0 ? ", expecting `" : " or `");
+			strcat(msg, yytname[x]);
+			strcat(msg, "'");
+			count++;
+		      }
+		}
+	      yyerror(msg);
+	      free(msg);
+	    }
+	  else
+	    yyerror ("parse error; also virtual memory exceeded");
+	}
+      else
+#endif /* YYERROR_VERBOSE */
+	yyerror("parse error");
+    }
+
+  goto yyerrlab1;
+yyerrlab1:   /* here on error raised explicitly by an action */
+
+  if (yyerrstatus == 3)
+    {
+      /* if just tried and failed to reuse lookahead token after an error, discard it.  */
+
+      /* return failure if at end of input */
+      if (yychar == YYEOF)
+	YYABORT;
+
+#if YYDEBUG != 0
+      if (yydebug)
+	fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
+#endif
+
+      yychar = YYEMPTY;
+    }
+
+  /* Else will try to reuse lookahead token
+     after shifting the error token.  */
+
+  yyerrstatus = 3;		/* Each real token shifted decrements this */
+
+  goto yyerrhandle;
+
+yyerrdefault:  /* current state does not do anything special for the error token. */
+
+#if 0
+  /* This is wrong; only states that explicitly want error tokens
+     should shift them.  */
+  yyn = yydefact[yystate];  /* If its default is to accept any token, ok.  Otherwise pop it.*/
+  if (yyn) goto yydefault;
+#endif
+
+yyerrpop:   /* pop the current state because it cannot handle the error token */
+
+  if (yyssp == yyss) YYABORT;
+  yyvsp--;
+  yystate = *--yyssp;
+#ifdef YYLSP_NEEDED
+  yylsp--;
+#endif
+
+#if YYDEBUG != 0
+  if (yydebug)
+    {
+      short *ssp1 = yyss - 1;
+      fprintf (stderr, "Error: state stack now");
+      while (ssp1 != yyssp)
+	fprintf (stderr, " %d", *++ssp1);
+      fprintf (stderr, "\n");
+    }
+#endif
+
+yyerrhandle:
+
+  yyn = yypact[yystate];
+  if (yyn == YYFLAG)
+    goto yyerrdefault;
+
+  yyn += YYTERROR;
+  if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
+    goto yyerrdefault;
+
+  yyn = yytable[yyn];
+  if (yyn < 0)
+    {
+      if (yyn == YYFLAG)
+	goto yyerrpop;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+  else if (yyn == 0)
+    goto yyerrpop;
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+#if YYDEBUG != 0
+  if (yydebug)
+    fprintf(stderr, "Shifting error token, ");
+#endif
+
+  *++yyvsp = yylval;
+#ifdef YYLSP_NEEDED
+  *++yylsp = yylloc;
+#endif
+
+  yystate = yyn;
+  goto yynewstate;
+
+ yyacceptlab:
+  /* YYACCEPT comes here.  */
+  if (yyfree_stacks)
+    {
+      free (yyss);
+      free (yyvs);
+#ifdef YYLSP_NEEDED
+      free (yyls);
+#endif
+    }
+  return 0;
+
+ yyabortlab:
+  /* YYABORT comes here.  */
+  if (yyfree_stacks)
+    {
+      free (yyss);
+      free (yyvs);
+#ifdef YYLSP_NEEDED
+      free (yyls);
+#endif
+    }
+  return 1;
+}
+#line 618 "grammar.y"
+
+
+int yyerror (const char *)  /* Called by yyparse on error */
+{
+//  fprintf(stderr, "ERROR: %s at line %d\n",
+//	  s, KJScript::lexer()->lineNo());
+  return 1;
+}
+
+/* may we automatically insert a semicolon ? */
+bool automatic()
+{
+  if (yychar == '}' || yychar == 0)
+    return true;
+  else if (Lexer::curr()->prevTerminator())
+    return true;
+
+  return false;
+}
diff --git a/WebCore/src/kdelibs/kjs/grammar.h b/WebCore/src/kdelibs/kjs/grammar.h
new file mode 100644
index 0000000..38eb0ba
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/grammar.h
@@ -0,0 +1,102 @@
+typedef union {
+  int                 ival;
+  double              dval;
+  UString             *ustr;
+  Node                *node;
+  StatementNode       *stat;
+  ParameterNode       *param;
+  FunctionBodyNode    *body;
+  FuncDeclNode        *func;
+  ProgramNode         *prog;
+  AssignExprNode      *init;
+  SourceElementNode   *src;
+  SourceElementsNode  *srcs;
+  StatListNode        *slist;
+  ArgumentsNode       *args;
+  ArgumentListNode    *alist;
+  VarDeclNode         *decl;
+  VarDeclListNode     *vlist;
+  CaseBlockNode       *cblk;
+  ClauseListNode      *clist;
+  CaseClauseNode      *ccl;
+  ElementNode         *elm;
+  ElisionNode         *eli;
+  Operator            op;
+} YYSTYPE;
+
+#ifndef YYLTYPE
+typedef
+  struct yyltype
+    {
+      int timestamp;
+      int first_line;
+      int first_column;
+      int last_line;
+      int last_column;
+      char *text;
+   }
+  yyltype;
+
+#define YYLTYPE yyltype
+#endif
+
+#define	NULLTOKEN	257
+#define	TRUETOKEN	258
+#define	FALSETOKEN	259
+#define	STRING	260
+#define	NUMBER	261
+#define	BREAK	262
+#define	CASE	263
+#define	DEFAULT	264
+#define	FOR	265
+#define	NEW	266
+#define	VAR	267
+#define	CONTINUE	268
+#define	FUNCTION	269
+#define	RETURN	270
+#define	VOID	271
+#define	DELETE	272
+#define	IF	273
+#define	THIS	274
+#define	DO	275
+#define	WHILE	276
+#define	ELSE	277
+#define	IN	278
+#define	INSTANCEOF	279
+#define	TYPEOF	280
+#define	SWITCH	281
+#define	WITH	282
+#define	RESERVED	283
+#define	THROW	284
+#define	TRY	285
+#define	CATCH	286
+#define	FINALLY	287
+#define	EQEQ	288
+#define	NE	289
+#define	STREQ	290
+#define	STRNEQ	291
+#define	LE	292
+#define	GE	293
+#define	OR	294
+#define	AND	295
+#define	PLUSPLUS	296
+#define	MINUSMINUS	297
+#define	LSHIFT	298
+#define	RSHIFT	299
+#define	URSHIFT	300
+#define	PLUSEQUAL	301
+#define	MINUSEQUAL	302
+#define	MULTEQUAL	303
+#define	DIVEQUAL	304
+#define	LSHIFTEQUAL	305
+#define	RSHIFTEQUAL	306
+#define	URSHIFTEQUAL	307
+#define	ANDEQUAL	308
+#define	MODEQUAL	309
+#define	XOREQUAL	310
+#define	OREQUAL	311
+#define	IDENT	312
+#define	AUTO	313
+
+
+extern YYSTYPE kjsyylval;
diff --git a/WebCore/src/kdelibs/kjs/grammar.y b/WebCore/src/kdelibs/kjs/grammar.y
new file mode 100644
index 0000000..cf07456
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/grammar.y
@@ -0,0 +1,636 @@
+%{
+
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <string.h>
+#include "kjs.h"
+#include "nodes.h"
+#include "lexer.h"
+
+/* default values for bison */
+#define YYDEBUG 0
+#define YYMAXDEPTH 0
+#ifdef KJS_DEBUGGER
+#define YYERROR_VERBOSE
+#define DBG(l, s, e) { l->setLoc(s.first_line, e.last_line); } // location
+#else
+#undef YYLSP_NEEDED
+#define DBG(l, s, e)
+#endif
+
+extern int yylex();
+int yyerror (const char *);
+bool automatic();
+
+using namespace KJS;
+
+%}
+
+%union {
+  int                 ival;
+  double              dval;
+  UString             *ustr;
+  Node                *node;
+  StatementNode       *stat;
+  ParameterNode       *param;
+  FunctionBodyNode    *body;
+  FuncDeclNode        *func;
+  ProgramNode         *prog;
+  AssignExprNode      *init;
+  SourceElementNode   *src;
+  SourceElementsNode  *srcs;
+  StatListNode        *slist;
+  ArgumentsNode       *args;
+  ArgumentListNode    *alist;
+  VarDeclNode         *decl;
+  VarDeclListNode     *vlist;
+  CaseBlockNode       *cblk;
+  ClauseListNode      *clist;
+  CaseClauseNode      *ccl;
+  ElementNode         *elm;
+  ElisionNode         *eli;
+  Operator            op;
+}
+
+%start Program
+
+/* expect a shift/reduce conflict from the "dangling else" problem
+   when using bison the warning can be supressed */
+// %expect 1
+
+/* literals */
+%token NULLTOKEN TRUETOKEN FALSETOKEN
+%token STRING NUMBER
+
+/* keywords */
+%token BREAK CASE DEFAULT FOR NEW VAR CONTINUE
+%token FUNCTION RETURN VOID DELETE
+%token IF THIS DO WHILE ELSE IN INSTANCEOF TYPEOF
+%token SWITCH WITH RESERVED
+%token THROW TRY CATCH FINALLY
+
+/* punctuators */
+%token EQEQ NE                     /* == and != */
+%token STREQ STRNEQ                /* === and !== */
+%token LE GE                       /* < and > */
+%token OR AND                      /* || and && */
+%token PLUSPLUS MINUSMINUS         /* ++ and --  */
+%token LSHIFT                      /* << */
+%token RSHIFT URSHIFT              /* >> and >>> */
+%token PLUSEQUAL MINUSEQUAL        /* += and -= */
+%token MULTEQUAL DIVEQUAL          /* *= and /= */
+%token LSHIFTEQUAL                 /* <<= */
+%token RSHIFTEQUAL URSHIFTEQUAL    /* >>= and >>>= */
+%token ANDEQUAL MODEQUAL           /* &= and %= */
+%token XOREQUAL OREQUAL            /* ^= and |= */
+
+/* terminal types */
+%token <dval> NUMBER
+%token <ustr> STRING
+%token <ustr> IDENT
+
+/* automatically inserted semicolon */
+%token AUTO
+
+/* non-terminal types */
+%type <node>  Literal PrimaryExpr Expr MemberExpr FunctionExpr NewExpr CallExpr
+%type <node>  ArrayLiteral PropertyName PropertyNameAndValueList
+%type <node>  LeftHandSideExpr PostfixExpr UnaryExpr
+%type <node>  MultiplicativeExpr AdditiveExpr
+%type <node>  ShiftExpr RelationalExpr EqualityExpr
+%type <node>  BitwiseANDExpr BitwiseXORExpr BitwiseORExpr
+%type <node>  LogicalANDExpr LogicalORExpr
+%type <node>  ConditionalExpr AssignmentExpr
+%type <node>  ExprOpt
+%type <node>  CallExpr
+%type <node>  Catch Finally
+
+%type <stat>  Statement Block
+%type <stat>  VariableStatement EmptyStatement ExprStatement
+%type <stat>  IfStatement IterationStatement ContinueStatement
+%type <stat>  BreakStatement ReturnStatement WithStatement
+%type <stat>  SwitchStatement LabelledStatement
+%type <stat>  ThrowStatement TryStatement
+
+%type <slist> StatementList
+%type <init>  Initializer
+%type <func>  FunctionDeclaration
+%type <body>  FunctionBody
+%type <src>   SourceElement
+%type <srcs>  SourceElements
+%type <param> FormalParameterList
+%type <op>    AssignmentOperator
+%type <prog>  Program
+%type <args>  Arguments
+%type <alist> ArgumentList
+%type <vlist> VariableDeclarationList
+%type <decl>  VariableDeclaration
+%type <cblk>  CaseBlock
+%type <ccl>   CaseClause DefaultClause
+%type <clist> CaseClauses  CaseClausesOpt
+%type <eli>   Elision ElisionOpt
+%type <elm>   ElementList
+
+%%
+
+Literal:
+    NULLTOKEN                      { $$ = new NullNode(); }
+  | TRUETOKEN                      { $$ = new BooleanNode(true); }
+  | FALSETOKEN                     { $$ = new BooleanNode(false); }
+  | NUMBER                         { $$ = new NumberNode($1); }
+  | STRING                         { $$ = new StringNode($1); delete $1; }
+  | '/'       /* a RegExp ? */     { Lexer *l = Lexer::curr();
+                                     if (!l->scanRegExp()) YYABORT;
+                                     $$ = new RegExpNode(l->pattern,l->flags);}
+;
+
+PrimaryExpr:
+    THIS                           { $$ = new ThisNode(); }
+  | IDENT                          { $$ = new ResolveNode($1);
+                                     delete $1; }
+  | Literal
+  | ArrayLiteral
+  | '(' Expr ')'                   { $$ = new GroupNode($2); }
+  | '{' '}'                        { $$ = new ObjectLiteralNode(0L); }
+  | '{' PropertyNameAndValueList '}'   { $$ = new ObjectLiteralNode($2); }
+;
+
+ArrayLiteral:
+    '[' ElisionOpt ']'                 { $$ = new ArrayNode($2); }
+  | '[' ElementList ']'                { $$ = new ArrayNode($2); }
+  | '[' ElementList ',' ElisionOpt ']' { $$ = new ArrayNode($4, $2); }
+;
+
+ElementList:
+    ElisionOpt AssignmentExpr      { $$ = new ElementNode($1, $2); }
+  | ElementList ',' ElisionOpt AssignmentExpr
+                                   { $$ = new ElementNode($1, $3, $4); }
+;
+
+ElisionOpt:
+    /* nothing */                  { $$ = 0L; }
+  | Elision
+;
+
+Elision:
+    ','                            { $$ = new ElisionNode(0L); }
+  | Elision ','                    { $$ = new ElisionNode($1); }
+;
+
+PropertyNameAndValueList:
+    PropertyName ':' AssignmentExpr     { $$ = new PropertyValueNode($1, $3); }
+  | PropertyNameAndValueList ',' PropertyName ':' AssignmentExpr
+                                   { $$ = new PropertyValueNode($3, $5, $1); }
+;
+
+PropertyName:
+    IDENT                          { $$ = new PropertyNode($1);
+                                     delete $1; }
+  | STRING                         { $$ = new PropertyNode($1); delete $1; }
+  | NUMBER                         { $$ = new PropertyNode($1); }
+;
+
+MemberExpr:
+    PrimaryExpr
+  | FunctionExpr
+  | MemberExpr '[' Expr ']'        { $$ = new AccessorNode1($1, $3); }
+  | MemberExpr '.' IDENT           { $$ = new AccessorNode2($1, $3);
+                                     delete $3; }
+  | NEW MemberExpr Arguments       { $$ = new NewExprNode($2, $3); }
+;
+
+NewExpr:
+    MemberExpr
+  | NEW NewExpr                    { $$ = new NewExprNode($2); }
+;
+
+CallExpr:
+    MemberExpr Arguments           { $$ = new FunctionCallNode($1, $2); }
+  | CallExpr Arguments             { $$ = new FunctionCallNode($1, $2); }
+  | CallExpr '[' Expr ']'          { $$ = new AccessorNode1($1, $3); }
+  | CallExpr '.' IDENT             { $$ = new AccessorNode2($1, $3); }
+;
+
+Arguments:
+    '(' ')'                        { $$ = new ArgumentsNode(0L); }
+  | '(' ArgumentList ')'           { $$ = new ArgumentsNode($2); }
+;
+
+ArgumentList:
+    AssignmentExpr                  { $$ = new ArgumentListNode($1); }
+  | ArgumentList ',' AssignmentExpr { $$ = new ArgumentListNode($1, $3); }
+;
+
+LeftHandSideExpr:
+    NewExpr
+  | CallExpr
+;
+
+PostfixExpr:    /* TODO: no line terminator here */
+    LeftHandSideExpr
+  | LeftHandSideExpr PLUSPLUS      { $$ = new PostfixNode($1, OpPlusPlus); }
+  | LeftHandSideExpr MINUSMINUS    { $$ = new PostfixNode($1, OpMinusMinus); }
+;
+
+UnaryExpr:
+    PostfixExpr
+  | DELETE UnaryExpr               { $$ = new DeleteNode($2); }
+  | VOID UnaryExpr                 { $$ = new VoidNode($2); }
+  | TYPEOF UnaryExpr               { $$ = new TypeOfNode($2); }
+  | PLUSPLUS UnaryExpr             { $$ = new PrefixNode(OpPlusPlus, $2); }
+  | AUTO PLUSPLUS UnaryExpr        { $$ = new PrefixNode(OpPlusPlus, $3); }
+  | MINUSMINUS UnaryExpr           { $$ = new PrefixNode(OpMinusMinus, $2); }
+  | AUTO MINUSMINUS UnaryExpr      { $$ = new PrefixNode(OpMinusMinus, $3); }
+  | '+' UnaryExpr                  { $$ = new UnaryPlusNode($2); }
+  | '-' UnaryExpr                  { $$ = new NegateNode($2); }
+  | '~' UnaryExpr                  { $$ = new BitwiseNotNode($2); }
+  | '!' UnaryExpr                  { $$ = new LogicalNotNode($2); }
+;
+
+MultiplicativeExpr:
+    UnaryExpr
+  | MultiplicativeExpr '*' UnaryExpr { $$ = new MultNode($1, $3, '*'); }
+  | MultiplicativeExpr '/' UnaryExpr { $$ = new MultNode($1, $3, '/'); }
+  | MultiplicativeExpr '%' UnaryExpr { $$ = new MultNode($1,$3,'%'); }
+;
+
+AdditiveExpr:
+    MultiplicativeExpr
+  | AdditiveExpr '+' MultiplicativeExpr { $$ = new AddNode($1, $3, '+'); }
+  | AdditiveExpr '-' MultiplicativeExpr { $$ = new AddNode($1, $3, '-'); }
+;
+
+ShiftExpr:
+    AdditiveExpr
+  | ShiftExpr LSHIFT AdditiveExpr  { $$ = new ShiftNode($1, OpLShift, $3); }
+  | ShiftExpr RSHIFT AdditiveExpr  { $$ = new ShiftNode($1, OpRShift, $3); }
+  | ShiftExpr URSHIFT AdditiveExpr { $$ = new ShiftNode($1, OpURShift, $3); }
+;
+
+RelationalExpr:
+    ShiftExpr
+  | RelationalExpr '<' ShiftExpr
+                           { $$ = new RelationalNode($1, OpLess, $3); }
+  | RelationalExpr '>' ShiftExpr
+                           { $$ = new RelationalNode($1, OpGreater, $3); }
+  | RelationalExpr LE ShiftExpr
+                           { $$ = new RelationalNode($1, OpLessEq, $3); }
+  | RelationalExpr GE ShiftExpr
+                           { $$ = new RelationalNode($1, OpGreaterEq, $3); }
+  | RelationalExpr INSTANCEOF ShiftExpr
+                           { $$ = new RelationalNode($1, OpInstanceOf, $3); }
+  | RelationalExpr IN ShiftExpr
+                           { $$ = new RelationalNode($1, OpIn, $3); }
+;
+
+EqualityExpr:
+    RelationalExpr
+  | EqualityExpr EQEQ RelationalExpr   { $$ = new EqualNode($1, OpEqEq, $3); }
+  | EqualityExpr NE RelationalExpr     { $$ = new EqualNode($1, OpNotEq, $3); }
+  | EqualityExpr STREQ RelationalExpr  { $$ = new EqualNode($1, OpStrEq, $3); }
+  | EqualityExpr STRNEQ RelationalExpr { $$ = new EqualNode($1, OpStrNEq, $3);}
+;
+
+BitwiseANDExpr:
+    EqualityExpr
+  | BitwiseANDExpr '&' EqualityExpr { $$ = new BitOperNode($1, OpBitAnd, $3); }
+;
+
+BitwiseXORExpr:
+    BitwiseANDExpr
+  | BitwiseXORExpr '^' EqualityExpr { $$ = new BitOperNode($1, OpBitXOr, $3); }
+;
+
+BitwiseORExpr:
+    BitwiseXORExpr
+  | BitwiseORExpr '|' EqualityExpr  { $$ = new BitOperNode($1, OpBitOr, $3); }
+;
+
+LogicalANDExpr:
+    BitwiseORExpr
+  | LogicalANDExpr AND BitwiseORExpr
+                           { $$ = new BinaryLogicalNode($1, OpAnd, $3); }
+;
+
+LogicalORExpr:
+    LogicalANDExpr
+  | LogicalORExpr OR LogicalANDExpr
+                           { $$ = new BinaryLogicalNode($1, OpOr, $3); }
+;
+
+ConditionalExpr:
+    LogicalORExpr
+  | LogicalORExpr '?' AssignmentExpr ':' AssignmentExpr
+                           { $$ = new ConditionalNode($1, $3, $5); }
+;
+
+AssignmentExpr:
+    ConditionalExpr
+  | LeftHandSideExpr AssignmentOperator AssignmentExpr
+                           { $$ = new AssignNode($1, $2, $3);}
+;
+
+AssignmentOperator:
+    '='                            { $$ = OpEqual; }
+  | PLUSEQUAL                      { $$ = OpPlusEq; }
+  | MINUSEQUAL                     { $$ = OpMinusEq; }
+  | MULTEQUAL                      { $$ = OpMultEq; }
+  | DIVEQUAL                       { $$ = OpDivEq; }
+  | LSHIFTEQUAL                    { $$ = OpLShift; }
+  | RSHIFTEQUAL                    { $$ = OpRShift; }
+  | URSHIFTEQUAL                   { $$ = OpURShift; }
+  | ANDEQUAL                       { $$ = OpAndEq; }
+  | XOREQUAL                       { $$ = OpXOrEq; }
+  | OREQUAL                        { $$ = OpOrEq; }
+  | MODEQUAL                       { $$ = OpModEq; }
+;
+
+Expr:
+    AssignmentExpr
+  | Expr ',' AssignmentExpr        { $$ = new CommaNode($1, $3); }
+;
+
+Statement:
+    Block
+  | VariableStatement
+  | EmptyStatement
+  | ExprStatement
+  | IfStatement
+  | IterationStatement
+  | ContinueStatement
+  | BreakStatement
+  | ReturnStatement
+  | WithStatement
+  | SwitchStatement
+  | LabelledStatement
+  | ThrowStatement
+  | TryStatement
+;
+
+Block:
+    '{' '}'                        { $$ = new BlockNode(0L); DBG($$, @2, @2); }
+  | '{' StatementList '}'          { $$ = new BlockNode($2); DBG($$, @3, @3); }
+;
+
+StatementList:
+    Statement                      { $$ = new StatListNode($1); }
+  | StatementList Statement        { $$ = new StatListNode($1, $2); }
+;
+
+VariableStatement:
+    VAR VariableDeclarationList ';' { $$ = new VarStatementNode($2);
+                                      DBG($$, @1, @3); }
+  | VAR VariableDeclarationList error { if (automatic()) {
+                                          $$ = new VarStatementNode($2);
+					  DBG($$, @1, @2);
+                                        } else {
+					  YYABORT;
+					}
+                                      }
+;
+
+VariableDeclarationList:
+    VariableDeclaration            { $$ = new VarDeclListNode($1); }
+  | VariableDeclarationList ',' VariableDeclaration
+                                   { $$ = new VarDeclListNode($1, $3); }
+;
+
+VariableDeclaration:
+    IDENT                          { $$ = new VarDeclNode($1, 0); delete $1; }
+  | IDENT Initializer              { $$ = new VarDeclNode($1, $2); delete $1; }
+;
+
+Initializer:
+    '=' AssignmentExpr             { $$ = new AssignExprNode($2); }
+;
+
+EmptyStatement:
+    ';'                            { $$ = new EmptyStatementNode(); }
+;
+
+ExprStatement:
+    Expr ';'                       { $$ = new ExprStatementNode($1);
+                                     DBG($$, @1, @2); }
+  | Expr error                     { if (automatic()) {
+                                       $$ = new ExprStatementNode($1);
+				       DBG($$, @1, @1);
+                                     } else
+				       YYABORT; }
+;
+
+IfStatement: /* shift/reduce conflict due to dangling else */
+    IF '(' Expr ')' Statement      { $$ = new IfNode($3,$5,0L);DBG($$, at 1, at 4); }
+  | IF '(' Expr ')' Statement ELSE Statement
+                                   { $$ = new IfNode($3,$5,$7);DBG($$, at 1, at 4); }
+;
+
+IterationStatement:
+    DO Statement WHILE '(' Expr ')' { $$=new DoWhileNode($2,$5);DBG($$, at 1, at 3);}
+  | WHILE '(' Expr ')' Statement   { $$ = new WhileNode($3,$5);DBG($$, at 1, at 4); }
+  | FOR '(' ExprOpt ';' ExprOpt ';' ExprOpt ')'
+            Statement              { $$ = new ForNode($3,$5,$7,$9);
+	                             DBG($$, at 1, at 8); }
+  | FOR '(' VAR VariableDeclarationList ';' ExprOpt ';' ExprOpt ')'
+            Statement              { $$ = new ForNode($4,$6,$8,$10);
+	                             DBG($$, at 1, at 9); }
+  | FOR '(' LeftHandSideExpr IN Expr ')'
+            Statement              { $$ = new ForInNode($3, $5, $7);
+	                             DBG($$, at 1, at 6); }
+  | FOR '(' VAR IDENT IN Expr ')'
+            Statement              { $$ = new ForInNode($4,0L,$6,$8);
+	                             DBG($$, at 1, at 7);
+                                     delete $4; }
+  | FOR '(' VAR IDENT Initializer IN Expr ')'
+            Statement              { $$ = new ForInNode($4,$5,$7,$9);
+	                             DBG($$, at 1, at 8);
+                                     delete $4; }
+;
+
+ExprOpt:
+    /* nothing */                  { $$ = 0L; }
+  | Expr
+;
+
+ContinueStatement:
+    CONTINUE ';'                   { $$ = new ContinueNode(); DBG($$, at 1, at 2); }
+  | CONTINUE error                 { if (automatic()) {
+                                       $$ = new ContinueNode(); DBG($$, at 1, at 2);
+                                     } else
+				       YYABORT; }
+  | CONTINUE IDENT ';'             { $$ = new ContinueNode($2); DBG($$, at 1, at 3);
+                                     delete $2; }
+  | CONTINUE IDENT error           { if (automatic()) {
+                                       $$ = new ContinueNode($2);DBG($$, at 1, at 2);
+				       delete $2;
+                                     } else
+				       YYABORT; }
+;
+
+BreakStatement:
+    BREAK ';'                      { $$ = new BreakNode();DBG($$, at 1, at 2); }
+  | BREAK error                    { if (automatic()) {
+                                       $$ = new BreakNode(); DBG($$, at 1, at 1);
+                                     } else
+				       YYABORT; }
+  | BREAK IDENT ';'                { $$ = new BreakNode($2); DBG($$, at 1, at 3);
+                                     delete $2; }
+  | BREAK IDENT error              { if (automatic()) {
+                                       $$ = new BreakNode($2); DBG($$, at 1, at 2);
+				       delete $2;
+                                     } else
+				       YYABORT;
+                                   }
+;
+
+ReturnStatement:
+    RETURN ';'                     { $$ = new ReturnNode(0L); DBG($$, at 1, at 2); }
+  | RETURN error                   { if (automatic()) {
+                                       $$ = new ReturnNode(0L); DBG($$, at 1, at 1);
+                                     } else
+				       YYABORT; }
+  | RETURN Expr ';'                { $$ = new ReturnNode($2); }
+  | RETURN Expr error              { if (automatic())
+                                       $$ = new ReturnNode($2);
+                                     else
+				       YYABORT; }
+;
+
+WithStatement:
+    WITH '(' Expr ')' Statement    { $$ = new WithNode($3,$5);
+                                     DBG($$, @1, @4); }
+;
+
+SwitchStatement:
+    SWITCH '(' Expr ')' CaseBlock  { $$ = new SwitchNode($3, $5);
+                                     DBG($$, @1, @4); }
+;
+
+CaseBlock:
+    '{' CaseClausesOpt '}'         { $$ = new CaseBlockNode($2, 0L, 0L); }
+  | '{' CaseClausesOpt DefaultClause CaseClausesOpt '}'
+                                   { $$ = new CaseBlockNode($2, $3, $4); }
+;
+
+CaseClausesOpt:
+    /* nothing */                  { $$ = 0L; }
+  | CaseClauses
+;
+
+CaseClauses:
+    CaseClause                     { $$ = new ClauseListNode($1); }
+  | CaseClauses CaseClause         { $$ = $1->append($2); }
+;
+
+CaseClause:
+    CASE Expr ':'                  { $$ = new CaseClauseNode($2, 0L); }
+  | CASE Expr ':' StatementList    { $$ = new CaseClauseNode($2, $4); }
+;
+
+DefaultClause:
+    DEFAULT ':'                    { $$ = new CaseClauseNode(0L, 0L);; }
+  | DEFAULT ':' StatementList      { $$ = new CaseClauseNode(0L, $3); }
+;
+
+LabelledStatement:
+    IDENT ':' Statement            { $3->pushLabel($1);
+                                     $$ = new LabelNode($1, $3);
+                                     delete $1; }
+;
+
+ThrowStatement:
+    THROW Expr ';'                 { $$ = new ThrowNode($2); }
+;
+
+TryStatement:
+    TRY Block Catch                { $$ = new TryNode($2, $3); }
+  | TRY Block Finally              { $$ = new TryNode($2, 0L, $3); }
+  | TRY Block Catch Finally        { $$ = new TryNode($2, $3, $4); }
+;
+
+Catch:
+    CATCH '(' IDENT ')' Block      { $$ = new CatchNode($3, $5); delete $3; }
+;
+
+Finally:
+    FINALLY Block                  { $$ = new FinallyNode($2); }
+;
+
+FunctionDeclaration:
+    FUNCTION IDENT '(' ')' FunctionBody    { $$ = new FuncDeclNode($2, 0L, $5);
+                                             delete $2; }
+  | FUNCTION IDENT '(' FormalParameterList ')' FunctionBody
+                                   { $$ = new FuncDeclNode($2, $4, $6);
+                                     delete $2; }
+
+FunctionExpr:
+    FUNCTION '(' ')' FunctionBody  { $$ = new FuncExprNode(0L, $4); }
+  | FUNCTION '(' FormalParameterList ')' FunctionBody
+                                   { $$ = new FuncExprNode($3, $5); }
+
+;
+
+FormalParameterList:
+    IDENT                          { $$ = new ParameterNode($1); delete $1; }
+  | FormalParameterList ',' IDENT  { $$ = $1->append($3);
+	                             delete $3; }
+;
+
+FunctionBody:
+    '{' '}'  /* TODO: spec ??? */  { $$ = new FunctionBodyNode(0L); }
+  | '{' SourceElements '}'         { $$ = new FunctionBodyNode($2); }
+;
+
+Program:
+    SourceElements                 { $$ = new ProgramNode($1);
+                                     KJScriptImp::current()->setProgNode($$); }
+;
+
+SourceElements:
+    SourceElement                  { $$ = new SourceElementsNode($1); }
+  | SourceElements SourceElement   { $$ = new SourceElementsNode($1, $2); }
+;
+
+SourceElement:
+    Statement                      { $$ = new SourceElementNode($1); }
+  | FunctionDeclaration            { $$ = new SourceElementNode($1); }
+;
+
+%%
+
+int yyerror (const char *)  /* Called by yyparse on error */
+{
+//  fprintf(stderr, "ERROR: %s at line %d\n",
+//	  s, KJScript::lexer()->lineNo());
+  return 1;
+}
+
+/* may we automatically insert a semicolon ? */
+bool automatic()
+{
+  if (yychar == '}' || yychar == 0)
+    return true;
+  else if (Lexer::curr()->prevTerminator())
+    return true;
+
+  return false;
+}
diff --git a/WebCore/src/kdelibs/kjs/internal.cpp b/WebCore/src/kdelibs/kjs/internal.cpp
new file mode 100644
index 0000000..9fc40fa
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/internal.cpp
@@ -0,0 +1,912 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2001 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#include "internal.h"
+
+#include <assert.h>
+#include <stdio.h>
+
+#include "kjs.h"
+#include "object.h"
+#include "types.h"
+#include "operations.h"
+#include "regexp.h"
+#include "nodes.h"
+#include "lexer.h"
+#include "collector.h"
+#include "debugger.h"
+
+#define I18N_NOOP(s) s
+
+extern int kjsyyparse();
+
+using namespace KJS;
+
+const TypeInfo UndefinedImp::info = { "Undefined", UndefinedType, 0, 0, 0 };
+const TypeInfo NullImp::info = { "Null", NullType, 0, 0, 0 };
+const TypeInfo NumberImp::info = { "Number", NumberType, 0, 0,0  };
+const TypeInfo StringImp::info = { "String", StringType, 0, 0, 0 };
+const TypeInfo BooleanImp::info = { "Boolean", BooleanType, 0, 0, 0 };
+const TypeInfo CompletionImp::info = { "Completion", CompletionType, 0, 0, 0 };
+const TypeInfo ReferenceImp::info = { "Reference", ReferenceType, 0, 0, 0 };
+
+UndefinedImp *UndefinedImp::staticUndefined = 0;
+
+UndefinedImp::UndefinedImp()
+{
+}
+
+KJSO UndefinedImp::toPrimitive(Type) const
+{
+  return (Imp*)this;
+}
+
+Boolean UndefinedImp::toBoolean() const
+{
+  return Boolean(false);
+}
+
+Number UndefinedImp::toNumber() const
+{
+  return Number(NaN);
+}
+
+String UndefinedImp::toString() const
+{
+  return String("undefined");
+}
+
+Object UndefinedImp::toObject() const
+{
+  return Error::createObject(TypeError, I18N_NOOP("Undefined value"));
+}
+
+NullImp *NullImp::staticNull = 0;
+
+NullImp::NullImp()
+{
+}
+
+KJSO NullImp::toPrimitive(Type) const
+{
+  return (Imp*)this;
+}
+
+Boolean NullImp::toBoolean() const
+{
+  return Boolean(false);
+}
+
+Number NullImp::toNumber() const
+{
+  return Number(0);
+}
+
+String NullImp::toString() const
+{
+  return String("null");
+}
+
+Object NullImp::toObject() const
+{
+  return Error::createObject(TypeError, I18N_NOOP("Null value"));
+}
+
+BooleanImp* BooleanImp::staticTrue = 0;
+BooleanImp* BooleanImp::staticFalse = 0;
+
+KJSO BooleanImp::toPrimitive(Type) const
+{
+  return (Imp*)this;
+}
+
+Boolean BooleanImp::toBoolean() const
+{
+  return Boolean((BooleanImp*)this);
+}
+
+Number BooleanImp::toNumber() const
+{
+  return Number(val ? 1 : 0);
+}
+
+String BooleanImp::toString() const
+{
+  return String(val ? "true" : "false");
+}
+
+Object BooleanImp::toObject() const
+{
+  return Object::create(BooleanClass, Boolean((BooleanImp*)this));
+}
+
+NumberImp::NumberImp(double v)
+  : val(v)
+{
+}
+
+KJSO NumberImp::toPrimitive(Type) const
+{
+  return (Imp*)this;
+}
+
+Boolean NumberImp::toBoolean() const
+{
+  bool b = !((val == 0) /* || (iVal() == N0) */ || isNaN(val));
+
+  return Boolean(b);
+}
+
+Number NumberImp::toNumber() const
+{
+  return Number((NumberImp*)this);
+}
+
+String NumberImp::toString() const
+{
+  return String(UString::from(val));
+}
+
+Object NumberImp::toObject() const
+{
+  return Object::create(NumberClass, Number((NumberImp*)this));
+}
+
+StringImp::StringImp(const UString& v)
+  : val(v)
+{
+}
+
+KJSO StringImp::toPrimitive(Type) const
+{
+  return (Imp*)this;
+}
+
+Boolean StringImp::toBoolean() const
+{
+  return Boolean(val.size() > 0);
+}
+
+Number StringImp::toNumber() const
+{
+  return Number(val.toDouble());
+}
+
+String StringImp::toString() const
+{
+  return String((StringImp*)this);
+}
+
+Object StringImp::toObject() const
+{
+  return Object::create(StringClass, String((StringImp*)this));
+}
+
+ReferenceImp::ReferenceImp(const KJSO& b, const UString& p)
+  : base(b), prop(p)
+{
+}
+
+void ReferenceImp::mark(Imp*)
+{
+  Imp::mark();
+  Imp *im = base.imp();
+  if (im && !im->marked())
+    im->mark();
+}
+
+CompletionImp::CompletionImp(Compl c, const KJSO& v, const UString& t)
+  : comp(c), val(v), tar(t)
+{
+}
+
+void CompletionImp::mark(Imp*)
+{
+  Imp::mark();
+  Imp *im = val.imp();
+  if (im && !im->marked())
+    im->mark();
+}
+
+RegExpImp::RegExpImp()
+  : ObjectImp(RegExpClass), reg(0L)
+{
+}
+
+RegExpImp::~RegExpImp()
+{
+  delete reg;
+}
+
+// ECMA 10.2
+Context::Context(CodeType type, Context *callingContext,
+		 FunctionImp *func, const List *args, Imp *thisV)
+{
+  Global glob(Global::current());
+
+  // create and initialize activation object (ECMA 10.1.6)
+  if (type == FunctionCode || type == AnonymousCode || type == HostCode) {
+    activation = new ActivationImp(func, args);
+    variable = activation;
+  } else {
+    activation = KJSO();
+    variable = glob;
+  }
+
+  // ECMA 10.2
+  switch(type) {
+    case EvalCode:
+      if (callingContext) {
+	scopeChain = callingContext->copyOfChain();
+	variable = callingContext->variableObject();
+	thisVal = callingContext->thisValue();
+	break;
+      } // else same as GlobalCode
+    case GlobalCode:
+      scopeChain = new List();
+      scopeChain->append(glob);
+      thisVal = glob.imp();
+      break;
+    case FunctionCode:
+    case AnonymousCode:
+      if (type == FunctionCode) {
+	scopeChain = ((DeclaredFunctionImp*)func)->scopeChain()->copy();
+	scopeChain->prepend(activation);
+      } else {
+	scopeChain = new List();
+	scopeChain->append(activation);
+	scopeChain->append(glob);
+      }
+      variable = activation; /* TODO: DontDelete ? (ECMA 10.2.3) */
+      if (thisV->type() >= ObjectType) {
+	thisVal = thisV;
+      }
+      else
+	thisVal = glob.imp();
+      break;
+    case HostCode:
+      if (thisV->type() >= ObjectType)
+	thisVal = thisV;
+      else
+	thisVal = glob;
+      variable = activation; /* TODO: DontDelete (ECMA 10.2.4) */
+      scopeChain = new List();
+      scopeChain->append(activation);
+      if (func->hasAttribute(ImplicitThis))
+	scopeChain->append(KJSO(thisVal));
+      if (func->hasAttribute(ImplicitParents)) {
+	/* TODO ??? */
+      }
+      scopeChain->append(glob);
+      break;
+    }
+}
+
+Context::~Context()
+{
+  delete scopeChain;
+}
+
+Context *Context::current()
+{
+  return KJScriptImp::curr ? KJScriptImp::curr->con : 0L;
+}
+
+void Context::setCurrent(Context *c)
+{
+  KJScriptImp::current()->con = c;
+}
+
+void Context::pushScope(const KJSO &s)
+{
+  scopeChain->prepend(s);
+}
+
+void Context::popScope()
+{
+  scopeChain->removeFirst();
+}
+
+List* Context::copyOfChain()
+{
+  return scopeChain->copy();
+}
+
+
+AnonymousFunction::AnonymousFunction()
+  : Function(0L)
+{
+  /* TODO */
+}
+
+DeclaredFunctionImp::DeclaredFunctionImp(const UString &n,
+					 FunctionBodyNode *b, const List *sc)
+  : ConstructorImp(n), body(b), scopes(sc->copy())
+{
+}
+
+DeclaredFunctionImp::~DeclaredFunctionImp()
+{
+  delete scopes;
+}
+
+// step 2 of ECMA 13.2.1. rest in FunctionImp::executeCall()
+Completion DeclaredFunctionImp::execute(const List &)
+{
+ /* TODO */
+
+#ifdef KJS_DEBUGGER
+  Debugger *dbg = KJScriptImp::current()->debugger();
+  int oldSourceId = -1;
+  if (dbg) {
+    oldSourceId = dbg->sourceId();
+    dbg->setSourceId(body->sourceId());
+  }
+#endif
+
+  Completion result = body->execute();
+
+#ifdef KJS_DEBUGGER
+  if (dbg) {
+    dbg->setSourceId(oldSourceId);
+  }
+#endif
+
+  if (result.complType() == Throw || result.complType() == ReturnValue)
+      return result;
+  return Completion(Normal, Undefined()); /* TODO: or ReturnValue ? */
+}
+
+// ECMA 13.2.2 [[Construct]]
+Object DeclaredFunctionImp::construct(const List &args)
+{
+  Object obj(ObjectClass);
+  KJSO p = get("prototype");
+  if (p.isObject())
+    obj.setPrototype(p);
+  else
+    obj.setPrototype(Global::current().objectPrototype());
+
+  KJSO res = executeCall(obj.imp(), &args);
+
+  Object v = Object::dynamicCast(res);
+  if (v.isNull())
+    return obj;
+  else
+    return v;
+}
+
+Completion AnonymousFunction::execute(const List &)
+{
+ /* TODO */
+  return Completion(Normal, Null());
+}
+
+// ECMA 10.1.8
+class ArgumentsObject : public ObjectImp {
+public:
+  ArgumentsObject(FunctionImp *func, const List *args);
+};
+
+ArgumentsObject::ArgumentsObject(FunctionImp *func, const List *args)
+  : ObjectImp(UndefClass)
+{
+  put("callee", Function(func), DontEnum);
+  if (args) {
+    put("length", Number(args->size()), DontEnum);
+    ListIterator arg = args->begin();
+    for (int i = 0; arg != args->end(); arg++, i++) {
+      put(UString::from(i), *arg, DontEnum);
+    }
+  }
+}
+
+const TypeInfo ActivationImp::info = { "Activation", ActivationType, 0, 0, 0 };
+
+// ECMA 10.1.6
+ActivationImp::ActivationImp(FunctionImp *f, const List *args)
+{
+  KJSO aobj(new ArgumentsObject(f, args));
+  put("arguments", aobj, DontDelete);
+  /* TODO: this is here to get myFunc.arguments and myFunc.a1 going.
+     I can't see this described in the spec but it's possible in browsers. */
+  if (!f->name().isNull())
+    f->put("arguments", aobj);
+}
+
+ExecutionStack::ExecutionStack()
+  : progNode(0L), firstNode(0L), prev(0)
+{
+}
+
+ExecutionStack* ExecutionStack::push()
+{
+  ExecutionStack *s = new ExecutionStack();
+  s->prev = this;
+
+  return s;
+}
+
+ExecutionStack* ExecutionStack::pop()
+{
+  ExecutionStack *s = prev;
+  delete this;
+
+  return s;
+}
+
+KJScriptImp* KJScriptImp::curr = 0L;
+KJScriptImp* KJScriptImp::hook = 0L;
+int          KJScriptImp::instances = 0;
+int          KJScriptImp::running = 0;
+
+KJScriptImp::KJScriptImp(KJScript *s)
+  : scr(s),
+    initialized(false),
+    glob(0L),
+#ifdef KJS_DEBUGGER
+    dbg(0L),
+#endif
+    retVal(0L)
+{
+  instances++;
+  KJScriptImp::curr = this;
+  // are we the first interpreter instance ? Initialize some stuff
+  if (instances == 1)
+    globalInit();
+  stack = new ExecutionStack();
+  clearException();
+  lex = new Lexer();
+}
+
+KJScriptImp::~KJScriptImp()
+{
+  KJScriptImp::curr = this;
+
+#ifdef KJS_DEBUGGER
+  attachDebugger(0L);
+#endif
+
+  clear();
+
+  delete lex;
+  lex = 0L;
+
+  delete stack;
+  stack = 0L;
+
+  KJScriptImp::curr = 0L;
+  // are we the last of our kind ? Free global stuff.
+  if (instances == 1)
+    globalClear();
+  instances--;
+}
+
+void KJScriptImp::globalInit()
+{
+  UndefinedImp::staticUndefined = new UndefinedImp();
+  UndefinedImp::staticUndefined->ref();
+  NullImp::staticNull = new NullImp();
+  NullImp::staticNull->ref();
+  BooleanImp::staticTrue = new BooleanImp(true);
+  BooleanImp::staticTrue->ref();
+  BooleanImp::staticFalse = new BooleanImp(false);
+  BooleanImp::staticFalse->ref();
+}
+
+void KJScriptImp::globalClear()
+{
+  UndefinedImp::staticUndefined->deref();
+  UndefinedImp::staticUndefined = 0L;
+  NullImp::staticNull->deref();
+  NullImp::staticNull = 0L;
+  BooleanImp::staticTrue->deref();
+  BooleanImp::staticTrue = 0L;
+  BooleanImp::staticFalse->deref();
+  BooleanImp::staticFalse = 0L;
+}
+
+void KJScriptImp::mark()
+{
+  if (exVal && !exVal->marked())
+    exVal->mark();
+  if (retVal && !retVal->marked())
+    retVal->mark();
+  UndefinedImp::staticUndefined->mark();
+  NullImp::staticNull->mark();
+  BooleanImp::staticTrue->mark();
+  BooleanImp::staticFalse->mark();
+}
+
+void KJScriptImp::init()
+{
+  KJScriptImp::curr = this;
+
+  clearException();
+  retVal = 0L;
+
+  if (!initialized) {
+    // add this interpreter to the global chain
+    // as a root set for garbage collection
+    if (hook) {
+      prev = hook;
+      next = hook->next;
+      hook->next->prev = this;
+      hook->next = this;
+    } else {
+      hook = next = prev = this;
+    }
+
+    glob.init();
+    con = new Context();
+    firstN = 0L;
+    progN = 0L;
+    recursion = 0;
+    errMsg = "";
+    initialized = true;
+#ifdef KJS_DEBUGGER
+    sid = -1;
+#endif
+  }
+}
+
+void KJScriptImp::clear()
+{
+  if ( recursion ) {
+#ifndef NDEBUG
+      fprintf(stderr, "KJS: ignoring clear() while running\n");
+#endif
+      return;
+  }
+  KJScriptImp *old = curr;
+  if (initialized) {
+    KJScriptImp::curr = this;
+
+    Node::setFirstNode(firstNode());
+    Node::deleteAllNodes();
+    setFirstNode(0L);
+    setProgNode(0L);
+
+    clearException();
+    retVal = 0L;
+
+    delete con; con = 0L;
+    glob.clear();
+
+    Collector::collect();
+
+    // remove from global chain (see init())
+    next->prev = prev;
+    prev->next = next;
+    hook = next;
+    if (hook == this)
+      hook = 0L;
+
+#ifdef KJS_DEBUGGER
+    sid = -1;
+#endif
+
+    initialized = false;
+  }
+  if (old != this)
+      KJScriptImp::curr = old;
+}
+
+bool KJScriptImp::evaluate(const UChar *code, unsigned int length, const KJSO &thisV,
+			   bool onlyCheckSyntax)
+{
+  init();
+
+#ifdef KJS_DEBUGGER
+  sid++;
+  if (debugger())
+    debugger()->setSourceId(sid);
+#endif
+  if (recursion > 7) {
+    fprintf(stderr, "KJS: breaking out of recursion\n");
+    return true;
+  } else if (recursion > 0) {
+#ifndef NDEBUG
+    fprintf(stderr, "KJS: entering recursion level %d\n", recursion);
+#endif
+    pushStack();
+  }
+
+  assert(Lexer::curr());
+  Lexer::curr()->setCode(code, length);
+  Node::setFirstNode(firstNode());
+  int parseError = kjsyyparse();
+  setFirstNode(Node::firstNode());
+
+  if (parseError) {
+    errType = 99; /* TODO */
+    errLine = Lexer::curr()->lineNo();
+    errMsg = "Parse error at line " + UString::from(errLine);
+#ifndef NDEBUG
+    fprintf(stderr, "JavaScript parse error at line %d.\n", errLine);
+#endif
+    /* TODO: either clear everything or keep previously
+       parsed function definitions */
+    //    Node::deleteAllNodes();
+    return false;
+  }
+
+  if (onlyCheckSyntax)
+      return true;
+
+  clearException();
+
+  KJSO oldVar;
+  if (!thisV.isNull()) {
+    context()->setThisValue(thisV);
+    context()->pushScope(thisV);
+    oldVar = context()->variableObject();
+    context()->setVariableObject(thisV);
+  }
+
+  running++;
+  recursion++;
+  assert(progNode());
+  Completion res = progNode()->execute();
+  recursion--;
+  running--;
+
+  if (hadException()) {
+    KJSO err = exception();
+    errType = 99; /* TODO */
+    errLine = err.get("line").toInt32();
+    errMsg = err.get("name").toString().value() + ". ";
+    errMsg += err.get("message").toString().value();
+#ifdef KJS_DEBUGGER
+    if (dbg)
+      dbg->setSourceId(err.get("sid").toInt32());
+#endif
+    clearException();
+  } else {
+    errType = 0;
+    errLine = -1;
+    errMsg = "";
+
+    // catch return value
+    retVal = 0L;
+    if (res.complType() == ReturnValue || !thisV.isNull())
+	retVal = res.value().imp();
+  }
+
+  if (!thisV.isNull()) {
+    context()->popScope();
+    context()->setVariableObject(oldVar);
+  }
+
+  if (progNode())
+    progNode()->deleteGlobalStatements();
+
+  if (recursion > 0) {
+    popStack();
+  }
+
+  return !errType;
+}
+
+void KJScriptImp::pushStack()
+{
+    stack = stack->push();
+}
+
+void KJScriptImp::popStack()
+{
+    stack = stack->pop();
+    assert(stack);
+}
+
+bool KJScriptImp::call(const KJSO &scope, const UString &func, const List &args)
+{
+  init();
+  KJSO callScope(scope);
+  if (callScope.isNull())
+    callScope = Global::current().imp();
+  if (!callScope.hasProperty(func)) {
+#ifndef NDEBUG
+      fprintf(stderr, "couldn't resolve function name %s. call() failed\n",
+	      func.ascii());
+#endif
+      return false;
+  }
+  KJSO v = callScope.get(func);
+  if (!v.isA(ConstructorType)) {
+#ifndef NDEBUG
+      fprintf(stderr, "%s is not a function. call() failed.\n", func.ascii());
+#endif
+      return false;
+  }
+  running++;
+  recursion++;
+  static_cast<ConstructorImp*>(v.imp())->executeCall(scope.imp(), &args);
+  recursion--;
+  running--;
+  return !hadException();
+}
+
+bool KJScriptImp::call(const KJSO &func, const KJSO &thisV,
+		       const List &args, const List &extraScope)
+{
+  init();
+  if(!func.implementsCall())
+    return false;
+
+  running++;
+  recursion++;
+  retVal = func.executeCall(thisV, &args, &extraScope).imp();
+  recursion--;
+  running--;
+
+  return !hadException();
+}
+
+void KJScriptImp::setException(Imp *e)
+{
+  assert(curr);
+  curr->exVal = e;
+  curr->exMsg = "Exception"; // not very meaningful but we use !0L to test
+}
+
+void KJScriptImp::setException(const char *msg)
+{
+  assert(curr);
+  curr->exVal = 0L;		// will be created later on exception()
+  curr->exMsg = msg;
+}
+
+KJSO KJScriptImp::exception()
+{
+  assert(curr);
+  if (!curr->exMsg)
+    return Undefined();
+  if (curr->exVal)
+    return curr->exVal;
+  return Error::create(GeneralError, curr->exMsg);
+}
+
+void KJScriptImp::clearException()
+{
+  assert(curr);
+  curr->exMsg = 0L;
+  curr->exVal = 0L;
+}
+
+#ifdef KJS_DEBUGGER
+void KJScriptImp::attachDebugger(Debugger *d)
+{
+  static bool detaching = false;
+  if (detaching) // break circular detaching
+    return;
+
+  if (dbg) {
+    detaching = true;
+    dbg->detach();
+    detaching = false;
+  }
+
+  dbg = d;
+}
+
+bool KJScriptImp::setBreakpoint(int id, int line, bool set)
+{
+  init();
+  return Node::setBreakpoint(firstNode(), id, line, set);
+}
+
+#endif
+
+bool PropList::contains(const UString &name)
+{
+  PropList *p = this;
+  while (p) {
+    if (name == p->name)
+      return true;
+    p = p->next;
+  }
+  return false;
+}
+
+bool LabelStack::push(const UString &id)
+{
+  if (id.isEmpty() || contains(id))
+    return false;
+
+  StackElm *newtos = new StackElm;
+  newtos->id = id;
+  newtos->prev = tos;
+  tos = newtos;
+  return true;
+}
+
+bool LabelStack::contains(const UString &id) const
+{
+  if (id.isEmpty())
+    return true;
+
+  for (StackElm *curr = tos; curr; curr = curr->prev)
+    if (curr->id == id)
+      return true;
+
+  return false;
+}
+
+void LabelStack::pop()
+{
+  if (tos) {
+    StackElm *prev = tos->prev;
+    delete tos;
+    tos = prev;
+  }
+}
+
+LabelStack::~LabelStack()
+{
+  StackElm *prev;
+
+  while (tos) {
+    prev = tos->prev;
+    delete tos;
+    tos = prev;
+  }
+}
+
+// ECMA 15.3.5.3 [[HasInstance]]
+// see comment in header file
+KJSO KJS::hasInstance(const KJSO &F, const KJSO &V)
+{
+  if (V.isObject()) {
+    KJSO prot = F.get("prototype");
+    if (!prot.isObject())
+      return Error::create(TypeError, "Invalid prototype encountered "
+			   "in instanceof operation.");
+    Imp *v = V.imp();
+    while ((v = v->prototype())) {
+      if (v == prot.imp())
+	return Boolean(true);
+    }
+  }
+  return Boolean(false);
+}
+
+#ifndef NDEBUG
+#include <stdio.h>
+void KJS::printInfo( const char *s, const KJSO &o )
+{
+    if (o.isNull())
+      fprintf(stderr, "%s: (null)\n", s);
+    else {
+      KJSO v = o;
+      if (o.isA(ReferenceType))
+	  v = o.getValue();
+      fprintf(stderr, "JS: %s: %s : %s (%p)\n",
+	      s,
+	      v.toString().value().ascii(),
+	      v.imp()->typeInfo()->name,
+	      (void*)v.imp());
+      if (o.isA(ReferenceType)) {
+	  fprintf(stderr, "JS: Was property '%s'\n", o.getPropertyName().ascii());
+	  printInfo("of", o.getBase());
+      }
+    }
+}
+#endif
diff --git a/WebCore/src/kdelibs/kjs/internal.h b/WebCore/src/kdelibs/kjs/internal.h
new file mode 100644
index 0000000..51a8ece
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/internal.h
@@ -0,0 +1,406 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _INTERNAL_H_
+#define _INTERNAL_H_
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "kjs.h"
+#include "object.h"
+#include "function.h"
+
+#define I18N_NOOP(s) s
+
+namespace KJS {
+
+  class Boolean;
+  class Number;
+  class String;
+  class Object;
+  class RegExp;
+  class Node;
+  class FunctionBodyNode;
+  class ProgramNode;
+#ifdef KJS_DEBUGGER
+  class Debugger;
+#endif
+
+  class UndefinedImp : public Imp {
+  public:
+    UndefinedImp();
+    virtual ~UndefinedImp() { }
+    virtual KJSO toPrimitive(Type preferred = UndefinedType) const;
+    virtual Boolean toBoolean() const;
+    virtual Number toNumber() const;
+    virtual String toString() const;
+    virtual Object toObject() const;
+
+    virtual const TypeInfo* typeInfo() const { return &info; }
+    static const TypeInfo info;
+      
+    static UndefinedImp *staticUndefined;
+  };
+
+  class NullImp : public Imp {
+  public:
+    NullImp();
+    virtual ~NullImp() { }
+    virtual KJSO toPrimitive(Type preferred = UndefinedType) const;
+    virtual Boolean toBoolean() const;
+    virtual Number toNumber() const;
+    virtual String toString() const;
+    virtual Object toObject() const;
+
+    virtual const TypeInfo* typeInfo() const { return &info; }
+    static const TypeInfo info;
+
+    static NullImp *staticNull;
+  };
+
+  class BooleanImp : public Imp {
+  public:
+    virtual ~BooleanImp() { }
+    BooleanImp(bool v = false) : val(v) { }
+    bool value() const { return val; }
+    virtual KJSO toPrimitive(Type preferred = UndefinedType) const;
+    virtual Boolean toBoolean() const;
+    virtual Number toNumber() const;
+    virtual String toString() const;
+    virtual Object toObject() const;
+
+    virtual const TypeInfo* typeInfo() const { return &info; }
+    static const TypeInfo info;
+
+    static BooleanImp *staticTrue, *staticFalse;
+  private:
+    bool val;
+  };
+
+  class NumberImp : public Imp {
+  public:
+    NumberImp(double v);
+    virtual ~NumberImp() { }
+    double value() const { return val; }
+    virtual KJSO toPrimitive(Type preferred = UndefinedType) const;
+    virtual Boolean toBoolean() const;
+    virtual Number toNumber() const;
+    virtual String toString() const;
+    virtual Object toObject() const;
+
+    virtual const TypeInfo* typeInfo() const { return &info; }
+    static const TypeInfo info;
+  private:
+    double val;
+  };
+
+  class StringImp : public Imp {
+  public:
+    StringImp(const UString& v);
+    virtual ~StringImp() { }
+    UString value() const { return val; }
+    virtual KJSO toPrimitive(Type preferred = UndefinedType) const;
+    virtual Boolean toBoolean() const;
+    virtual Number toNumber() const;
+    virtual String toString() const;
+    virtual Object toObject() const;
+
+    virtual const TypeInfo* typeInfo() const { return &info; }
+    static const TypeInfo info;
+  private:
+    UString val;
+  };
+
+  class ReferenceImp : public Imp {
+  public:
+    ReferenceImp(const KJSO& b, const UString& p);
+    virtual ~ReferenceImp() { }
+    virtual void mark(Imp*);
+    KJSO getBase() const { return base; }
+    UString getPropertyName() const { return prop; }
+
+    virtual const TypeInfo* typeInfo() const { return &info; }
+    static const TypeInfo info;
+  private:
+    KJSO base;
+    UString prop;
+  };
+
+  class CompletionImp : public Imp {
+  public:
+    CompletionImp(Compl c, const KJSO& v, const UString& t);
+    virtual ~CompletionImp() { }
+    virtual void mark(Imp*);
+    Compl completion() const { return comp; }
+    KJSO value() const { return val; }
+    UString target() const { return tar; }
+
+    virtual const TypeInfo* typeInfo() const { return &info; }
+    static const TypeInfo info;
+  private:
+    Compl comp;
+    KJSO val;
+    UString tar;
+  };
+
+  class RegExpImp : public ObjectImp {
+  public:
+    RegExpImp();
+    ~RegExpImp();
+    void setRegExp(RegExp *r) { reg = r; }
+    RegExp* regExp() const { return reg; }
+  private:
+    RegExp *reg;
+  };
+
+  class StatementNode;
+  class UString;
+
+  class Reference : public KJSO {
+  public:
+    Reference(const KJSO& b, const UString &p);
+    virtual ~Reference();
+  };
+
+  /**
+   * @short The "label set" in Ecma-262 spec
+   */
+  class LabelStack {
+  public:
+    LabelStack(): tos(0L) {}
+    ~LabelStack();
+
+    /**
+     * If id is not empty and is not in the stack already, puts it on top of
+     * the stack and returns true, otherwise returns false
+     */
+    bool push(const UString &id);
+    /**
+     * Is the id in the stack?
+     */
+    bool contains(const UString &id) const;
+    /**
+     * Removes from the stack the last pushed id (what else?)
+     */
+    void pop();
+  private:
+    struct StackElm {
+      UString id;
+      StackElm *prev;
+    };
+
+    StackElm *tos;
+  };
+
+  /**
+   * @short Execution context.
+   */
+  class Context {
+  public:
+    Context(CodeType type = GlobalCode, Context *callingContext = 0L,
+	       FunctionImp *func = 0L, const List *args = 0L, Imp *thisV = 0L);
+    virtual ~Context();
+    static Context *current();
+    static void setCurrent(Context *c);
+    const List *pScopeChain() const { return scopeChain; }
+    void pushScope(const KJSO &s);
+    void popScope();
+    List *copyOfChain();
+    KJSO variableObject() const { return variable; }
+    void setVariableObject( const KJSO &obj ) { variable = obj; }
+    KJSO thisValue() const { return thisVal; }
+    void setThisValue(const KJSO &t) { thisVal = t; }
+    LabelStack *seenLabels() { return &ls; }
+  private:
+    LabelStack ls;
+    KJSO thisVal;
+    KJSO activation;
+    KJSO variable;
+    List *scopeChain;
+  };
+
+  class DeclaredFunctionImp : public ConstructorImp {
+  public:
+    DeclaredFunctionImp(const UString &n, FunctionBodyNode *b,
+			const List *sc);
+    ~DeclaredFunctionImp();
+    Completion execute(const List &);
+    Object construct(const List &);
+    CodeType codeType() const { return FunctionCode; }
+    List *scopeChain() const { return scopes; }
+  private:
+    FunctionBodyNode *body;
+    List *scopes;
+  };
+
+  class AnonymousFunction : public Function {
+  public:
+    AnonymousFunction();
+    Completion execute(const List &);
+    CodeType codeType() const { return AnonymousCode; }
+  };
+
+  class ActivationImp : public Imp {
+  public:
+    ActivationImp(FunctionImp *f, const List *args);
+    virtual const TypeInfo* typeInfo() const { return &info; }
+    static const TypeInfo info;
+  };
+
+  class ExecutionStack {
+  public:
+    ExecutionStack();
+    ExecutionStack *push();
+    ExecutionStack *pop();
+    
+    ProgramNode *progNode;
+    Node *firstNode;
+  private:
+    ExecutionStack *prev;
+  };
+
+  class KJScriptImp {
+    friend class ::KJScript;
+    friend class Lexer;
+    friend class Context;
+    friend class Global;
+    friend class Collector;
+  public:
+    KJScriptImp(KJScript *s);
+    ~KJScriptImp();
+    void mark();
+    static KJScriptImp *current() { return curr; }
+    static void setException(Imp *e);
+    static void setException(const char *msg);
+    static bool hadException();
+    static KJSO exception();
+    static void clearException();
+
+    Context *context() const { return con; }
+    void setContext(Context *c) { con = c; }
+
+#ifdef KJS_DEBUGGER
+    /**
+     * Attach debugger d to this engine. If there already was another instance
+     * attached it will be detached.
+     */
+    void attachDebugger(Debugger *d);
+    Debugger *debugger() const { return dbg; }
+    int sourceId() const { return sid; }
+    bool setBreakpoint(int id, int line, bool set);
+#endif
+  private:
+    /**
+     * Initialize global object and context. For internal use only.
+     */
+    void init();
+    void clear();
+    /**
+     * Called when the first interpreter is instanciated. Initializes
+     * global pointers.
+     */
+    void globalInit();
+    /**
+     * Called when the last interpreter instance is destroyed. Frees
+     * globally allocated memory.
+     */
+    void globalClear();
+    bool evaluate(const UChar *code, unsigned int length, const KJSO &thisV = KJSO(),
+		  bool onlyCheckSyntax = false);
+    bool call(const KJSO &scope, const UString &func, const List &args);
+    bool call(const KJSO &func, const KJSO &thisV,
+	      const List &args, const List &extraScope);
+
+  public:
+    ProgramNode *progNode() const { return stack->progNode; }
+    void setProgNode(ProgramNode *p) { stack->progNode = p; }
+    Node *firstNode() const { return stack->firstNode; }
+    void setFirstNode(Node *n) { stack->firstNode = n; }
+    void pushStack();
+    void popStack();
+    KJScriptImp *next, *prev;
+    KJScript *scr;
+    ExecutionStack *stack;
+
+  private:
+    ProgramNode *progN;
+    Node *firstN;
+
+    static KJScriptImp *curr, *hook;
+    static int instances; // total number of instances
+    static int running;	// total number running
+    bool initialized;
+    Lexer *lex;
+    Context *con;
+    Global glob;
+    int errType, errLine;
+    UString errMsg;
+#ifdef KJS_DEBUGGER
+    Debugger *dbg;
+    int sid;
+#endif
+    const char *exMsg;
+    Imp *exVal;
+    Imp *retVal;
+    int recursion;
+  };
+
+  inline bool KJScriptImp::hadException()
+  {
+    assert(curr);
+    return curr->exMsg;
+  }
+
+  /**
+   * @short Struct used to return the property names of an object
+   */
+  class PropList {
+  public:
+    PropList(UString nm = UString::null, PropList *nx = 0) :
+			  name(nm), next(nx) {};
+    ~PropList() {
+      if(next) delete next;
+    }
+    /**
+     * The property name
+     */
+    UString name;
+    /**
+     * The next property
+     */
+    PropList *next;
+    bool contains(const UString &name);
+  };
+
+  /* TODO just temporary until functions are objects and this becomes
+     a member function. Called by RelationNode for 'instanceof' operator. */
+  KJSO hasInstance(const KJSO &F, const KJSO &V);
+
+// #define KJS_VERBOSE
+#ifndef NDEBUG
+  void printInfo( const char *s, const KJSO &o );
+#endif
+
+}; // namespace
+
+
+#endif
diff --git a/WebCore/src/kdelibs/kjs/keywords.table b/WebCore/src/kdelibs/kjs/keywords.table
new file mode 100644
index 0000000..391aa34
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/keywords.table
@@ -0,0 +1,66 @@
+# main keywords
+ at begin mainTable 41
+# types
+null		NULLTOKEN
+true		TRUETOKEN
+false		FALSETOKEN
+# keywords
+break		BREAK
+case		CASE
+catch		CATCH
+default		DEFAULT
+finally		FINALLY
+for		FOR
+instanceof	INSTANCEOF
+new		NEW
+var		VAR
+continue	CONTINUE
+function	FUNCTION
+return		RETURN
+void		VOID
+delete		DELETE
+if		IF
+this		THIS
+do		DO
+while		WHILE
+else		ELSE
+in		IN
+switch		SWITCH
+throw		THROW
+try		TRY
+typeof		TYPEOF
+with		WITH
+# reserved for future use
+abstract	RESERVED
+boolean		RESERVED
+byte		RESERVED
+char		RESERVED
+class		RESERVED
+const		RESERVED
+debugger	RESERVED
+double		RESERVED
+enum		RESERVED
+export		RESERVED
+extends		RESERVED
+final		RESERVED
+float		RESERVED
+goto		RESERVED
+implements	RESERVED
+import		RESERVED
+int		RESERVED
+interface	RESERVED
+long		RESERVED
+native		RESERVED
+package		RESERVED
+private		RESERVED
+protected	RESERVED
+public		RESERVED
+short		RESERVED
+static		RESERVED
+super		RESERVED
+synchronized	RESERVED
+throws		RESERVED
+transient	RESERVED
+volatile	RESERVED
+ at end
+
diff --git a/WebCore/src/kdelibs/kjs/kjs.cpp b/WebCore/src/kdelibs/kjs/kjs.cpp
new file mode 100644
index 0000000..d6c0260
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/kjs.cpp
@@ -0,0 +1,156 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "kjs.h"
+#include "types.h"
+#include "internal.h"
+#include "collector.h"
+
+using namespace KJS;
+
+KJScript::KJScript()
+{
+  rep = new KJScriptImp(this);
+  rep->init();
+}
+
+KJScript::~KJScript()
+{
+  delete rep;
+
+#ifdef KJS_DEBUG_MEM
+  //printf("Imp::count: %d\n", Imp::count);
+  //  assert(Imp::count == 0);
+#endif
+}
+
+void KJScript::init()
+{
+  rep->init();
+}
+
+Imp *KJScript::globalObject() const
+{
+  return rep->glob.imp();
+}
+
+void KJScript::setCurrent( KJScript *newCurr )
+{
+  KJScriptImp::curr = newCurr ? newCurr->rep : 0L;
+}
+
+KJScript *KJScript::current()
+{
+  return KJScriptImp::current() ? KJScriptImp::current()->scr : 0L;
+}
+
+int KJScript::recursion() const
+{
+  return rep->recursion;
+}
+
+bool KJScript::evaluate(const char *code)
+{
+  return rep->evaluate(UString(code).data(), strlen(code));
+}
+
+bool KJScript::evaluate(const UString &code)
+{
+  return rep->evaluate(code.data(), code.size());
+}
+
+bool KJScript::evaluate(const KJSO &thisV,
+			const QChar *code, unsigned int length)
+{
+  return rep->evaluate((UChar*)code, length, thisV);
+}
+
+bool KJScript::call(const KJS::UString &func, const List &args)
+{
+  return rep->call(0, func, args);
+}
+
+bool KJScript::call(const KJSO &scope, const KJS::UString &func,
+		    const KJS::List &args)
+{
+  return rep->call(scope.imp(), func, args);
+}
+
+bool KJScript::call(const KJS::KJSO &func, const KJSO &thisV,
+		    const KJS::List &args, const KJS::List &extraScope)
+{
+  return rep->call(func, thisV, args, extraScope);
+}
+
+void KJScript::clear()
+{
+  rep->clear();
+}
+
+Imp *KJScript::returnValue() const
+{
+  return rep->retVal;
+}
+
+int KJScript::errorType() const
+{
+  return rep->errType;
+}
+
+int KJScript::errorLine() const
+{
+  return rep->errLine;
+}
+
+const char* KJScript::errorMsg() const
+{
+  return rep->errMsg.ascii();
+}
+
+bool KJScript::checkSyntax(const KJS::UString &code )
+{
+  return rep->evaluate(code.data(), code.size(), 0, true);
+}
+
+/**
+ * @short Print to stderr for debugging purposes.
+ */
+namespace KJS {
+  class DebugPrint : public InternalFunctionImp {
+  public:
+    Completion execute(const List &args)
+      {
+	KJSO v = args[0];
+	String s = v.toString();
+	fprintf(stderr, "---> %s\n", s.value().cstring().c_str());
+
+	return Completion(Normal);
+      }
+  };
+};
+
+void KJScript::enableDebug()
+{
+  rep->init();
+  Global::current().put("debug", Function(new DebugPrint()));
+}
diff --git a/WebCore/src/kdelibs/kjs/kjs.h b/WebCore/src/kdelibs/kjs/kjs.h
new file mode 100644
index 0000000..42a866d
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/kjs.h
@@ -0,0 +1,170 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _KJS_H_
+#define _KJS_H_
+
+class QChar;
+
+namespace KJS {
+  class UString;
+  class Lexer;
+  class Context;
+  class Global;
+  class KJSO;
+  class Object;
+  class Imp;
+  class List;
+  class KJScriptImp;
+#ifdef KJS_DEBUGGER
+  class Debugger;
+#endif
+};
+
+/**
+ * @libdoc ECMAScript interpreter
+ *
+ * This library provides an interpreter for ECMAScript aka JavaScript.
+ * It currently aims at compliance with Edition 3 of the standard.
+ */
+
+/**
+ * @short ECMAScript interpreter
+ */
+class KJScript {
+  friend class KJS::KJScriptImp;
+  friend class KJS::KJSO;
+  friend class KJS::Context;
+  friend class KJS::Lexer;
+  friend class KJS::Global;
+public:
+  /**
+   * Create a new ECMAScript interpreter. You can later ask it to interprete
+   * code by passing it via @ref #evaluate.
+   */
+  KJScript();
+  /**
+   *  Destructor
+   */
+  ~KJScript();
+  /**
+   * Force a "context switch". You usually do not need to do that,
+   * evaluate() does it too.
+   */
+  void init();
+  /**
+   * Returns a pointer to the Global object.
+   */
+  KJS::Imp *globalObject() const;
+  /**
+   * Don't use. May disappear.
+   */
+  static KJScript *current();
+  /**
+   * Don't use. May disappear.
+   */
+  static void setCurrent( KJScript *newCurr );
+
+  /**
+   * Current level of recursive calls to this interpreter. 0 initially.
+   */
+  int recursion() const;
+  /**
+   * Asks the interpreter to evaluate a piece of code. If called more than
+   * once the state (global variables, functions etc.) will be preserved
+   * between each call.
+   * @param code is a string containing the code to be executed.
+   * @return True if the code was evaluated successfully, false if an error
+   * occured.
+   */
+  bool evaluate(const char *code);
+  /**
+   * Same as above. Only differing in the arguments accepted.
+   * @param code is a pointer to an Unicode string containing the code to
+   * be executed.
+   * @param length number of characters.
+   */
+  bool evaluate(const KJS::KJSO &thisV,
+		const QChar *code, unsigned int length);
+  /**
+   * Added for convenience in case you have the code in available in
+   * internal representation already.
+   * @param code is an Unicode string containing the code to be executed.
+   */
+  bool evaluate(const KJS::UString &code);
+  /**
+   * Call the specified function directly, optionally passing args as a
+   * list of arguments. Return value and treatment of errors is analog
+   * to the evaluate() calls.
+   */
+  bool call(const KJS::UString &func, const KJS::List &args);
+  bool call(const KJS::KJSO &scope, const KJS::UString &func,
+	    const KJS::List &args);
+  bool call(const KJS::KJSO &func, const KJS::KJSO &thisV,
+	    const KJS::List &args, const KJS::List &extraScope );
+  /**
+   * Clear the interpreter's memory. Otherwise, function declarations
+   * and global variables will be remembered after each invokation of
+   * @ref KJScript::evaluate.
+   */
+  void clear();
+  /**
+   * @return Return value from the last call to @ref evaluate(). Null if there
+   * hasn't been any.
+   */
+  KJS::Imp *returnValue() const;
+  /**
+   * @return Return code from last call to @ref evaluate(). 0 on success.
+   */
+  int errorType() const;
+  /**
+   * @return Return line of last error. -1 if last call didn't have an error.
+   */
+  int errorLine() const;
+  /**
+   * @return Error message from last call to @ref evaluate(). Empty string
+   * if no error occured.
+   */
+  const char *errorMsg() const;
+  /**
+   * Check the syntax of a piece of code. Return true if the code could be
+   * parsed without errors, false otherwise. @ref errorLine() will tell you
+   * approximately where the syntax error happened.
+   */
+  bool checkSyntax(const KJS::UString &code);
+  /**
+   * Adds a debug() function to the set of pre-defined properties.
+   * debug(arg) tries to convert 'arg' to a string and prints the result
+   * to stderr. If you want to debug self defined Host Objects this way
+   * you should provide them with a toString() method that returns a string.
+   */
+  void enableDebug();
+private:
+  KJS::KJScriptImp *rep;
+  // not implemented
+  KJScript(const KJScript&);
+  KJScript operator=(const KJScript&);
+
+#ifdef KJS_DEBUGGER
+  friend class KJS::Debugger;
+#endif
+};
+
+#endif
diff --git a/WebCore/src/kdelibs/kjs/lexer.cpp b/WebCore/src/kdelibs/kjs/lexer.cpp
new file mode 100644
index 0000000..7ce1a3d
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/lexer.cpp
@@ -0,0 +1,744 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include "kjs.h"
+#include "nodes.h"
+#include "lexer.h"
+#include "ustring.h"
+#include "lookup.h"
+#include "internal.h"
+
+// we can't specify the namespace in yacc's C output, so do it here
+using namespace KJS;
+
+#ifndef KDE_USE_FINAL
+#include "grammar.h"
+#endif
+
+#include "lexer.lut.h"
+
+#ifdef KJS_DEBUGGER
+extern YYLTYPE yylloc;	// global bison variable holding token info
+#endif
+
+// a bridge for yacc from the C world to C++
+int kjsyylex()
+{
+  return Lexer::curr()->lex();
+}
+
+Lexer::Lexer()
+  : yylineno(0),
+    size8(128), size16(128), restrKeyword(false),
+    stackToken(-1), pos(0),
+    code(0), length(0),
+#ifndef KJS_PURE_ECMA
+    bol(true),
+#endif
+    current(0), next1(0), next2(0), next3(0)
+{
+  // allocate space for read buffers
+  buffer8 = new char[size8];
+  buffer16 = new UChar[size16];
+
+}
+
+Lexer::~Lexer()
+{
+  delete [] buffer8;
+  delete [] buffer16;
+}
+
+Lexer *Lexer::curr()
+{
+  assert(KJScriptImp::current());
+  return KJScriptImp::current()->lex;
+}
+
+void Lexer::setCode(const UChar *c, unsigned int len)
+{
+  yylineno = 0;
+  restrKeyword = false;
+  delimited = false;
+  stackToken = -1;
+  pos = 0;
+  code = c;
+  length = len;
+#ifndef KJS_PURE_ECMA
+  bol = true;
+#endif
+
+  // read first characters
+  current = (length > 0) ? code[0].unicode() : 0;
+  next1 = (length > 1) ? code[1].unicode() : 0;
+  next2 = (length > 2) ? code[2].unicode() : 0;
+  next3 = (length > 3) ? code[3].unicode() : 0;
+}
+
+void Lexer::shift(unsigned int p)
+{
+  while (p--) {
+    pos++;
+    current = next1;
+    next1 = next2;
+    next2 = next3;
+    next3 = (pos + 3 < length) ? code[pos+3].unicode() : 0;
+  }
+}
+
+void Lexer::setDone(State s)
+{
+  state = s;
+  done = true;
+}
+
+int Lexer::lex()
+{
+  int token = 0;
+  state = Start;
+  unsigned short stringType = 0; // either single or double quotes
+  pos8 = pos16 = 0;
+  done = false;
+  terminator = false;
+
+  // did we push a token on the stack previously ?
+  // (after an automatic semicolon insertion)
+  if (stackToken >= 0) {
+    setDone(Other);
+    token = stackToken;
+    stackToken = 0;
+  }
+
+  while (!done) {
+    switch (state) {
+    case Start:
+      if (isWhiteSpace()) {
+	// do nothing
+      } else if (current == '/' && next1 == '/') {
+	shift(1);
+	state = InSingleLineComment;
+      } else if (current == '/' && next1 == '*') {
+	shift(1);
+	state = InMultiLineComment;
+      } else if (current == 0) {
+	if (!terminator && !delimited) {
+	  // automatic semicolon insertion if program incomplete
+	  token = ';';
+	  stackToken = 0;
+	  setDone(Other);
+	} else
+	  setDone(Eof);
+      } else if (isLineTerminator()) {
+	yylineno++;
+#ifndef KJS_PURE_ECMA
+	bol = true;
+#endif
+	terminator = true;
+	if (restrKeyword) {
+	  token = ';';
+	  setDone(Other);
+	}
+      } else if (current == '"' || current == '\'') {
+	state = InString;
+	stringType = current;
+      } else if (isIdentLetter(current)) {
+	record16(current);
+	state = InIdentifier;
+      } else if (current == '0') {
+	record8(current);
+	state = InNum0;
+      } else if (isDecimalDigit(current)) {
+	record8(current);
+	state = InNum;
+      } else if (current == '.' && isDecimalDigit(next1)) {
+	record8(current);
+	state = InDecimal;
+#ifndef KJS_PURE_ECMA
+	// <!-- marks the beginning of a line comment (for www usage)
+      } else if (bol && current == '<' && next1 == '!' &&
+		 next2 == '-' && next3 == '-') {
+	shift(3);
+	state = InSingleLineComment;
+	// same of -->
+      } else if (bol && current == '-' && next1 == '-' &&  next2 == '>') {
+	shift(2);
+	state = InSingleLineComment;
+#endif
+      } else {
+	token = matchPunctuator(current, next1, next2, next3);
+	if (token != -1) {
+	  setDone(Other);
+	} else {
+	  //	  cerr << "encountered unknown character" << endl;
+	  setDone(Bad);
+	}
+      }
+      break;
+    case InString:
+      if (current == stringType) {
+	shift(1);
+	setDone(String);
+      } else if (current == 0 || isLineTerminator()) {
+	setDone(Bad);
+      } else if (current == '\\') {
+	state = InEscapeSequence;
+      } else {
+	record16(current);
+      }
+      break;
+    // Escape Sequences inside of strings
+    case InEscapeSequence:
+      if (isOctalDigit(current)) {
+	if (current >= '0' && current <= '3' &&
+	    isOctalDigit(next1) && isOctalDigit(next2)) {
+	  record16(convertOctal(current, next1, next2));
+	  shift(2);
+	  state = InString;
+	} else if (isOctalDigit(current) && isOctalDigit(next1)) {
+	  record16(convertOctal('0', current, next1));
+	  shift(1);
+	  state = InString;
+	} else if (isOctalDigit(current)) {
+	  record16(convertOctal('0', '0', current));
+	  state = InString;
+	} else {
+	  setDone(Bad);
+	}
+      } else if (current == 'x')
+	state = InHexEscape;
+      else if (current == 'u')
+	state = InUnicodeEscape;
+      else {
+	record16(singleEscape(current));
+	state = InString;
+      }
+      break;
+    case InHexEscape:
+      if (isHexDigit(current) && isHexDigit(next1)) {
+	state = InString;
+	record16(convertHex(current, next1));
+	shift(1);
+      } else if (current == stringType) {
+	record16('x');
+	shift(1);
+	setDone(String);
+      } else {
+	record16('x');
+	record16(current);
+	state = InString;
+      }
+      break;
+    case InUnicodeEscape:
+      if (isHexDigit(current) && isHexDigit(next1) &&
+	  isHexDigit(next2) && isHexDigit(next3)) {
+	record16(convertUnicode(current, next1, next2, next3));
+	shift(3);
+	state = InString;
+      } else if (current == stringType) {
+	record16('u');
+	shift(1);
+	setDone(String);
+      } else {
+	setDone(Bad);
+      }
+      break;
+    case InSingleLineComment:
+      if (isLineTerminator()) {
+	yylineno++;
+	terminator = true;
+#ifndef KJS_PURE_ECMA
+	bol = true;
+#endif
+	if (restrKeyword) {
+	  token = ';';
+	  setDone(Other);
+	} else
+	  state = Start;
+      } else if (current == 0) {
+	setDone(Eof);
+      }
+      break;
+    case InMultiLineComment:
+      if (current == 0) {
+	setDone(Bad);
+      } else if (isLineTerminator()) {
+	yylineno++;
+      } else if (current == '*' && next1 == '/') {
+	state = Start;
+	shift(1);
+      }
+      break;
+    case InIdentifier:
+      if (isIdentLetter(current) || isDecimalDigit(current)) {
+	record16(current);
+	break;
+      }
+      setDone(Identifier);
+      break;
+    case InNum0:
+      if (current == 'x' || current == 'X') {
+	record8(current);
+	state = InHex;
+      } else if (current == '.') {
+	record8(current);
+	state = InDecimal;
+      } else if (current == 'e' || current == 'E') {
+	record8(current);
+	state = InExponentIndicator;
+      } else if (isOctalDigit(current)) {
+	record8(current);
+	state = InOctal;
+      } else {
+	setDone(Number);
+      }
+      break;
+    case InHex:
+      if (isHexDigit(current)) {
+	record8(current);
+      } else {
+	setDone(Hex);
+      }
+      break;
+    case InOctal:
+      if (isOctalDigit(current)) {
+	record8(current);
+      } else
+	setDone(Octal);
+      break;
+    case InNum:
+      if (isDecimalDigit(current)) {
+	record8(current);
+      } else if (current == '.') {
+	record8(current);
+	state = InDecimal;
+      } else if (current == 'e' || current == 'E') {
+	record8(current);
+	state = InExponentIndicator;
+      } else
+	setDone(Number);
+      break;
+    case InDecimal:
+      if (isDecimalDigit(current)) {
+	record8(current);
+      } else if (current == 'e' || current == 'E') {
+	record8(current);
+	state = InExponentIndicator;
+      } else
+	setDone(Number);
+      break;
+    case InExponentIndicator:
+      if (current == '+' || current == '-') {
+	record8(current);
+      } else if (isDecimalDigit(current)) {
+	record8(current);
+	state = InExponent;
+      } else
+	setDone(Bad);
+      break;
+    case InExponent:
+      if (isDecimalDigit(current)) {
+	record8(current);
+      } else
+	setDone(Number);
+      break;
+    default:
+      assert(!"Unhandled state in switch statement");
+    }
+
+    // move on to the next character
+    if (!done)
+      shift(1);
+#ifndef KJS_PURE_ECMA
+    if (state != Start && state != InSingleLineComment)
+      bol = false;
+#endif
+  }
+
+  // no identifiers allowed directly after numeric literal, e.g. "3in" is bad
+  if ((state == Number || state == Octal || state == Hex)
+      && isIdentLetter(current))
+    state = Bad;
+
+  // terminate string
+  buffer8[pos8] = '\0';
+
+#ifdef KJS_DEBUG_LEX
+  fprintf(stderr, "line: %d ", lineNo());
+  fprintf(stderr, "yytext (%x): ", buffer8[0]);
+  fprintf(stderr, "%s ", buffer8);
+#endif
+
+  double dval = 0;
+  if (state == Number) {
+    dval = strtod(buffer8, 0L);
+  } else if (state == Hex) { // scan hex numbers
+    // TODO: support long unsigned int
+    unsigned int i;
+    sscanf(buffer8, "%x", &i);
+    dval = i;
+    state = Number;
+  } else if (state == Octal) {   // scan octal number
+    unsigned int ui;
+    sscanf(buffer8, "%o", &ui);
+    dval = ui;
+    state = Number;
+  }
+
+#ifdef KJS_DEBUG_LEX
+  switch (state) {
+  case Eof:
+    printf("(EOF)\n");
+    break;
+  case Other:
+    printf("(Other)\n");
+    break;
+  case Identifier:
+    printf("(Identifier)/(Keyword)\n");
+    break;
+  case String:
+    printf("(String)\n");
+    break;
+  case Number:
+    printf("(Number)\n");
+    break;
+  default:
+    printf("(unknown)");
+  }
+#endif
+
+  restrKeyword = false;
+  delimited = false;
+#ifdef KJS_DEBUGGER
+  yylloc.first_line = yylineno; // ???
+  yylloc.last_line = yylineno;
+#endif
+
+  switch (state) {
+  case Eof:
+    return 0;
+  case Other:
+    if(token == '}' || token == ';') {
+      delimited = true;
+    }
+    return token;
+  case Identifier:
+    if ((token = Lookup::find(&mainTable, buffer16, pos16)) < 0) {
+      /* TODO: close leak on parse error. same holds true for String */
+      kjsyylval.ustr = new UString(buffer16, pos16);
+      return IDENT;
+    }
+    if (token == CONTINUE || token == BREAK ||
+	token == RETURN || token == THROW)
+      restrKeyword = true;
+    return token;
+  case String:
+    kjsyylval.ustr = new UString(buffer16, pos16); return STRING;
+  case Number:
+    kjsyylval.dval = dval;
+    return NUMBER;
+  case Bad:
+    fprintf(stderr, "yylex: ERROR.\n");
+    return -1;
+  default:
+    assert(!"unhandled numeration value in switch");
+    return -1;
+  }
+}
+
+bool Lexer::isWhiteSpace() const
+{
+  return (current == ' ' || current == '\t' ||
+	  current == 0x0b || current == 0x0c);
+}
+
+bool Lexer::isLineTerminator() const
+{
+  return (current == '\n' || current == '\r');
+}
+
+bool Lexer::isIdentLetter(unsigned short c)
+{
+  /* TODO: allow other legitimate unicode chars */
+  return (c >= 'a' && c <= 'z' ||
+	  c >= 'A' && c <= 'Z' ||
+	  c == '$' || c == '_');
+}
+
+bool Lexer::isDecimalDigit(unsigned short c)
+{
+  return (c >= '0' && c <= '9');
+}
+
+bool Lexer::isHexDigit(unsigned short c) const
+{
+  return (c >= '0' && c <= '9' ||
+	  c >= 'a' && c <= 'f' ||
+	  c >= 'A' && c <= 'F');
+}
+
+bool Lexer::isOctalDigit(unsigned short c) const
+{
+  return (c >= '0' && c <= '7');
+}
+
+int Lexer::matchPunctuator(unsigned short c1, unsigned short c2,
+			      unsigned short c3, unsigned short c4)
+{
+  if (c1 == '>' && c2 == '>' && c3 == '>' && c4 == '=') {
+    shift(4);
+    return URSHIFTEQUAL;
+  } else if (c1 == '=' && c2 == '=' && c3 == '=') {
+    shift(3);
+    return STREQ;
+  } else if (c1 == '!' && c2 == '=' && c3 == '=') {
+    shift(3);
+    return STRNEQ;
+   } else if (c1 == '>' && c2 == '>' && c3 == '>') {
+    shift(3);
+    return URSHIFT;
+  } else if (c1 == '<' && c2 == '<' && c3 == '=') {
+    shift(3);
+    return LSHIFTEQUAL;
+  } else if (c1 == '>' && c2 == '>' && c3 == '=') {
+    shift(3);
+    return RSHIFTEQUAL;
+  } else if (c1 == '<' && c2 == '=') {
+    shift(2);
+    return LE;
+  } else if (c1 == '>' && c2 == '=') {
+    shift(2);
+    return GE;
+  } else if (c1 == '!' && c2 == '=') {
+    shift(2);
+    return NE;
+  } else if (c1 == '+' && c2 == '+') {
+    shift(2);
+    if (terminator) {
+      // automatic semicolon insertion
+      stackToken = PLUSPLUS;
+      return AUTO;
+    } else
+      return PLUSPLUS;
+  } else if (c1 == '-' && c2 == '-') {
+    shift(2);
+    if (terminator) {
+      // automatic semicolon insertion
+      stackToken = MINUSMINUS;
+      return AUTO;
+    } else
+      return MINUSMINUS;
+  } else if (c1 == '=' && c2 == '=') {
+    shift(2);
+    return EQEQ;
+  } else if (c1 == '+' && c2 == '=') {
+    shift(2);
+    return PLUSEQUAL;
+  } else if (c1 == '-' && c2 == '=') {
+    shift(2);
+    return MINUSEQUAL;
+  } else if (c1 == '*' && c2 == '=') {
+    shift(2);
+    return MULTEQUAL;
+  } else if (c1 == '/' && c2 == '=') {
+    shift(2);
+    return DIVEQUAL;
+  } else if (c1 == '&' && c2 == '=') {
+    shift(2);
+    return ANDEQUAL;
+  } else if (c1 == '^' && c2 == '=') {
+    shift(2);
+    return XOREQUAL;
+  } else if (c1 == '%' && c2 == '=') {
+    shift(2);
+    return MODEQUAL;
+  } else if (c1 == '|' && c2 == '=') {
+    shift(2);
+    return OREQUAL;
+  } else if (c1 == '<' && c2 == '<') {
+    shift(2);
+    return LSHIFT;
+  } else if (c1 == '>' && c2 == '>') {
+    shift(2);
+    return RSHIFT;
+  } else if (c1 == '&' && c2 == '&') {
+    shift(2);
+    return AND;
+  } else if (c1 == '|' && c2 == '|') {
+    shift(2);
+    return OR;
+  }
+
+  switch(c1) {
+    case '=':
+    case '>':
+    case '<':
+    case ',':
+    case '!':
+    case '~':
+    case '?':
+    case ':':
+    case '.':
+    case '+':
+    case '-':
+    case '*':
+    case '/':
+    case '&':
+    case '|':
+    case '^':
+    case '%':
+    case '(':
+    case ')':
+    case '{':
+    case '}':
+    case '[':
+    case ']':
+    case ';':
+      shift(1);
+      return static_cast<int>(c1);
+    default:
+      return -1;
+  }
+}
+
+unsigned short Lexer::singleEscape(unsigned short c) const
+{
+  switch(c) {
+  case 'b':
+    return 0x08;
+  case 't':
+    return 0x09;
+  case 'n':
+    return 0x0A;
+  case 'v':
+    return 0x0B;
+  case 'f':
+    return 0x0C;
+  case 'r':
+    return 0x0D;
+  case '"':
+    return 0x22;
+  case '\'':
+    return 0x27;
+  case '\\':
+    return 0x5C;
+  default:
+    return c;
+  }
+}
+
+unsigned short Lexer::convertOctal(unsigned short c1, unsigned short c2,
+                                      unsigned short c3) const
+{
+  return ((c1 - '0') * 64 + (c2 - '0') * 8 + c3 - '0');
+}
+
+unsigned char Lexer::convertHex(unsigned short c)
+{
+  if (c >= '0' && c <= '9')
+    return (c - '0');
+  else if (c >= 'a' && c <= 'f')
+    return (c - 'a' + 10);
+  else
+    return (c - 'A' + 10);
+}
+
+unsigned char Lexer::convertHex(unsigned short c1, unsigned short c2)
+{
+  return ((convertHex(c1) << 4) + convertHex(c2));
+}
+
+UChar Lexer::convertUnicode(unsigned short c1, unsigned short c2,
+                                     unsigned short c3, unsigned short c4)
+{
+  return UChar((convertHex(c1) << 4) + convertHex(c2),
+	       (convertHex(c3) << 4) + convertHex(c4));
+}
+
+void Lexer::record8(unsigned short c)
+{
+  assert(c <= 0xff);
+
+  // enlarge buffer if full
+  if (pos8 >= size8 - 1) {
+    char *tmp = new char[2 * size8];
+    memcpy(tmp, buffer8, size8 * sizeof(char));
+    delete [] buffer8;
+    buffer8 = tmp;
+    size8 *= 2;
+  }
+
+  buffer8[pos8++] = (char) c;
+}
+
+void Lexer::record16(UChar c)
+{
+  // enlarge buffer if full
+  if (pos16 >= size16 - 1) {
+    UChar *tmp = new UChar[2 * size16];
+    memcpy(tmp, buffer16, size16 * sizeof(UChar));
+    delete [] buffer16;
+    buffer16 = tmp;
+    size16 *= 2;
+  }
+
+  buffer16[pos16++] = c;
+}
+
+bool Lexer::scanRegExp()
+{
+  pos16 = 0;
+  bool lastWasEscape = false;
+
+  while (1) {
+    if (isLineTerminator() || current == 0)
+      return false;
+    else if (current != '/' || lastWasEscape == true)
+    {
+        record16(current);
+        lastWasEscape =
+            !lastWasEscape && (current == '\\');
+    }
+    else {
+      pattern = UString(buffer16, pos16);
+      pos16 = 0;
+      shift(1);
+      break;
+    }
+    shift(1);
+  }
+
+  while (isIdentLetter(current)) {
+    record16(current);
+    shift(1);
+  }
+  flags = UString(buffer16, pos16);
+
+  return true;
+}
diff --git a/WebCore/src/kdelibs/kjs/lexer.h b/WebCore/src/kdelibs/kjs/lexer.h
new file mode 100644
index 0000000..0acc130
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/lexer.h
@@ -0,0 +1,134 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _KJSLEXER_H_
+#define _KJSLEXER_H_
+
+#include "ustring.h"
+
+namespace KJS {
+
+  class RegExp;
+
+  class Lexer {
+  public:
+    Lexer();
+    ~Lexer();
+    static Lexer *curr();
+
+    void setCode(const UChar *c, unsigned int len);
+    int lex();
+
+    int lineNo() const { return yylineno + 1; }
+
+    bool prevTerminator() const { return terminator; }
+
+    enum State { Start,
+		 Identifier,
+		 InIdentifier,
+		 InSingleLineComment,
+		 InMultiLineComment,
+		 InNum,
+		 InNum0,
+		 InHex,
+		 InOctal,
+		 InDecimal,
+		 InExponentIndicator,
+		 InExponent,
+		 Hex,
+		 Octal,
+		 Number,
+		 String,
+		 Eof,
+		 InString,
+		 InEscapeSequence,
+		 InHexEscape,
+		 InUnicodeEscape,
+		 Other,
+		 Bad };
+    
+    bool scanRegExp();
+    UString pattern, flags;
+
+  private:
+    int yylineno;
+    bool done;
+    char *buffer8;
+    UChar *buffer16;
+    unsigned int size8, size16;
+    unsigned int pos8, pos16;
+    bool terminator;
+    bool restrKeyword;
+    // encountered delimiter like "'" and "}" on last run
+    bool delimited;
+    int stackToken;
+
+    State state;
+    void setDone(State s);
+    unsigned int pos;
+    void shift(unsigned int p);
+    int lookupKeyword(const char *);
+
+    bool isWhiteSpace() const;
+    bool isLineTerminator() const;
+    bool isHexDigit(unsigned short c) const;
+    bool isOctalDigit(unsigned short c) const;
+
+    int matchPunctuator(unsigned short c1, unsigned short c2,
+			unsigned short c3, unsigned short c4);
+    unsigned short singleEscape(unsigned short c) const;
+    unsigned short convertOctal(unsigned short c1, unsigned short c2,
+                                unsigned short c3) const;
+  public:
+    static unsigned char convertHex(unsigned short c1);
+    static unsigned char convertHex(unsigned short c1, unsigned short c2);
+    static UChar convertUnicode(unsigned short c1, unsigned short c2,
+				unsigned short c3, unsigned short c4);
+    static bool isIdentLetter(unsigned short c);
+    static bool isDecimalDigit(unsigned short c);
+
+  private:
+
+    void record8(unsigned short c);
+    void record16(UChar c);
+
+    const UChar *code;
+    unsigned int length;
+    int yycolumn;
+#ifndef KJS_PURE_ECMA
+    int bol;     // begin of line
+#endif
+
+    // current and following unicode characters
+    unsigned short current, next1, next2, next3;
+
+    struct keyword {
+      const char *name;
+      int token;
+    };
+
+    // for future extensions
+    class LexerPrivate;
+    LexerPrivate *priv;
+  };
+
+}; // namespace
+
+#endif
diff --git a/WebCore/src/kdelibs/kjs/lexer.lut.h b/WebCore/src/kdelibs/kjs/lexer.lut.h
new file mode 100644
index 0000000..2ddc9d8
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/lexer.lut.h
@@ -0,0 +1,77 @@
+/* automatically generated from keywords.table. DO NOT EDIT ! */
+
+namespace KJS {
+
+const struct HashEntry2 mainTableEntries[] = {
+   { "instanceof", INSTANCEOF, 0, &mainTableEntries[63] },
+   { "var", VAR, 0, &mainTableEntries[47] },
+   { "case", CASE, 0, &mainTableEntries[41] },
+   { "default", DEFAULT, 0, &mainTableEntries[54] },
+   { "while", WHILE, 0, &mainTableEntries[46] },
+   { 0, 0, 0, 0 },
+   { "do", DO, 0, 0 },
+   { "typeof", TYPEOF, 0, 0 },
+   { "continue", CONTINUE, 0, 0 },
+   { "function", FUNCTION, 0, 0 },
+   { "in", IN, 0, 0 },
+   { "import", RESERVED, 0, 0 },
+   { "delete", DELETE, 0, 0 },
+   { "finally", FINALLY, 0, 0 },
+   { 0, 0, 0, 0 },
+   { "else", ELSE, 0, 0 },
+   { "return", RETURN, 0, 0 },
+   { "debugger", RESERVED, 0, 0 },
+   { "const", RESERVED, 0, &mainTableEntries[48] },
+   { "package", RESERVED, 0, 0 },
+   { "double", RESERVED, 0, &mainTableEntries[53] },
+   { 0, 0, 0, 0 },
+   { "long", RESERVED, 0, 0 },
+   { "catch", CATCH, 0, &mainTableEntries[45] },
+   { "void", VOID, 0, &mainTableEntries[59] },
+   { "break", BREAK, 0, &mainTableEntries[49] },
+   { "byte", RESERVED, 0, &mainTableEntries[62] },
+   { "enum", RESERVED, 0, &mainTableEntries[58] },
+   { 0, 0, 0, 0 },
+   { 0, 0, 0, 0 },
+   { "this", THIS, 0, &mainTableEntries[50] },
+   { "false", FALSETOKEN, 0, &mainTableEntries[44] },
+   { "abstract", RESERVED, 0, &mainTableEntries[56] },
+   { "null", NULLTOKEN, 0, &mainTableEntries[61] },
+   { "with", WITH, 0, 0 },
+   { 0, 0, 0, 0 },
+   { 0, 0, 0, 0 },
+   { 0, 0, 0, 0 },
+   { "true", TRUETOKEN, 0, 0 },
+   { "boolean", RESERVED, 0, 0 },
+   { "for", FOR, 0, 0 },
+   { "new", NEW, 0, &mainTableEntries[42] },
+   { "if", IF, 0, &mainTableEntries[43] },
+   { "switch", SWITCH, 0, &mainTableEntries[55] },
+   { "throw", THROW, 0, &mainTableEntries[52] },
+   { "try", TRY, 0, &mainTableEntries[64] },
+   { "char", RESERVED, 0, 0 },
+   { "class", RESERVED, 0, &mainTableEntries[51] },
+   { "export", RESERVED, 0, 0 },
+   { "extends", RESERVED, 0, &mainTableEntries[57] },
+   { "final", RESERVED, 0, 0 },
+   { "float", RESERVED, 0, 0 },
+   { "goto", RESERVED, 0, 0 },
+   { "implements", RESERVED, 0, 0 },
+   { "int", RESERVED, 0, &mainTableEntries[66] },
+   { "interface", RESERVED, 0, 0 },
+   { "native", RESERVED, 0, 0 },
+   { "private", RESERVED, 0, 0 },
+   { "protected", RESERVED, 0, &mainTableEntries[60] },
+   { "public", RESERVED, 0, 0 },
+   { "short", RESERVED, 0, 0 },
+   { "static", RESERVED, 0, 0 },
+   { "super", RESERVED, 0, 0 },
+   { "synchronized", RESERVED, 0, &mainTableEntries[65] },
+   { "throws", RESERVED, 0, 0 },
+   { "transient", RESERVED, 0, 0 },
+   { "volatile", RESERVED, 0, 0 }
+};
+
+const struct HashTable2 mainTable = { 2, 67, mainTableEntries, 41 };
+
+}; // namespace
diff --git a/WebCore/src/kdelibs/kjs/lookup.cpp b/WebCore/src/kdelibs/kjs/lookup.cpp
new file mode 100644
index 0000000..fcd3055
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/lookup.cpp
@@ -0,0 +1,145 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "lookup.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+using namespace KJS;
+
+int Lookup::find(const struct HashTable *table,
+		 const UChar *c, unsigned int len)
+{
+  // we only know about version 1 so far
+  if (table->type != 1) {
+    fprintf(stderr, "Unknown hash table version.\n");
+    return -1;
+  }
+
+  int h = hash(c, len) % table->hashSize;
+  const HashEntry *e = &table->entries[h];
+
+  // empty bucket ?
+  if (!e->c)
+    return -1;
+
+  do {
+    // compare strings
+#ifdef KJS_SWAPPED_CHAR
+    /* TODO: not exactly as optimized as the other version ... */
+    if (len == e->len) {
+	const UChar *u = (const UChar*)e->c;
+	const UChar *c2 = c;
+	unsigned int i;
+	for (i = 0; i < len; i++, u++, c2++)
+	    if (!(*c2 == UChar(u->low(), u->high()))) // reverse byte order
+		goto next;
+        return e->value;
+    }
+next:
+#else
+    if ((len == e->len) && (memcmp(c, e->c, len * sizeof(UChar)) == 0))
+	return e->value;
+#endif
+    // try next bucket
+    e = e->next;
+  } while (e);
+
+  return -1;
+}
+
+int Lookup::find(const struct HashTable *table, const UString &s)
+{
+  return find(table, s.data(), s.size());
+}
+
+int Lookup::find(const struct HashTable2 *table,
+		 const UChar *c, unsigned int len)
+{
+  if (table->type != 2) {
+    fprintf(stderr, "Unknown hash table version.\n");
+    return -1;
+  }
+
+  char *ascii = new char[len+1];
+  unsigned int i;
+  for(i = 0; i < len; i++, c++) {
+    if (!c->high())
+      ascii[i] = c->low();
+    else
+      break;
+  }
+  ascii[i] = '\0';
+
+  int h = hash(ascii) % table->hashSize;
+  const HashEntry2 *e = &table->entries[h];
+
+  // empty bucket ?
+  if (!e->s) {
+    delete [] ascii;
+    return -1;
+  }
+
+  do {
+    // compare strings
+    if (strcmp(ascii, e->s) == 0) {
+      delete [] ascii;
+      return e->value;
+    }
+    // try next bucket
+    e = e->next;
+  } while (e);
+
+  delete [] ascii;
+  return -1;
+}
+
+int Lookup::find(const struct HashTable2 *table, const UString &s)
+{
+  return find(table, s.data(), s.size());
+}
+
+unsigned int Lookup::hash(const UChar *c, unsigned int len)
+{
+  unsigned int val = 0;
+  // ignoring higher byte
+  for (unsigned int i = 0; i < len; i++, c++)
+    val += c->low();
+
+  return val;
+}
+
+unsigned int Lookup::hash(const UString &key)
+{
+  return hash(key.data(), key.size());
+}
+
+unsigned int Lookup::hash(const char *s)
+{
+  unsigned int val = 0;
+  while (*s)
+    val += *s++;
+
+  return val;
+}
diff --git a/WebCore/src/kdelibs/kjs/lookup.h b/WebCore/src/kdelibs/kjs/lookup.h
new file mode 100644
index 0000000..9301ad6
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/lookup.h
@@ -0,0 +1,80 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _KJSLOOKUP_H_
+#define _KJSLOOKUP_H_
+
+#include "ustring.h"
+
+namespace KJS {
+
+#if 1  // obsolete version 1
+  struct HashEntry {
+    unsigned int len;
+    const void *c; // unicode data
+    int value;
+    const HashEntry *next;
+  };
+
+  struct HashTable {
+    int type;
+    int size;
+    const HashEntry *entries;
+    int hashSize;
+  };
+#endif
+
+  // version 2
+  struct HashEntry2 {
+    const char *s;
+    int value;
+    int attr;
+    const HashEntry2 *next;
+  };
+
+  struct HashTable2 {
+    int type;
+    int size;
+    const HashEntry2 *entries;
+    int hashSize;
+  };
+
+  /**
+   * @short Fast keyword lookup.
+   */
+  class Lookup {
+  public:
+#if 1 // obsolete
+    static int find(const struct HashTable *table, const UString &s);
+    static int find(const struct HashTable *table,
+		    const UChar *c, unsigned int len);
+#endif
+    static int find(const struct HashTable2 *table, const UString &s);
+    static int find(const struct HashTable2 *table,
+		    const UChar *c, unsigned int len);
+    static unsigned int hash(const UChar *c, unsigned int len);
+    static unsigned int hash(const UString &key);
+    static unsigned int hash(const char *s);
+  private:
+    HashTable *table;
+  };
+
+}; // namespace
+
+#endif
diff --git a/WebCore/src/kdelibs/kjs/math_object.cpp b/WebCore/src/kdelibs/kjs/math_object.cpp
new file mode 100644
index 0000000..c9ebb79
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/math_object.cpp
@@ -0,0 +1,163 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <math.h>
+#include <stdlib.h>
+
+#include "kjs.h"
+#include "types.h"
+#include "operations.h"
+#include "math_object.h"
+#include "lookup.h"
+
+#include "math_object.lut.h"
+
+using namespace KJS;
+
+KJSO Math::get(const UString &p) const
+{
+  int token = Lookup::find(&mathTable, p);
+
+  if (token < 0)
+    return Imp::get(p);
+
+  double d;
+  int len = 1;
+  switch (token) {
+  case Math::Euler:
+    d = exp(1.0);
+    break;
+  case Math::Ln2:
+    d = log(2.0);
+    break;
+  case Math::Ln10:
+    d = log(10.0);
+    break;
+  case Math::Log2E:
+    d = 1.0/log(2.0);
+    break;
+  case Math::Log10E:
+    d = 1.0/log(10.0);
+    break;
+  case Math::Pi:
+    d = 2.0 * asin(1.0);
+    break;
+  case Math::Sqrt1_2:
+    d = sqrt(0.5);
+    break;
+  case Math::Sqrt2:
+    d = sqrt(2.0);
+    break;
+  default:
+    if (token == Math::Min || token == Math::Max || token == Math::Pow)
+      len = 2;
+    return Function(new MathFunc(token, len));
+  };
+
+  return Number(d);
+}
+
+bool Math::hasProperty(const UString &p, bool recursive) const
+{
+  return (Lookup::find(&mathTable, p) >= 0 ||
+	  (recursive && Imp::hasProperty(p, recursive)));
+}
+
+Completion MathFunc::execute(const List &args)
+{
+  KJSO v = args[0];
+  Number n = v.toNumber();
+  double arg = n.value();
+
+  KJSO v2 = args[1];
+  Number n2 = v2.toNumber();
+  double arg2 = n2.value();
+  double result;
+
+  switch (id) {
+  case Math::Abs:
+    result = ( arg < 0 ) ? (-arg) : arg;
+    break;
+  case Math::ACos:
+    result = ::acos(arg);
+    break;
+  case Math::ASin:
+    result = ::asin(arg);
+    break;
+  case Math::ATan:
+    result = ::atan(arg);
+    break;
+  case Math::ATan2:
+    result = ::atan2(arg, arg2);
+    break;
+  case Math::Ceil:
+    result = ::ceil(arg);
+    break;
+  case Math::Cos:
+    result = ::cos(arg);
+    break;
+  case Math::Exp:
+    result = ::exp(arg);
+    break;
+  case Math::Floor:
+    result = ::floor(arg);
+    break;
+  case Math::Log:
+    result = ::log(arg);
+    break;
+  case Math::Max:
+    result = ( arg > arg2 ) ? arg : arg2;
+    break;
+  case Math::Min:
+    result = ( arg < arg2 ) ? arg : arg2;
+    break;
+  case Math::Pow:
+    result = ::pow(arg, arg2);
+    break;
+  case Math::Random:
+    result = ::rand();
+    result = result / RAND_MAX;
+    break;
+  case Math::Round:
+    if (isNaN(arg))
+      result = arg;
+    if (isInf(arg) || isInf(-arg))
+      result = arg;
+    else if (arg == -0.5)
+      result = 0;
+    else
+      result = (double)(arg >= 0.0 ? int(arg + 0.5) : int(arg - 0.5));
+    break;
+  case Math::Sin:
+    result = ::sin(arg);
+    break;
+  case Math::Sqrt:
+    result = ::sqrt(arg);
+    break;
+  case Math::Tan:
+    result = ::tan(arg);
+    break;
+
+  default:
+    result = 0.0;
+    assert(0);
+  }
+
+  return Completion(ReturnValue, Number(result));
+}
diff --git a/WebCore/src/kdelibs/kjs/math_object.h b/WebCore/src/kdelibs/kjs/math_object.h
new file mode 100644
index 0000000..a04cfc1
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/math_object.h
@@ -0,0 +1,48 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _MATH_OBJECT_H_
+#define _MATH_OBJECT_H_
+
+#include "object.h"
+#include "function.h"
+
+namespace KJS {
+
+  class Math : public ObjectImp {
+  public:
+    Math() : ObjectImp(BooleanClass) { }
+    virtual KJSO get(const UString &p) const;
+    virtual bool hasProperty(const UString &p, bool recursive = true) const;
+    enum { Euler, Ln2, Ln10, Log2E, Log10E, Pi, Sqrt1_2, Sqrt2,
+	   Abs, ACos, ASin, ATan, ATan2, Ceil, Cos, Pow,
+	   Exp, Floor, Log, Max, Min, Random, Round, Sin, Sqrt, Tan };
+  };
+
+  class MathFunc : public InternalFunctionImp {
+  public:
+    MathFunc(int i, int l) : InternalFunctionImp(l), id(i) { }
+    Completion execute(const List &);
+  private:
+    int id;
+  };
+
+}; // namespace
+
+#endif
diff --git a/WebCore/src/kdelibs/kjs/math_object.lut.h b/WebCore/src/kdelibs/kjs/math_object.lut.h
new file mode 100644
index 0000000..e422d18
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/math_object.lut.h
@@ -0,0 +1,42 @@
+/* automatically generated from math.table. DO NOT EDIT ! */
+
+namespace KJS {
+
+const struct HashEntry2 mathTableEntries[] = {
+   { "atan", Math::ATan, DontEnum|ReadOnly, &mathTableEntries[25] },
+   { 0, 0, 0, 0 },
+   { "SQRT2", Math::Sqrt2, DontEnum|ReadOnly, &mathTableEntries[23] },
+   { 0, 0, 0, 0 },
+   { 0, 0, 0, 0 },
+   { 0, 0, 0, 0 },
+   { "E", Math::Euler, DontEnum|ReadOnly, &mathTableEntries[21] },
+   { "asin", Math::ASin, DontEnum|ReadOnly, &mathTableEntries[26] },
+   { "atan2", Math::ATan2, DontEnum|ReadOnly, &mathTableEntries[31] },
+   { "LOG2E", Math::Log2E, DontEnum|ReadOnly, &mathTableEntries[27] },
+   { "cos", Math::Cos, DontEnum|ReadOnly, 0 },
+   { "max", Math::Max, DontEnum|ReadOnly, &mathTableEntries[28] },
+   { 0, 0, 0, 0 },
+   { 0, 0, 0, 0 },
+   { "LOG10E", Math::Log10E, DontEnum|ReadOnly, &mathTableEntries[24] },
+   { "LN2", Math::Ln2, DontEnum|ReadOnly, &mathTableEntries[30] },
+   { "abs", Math::Abs, DontEnum|ReadOnly, 0 },
+   { "sqrt", Math::Sqrt, DontEnum|ReadOnly, 0 },
+   { "exp", Math::Exp, DontEnum|ReadOnly, 0 },
+   { 0, 0, 0, 0 },
+   { "LN10", Math::Ln10, DontEnum|ReadOnly, &mathTableEntries[22] },
+   { "PI", Math::Pi, DontEnum|ReadOnly, &mathTableEntries[29] },
+   { "SQRT1_2", Math::Sqrt1_2, DontEnum|ReadOnly, 0 },
+   { "acos", Math::ACos, DontEnum|ReadOnly, 0 },
+   { "ceil", Math::Ceil, DontEnum|ReadOnly, 0 },
+   { "floor", Math::Floor, DontEnum|ReadOnly, 0 },
+   { "log", Math::Log, DontEnum|ReadOnly, 0 },
+   { "min", Math::Min, DontEnum|ReadOnly, 0 },
+   { "random", Math::Random, DontEnum|ReadOnly, 0 },
+   { "round", Math::Round, DontEnum|ReadOnly, 0 },
+   { "sin", Math::Sin, DontEnum|ReadOnly, 0 },
+   { "tan", Math::Tan, DontEnum|ReadOnly, 0 }
+};
+
+const struct HashTable2 mathTable = { 2, 32, mathTableEntries, 21 };
+
+}; // namespace
diff --git a/WebCore/src/kdelibs/kjs/nodes.cpp b/WebCore/src/kdelibs/kjs/nodes.cpp
new file mode 100644
index 0000000..ab20d3b
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/nodes.cpp
@@ -0,0 +1,1487 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2001 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#include "nodes.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <math.h>
+
+#include "kjs.h"
+#include "ustring.h"
+#include "lexer.h"
+#include "types.h"
+#include "internal.h"
+#include "operations.h"
+#include "regexp_object.h"
+#include "debugger.h"
+
+using namespace KJS;
+
+#ifdef KJS_DEBUGGER
+#define KJS_BREAKPOINT if (!hitStatement()) return Completion(Normal);
+#define KJS_ABORTPOINT if (abortStatement()) return Completion(Normal);
+#else
+#define KJS_BREAKPOINT
+#define KJS_ABORTPOINT
+#endif
+
+int   Node::nodeCount = 0;
+Node* Node::first = 0;
+
+Node::Node()
+{
+  assert(Lexer::curr());
+  line = Lexer::curr()->lineNo();
+  nodeCount++;
+  //  cout << "Node()" << endl;
+
+  // create a list of allocated objects. Makes
+  // deleting (even after a parse error) quite easy
+  next = first;
+  prev = 0L;
+  if (first)
+    first->prev = this;
+  first = this;
+}
+
+Node::~Node()
+{
+  //  cout << "~Node()" << endl;
+  if (next)
+    next->prev = prev;
+  if (prev)
+    prev->next = next;
+  nodeCount--;
+}
+
+void Node::deleteAllNodes()
+{
+  Node *tmp, *n = first;
+
+  while ((tmp = n)) {
+    n = n->next;
+    delete tmp;
+  }
+  first = 0L;
+  //  assert(nodeCount == 0);
+}
+
+KJSO Node::throwError(ErrorType e, const char *msg)
+{
+  return Error::create(e, msg, lineNo());
+}
+
+#ifdef KJS_DEBUGGER
+void StatementNode::setLoc(int line0, int line1)
+{
+    l0 = line0;
+    l1 = line1;
+    sid = KJScriptImp::current()->sourceId();
+}
+
+bool StatementNode::hitStatement()
+{
+  if (KJScriptImp::current()->debugger())
+    return KJScriptImp::current()->debugger()->hit(firstLine(), breakPoint);
+  else
+    return true;
+}
+
+// return true if the debugger wants us to stop at this point
+bool StatementNode::abortStatement()
+{
+  if (KJScriptImp::current()->debugger() &&
+      KJScriptImp::current()->debugger()->mode() == Debugger::Stop)
+      return true;
+
+  return false;
+}
+
+bool Node::setBreakpoint(Node *firstNode, int id, int line, bool set)
+{
+  while (firstNode) {
+    if (firstNode->setBreakpoint(id, line, set) && line >= 0) // line<0 for all
+      return true;
+    firstNode = firstNode->next;
+  }
+  return false;
+}
+
+/**
+ * Try to set or delete a breakpoint depending on the value of set.
+ * The call will return true if successful, i.e. if line is inside
+ * of the statement's range. Additionally, a breakpoint had to
+ * be set already if you tried to delete with set=false.
+ */
+bool StatementNode::setBreakpoint(int id, int line, bool set)
+{
+  // in our source unit and line range ?
+  if (id != sid || ((line < l0 || line > l1) && line >= 0))
+    return false;
+
+  if (!set && !breakPoint)
+    return false;
+
+  breakPoint = set;
+  return true;
+}
+#endif
+
+KJSO NullNode::evaluate()
+{
+  return Null();
+}
+
+KJSO BooleanNode::evaluate()
+{
+  return Boolean(value);
+}
+
+KJSO NumberNode::evaluate()
+{
+  return Number(value);
+}
+
+KJSO StringNode::evaluate()
+{
+  return String(value);
+}
+
+KJSO RegExpNode::evaluate()
+{
+  List list;
+  String p(pattern);
+  String f(flags);
+  list.append(p);
+  list.append(f);
+
+  // very ugly
+  KJSO r = Global::current().get("RegExp");
+  RegExpObject *r2 = (RegExpObject*)r.imp();
+  return r2->construct(list);
+}
+
+// ECMA 11.1.1
+KJSO ThisNode::evaluate()
+{
+  return Context::current()->thisValue();
+}
+
+// ECMA 11.1.2 & 10.1.4
+KJSO ResolveNode::evaluate()
+{
+  assert(Context::current());
+  const List *chain = Context::current()->pScopeChain();
+  assert(chain);
+  ListIterator scope = chain->begin();
+
+  while (scope != chain->end()) {
+    if (scope->hasProperty(ident)) {
+//        cout << "Resolve: found '" << ident.ascii() << "'"
+// 	    << " type " << scope->get(ident).imp()->typeInfo()->name << endl;
+      return Reference(*scope, ident);
+    }
+    scope++;
+  }
+
+  // identifier not found
+//  cout << "Resolve: didn't find '" << ident.ascii() << "'" << endl;
+  return Reference(Null(), ident);
+}
+
+// ECMA 11.1.4
+KJSO ArrayNode::evaluate()
+{
+  KJSO array;
+  int length;
+  int elisionLen = elision ? elision->evaluate().toInt32() : 0;
+
+  if (element) {
+    array = element->evaluate();
+    length = opt ? array.get("length").toInt32() : 0;
+  } else {
+    array = Object::create(ArrayClass);
+    length = 0;
+  }
+
+  if (opt)
+    array.put("length", Number(elisionLen + length), DontEnum | DontDelete);
+
+  return array;
+}
+
+// ECMA 11.1.4
+KJSO ElementNode::evaluate()
+{
+  KJSO array, val;
+  int length = 0;
+  int elisionLen = elision ? elision->evaluate().toInt32() : 0;
+
+  if (list) {
+    array = list->evaluate();
+    val = node->evaluate().getValue();
+    length = array.get("length").toInt32();
+  } else {
+    array = Object::create(ArrayClass);
+    val = node->evaluate().getValue();
+  }
+
+  array.putArrayElement(UString::from(elisionLen + length), val);
+
+  return array;
+}
+
+// ECMA 11.1.4
+KJSO ElisionNode::evaluate()
+{
+  if (elision)
+    return Number(elision->evaluate().toNumber().value() + 1);
+  else
+    return Number(1);
+}
+
+// ECMA 11.1.5
+KJSO ObjectLiteralNode::evaluate()
+{
+  if (list)
+    return list->evaluate();
+
+  return Object::create(ObjectClass);
+}
+
+// ECMA 11.1.5
+KJSO PropertyValueNode::evaluate()
+{
+  KJSO obj;
+  if (list)
+    obj = list->evaluate();
+  else
+    obj = Object::create(ObjectClass);
+  KJSO n = name->evaluate();
+  KJSO a = assign->evaluate();
+  KJSO v = a.getValue();
+
+  obj.put(n.toString().value(), v);
+
+  return obj;
+}
+
+// ECMA 11.1.5
+KJSO PropertyNode::evaluate()
+{
+  KJSO s;
+
+  if (str.isNull()) {
+    s = String(UString::from(numeric));
+  } else
+    s = String(str);
+
+  return s;
+}
+
+// ECMA 11.1.6
+KJSO GroupNode::evaluate()
+{
+  return group->evaluate();
+}
+
+// ECMA 11.2.1a
+KJSO AccessorNode1::evaluate()
+{
+  KJSO e1 = expr1->evaluate();
+  KJSO v1 = e1.getValue();
+  KJSO e2 = expr2->evaluate();
+  KJSO v2 = e2.getValue();
+  Object o = v1.toObject();
+  String s = v2.toString();
+  return Reference(o, s.value());
+}
+
+// ECMA 11.2.1b
+KJSO AccessorNode2::evaluate()
+{
+  KJSO e = expr->evaluate();
+  KJSO v = e.getValue();
+  KJSO o = v.toObject();
+  return Reference(o, ident);
+}
+
+// ECMA 11.2.2
+KJSO NewExprNode::evaluate()
+{
+  KJSO e = expr->evaluate();
+  KJSO v = e.getValue();
+
+  List *argList = args ? args->evaluateList() : 0;
+
+  if (!v.isObject()) {
+    delete argList;
+    return throwError(TypeError, "Expression is no object. Cannot be new'ed");
+  }
+
+  Constructor constr = Constructor::dynamicCast(v);
+  if (constr.isNull()) {
+    delete argList;
+    return throwError(TypeError, "Expression is no constructor.");
+  }
+
+  if (!argList)
+    argList = new List;
+
+  KJSO res = constr.construct(*argList);
+
+  delete argList;
+
+  return res;
+}
+
+// ECMA 11.2.3
+KJSO FunctionCallNode::evaluate()
+{
+  KJSO e = expr->evaluate();
+
+  List *argList = args->evaluateList();
+
+  KJSO v = e.getValue();
+
+  if (!v.isObject()) {
+#ifndef NDEBUG
+    printInfo("Failed function call attempt on", e);
+#endif
+    delete argList;
+    return throwError(TypeError, "Expression is no object. Cannot be called.");
+  }
+
+  if (!v.implementsCall()) {
+#ifndef NDEBUG
+    printInfo("Failed function call attempt on", e);
+#endif
+    delete argList;
+    return throwError(TypeError, "Expression does not allow calls.");
+  }
+
+  KJSO o;
+  if (e.isA(ReferenceType))
+    o = e.getBase();
+  else
+    o = Null();
+
+  if (o.isA(ActivationType))
+    o = Null();
+
+#ifdef KJS_DEBUGGER
+  steppingInto(true);
+#endif
+
+  KJSO result = v.executeCall(o, argList);
+
+#ifdef KJS_DEBUGGER
+  steppingInto(false);
+#endif
+
+  delete argList;
+
+  return result;
+}
+
+#ifdef KJS_DEBUGGER
+void FunctionCallNode::steppingInto(bool in)
+{
+  Debugger *dbg = KJScriptImp::current()->debugger();
+  if (!dbg)
+    return;
+  if (in) {
+    // before entering function. Don't step inside if 'Next' is chosen.
+    previousMode = dbg->mode();
+    if (previousMode == Debugger::Next)
+      dbg->setMode(Debugger::Continue);
+  } else {
+    // restore mode after leaving function
+    dbg->setMode(previousMode);
+  }
+}
+#endif
+
+KJSO ArgumentsNode::evaluate()
+{
+  assert(0);
+  return KJSO(); // dummy, see evaluateList()
+}
+
+// ECMA 11.2.4
+List* ArgumentsNode::evaluateList()
+{
+  if (!list)
+    return new List();
+
+  return list->evaluateList();
+}
+
+KJSO ArgumentListNode::evaluate()
+{
+  assert(0);
+  return KJSO(); // dummy, see evaluateList()
+}
+
+// ECMA 11.2.4
+List* ArgumentListNode::evaluateList()
+{
+  KJSO e = expr->evaluate();
+  KJSO v = e.getValue();
+
+  if (!list) {
+    List *l = new List();
+    l->append(v);
+    return l;
+  }
+
+  List *l = list->evaluateList();
+  l->append(v);
+
+  return l;
+}
+
+// ECMA 11.8
+KJSO RelationalNode::evaluate()
+{
+  KJSO e1 = expr1->evaluate();
+  KJSO v1 = e1.getValue();
+  KJSO e2 = expr2->evaluate();
+  KJSO v2 = e2.getValue();
+
+  bool b;
+  if (oper == OpLess || oper == OpGreaterEq) {
+    int r = relation(v1, v2);
+    if (r < 0)
+      b = false;
+    else
+      b = (oper == OpLess) ? (r == 1) : (r == 0);
+  } else if (oper == OpGreater || oper == OpLessEq) {
+    int r = relation(v2, v1);
+    if (r < 0)
+      b = false;
+    else
+      b = (oper == OpGreater) ? (r == 1) : (r == 0);
+  } else if (oper == OpIn) {
+      /* Is all of this OK for host objects? */
+      if (!v2.isObject())
+          return throwError( TypeError,
+                             "Shift expression not an object into IN expression." );
+      b = v2.hasProperty(v1.toString().value());
+  } else {
+    /* TODO: should apply to Function _objects_ only */
+    if (!v2.derivedFrom("Function"))
+      return throwError(TypeError,
+			"Called instanceof operator on non-function object." );
+    return hasInstance(v2, v1);	/* TODO: make object member function */
+  }
+
+  return Boolean(b);
+}
+
+// ECMA 11.9
+KJSO EqualNode::evaluate()
+{
+  KJSO e1 = expr1->evaluate();
+  KJSO e2 = expr2->evaluate();
+  KJSO v1 = e1.getValue();
+  KJSO v2 = e2.getValue();
+
+  bool result;
+  if (oper == OpEqEq || oper == OpNotEq) {
+    // == and !=
+    bool eq = equal(v1, v2);
+    result = oper == OpEqEq ? eq : !eq;
+  } else {
+    // === and !==
+    bool eq = strictEqual(v1, v2);
+    result = oper == OpStrEq ? eq : !eq;
+  }
+  return Boolean(result);
+}
+
+// ECMA 11.10
+KJSO BitOperNode::evaluate()
+{
+  KJSO e1 = expr1->evaluate();
+  KJSO v1 = e1.getValue();
+  KJSO e2 = expr2->evaluate();
+  KJSO v2 = e2.getValue();
+  int i1 = v1.toInt32();
+  int i2 = v2.toInt32();
+  int result;
+  if (oper == OpBitAnd)
+    result = i1 & i2;
+  else if (oper == OpBitXOr)
+    result = i1 ^ i2;
+  else
+    result = i1 | i2;
+
+  return Number(result);
+}
+
+// ECMA 11.11
+KJSO BinaryLogicalNode::evaluate()
+{
+  KJSO e1 = expr1->evaluate();
+  KJSO v1 = e1.getValue();
+  Boolean b1 = v1.toBoolean();
+  if ((!b1.value() && oper == OpAnd) || (b1.value() && oper == OpOr))
+    return v1;
+
+  KJSO e2 = expr2->evaluate();
+  KJSO v2 = e2.getValue();
+
+  return v2;
+}
+
+// ECMA 11.12
+KJSO ConditionalNode::evaluate()
+{
+  KJSO e = logical->evaluate();
+  KJSO v = e.getValue();
+  Boolean b = v.toBoolean();
+
+  if (b.value())
+    e = expr1->evaluate();
+  else
+    e = expr2->evaluate();
+
+  return e.getValue();
+}
+
+// ECMA 11.13
+KJSO AssignNode::evaluate()
+{
+  KJSO l, e, v;
+  ErrorType err;
+  if (oper == OpEqual) {
+    l = left->evaluate();
+    e = expr->evaluate();
+    v = e.getValue();
+  } else {
+    l = left->evaluate();
+    KJSO v1 = l.getValue();
+    e = expr->evaluate();
+    KJSO v2 = e.getValue();
+    int i1 = v1.toInt32();
+    int i2 = v2.toInt32();
+    switch (oper) {
+    case OpMultEq:
+      v = mult(v1, v2, '*');
+      break;
+    case OpDivEq:
+      v = mult(v1, v2, '/');
+      break;
+    case OpPlusEq:
+      v = add(v1, v2, '+');
+      break;
+    case OpMinusEq:
+      v = add(v1, v2, '-');
+      break;
+    case OpLShift:
+      v = Number(i1 <<= i2);
+      break;
+    case OpRShift:
+      v = Number(i1 >>= i2);
+      break;
+    case OpURShift:
+      i1 = v1.toUInt32();
+      v = Number(i1 >>= i2);
+      break;
+    case OpAndEq:
+      v = Number(i1 &= i2);
+      break;
+    case OpXOrEq:
+      v = Number(i1 ^= i2);
+      break;
+    case OpOrEq:
+      v = Number(i1 |= i2);
+      break;
+    case OpModEq:
+      v = Number(i1 %= i2);
+      break;
+    default:
+      v = Undefined();
+    }
+    err = l.putValue(v);
+  };
+
+  err = l.putValue(v);
+  if (err == NoError)
+    return v;
+  else
+    return throwError(err, "Invalid reference.");
+}
+
+// ECMA 11.3
+KJSO PostfixNode::evaluate()
+{
+  KJSO e = expr->evaluate();
+  KJSO v = e.getValue();
+  Number n = v.toNumber();
+
+  double newValue = (oper == OpPlusPlus) ? n.value() + 1 : n.value() - 1;
+  KJSO n2 = Number(newValue);
+
+  e.putValue(n2);
+
+  return n;
+}
+
+// ECMA 11.4.1
+KJSO DeleteNode::evaluate()
+{
+  KJSO e = expr->evaluate();
+  if (!e.isA(ReferenceType))
+    return Boolean(true);
+  KJSO b = e.getBase();
+  UString n = e.getPropertyName();
+  bool ret = b.deleteProperty(n);
+
+  return Boolean(ret);
+}
+
+// ECMA 11.4.2
+KJSO VoidNode::evaluate()
+{
+  KJSO dummy1 = expr->evaluate();
+  KJSO dummy2 = dummy1.getValue();
+
+  return Undefined();
+}
+
+// ECMA 11.4.3
+KJSO TypeOfNode::evaluate()
+{
+  const char *s = 0L;
+  KJSO e = expr->evaluate();
+  if (e.isA(ReferenceType)) {
+    KJSO b = e.getBase();
+    if (b.isA(NullType))
+      return String("undefined");
+  }
+  KJSO v = e.getValue();
+  switch (v.type())
+    {
+    case UndefinedType:
+      s = "undefined";
+      break;
+    case NullType:
+      s = "object";
+      break;
+    case BooleanType:
+      s = "boolean";
+      break;
+    case NumberType:
+      s = "number";
+      break;
+    case StringType:
+      s = "string";
+      break;
+    default:
+      if (v.implementsCall())
+	s = "function";
+      else
+	s = "object";
+      break;
+    }
+
+  return String(s);
+}
+
+// ECMA 11.4.4 and 11.4.5
+KJSO PrefixNode::evaluate()
+{
+  KJSO e = expr->evaluate();
+  KJSO v = e.getValue();
+  Number n = v.toNumber();
+
+  double newValue = (oper == OpPlusPlus) ? n.value() + 1 : n.value() - 1;
+  KJSO n2 = Number(newValue);
+
+  e.putValue(n2);
+
+  return n2;
+}
+
+// ECMA 11.4.6
+KJSO UnaryPlusNode::evaluate()
+{
+  KJSO e = expr->evaluate();
+  KJSO v = e.getValue();
+
+  return v.toNumber();
+}
+
+// ECMA 11.4.7
+KJSO NegateNode::evaluate()
+{
+  KJSO e = expr->evaluate();
+  KJSO v = e.getValue();
+  Number n = v.toNumber();
+
+  double d = -n.value();
+
+  return Number(d);
+}
+
+// ECMA 11.4.8
+KJSO BitwiseNotNode::evaluate()
+{
+  KJSO e = expr->evaluate();
+  KJSO v = e.getValue();
+  int i32 = v.toInt32();
+
+  return Number(~i32);
+}
+
+// ECMA 11.4.9
+KJSO LogicalNotNode::evaluate()
+{
+  KJSO e = expr->evaluate();
+  KJSO v = e.getValue();
+  Boolean b = v.toBoolean();
+
+  return Boolean(!b.value());
+}
+
+// ECMA 11.5
+KJSO MultNode::evaluate()
+{
+  KJSO t1 = term1->evaluate();
+  KJSO v1 = t1.getValue();
+
+  KJSO t2 = term2->evaluate();
+  KJSO v2 = t2.getValue();
+
+  return mult(v1, v2, oper);
+}
+
+// ECMA 11.7
+KJSO ShiftNode::evaluate()
+{
+  KJSO t1 = term1->evaluate();
+  KJSO v1 = t1.getValue();
+  KJSO t2 = term2->evaluate();
+  KJSO v2 = t2.getValue();
+  unsigned int i2 = v2.toUInt32();
+  i2 &= 0x1f;
+
+  long result;
+  switch (oper) {
+  case OpLShift:
+    result = v1.toInt32() << i2;
+    break;
+  case OpRShift:
+    result = v1.toInt32() >> i2;
+    break;
+  case OpURShift:
+    result = v1.toUInt32() >> i2;
+    break;
+  default:
+    assert(!"ShiftNode: unhandled switch case");
+    result = 0L;
+  }
+
+  return Number(static_cast<double>(result));
+}
+
+// ECMA 11.6
+KJSO AddNode::evaluate()
+{
+  KJSO t1 = term1->evaluate();
+  KJSO v1 = t1.getValue();
+
+  KJSO t2 = term2->evaluate();
+  KJSO v2 = t2.getValue();
+
+  return add(v1, v2, oper);
+}
+
+// ECMA 11.14
+KJSO CommaNode::evaluate()
+{
+  KJSO e = expr1->evaluate();
+  KJSO dummy = e.getValue(); // ignore return value
+  e = expr2->evaluate();
+
+  return e.getValue();
+}
+
+// ECMA 12.1
+Completion BlockNode::execute()
+{
+  if (!statlist)
+    return Completion(Normal);
+
+  return statlist->execute();
+}
+
+// ECMA 12.1
+Completion StatListNode::execute()
+{
+  if (!list) {
+    Completion c = statement->execute();
+    KJS_ABORTPOINT
+    if (KJScriptImp::hadException()) {
+      KJSO ex = KJScriptImp::exception();
+      KJScriptImp::clearException();
+      return Completion(Throw, ex);
+    } else
+      return c;
+  }
+
+  Completion l = list->execute();
+  KJS_ABORTPOINT
+  if (l.complType() != Normal)
+    return l;
+  Completion e = statement->execute();
+  KJS_ABORTPOINT;
+  if (KJScriptImp::hadException()) {
+    KJSO ex = KJScriptImp::exception();
+    KJScriptImp::clearException();
+    return Completion(Throw, ex);
+  }
+
+  KJSO v = e.isValueCompletion() ? e.value() : l.value();
+
+  return Completion(e.complType(), v, e.target() );
+}
+
+// ECMA 12.2
+Completion VarStatementNode::execute()
+{
+  KJS_BREAKPOINT;
+
+  (void) list->evaluate(); // returns 0L
+
+  return Completion(Normal);
+}
+
+// ECMA 12.2
+KJSO VarDeclNode::evaluate()
+{
+  KJSO variable = Context::current()->variableObject();
+
+  KJSO val, tmp;
+  if (init) {
+      tmp = init->evaluate();
+      val = tmp.getValue();
+  } else {
+      if ( variable.hasProperty( ident ) ) // already declared ?
+          return KJSO();
+      val = Undefined();
+  }
+  variable.put(ident, val, DontDelete);
+
+  // spec wants to return ident. But what for ? Will be ignored above.
+  return KJSO();
+}
+
+// ECMA 12.2
+KJSO VarDeclListNode::evaluate()
+{
+  if (list)
+    (void) list->evaluate();
+
+  (void) var->evaluate();
+
+  return KJSO();
+}
+
+// ECMA 12.2
+KJSO AssignExprNode::evaluate()
+{
+  return expr->evaluate();
+}
+
+// ECMA 12.3
+Completion EmptyStatementNode::execute()
+{
+  return Completion(Normal);
+}
+
+// ECMA 12.6.3
+Completion ForNode::execute()
+{
+  KJSO e, v, cval;
+  Boolean b;
+
+  if (expr1) {
+    e = expr1->evaluate();
+    v = e.getValue();
+  }
+  while (1) {
+    if (expr2) {
+      e = expr2->evaluate();
+      v = e.getValue();
+      b = v.toBoolean();
+      if (b.value() == false)
+	return Completion(Normal, cval);
+    }
+    // bail out on error
+    if (KJScriptImp::hadException())
+      return Completion(Throw, KJScriptImp::exception());
+
+    Completion c = stat->execute();
+    if (c.isValueCompletion())
+      cval = c.value();
+    if (!((c.complType() == Continue) && ls.contains(c.target()))) {
+      if ((c.complType() == Break) && ls.contains(c.target()))
+        return Completion(Normal, cval);
+      if (c.complType() != Normal)
+      return c;
+    }
+    if (expr3) {
+      e = expr3->evaluate();
+      v = e.getValue();
+    }
+  }
+}
+
+// ECMA 12.6.4
+Completion ForInNode::execute()
+{
+  KJSO e, v, retval;
+  Completion c;
+  VarDeclNode *vd = 0;
+  const PropList *lst, *curr;
+
+  // This should be done in the constructor
+  if (!lexpr) { // for( var foo = bar in baz )
+    vd = new VarDeclNode(&ident, init);
+    vd->evaluate();
+
+    lexpr = new ResolveNode(&ident);
+  }
+
+  e = expr->evaluate();
+  v = e.getValue().toObject();
+  curr = lst = v.imp()->propList();
+
+  while (curr) {
+    if (!v.hasProperty(curr->name)) {
+      curr = curr->next;
+      continue;
+    }
+
+    e = lexpr->evaluate();
+    e.putValue(String(curr->name));
+
+    c = stat->execute();
+    if (c.isValueCompletion())
+      retval = c.value();
+
+    if (!((c.complType() == Continue) && ls.contains(c.target()))) {
+      if ((c.complType() == Break) && ls.contains(c.target()))
+        break;
+      if (c.complType() != Normal) {
+        delete lst;
+        return c;
+      }
+    }
+
+    curr = curr->next;
+  }
+
+  delete lst;
+  return Completion(Normal, retval);
+}
+
+// ECMA 12.4
+Completion ExprStatementNode::execute()
+{
+  KJS_BREAKPOINT;
+
+  KJSO e = expr->evaluate();
+  KJSO v = e.getValue();
+
+  return Completion(Normal, v);
+}
+
+// ECMA 12.5
+Completion IfNode::execute()
+{
+  KJS_BREAKPOINT;
+
+  KJSO e = expr->evaluate();
+  KJSO v = e.getValue();
+  Boolean b = v.toBoolean();
+
+  // if ... then
+  if (b.value())
+    return statement1->execute();
+
+  // no else
+  if (!statement2)
+    return Completion(Normal);
+
+  // else
+  return statement2->execute();
+}
+
+// ECMA 12.6.1
+Completion DoWhileNode::execute()
+{
+  KJS_BREAKPOINT;
+
+  KJSO be, bv;
+  Completion c;
+  KJSO value;
+
+  do {
+    // bail out on error
+    if (KJScriptImp::hadException())
+      return Completion(Throw, KJScriptImp::exception());
+
+    c = statement->execute();
+    if (!((c.complType() == Continue) && ls.contains(c.target()))) {
+      if ((c.complType() == Break) && ls.contains(c.target()))
+        return Completion(Normal, value);
+      if (c.complType() != Normal)
+        return c;
+    }
+    be = expr->evaluate();
+    bv = be.getValue();
+  } while (bv.toBoolean().value());
+
+  return Completion(Normal, value);
+}
+
+// ECMA 12.6.2
+Completion WhileNode::execute()
+{
+  KJS_BREAKPOINT;
+
+  KJSO be, bv;
+  Completion c;
+  Boolean b(false);
+  KJSO value;
+
+  while (1) {
+    be = expr->evaluate();
+    bv = be.getValue();
+    b = bv.toBoolean();
+
+    // bail out on error
+    if (KJScriptImp::hadException())
+      return Completion(Throw, KJScriptImp::exception());
+
+    if (!b.value())
+      return Completion(Normal, value);
+
+    c = statement->execute();
+    if (c.isValueCompletion())
+      value = c.value();
+
+    if ((c.complType() == Continue) && ls.contains(c.target()))
+      continue;
+    if ((c.complType() == Break) && ls.contains(c.target()))
+      return Completion(Normal, value);
+    if (c.complType() != Normal)
+      return c;
+  }
+}
+
+// ECMA 12.7
+Completion ContinueNode::execute()
+{
+  KJS_BREAKPOINT;
+
+  KJSO dummy;
+  return Context::current()->seenLabels()->contains(ident) ?
+    Completion(Continue, dummy, ident) :
+    Completion(Throw,
+	       throwError(SyntaxError, "Label not found in containing block"));
+}
+
+// ECMA 12.8
+Completion BreakNode::execute()
+{
+  KJS_BREAKPOINT;
+
+  KJSO dummy;
+  return Context::current()->seenLabels()->contains(ident) ?
+    Completion(Break, dummy, ident) :
+    Completion(Throw,
+	       throwError(SyntaxError, "Label not found in containing block"));
+}
+
+// ECMA 12.9
+Completion ReturnNode::execute()
+{
+  KJS_BREAKPOINT;
+
+  if (!value)
+    return Completion(ReturnValue, Undefined());
+
+  KJSO e = value->evaluate();
+  KJSO v = e.getValue();
+
+  return Completion(ReturnValue, v);
+}
+
+// ECMA 12.10
+Completion WithNode::execute()
+{
+  KJS_BREAKPOINT;
+
+  KJSO e = expr->evaluate();
+  KJSO v = e.getValue();
+  Object o = v.toObject();
+  Context::current()->pushScope(o);
+  Completion res = stat->execute();
+  Context::current()->popScope();
+
+  return res;
+}
+
+// ECMA 12.11
+ClauseListNode* ClauseListNode::append(CaseClauseNode *c)
+{
+  ClauseListNode *l = this;
+  while (l->nx)
+    l = l->nx;
+  l->nx = new ClauseListNode(c);
+
+  return this;
+}
+
+// ECMA 12.11
+Completion SwitchNode::execute()
+{
+  KJS_BREAKPOINT;
+
+  KJSO e = expr->evaluate();
+  KJSO v = e.getValue();
+  Completion res = block->evalBlock(v);
+
+  if ((res.complType() == Break) && ls.contains(res.target()))
+    return Completion(Normal, res.value());
+  else
+    return res;
+}
+
+// ECMA 12.11
+Completion CaseBlockNode::evalBlock(const KJSO& input)
+{
+  KJSO v;
+  Completion res;
+  ClauseListNode *a = list1, *b = list2;
+  CaseClauseNode *clause;
+
+  if (a) {
+    while (a) {
+      clause = a->clause();
+      a = a->next();
+      v = clause->evaluate();
+      if (strictEqual(input, v)) {
+	res = clause->evalStatements();
+	if (res.complType() != Normal)
+	  return res;
+	while (a) {
+	  res = a->clause()->evalStatements();
+	  if (res.complType() != Normal)
+	    return res;
+	  a = a->next();
+	}
+	break;
+      }
+    }
+  }
+
+  while (b) {
+    clause = b->clause();
+    b = b->next();
+    v = clause->evaluate();
+    if (strictEqual(input, v)) {
+      res = clause->evalStatements();
+      if (res.complType() != Normal)
+	return res;
+      goto step18;
+    }
+  }
+
+  // default clause
+  if (def) {
+    res = def->evalStatements();
+    if (res.complType() != Normal)
+      return res;
+  }
+  b = list2;
+ step18:
+  while (b) {
+    clause = b->clause();
+    res = clause->evalStatements();
+    if (res.complType() != Normal)
+      return res;
+    b = b->next();
+  }
+
+  return Completion(Normal);
+}
+
+// ECMA 12.11
+KJSO CaseClauseNode::evaluate()
+{
+  KJSO e = expr->evaluate();
+  KJSO v = e.getValue();
+
+  return v;
+}
+
+// ECMA 12.11
+Completion CaseClauseNode::evalStatements()
+{
+  if (list)
+    return list->execute();
+  else
+    return Completion(Normal, Undefined());
+}
+
+// ECMA 12.12
+Completion LabelNode::execute()
+{
+  Completion e;
+
+  if (!Context::current()->seenLabels()->push(label)) {
+    return Completion( Throw,
+		       throwError(SyntaxError, "Duplicated label found" ));
+  };
+  e = stat->execute();
+  Context::current()->seenLabels()->pop();
+
+  if ((e.complType() == Break) && (e.target() == label))
+    return Completion(Normal, e.value());
+  else
+    return e;
+}
+
+// ECMA 12.13
+Completion ThrowNode::execute()
+{
+  KJS_BREAKPOINT;
+
+  KJSO v = expr->evaluate().getValue();
+
+  return Completion(Throw, v);
+}
+
+// ECMA 12.14
+Completion TryNode::execute()
+{
+  KJS_BREAKPOINT;
+
+  Completion c, c2;
+
+  c = block->execute();
+
+  if (!_final) {
+    if (c.complType() != Throw)
+      return c;
+    return _catch->execute(c.value());
+  }
+
+  if (!_catch) {
+    c2 = _final->execute();
+    return (c2.complType() == Normal) ? c : c2;
+  }
+
+  if (c.complType() == Throw)
+    c = _catch->execute(c.value());
+
+  c2 = _final->execute();
+  return (c2.complType() == Normal) ? c : c2;
+}
+
+Completion CatchNode::execute()
+{
+  // should never be reached. execute(const KJS &arg) is used instead
+  assert(0L);
+  return Completion();
+}
+
+// ECMA 12.14
+Completion CatchNode::execute(const KJSO &arg)
+{
+  /* TODO: correct ? Not part of the spec */
+  KJScriptImp::clearException();
+
+  Object obj;
+  obj.put(ident, arg, DontDelete);
+  Context::current()->pushScope(obj);
+  Completion c = block->execute();
+  Context::current()->popScope();
+
+  return c;
+}
+
+// ECMA 12.14
+Completion FinallyNode::execute()
+{
+  return block->execute();
+}
+
+FunctionBodyNode::FunctionBodyNode(SourceElementsNode *s)
+  : source(s)
+{
+#ifdef KJS_DEBUGGER
+  setLoc(-1, -1);
+#endif
+}
+
+// ECMA 13 + 14 for ProgramNode
+Completion FunctionBodyNode::execute()
+{
+  /* TODO: workaround for empty body which I don't see covered by the spec */
+  if (!source)
+    return Completion(ReturnValue, Undefined());
+
+  source->processFuncDecl();
+
+  return source->execute();
+}
+
+// ECMA 13
+void FuncDeclNode::processFuncDecl()
+{
+  const List *sc = Context::current()->pScopeChain();
+  /* TODO: let this be an object with [[Class]] property "Function" */
+  FunctionImp *fimp = new DeclaredFunctionImp(ident, body, sc);
+  Function func(fimp); // protect from GC
+  fimp->put("prototype", Object::create(ObjectClass), DontDelete);
+
+  int plen = 0;
+  for(ParameterNode *p = param; p != 0L; p = p->nextParam(), plen++)
+    fimp->addParameter(p->ident());
+
+  fimp->setLength(plen);
+
+  Context::current()->variableObject().put(ident, func);
+}
+
+// ECMA 13
+KJSO FuncExprNode::evaluate()
+{
+  const List *sc = Context::current()->pScopeChain();
+  FunctionImp *fimp = new DeclaredFunctionImp(UString::null, body, sc->copy());
+  Function ret(fimp);
+
+  int plen = 0;
+  for(ParameterNode *p = param; p != 0L; p = p->nextParam(), plen++)
+    fimp->addParameter(p->ident());
+  fimp->setLength(plen);
+
+  return ret;
+}
+
+ParameterNode* ParameterNode::append(const UString *i)
+{
+  ParameterNode *p = this;
+  while (p->next)
+    p = p->next;
+
+  p->next = new ParameterNode(i);
+
+  return this;
+}
+
+// ECMA 13
+KJSO ParameterNode::evaluate()
+{
+  return Undefined();
+}
+
+void ProgramNode::deleteGlobalStatements()
+{
+  source->deleteStatements();
+}
+
+// ECMA 14
+Completion SourceElementsNode::execute()
+{
+  if (KJScriptImp::hadException())
+    return Completion(Throw, KJScriptImp::exception());
+
+  if (!elements)
+    return element->execute();
+
+  Completion c1 = elements->execute();
+  if (KJScriptImp::hadException())
+    return Completion(Throw, KJScriptImp::exception());
+  if (c1.complType() != Normal)
+    return c1;
+
+  Completion c2 = element->execute();
+  if (KJScriptImp::hadException())
+    return Completion(Throw, KJScriptImp::exception());
+
+  return c2;
+}
+
+// ECMA 14
+void SourceElementsNode::processFuncDecl()
+{
+  if (elements)
+    elements->processFuncDecl();
+
+  element->processFuncDecl();
+}
+
+void SourceElementsNode::deleteStatements()
+{
+  element->deleteStatements();
+
+  if (elements)
+    elements->deleteStatements();
+}
+
+// ECMA 14
+Completion SourceElementNode::execute()
+{
+  if (statement)
+    return statement->execute();
+
+  return Completion(Normal);
+}
+
+// ECMA 14
+void SourceElementNode::processFuncDecl()
+{
+  if (function)
+    function->processFuncDecl();
+}
+
+void SourceElementNode::deleteStatements()
+{
+  delete statement;
+}
+
+ArgumentListNode::ArgumentListNode(Node *e) : list(0L), expr(e) {}
+
+VarDeclNode::VarDeclNode(const UString *id, AssignExprNode *in)
+    : ident(*id), init(in) { }
+
+ArgumentListNode::ArgumentListNode(ArgumentListNode *l, Node *e) :
+    list(l), expr(e) {}
+
+ArgumentsNode::ArgumentsNode(ArgumentListNode *l) : list(l) {}
diff --git a/WebCore/src/kdelibs/kjs/nodes.h b/WebCore/src/kdelibs/kjs/nodes.h
new file mode 100644
index 0000000..223109a
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/nodes.h
@@ -0,0 +1,789 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _NODES_H_
+#define _NODES_H_
+
+#include "internal.h"
+#include "ustring.h"
+#include "object.h"
+#include "types.h"
+#include "debugger.h"
+
+namespace KJS {
+
+  class KJSO;
+  class RegExp;
+  class SourceElementsNode;
+  class ProgramNode;
+
+  enum Operator { OpEqual,
+		  OpEqEq,
+		  OpNotEq,
+		  OpStrEq,
+		  OpStrNEq,
+		  OpPlusEq,
+		  OpMinusEq,
+		  OpMultEq,
+		  OpDivEq,
+                  OpPlusPlus,
+		  OpMinusMinus,
+		  OpLess,
+		  OpLessEq,
+		  OpGreater,
+		  OpGreaterEq,
+		  OpAndEq,
+		  OpXOrEq,
+		  OpOrEq,
+		  OpModEq,
+                  OpAnd,
+                  OpOr,
+		  OpBitAnd,
+		  OpBitXOr,
+		  OpBitOr,
+		  OpLShift,
+		  OpRShift,
+		  OpURShift,
+		  OpIn,
+		  OpInstanceOf
+  };
+
+  class Node {
+  public:
+    Node();
+    virtual ~Node();
+    virtual KJSO evaluate() = 0;
+    int lineNo() const { return line; }
+    static Node *firstNode() { return first; }
+    static void setFirstNode(Node *n) { first = n; }
+    static void deleteAllNodes();
+#ifdef KJS_DEBUGGER
+    static bool setBreakpoint(Node *firstNode, int id, int line, bool set);
+    virtual bool setBreakpoint(int, int, bool) { return false; }
+#endif
+  protected:
+    KJSO throwError(ErrorType e, const char *msg);
+  private:
+    // disallow assignment and copy-construction
+    Node(const Node &);
+    Node& operator=(const Node&);
+    int line;
+    static  int nodeCount;
+    static Node *first;
+    Node *next, *prev;
+  };
+
+  class StatementNode : public Node {
+  public:
+#ifdef KJS_DEBUGGER
+    StatementNode() : l0(-1), l1(-1), sid(-1), breakPoint(false) { }
+    void setLoc(int line0, int line1);
+    int firstLine() const { return l0; }
+    int lastLine() const { return l1; }
+    int sourceId() const { return sid; }
+    bool hitStatement();
+    bool abortStatement();
+    virtual bool setBreakpoint(int id, int line, bool set);
+#endif
+    virtual Completion execute() = 0;
+    void pushLabel(const UString *id) {
+      if (id) ls.push(*id);
+    }
+  protected:
+    LabelStack ls;
+  private:
+    KJSO evaluate() { return Undefined(); }
+#ifdef KJS_DEBUGGER
+    int l0, l1;
+    int sid;
+    bool breakPoint;
+#endif
+  };
+
+  class NullNode : public Node {
+  public:
+    KJSO evaluate();
+  };
+
+  class BooleanNode : public Node {
+  public:
+    BooleanNode(bool v) : value(v) {}
+    KJSO evaluate();
+  private:
+    bool value;
+  };
+
+  class NumberNode : public Node {
+  public:
+    NumberNode(double v) : value(v) { }
+    KJSO evaluate();
+  private:
+    double value;
+  };
+
+  class StringNode : public Node {
+  public:
+    StringNode(const UString *v) { value = *v; }
+    KJSO evaluate();
+  private:
+    UString value;
+  };
+
+  class RegExpNode : public Node {
+  public:
+    RegExpNode(const UString &p, const UString &f)
+      : pattern(p), flags(f) { }
+    KJSO evaluate();
+  private:
+    UString pattern, flags;
+  };
+
+  class ThisNode : public Node {
+  public:
+    KJSO evaluate();
+  };
+
+  class ResolveNode : public Node {
+  public:
+    ResolveNode(const UString *s) : ident(*s) { }
+    KJSO evaluate();
+  private:
+    UString ident;
+  };
+
+  class GroupNode : public Node {
+  public:
+    GroupNode(Node *g) : group(g) { }
+    KJSO evaluate();
+  private:
+    Node *group;
+  };
+
+  class ElisionNode : public Node {
+  public:
+    ElisionNode(ElisionNode *e) : elision(e) { }
+    KJSO evaluate();
+  private:
+    ElisionNode *elision;
+  };
+
+  class ElementNode : public Node {
+  public:
+    ElementNode(ElisionNode *e, Node *n) : list(0l), elision(e), node(n) { }
+    ElementNode(ElementNode *l, ElisionNode *e, Node *n)
+      : list(l), elision(e), node(n) { }
+    KJSO evaluate();
+  private:
+    ElementNode *list;
+    ElisionNode *elision;
+    Node *node;
+  };
+
+  class ArrayNode : public Node {
+  public:
+    ArrayNode(ElisionNode *e) : element(0L), elision(e), opt(true) { }
+    ArrayNode(ElementNode *ele)
+      : element(ele), elision(0), opt(false) { }
+    ArrayNode(ElisionNode *eli, ElementNode *ele)
+      : element(ele), elision(eli), opt(true) { }
+    KJSO evaluate();
+  private:
+    ElementNode *element;
+    ElisionNode *elision;
+    bool opt;
+  };
+
+  class ObjectLiteralNode : public Node {
+  public:
+    ObjectLiteralNode(Node *l) : list(l) { }
+    KJSO evaluate();
+  private:
+    Node *list;
+  };
+
+  class PropertyValueNode : public Node {
+  public:
+    PropertyValueNode(Node *n, Node *a, Node *l = 0L)
+      : name(n), assign(a), list(l) { }
+    KJSO evaluate();
+  private:
+    Node *name, *assign, *list;
+  };
+
+  class PropertyNode : public Node {
+  public:
+    PropertyNode(double d) : numeric(d) { }
+    PropertyNode(const UString *s) : str(*s) { }
+    KJSO evaluate();
+  private:
+    double numeric;
+    UString str;
+  };
+
+  class AccessorNode1 : public Node {
+  public:
+    AccessorNode1(Node *e1, Node *e2) : expr1(e1), expr2(e2) {}
+    KJSO evaluate();
+  private:
+    Node *expr1;
+    Node *expr2;
+  };
+
+  class AccessorNode2 : public Node {
+  public:
+    AccessorNode2(Node *e, const UString *s) : expr(e), ident(*s) { }
+    KJSO evaluate();
+  private:
+    Node *expr;
+    UString ident;
+  };
+
+  class ArgumentListNode : public Node {
+  public:
+    ArgumentListNode(Node *e);
+    ArgumentListNode(ArgumentListNode *l, Node *e);
+    KJSO evaluate();
+    List *evaluateList();
+  private:
+    ArgumentListNode *list;
+    Node *expr;
+  };
+
+  class ArgumentsNode : public Node {
+  public:
+    ArgumentsNode(ArgumentListNode *l);
+    KJSO evaluate();
+    List *evaluateList();
+  private:
+    ArgumentListNode *list;
+  };
+
+  class NewExprNode : public Node {
+  public:
+    NewExprNode(Node *e) : expr(e), args(0L) {}
+    NewExprNode(Node *e, ArgumentsNode *a) : expr(e), args(a) {}
+    KJSO evaluate();
+  private:
+    Node *expr;
+    ArgumentsNode *args;
+  };
+
+  class FunctionCallNode : public Node {
+  public:
+    FunctionCallNode(Node *e, ArgumentsNode *a) : expr(e), args(a) {}
+    KJSO evaluate();
+#ifdef KJS_DEBUGGER
+    void steppingInto(bool in);
+    Debugger::Mode previousMode;
+#endif
+  private:
+    Node *expr;
+    ArgumentsNode *args;
+  };
+
+  class PostfixNode : public Node {
+  public:
+    PostfixNode(Node *e, Operator o) : expr(e), oper(o) {}
+    KJSO evaluate();
+  private:
+    Node *expr;
+    Operator oper;
+  };
+
+  class DeleteNode : public Node {
+  public:
+    DeleteNode(Node *e) : expr(e) {}
+    KJSO evaluate();
+  private:
+    Node *expr;
+  };
+
+  class VoidNode : public Node {
+  public:
+    VoidNode(Node *e) : expr(e) {}
+    KJSO evaluate();
+  private:
+    Node *expr;
+  };
+
+  class TypeOfNode : public Node {
+  public:
+    TypeOfNode(Node *e) : expr(e) {}
+    KJSO evaluate();
+  private:
+    Node *expr;
+  };
+
+  class PrefixNode : public Node {
+  public:
+    PrefixNode(Operator o, Node *e) : oper(o), expr(e) {}
+    KJSO evaluate();
+  private:
+    Operator oper;
+    Node *expr;
+  };
+
+  class UnaryPlusNode : public Node {
+  public:
+    UnaryPlusNode(Node *e) : expr(e) {}
+    KJSO evaluate();
+  private:
+    Node *expr;
+  };
+
+  class NegateNode : public Node {
+  public:
+    NegateNode(Node *e) : expr(e) {}
+    KJSO evaluate();
+  private:
+    Node *expr;
+  };
+
+  class BitwiseNotNode : public Node {
+  public:
+    BitwiseNotNode(Node *e) : expr(e) {}
+    KJSO evaluate();
+  private:
+    Node *expr;
+  };
+
+  class LogicalNotNode : public Node {
+  public:
+    LogicalNotNode(Node *e) : expr(e) {}
+    KJSO evaluate();
+  private:
+    Node *expr;
+  };
+
+  class MultNode : public Node {
+  public:
+    MultNode(Node *t1, Node *t2, char op) : term1(t1), term2(t2), oper(op) {}
+    KJSO evaluate();
+  private:
+    Node *term1, *term2;
+    char oper;
+  };
+
+  class AddNode : public Node {
+  public:
+    AddNode(Node *t1, Node *t2, char op) : term1(t1), term2(t2), oper(op) {}
+    KJSO evaluate();
+  private:
+    Node *term1, *term2;
+    char oper;
+  };
+
+  class ShiftNode : public Node {
+  public:
+    ShiftNode(Node *t1, Operator o, Node *t2)
+      : term1(t1), term2(t2), oper(o) {}
+    KJSO evaluate();
+  private:
+    Node *term1, *term2;
+    Operator oper;
+  };
+
+  class RelationalNode : public Node {
+  public:
+    RelationalNode(Node *e1, Operator o, Node *e2) :
+      expr1(e1), expr2(e2), oper(o) {}
+    KJSO evaluate();
+  private:
+    Node *expr1, *expr2;
+    Operator oper;
+  };
+
+  class EqualNode : public Node {
+  public:
+    EqualNode(Node *e1, Operator o, Node *e2)
+      : expr1(e1), expr2(e2), oper(o) {}
+    KJSO evaluate();
+  private:
+    Node *expr1, *expr2;
+    Operator oper;
+  };
+
+  class BitOperNode : public Node {
+  public:
+    BitOperNode(Node *e1, Operator o, Node *e2) :
+      expr1(e1), expr2(e2), oper(o) {}
+    KJSO evaluate();
+  private:
+    Node *expr1, *expr2;
+    Operator oper;
+  };
+
+  class BinaryLogicalNode : public Node {
+  public:
+    BinaryLogicalNode(Node *e1, Operator o, Node *e2) :
+      expr1(e1), expr2(e2), oper(o) {}
+    KJSO evaluate();
+  private:
+    Node *expr1, *expr2;
+    Operator oper;
+  };
+
+  class ConditionalNode : public Node {
+  public:
+    ConditionalNode(Node *l, Node *e1, Node *e2) :
+      logical(l), expr1(e1), expr2(e2) {}
+    KJSO evaluate();
+  private:
+    Node *logical, *expr1, *expr2;
+  };
+
+  class AssignNode : public Node {
+  public:
+    AssignNode(Node *l, Operator o, Node *e) : left(l), oper(o), expr(e) {}
+    KJSO evaluate();
+  private:
+    Node *left;
+    Operator oper;
+    Node *expr;
+  };
+
+  class CommaNode : public Node {
+  public:
+    CommaNode(Node *e1, Node *e2) : expr1(e1), expr2(e2) {}
+    KJSO evaluate();
+  private:
+    Node *expr1, *expr2;
+  };
+
+  class StatListNode : public StatementNode {
+  public:
+    StatListNode(StatementNode *s) : statement(s), list(0L) { }
+    StatListNode(StatListNode *l, StatementNode *s) : statement(s), list(l) { }
+    Completion execute();
+  private:
+    StatementNode *statement;
+    StatListNode *list;
+  };
+
+  class AssignExprNode : public Node {
+  public:
+    AssignExprNode(Node *e) : expr(e) {}
+    KJSO evaluate();
+  private:
+    Node *expr;
+  };
+
+  class VarDeclNode : public Node {
+  public:
+    VarDeclNode(const UString *id, AssignExprNode *in);
+    KJSO evaluate();
+  private:
+    UString ident;
+    AssignExprNode *init;
+  };
+
+  class VarDeclListNode : public Node {
+  public:
+    VarDeclListNode(VarDeclNode *v) : list(0L), var(v) {}
+    VarDeclListNode(Node *l, VarDeclNode *v) : list(l), var(v) {}
+    KJSO evaluate();
+  private:
+    Node *list;
+    VarDeclNode *var;
+  };
+
+  class VarStatementNode : public StatementNode {
+  public:
+    VarStatementNode(VarDeclListNode *l) : list(l) {}
+    Completion execute();
+  private:
+    VarDeclListNode *list;
+  };
+
+  class BlockNode : public StatementNode {
+  public:
+    BlockNode(StatListNode *s) : statlist(s) {}
+    Completion execute();
+  private:
+    StatListNode *statlist;
+  };
+
+  class EmptyStatementNode : public StatementNode {
+  public:
+    EmptyStatementNode() { } // debug
+    Completion execute();
+  };
+
+  class ExprStatementNode : public StatementNode {
+  public:
+    ExprStatementNode(Node *e) : expr(e) { }
+    Completion execute();
+  private:
+    Node *expr;
+  };
+
+  class IfNode : public StatementNode {
+  public:
+    IfNode(Node *e, StatementNode *s1, StatementNode *s2)
+      : expr(e), statement1(s1), statement2(s2) {}
+    Completion execute();
+  private:
+    Node *expr;
+    StatementNode *statement1, *statement2;
+  };
+
+  class DoWhileNode : public StatementNode {
+  public:
+    DoWhileNode(StatementNode *s, Node *e) : statement(s), expr(e) {}
+    Completion execute();
+  private:
+    StatementNode *statement;
+    Node *expr;
+  };
+
+  class WhileNode : public StatementNode {
+  public:
+    WhileNode(Node *e, StatementNode *s) : expr(e), statement(s) {}
+    Completion execute();
+  private:
+    Node *expr;
+    StatementNode *statement;
+  };
+
+  class ForNode : public StatementNode {
+  public:
+    ForNode(Node *e1, Node *e2, Node *e3, StatementNode *s) :
+      expr1(e1), expr2(e2), expr3(e3), stat(s) {}
+    Completion execute();
+  private:
+    Node *expr1, *expr2, *expr3;
+    StatementNode *stat;
+  };
+
+  class ForInNode : public StatementNode {
+  public:
+    ForInNode(Node *l, Node *e, StatementNode *s) :
+      init(0L), lexpr(l), expr(e), stat(s) {}
+    ForInNode(const UString *i, AssignExprNode *in, Node *e, StatementNode *s)
+      : ident(*i), init(in), lexpr(0L), expr(e), stat(s) {}
+    Completion execute();
+  private:
+    UString ident;
+    AssignExprNode *init;
+    Node *lexpr, *expr;
+    StatementNode *stat;
+  };
+
+  class ContinueNode : public StatementNode {
+  public:
+    ContinueNode() { }
+    ContinueNode(const UString *i) : ident(*i) { }
+    Completion execute();
+  private:
+    UString ident;
+  };
+
+  class BreakNode : public StatementNode {
+  public:
+    BreakNode() { }
+    BreakNode(const UString *i) : ident(*i) { }
+    Completion execute();
+  private:
+    UString ident;
+  };
+
+  class ReturnNode : public StatementNode {
+  public:
+    ReturnNode(Node *v) : value(v) {}
+    Completion execute();
+  private:
+    Node *value;
+  };
+
+  class WithNode : public StatementNode {
+  public:
+    WithNode(Node *e, StatementNode *s) : expr(e), stat(s) {}
+    Completion execute();
+  private:
+    Node *expr;
+    StatementNode *stat;
+  };
+
+  class CaseClauseNode: public Node {
+  public:
+    CaseClauseNode(Node *e, StatListNode *l) : expr(e), list(l) { }
+    KJSO evaluate();
+    Completion evalStatements();
+  private:
+    Node *expr;
+    StatListNode *list;
+  };
+
+  class ClauseListNode : public Node {
+  public:
+    ClauseListNode(CaseClauseNode *c) : cl(c), nx(0L) { }
+    ClauseListNode* append(CaseClauseNode *c);
+    KJSO evaluate() { /* should never be called */ return KJSO(); }
+    CaseClauseNode *clause() const { return cl; }
+    ClauseListNode *next() const { return nx; }
+  private:
+    CaseClauseNode *cl;
+    ClauseListNode *nx;
+  };
+
+  class CaseBlockNode: public Node {
+  public:
+    CaseBlockNode(ClauseListNode *l1, CaseClauseNode *d, ClauseListNode *l2)
+      : list1(l1), def(d), list2(l2) { }
+    KJSO evaluate() { /* should never be called */ return KJSO(); }
+    Completion evalBlock(const KJSO& input);
+  private:
+    ClauseListNode *list1;
+    CaseClauseNode *def;
+    ClauseListNode *list2;
+  };
+
+  class SwitchNode : public StatementNode {
+  public:
+    SwitchNode(Node *e, CaseBlockNode *b) : expr(e), block(b) { }
+    Completion execute();
+  private:
+    Node *expr;
+    CaseBlockNode *block;
+  };
+
+  class LabelNode : public StatementNode {
+  public:
+    LabelNode(const UString *l, StatementNode *s) : label(*l), stat(s) { }
+    Completion execute();
+  private:
+    UString label;
+    StatementNode *stat;
+  };
+
+  class ThrowNode : public StatementNode {
+  public:
+    ThrowNode(Node *e) : expr(e) {}
+    Completion execute();
+  private:
+    Node *expr;
+  };
+
+  class CatchNode : public StatementNode {
+  public:
+    CatchNode(UString *i, StatementNode *b) : ident(*i), block(b) {}
+    Completion execute();
+    Completion execute(const KJSO &arg);
+  private:
+    UString ident;
+    StatementNode *block;
+  };
+
+  class FinallyNode : public StatementNode {
+  public:
+    FinallyNode(StatementNode *b) : block(b) {}
+    Completion execute();
+  private:
+    StatementNode *block;
+  };
+
+  class TryNode : public StatementNode {
+  public:
+    TryNode(StatementNode *b, Node *c = 0L, Node *f = 0L)
+      : block(b), _catch((CatchNode*)c), _final((FinallyNode*)f) {}
+    Completion execute();
+  private:
+    StatementNode *block;
+    CatchNode *_catch;
+    FinallyNode *_final;
+  };
+
+  class ParameterNode : public Node {
+  public:
+    ParameterNode(const UString *i) : id(*i), next(0L) { }
+    ParameterNode *append(const UString *i);
+    KJSO evaluate();
+    UString ident() { return id; }
+    ParameterNode *nextParam() { return next; }
+  private:
+    UString id;
+    ParameterNode *next;
+  };
+
+  // inherited by ProgramNode
+  class FunctionBodyNode : public StatementNode {
+  public:
+      FunctionBodyNode(SourceElementsNode *s);
+      Completion execute();
+  protected:
+      SourceElementsNode *source;
+  };
+
+  class FuncDeclNode : public StatementNode {
+  public:
+    FuncDeclNode(const UString *i, ParameterNode *p, FunctionBodyNode *b)
+      : ident(*i), param(p), body(b) { }
+    Completion execute() { /* empty */ return Completion(); }
+    void processFuncDecl();
+  private:
+    UString ident;
+    ParameterNode *param;
+    FunctionBodyNode *body;
+  };
+
+  class FuncExprNode : public Node {
+  public:
+    FuncExprNode(ParameterNode *p, FunctionBodyNode *b)
+	: param(p), body(b) { }
+    KJSO evaluate();
+  private:
+    ParameterNode *param;
+    FunctionBodyNode *body;
+  };
+
+  class SourceElementNode : public StatementNode {
+  public:
+    SourceElementNode(StatementNode *s) { statement = s; function = 0L; }
+    SourceElementNode(FuncDeclNode *f) { function = f; statement = 0L;}
+    Completion execute();
+    virtual void processFuncDecl();
+    void deleteStatements();
+  private:
+    StatementNode *statement;
+    FuncDeclNode *function;
+  };
+
+  class SourceElementsNode : public StatementNode {
+  public:
+    SourceElementsNode(SourceElementNode *s1) { element = s1; elements = 0L; }
+    SourceElementsNode(SourceElementsNode *s1, SourceElementNode *s2)
+      { elements = s1; element = s2; }
+    Completion execute();
+    virtual void processFuncDecl();
+    void deleteStatements();
+  private:
+    SourceElementNode *element;
+    SourceElementsNode *elements;
+  };
+
+  class ProgramNode : public FunctionBodyNode {
+  public:
+    ProgramNode(SourceElementsNode *s) : FunctionBodyNode(s) { }
+    void deleteGlobalStatements();
+  };
+
+}; // namespace
+
+#endif
diff --git a/WebCore/src/kdelibs/kjs/number_object.cpp b/WebCore/src/kdelibs/kjs/number_object.cpp
new file mode 100644
index 0000000..af37d48
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/number_object.cpp
@@ -0,0 +1,131 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "kjs.h"
+#include "operations.h"
+#include "number_object.h"
+
+using namespace KJS;
+
+NumberObject::NumberObject(const Object& funcProto, const Object &numProto)
+  : ConstructorImp(funcProto, 1)
+{
+  // Number.Prototype
+  setPrototypeProperty(numProto);
+}
+
+// ECMA 15.7.3
+KJSO NumberObject::get(const UString &p) const
+{
+  double d;
+
+  if (p == "NaN")
+    d = NaN;
+  else if (p == "NEGATIVE_INFINITY")
+    d = -Inf;
+  else if (p == "POSITIVE_INFINITY")
+    d = Inf;
+  else
+    return Imp::get(p);
+
+  return Number(d);
+}
+
+// ECMA 15.7.1
+Completion NumberObject::execute(const List &args)
+{
+  Number n;
+  if (args.isEmpty())
+    n = Number(0);
+  else
+    n = args[0].toNumber();
+
+  return Completion(ReturnValue, n);
+}
+
+// ECMA 15.7.2
+Object NumberObject::construct(const List &args)
+{
+  Number n;
+  if (args.isEmpty())
+    n = Number(0);
+  else
+    n = args[0].toNumber();
+
+  return Object::create(NumberClass, n);
+}
+
+class NumberProtoFunc : public InternalFunctionImp {
+public:
+  NumberProtoFunc(int i) : id (i) { }
+  Completion execute(const List &);
+  enum { ToString, ToLocaleString, ValueOf };
+private:
+  int id;
+};
+
+// ECMA 15.7.4.2 - 15.7.4.7
+Completion NumberProtoFunc::execute(const List &)
+{
+  KJSO result;
+
+  Object thisObj = Object::dynamicCast(thisValue());
+
+  // no generic function. "this" has to be a Number object
+  if (thisObj.isNull() || thisObj.getClass() != NumberClass) {
+    result = Error::create(TypeError);
+    return Completion(ReturnValue, result);
+  }
+
+  // execute "toString()" or "valueOf()", respectively
+  KJSO v = thisObj.internalValue();
+  switch (id) {
+  case ToString:
+  case ToLocaleString: /* TODO */
+    result = v.toString();
+    break;
+  case ValueOf:
+    result = v.toNumber();
+    break;
+  }
+
+  return Completion(ReturnValue, result);
+}
+
+// ECMA 15.7.4
+NumberPrototype::NumberPrototype(const Object& proto)
+  : ObjectImp(NumberClass, Number(0), proto)
+{
+  // The constructor will be added later in NumberObject's constructor
+}
+
+KJSO NumberPrototype::get(const UString &p) const
+{
+  int t;
+  if (p == "toString")
+    t = NumberProtoFunc::ToString;
+  else if (p == "toLocaleString")
+    t = NumberProtoFunc::ToLocaleString;
+  else if (p == "valueOf")
+    t = NumberProtoFunc::ValueOf;
+  else
+    return Imp::get(p);
+
+  return Function(new NumberProtoFunc(t));
+}
diff --git a/WebCore/src/kdelibs/kjs/number_object.h b/WebCore/src/kdelibs/kjs/number_object.h
new file mode 100644
index 0000000..3addbdf
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/number_object.h
@@ -0,0 +1,44 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _NUMBER_OBJECT_H_
+#define _NUMBER_OBJECT_H_
+
+#include "object.h"
+#include "function.h"
+
+namespace KJS {
+
+  class NumberObject : public ConstructorImp {
+  public:
+    NumberObject(const Object& funcProto, const Object &numProto);
+    virtual KJSO get(const UString &p) const;
+    Completion execute(const List &);
+    Object construct(const List &);
+  };
+
+  class NumberPrototype : public ObjectImp {
+  public:
+    NumberPrototype(const Object& proto);
+    virtual KJSO get(const UString &p) const;
+  };
+
+}; // namespace
+
+#endif
diff --git a/WebCore/src/kdelibs/kjs/object.cpp b/WebCore/src/kdelibs/kjs/object.cpp
new file mode 100644
index 0000000..adcc0fb
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/object.cpp
@@ -0,0 +1,1062 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#include "object.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#include "kjs.h"
+#include "types.h"
+#include "internal.h"
+#include "operations.h"
+#include "collector.h"
+#include "error_object.h"
+
+namespace KJS {
+
+#ifdef WORDS_BIGENDIAN
+  unsigned char NaN_Bytes[] = { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 };
+  unsigned char Inf_Bytes[] = { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 };
+#elif defined(arm)
+  unsigned char NaN_Bytes[] = { 0, 0, 0xf8, 0x7f, 0, 0, 0, 0 };
+  unsigned char Inf_Bytes[] = { 0, 0, 0xf0, 0x7f, 0, 0, 0, 0 };
+#else
+  unsigned char NaN_Bytes[] = { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f };
+  unsigned char Inf_Bytes[] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f };
+#endif
+
+  const double NaN = *(const double*) NaN_Bytes;
+  const double Inf = *(const double*) Inf_Bytes;
+  const double D16 = 65536.0;
+  const double D31 = 2147483648.0; 	/* TODO: remove in next version */
+  const double D32 = 4294967296.0;
+
+  // TODO: -0
+};
+
+using namespace KJS;
+
+const TypeInfo Imp::info = { "Imp", AbstractType, 0, 0, 0 };
+
+namespace KJS {
+  struct Property {
+    UString name;
+    Imp *object;
+    int attribute;
+    Property *next;
+  };
+}
+
+KJSO::KJSO()
+  : rep(0)
+{
+#ifdef KJS_DEBUG_MEM
+  count++;
+#endif
+}
+
+KJSO::KJSO(Imp *d)
+  : rep(d)
+{
+#ifdef KJS_DEBUG_MEM
+  count++;
+#endif
+
+  if (rep) {
+    rep->ref();
+    rep->setGcAllowed(true);
+  }
+}
+
+KJSO::KJSO(const KJSO &o)
+{
+#ifdef KJS_DEBUG_MEM
+  count++;
+#endif
+
+  rep = o.rep;
+  if (rep) {
+    rep->ref();
+    rep->setGcAllowed(true);
+  }
+}
+
+KJSO& KJSO::operator=(const KJSO &o)
+{
+  if (rep)
+    rep->deref();
+  rep = o.rep;
+  if (rep) {
+    rep->ref();
+    rep->setGcAllowed(true);
+  }
+
+  return *this;
+}
+
+KJSO::~KJSO()
+{
+#ifdef KJS_DEBUG_MEM
+  count--;
+#endif
+
+  if (rep)
+    rep->deref();
+}
+
+bool KJSO::isDefined() const
+{
+  return !isA(UndefinedType);
+}
+
+bool KJSO::isNull() const
+{
+  return !rep;
+}
+
+Type KJSO::type() const
+{
+#ifdef KJS_VERBOSE
+  if (!rep)
+    fprintf(stderr, "requesting type of null object\n");
+#endif
+
+  return rep ? rep->typeInfo()->type : UndefinedType;
+}
+
+bool KJSO::isObject() const
+{
+  return (type() >= ObjectType);
+}
+
+bool KJSO::isA(const char *s) const
+{
+  assert(rep);
+  const TypeInfo *info = rep->typeInfo();
+
+  if (!s || !info || !info->name)
+    return false;
+
+  if (info->type == HostType && strcmp(s, "HostObject") == 0)
+    return true;
+
+  return (strcmp(s, info->name) == 0);
+}
+
+bool KJSO::derivedFrom(const char *s) const
+{
+  if (!s)
+    return false;
+
+  assert(rep);
+  const TypeInfo *info = rep->typeInfo();
+  while (info) {
+    if (info->name && strcmp(s, info->name) == 0)
+      return true;
+    info = info->base;
+  }
+
+  return false;
+}
+
+KJSO KJSO::toPrimitive(Type preferred) const
+{
+  assert(rep);
+  return rep->toPrimitive(preferred);
+}
+
+Boolean KJSO::toBoolean() const
+{
+  assert(rep);
+  return rep->toBoolean();
+}
+
+Number KJSO::toNumber() const
+{
+  assert(rep);
+  return rep->toNumber();
+}
+
+// helper function for toInteger, toInt32, toUInt32 and toUInt16
+double KJSO::round() const
+{
+  if (isA(UndefinedType)) /* TODO: see below */
+    return 0.0;
+  Number n = toNumber();
+  if (n.value() == 0.0)   /* TODO: -0, NaN, Inf */
+    return 0.0;
+  double d = floor(fabs(n.value()));
+  if (n.value() < 0)
+    d *= -1;
+
+  return d;
+}
+
+// ECMA 9.4
+Number KJSO::toInteger() const
+{
+  return Number(round());
+}
+
+// ECMA 9.5
+int KJSO::toInt32() const
+{
+  double d = round();
+  double d32 = fmod(d, D32);
+
+  if (d32 >= D32 / 2.0)
+    d32 -= D32;
+
+  return static_cast<int>(d32);
+}
+
+// ECMA 9.6
+unsigned int KJSO::toUInt32() const
+{
+  double d = round();
+  double d32 = fmod(d, D32);
+
+  return static_cast<unsigned int>(d32);
+}
+
+// ECMA 9.7
+unsigned short KJSO::toUInt16() const
+{
+  double d = round();
+  double d16 = fmod(d, D16);
+
+  return static_cast<unsigned short>(d16);
+}
+
+String KJSO::toString() const
+{
+  assert(rep);
+  return rep->toString();
+}
+
+Object KJSO::toObject() const
+{
+  assert(rep);
+  if (isObject())
+    return Object(rep);
+
+  return rep->toObject();
+}
+
+bool KJSO::implementsCall() const
+{
+  return (type() == FunctionType ||
+	  type() == InternalFunctionType ||
+	  type() == ConstructorType ||
+	  type() == DeclaredFunctionType ||
+	  type() == AnonymousFunctionType);
+}
+
+// [[call]]
+KJSO KJSO::executeCall(const KJSO &thisV, const List *args)
+{
+  assert(rep);
+  assert(implementsCall());
+  return (static_cast<FunctionImp*>(rep))->executeCall(thisV.imp(), args);
+}
+
+KJSO KJSO::executeCall(const KJSO &thisV, const List *args, const List *extraScope) const
+{
+  assert(rep);
+  assert(implementsCall());
+  return (static_cast<FunctionImp*>(rep))->executeCall(thisV.imp(), args, extraScope);
+}
+
+void KJSO::setConstructor(KJSO c)
+{
+  put("constructor", c, DontEnum | DontDelete | ReadOnly);
+}
+
+// ECMA 8.7.1
+KJSO KJSO::getBase() const
+{
+  if (!isA(ReferenceType))
+    return Error::create(ReferenceError, I18N_NOOP("Invalid reference base"));
+
+  return ((ReferenceImp*)rep)->getBase();
+}
+
+// ECMA 8.7.2
+UString KJSO::getPropertyName() const
+{
+  if (!isA(ReferenceType))
+    // the spec wants a runtime error here. But getValue() and putValue()
+    // will catch this case on their own earlier. When returning a Null
+    // string we should be on the safe side.
+    return UString();
+
+  return ((ReferenceImp*)rep)->getPropertyName();
+}
+
+// ECMA 8.7.1
+KJSO KJSO::getValue() const
+{
+  if (!isA(ReferenceType)) {
+    return *this;
+  }
+  KJSO o = getBase();
+  if (o.isNull() || o.isA(NullType)) {
+    UString m = I18N_NOOP("Can't find variable: ") + getPropertyName();
+    return Error::create(ReferenceError, m.ascii());
+  }
+
+  return o.get(getPropertyName());
+}
+
+/* TODO: remove in next version */
+KJSO KJSO::getValue()
+{
+    return const_cast<const KJSO*>(this)->getValue();
+}
+
+// ECMA 8.7.2
+ErrorType KJSO::putValue(const KJSO& v)
+{
+  if (!isA(ReferenceType))
+    return ReferenceError;
+
+  KJSO o = getBase();
+  if (o.isA(NullType))
+    Global::current().put(getPropertyName(), v);
+  else {
+    // are we writing into an array ?
+    if (o.isA(ObjectType) && (o.toObject().getClass() == ArrayClass))
+      o.putArrayElement(getPropertyName(), v);
+    else
+      o.put(getPropertyName(), v);
+  }
+
+  return NoError;
+}
+
+void KJSO::setPrototype(const KJSO& p)
+{
+  assert(rep);
+  rep->setPrototype(p);
+}
+
+void KJSO::setPrototypeProperty(const KJSO& p)
+{
+  assert(rep);
+  put("prototype", p, DontEnum | DontDelete | ReadOnly);
+}
+
+KJSO KJSO::prototype() const
+{
+  if (rep)
+    return KJSO(rep->proto);
+  else
+    return KJSO();
+}
+
+// ECMA 8.6.2.1
+KJSO KJSO::get(const UString &p) const
+{
+  assert(rep);
+  return rep->get(p);
+}
+
+// ECMA 8.6.2.2
+void KJSO::put(const UString &p, const KJSO& v)
+{
+  assert(rep);
+  rep->put(p, v);
+}
+
+// ECMA 8.6.2.2
+void KJSO::put(const UString &p, const KJSO& v, int attr)
+{
+  static_cast<Imp*>(rep)->put(p, v, attr);
+}
+
+// provided for convenience.
+void KJSO::put(const UString &p, double d, int attr)
+{
+  put(p, Number(d), attr);
+}
+
+// provided for convenience.
+void KJSO::put(const UString &p, int i, int attr)
+{
+  put(p, Number(i), attr);
+}
+
+// provided for convenience.
+void KJSO::put(const UString &p, unsigned int u, int attr)
+{
+  put(p, Number(u), attr);
+}
+
+// ECMA 15.4.5.1
+void KJSO::putArrayElement(const UString &p, const KJSO& v)
+{
+  assert(rep);
+  rep->putArrayElement(p, v);
+}
+
+// ECMA 8.6.2.3
+bool KJSO::canPut(const UString &p) const
+{
+  assert(rep);
+  return rep->canPut(p);
+}
+
+// ECMA 8.6.2.4
+bool KJSO::hasProperty(const UString &p, bool recursive) const
+{
+  assert(rep);
+  return rep->hasProperty(p, recursive);
+}
+
+// ECMA 8.6.2.5
+bool KJSO::deleteProperty(const UString &p)
+{
+  assert(rep);
+  return rep->deleteProperty(p);
+}
+
+Object::Object(Imp *d) : KJSO(d) { }
+
+Object::Object(Class c) : KJSO(new ObjectImp(c)) { }
+
+Object::Object(Class c, const KJSO& v) : KJSO(new ObjectImp(c, v)) { }
+
+Object::Object(Class c, const KJSO& v, const Object& p)
+  : KJSO(new ObjectImp(c, v))
+{
+  setPrototype(p);
+}
+
+Object::~Object() { }
+
+void Object::setClass(Class c)
+{
+  static_cast<ObjectImp*>(rep)->cl = c;
+}
+
+Class Object::getClass() const
+{
+  assert(rep);
+  return static_cast<ObjectImp*>(rep)->cl;
+}
+
+void Object::setInternalValue(const KJSO& v)
+{
+  assert(rep);
+  static_cast<ObjectImp*>(rep)->val = v.imp();
+}
+
+KJSO Object::internalValue()
+{
+  assert(rep);
+  return KJSO(static_cast<ObjectImp*>(rep)->val);
+}
+
+Object Object::create(Class c)
+{
+  return Object::create(c, KJSO());
+}
+
+// factory
+Object Object::create(Class c, const KJSO& val)
+{
+  Global global(Global::current());
+  Object obj = Object();
+  obj.setClass(c);
+  obj.setInternalValue(val);
+
+  UString p = "[[";
+  switch (c) {
+  case UndefClass:
+  case ObjectClass:
+    p += "Object";
+    break;
+  case FunctionClass:
+    p += "Function";
+    break;
+  case ArrayClass:
+    p += "Array";
+    obj.put("length", Number(0), DontEnum | DontDelete);
+    break;
+  case StringClass:
+    p += "String";
+    obj.put("length", val.toString().value().size());
+    break;
+  case BooleanClass:
+    p += "Boolean";
+    break;
+  case NumberClass:
+    p += "Number";
+    break;
+  case DateClass:
+    p += "Date";
+    break;
+  case RegExpClass:
+    p += "RegExp";
+    break;
+  case ErrorClass:
+    p += "Error";
+    break;
+  }
+  p += ".prototype]]";
+
+  //  KJSO prot = global.get(p).get("prototype");
+  KJSO prot = global.get(p);
+  assert(prot.isDefined());
+
+  obj.setPrototype(prot);
+  return obj;
+}
+
+Object Object::create(Class c, const KJSO& val, const Object& p)
+{
+  Global global(Global::current());
+  Object obj = Object();
+  Object prot;
+  obj.setClass(c);
+  obj.setInternalValue(val);
+
+  prot = p;
+  obj.setPrototype(prot);
+  return obj;
+}
+
+Object Object::dynamicCast(const KJSO &obj)
+{
+  // return null object on type mismatch
+  if (!obj.isA(ObjectType))
+    return Object(0L);
+
+  return Object(obj.imp());
+
+}
+
+#ifdef KJS_DEBUG_MEM
+int KJSO::count = 0;
+int Imp::count = 0;
+int List::count = 0;
+#endif
+
+Imp::Imp()
+  : refcount(0), prop(0), proto(0)
+{
+  setCreated(true);
+#ifdef KJS_DEBUG_MEM
+  count++;
+#endif
+}
+
+Imp::~Imp()
+{
+#ifdef KJS_DEBUG_MEM
+  assert(Collector::collecting);
+  count--;
+#endif
+
+// dangling pointer during garbage collection !
+//   if (proto)
+//     proto->deref();
+
+  // delete attached properties
+  Property *tmp, *p = prop;
+  while (p) {
+    tmp = p;
+    p = p->next;
+    delete tmp;
+  }
+}
+
+KJSO Imp::toPrimitive(Type preferred) const
+{
+  return defaultValue(preferred);
+  /* TODO: is there still any need to throw a runtime error _here_ ? */
+}
+
+Boolean Imp::toBoolean() const
+{
+  return Boolean();
+}
+
+Number Imp::toNumber() const
+{
+  return Number();
+}
+
+String Imp::toString() const
+{
+  return String();
+}
+
+Object Imp::toObject() const
+{
+  return Object(Error::create(TypeError).imp());
+}
+
+
+PropList* Imp::propList(PropList *first, PropList *last, bool recursive) const
+{
+  Property *pr = prop;
+  while(pr) {
+    if (!(pr->attribute & DontEnum) && !first->contains(pr->name)) {
+      if(last) {
+        last->next = new PropList();
+	last = last->next;
+      } else {
+        first = new PropList();
+	last = first;
+      }
+      last->name = pr->name;
+    }
+    pr = pr->next;
+  }
+  if (proto && recursive)
+    proto->propList(first, last);
+
+  return first;
+}
+
+KJSO Imp::get(const UString &p) const
+{
+  Property *pr = prop;
+  while (pr) {
+    if (pr->name == p) {
+      return pr->object;
+    }
+    pr = pr->next;
+  }
+
+  if (!proto)
+    return Undefined();
+
+  return proto->get(p);
+}
+
+// may be overriden
+void Imp::put(const UString &p, const KJSO& v)
+{
+  put(p, v, None);
+}
+
+// ECMA 8.6.2.2
+void Imp::put(const UString &p, const KJSO& v, int attr)
+{
+  /* TODO: check for write permissions directly w/o this call */
+  // putValue() is used for JS assignemnts. It passes no attribute.
+  // Assume that a C++ implementation knows what it is doing
+  // and let it override the canPut() check.
+  if (attr == None && !canPut(p))
+    return;
+
+  Property *pr;
+
+  if (prop) {
+    pr = prop;
+    while (pr) {
+      if (pr->name == p) {
+	// replace old value
+	pr->object = v.imp();
+	pr->attribute = attr;
+	return;
+      }
+      pr = pr->next;
+    }
+  }
+
+  // add new property
+  pr = new Property;
+  pr->name = p;
+  pr->object = v.imp();
+  pr->attribute = attr;
+  pr->next = prop;
+  prop = pr;
+}
+
+// ECMA 8.6.2.3
+bool Imp::canPut(const UString &p) const
+{
+  if (prop) {
+    const Property *pr = prop;
+    while (pr) {
+      if (pr->name == p)
+	return !(pr->attribute & ReadOnly);
+      pr = pr->next;
+    }
+  }
+  if (!proto)
+    return true;
+
+  return proto->canPut(p);
+}
+
+// ECMA 8.6.2.4
+bool Imp::hasProperty(const UString &p, bool recursive) const
+{
+  const Property *pr = prop;
+  while (pr) {
+    if (pr->name == p)
+      return true;
+    pr = pr->next;
+  }
+
+  if (!proto || !recursive)
+    return false;
+
+  return proto->hasProperty(p);
+}
+
+// ECMA 8.6.2.5
+bool Imp::deleteProperty(const UString &p)
+{
+  Property *pr = prop;
+  Property **prev = &prop;
+  while (pr) {
+    if (pr->name == p) {
+      if ((pr->attribute & DontDelete))
+	return false;
+      *prev = pr->next;
+      delete pr;
+      return true;
+    }
+    prev = &(pr->next);
+    pr = pr->next;
+  }
+  return true;
+}
+
+// ECMA 15.4.5.1
+void Imp::putArrayElement(const UString &p, const KJSO& v)
+{
+  if (!canPut(p))
+    return;
+
+  if (hasProperty(p)) {
+    if (p == "length") {
+      KJSO len = get("length");
+      unsigned int oldLen = len.toUInt32();
+      unsigned int newLen = v.toUInt32();
+      // shrink array
+      for (unsigned int u = newLen; u < oldLen; u++) {
+	UString p = UString::from(u);
+	if (hasProperty(p, false))
+	  deleteProperty(p);
+      }
+      put("length", Number(newLen), DontEnum | DontDelete);
+      return;
+    }
+    //    put(p, v);
+    } //  } else
+    put(p, v);
+
+  // array index ?
+  unsigned int idx;
+  if (!sscanf(p.cstring().c_str(), "%u", &idx)) /* TODO */
+    return;
+
+  // do we need to update/create the length property ?
+  if (hasProperty("length", false)) {
+    KJSO len = get("length");
+    if (idx < len.toUInt32())
+      return;
+  }
+
+  put("length", Number(idx+1), DontDelete | DontEnum);
+}
+
+bool Imp::implementsCall() const
+{
+  return (type() == FunctionType ||
+	  type() == InternalFunctionType ||
+	  type() == ConstructorType ||
+	  type() == DeclaredFunctionType ||
+	  type() == AnonymousFunctionType);
+}
+
+// ECMA 8.6.2.6 (new draft)
+KJSO Imp::defaultValue(Type hint) const
+{
+  KJSO o;
+
+  /* TODO String on Date object */
+  if (hint != StringType && hint != NumberType)
+    hint = NumberType;
+
+  if (hint == StringType)
+    o = get("toString");
+  else
+    o = get("valueOf");
+
+  Imp *that = const_cast<Imp*>(this);
+  if (o.implementsCall()) { // spec says "not primitive type" but ...
+    FunctionImp *f = static_cast<FunctionImp*>(o.imp());
+    KJSO s = f->executeCall(that, 0L);
+    if (!s.isObject())
+      return s;
+  }
+
+  if (hint == StringType)
+    o = get("valueOf");
+  else
+    o = get("toString");
+
+  if (o.implementsCall()) {
+    FunctionImp *f = static_cast<FunctionImp*>(o.imp());
+    KJSO s = f->executeCall(that, 0L);
+    if (!s.isObject())
+      return s;
+  }
+
+  return Error::create(TypeError, I18N_NOOP("No default value"));
+}
+
+void Imp::mark(Imp*)
+{
+  setMarked(true);
+
+  if (proto && !proto->marked())
+    proto->mark();
+
+  struct Property *p = prop;
+  while (p) {
+    if (p->object && !p->object->marked())
+      p->object->mark();
+    p = p->next;
+  }
+}
+
+bool Imp::marked() const
+{
+  return prev;
+}
+
+void Imp::setPrototype(const KJSO& p)
+{
+  if (proto)
+    proto->deref();
+  proto = p.imp();
+  if (proto)
+    proto->ref();
+}
+
+void Imp::setPrototypeProperty(const KJSO &p)
+{
+  put("prototype", p, DontEnum | DontDelete | ReadOnly);
+}
+
+void Imp::setConstructor(const KJSO& c)
+{
+  put("constructor", c, DontEnum | DontDelete | ReadOnly);
+}
+
+void* Imp::operator new(size_t s)
+{
+  return Collector::allocate(s);
+}
+
+void Imp::operator delete(void*, size_t)
+{
+  // deprecated. a mistake.
+}
+
+void Imp::operator delete(void*)
+{
+  // Do nothing. So far.
+}
+
+void Imp::setMarked(bool m)
+{
+  prev = m ? this : 0L;
+}
+
+void Imp::setGcAllowed(bool a)
+{
+  next = this;
+  if (a)
+    next++;
+}
+
+bool Imp::gcAllowed() const
+{
+  return (next && next != this);
+}
+
+void Imp::setCreated(bool c)
+{
+  next = c ? this : 0L;
+}
+
+bool Imp::created() const
+{
+  return next;
+}
+
+ObjectImp::ObjectImp(Class c) : cl(c), val(0L) { }
+
+ObjectImp::ObjectImp(Class c, const KJSO &v) : cl(c), val(v.imp()) { }
+
+ObjectImp::ObjectImp(Class c, const KJSO &v, const KJSO &p)
+  : cl(c), val(v.imp())
+{
+  setPrototype(p);
+}
+
+ObjectImp::~ObjectImp() { }
+
+Boolean ObjectImp::toBoolean() const
+{
+  return Boolean(true);
+}
+
+Number ObjectImp::toNumber() const
+{
+  return toPrimitive(NumberType).toNumber();
+}
+
+String ObjectImp::toString() const
+{
+  KJSO tmp;
+  String res;
+
+  if (hasProperty("toString") && (tmp = get("toString")).implementsCall()) {
+    // TODO live w/o hack
+    res = tmp.executeCall(KJSO(const_cast<ObjectImp*>(this)), 0L).toString();
+  } else {
+    tmp = toPrimitive(StringType);
+    res = tmp.toString();
+  }
+
+  return res;
+}
+
+const TypeInfo ObjectImp::info = { "Object", ObjectType, 0, 0, 0 };
+
+Object ObjectImp::toObject() const
+{
+  return Object(const_cast<ObjectImp*>(this));
+}
+
+KJSO ObjectImp::toPrimitive(Type preferred) const
+{
+  // ### Imp already does that now. Remove in KDE 3.0.
+  return defaultValue(preferred);
+  /* TODO: is there still any need to throw a runtime error _here_ ? */
+}
+
+void ObjectImp::mark(Imp*)
+{
+  // mark objects from the base
+  Imp::mark();
+
+  // mark internal value, if any and it has not been visited yet
+  if (val && !val->marked())
+    val->mark();
+}
+
+HostImp::HostImp()
+{
+    setPrototype(Global::current().objectPrototype());
+    //printf("HostImp::HostImp() %p\n",this);
+}
+
+HostImp::~HostImp() { }
+
+Boolean HostImp::toBoolean() const
+{
+  return Boolean(true);
+}
+
+String HostImp::toString() const
+{
+  // Exact copy of ObjectImp::toString....
+  KJSO tmp;
+  String res;
+
+  if (hasProperty("toString") && (tmp = get("toString")).implementsCall()) {
+    // TODO live w/o hack
+    res = tmp.executeCall(KJSO(const_cast<HostImp*>(this)), 0L).toString();
+  } else {
+    tmp = toPrimitive(StringType);
+    res = tmp.toString();
+  }
+
+  return res;
+}
+
+const TypeInfo HostImp::info = { "HostObject", HostType, 0, 0, 0 };
+
+Object Error::createObject(ErrorType e, const char *m, int l)
+{
+  Context *context = Context::current();
+  if (!context)
+    return Object();
+
+  Object err = ErrorObject::create(e, m, l);
+
+  if (!KJScriptImp::hadException())
+    KJScriptImp::setException(err.imp());
+
+  const struct ErrorStruct {
+      ErrorType e;
+      const char *s;
+  } errtab[] = {
+      { GeneralError, I18N_NOOP("General error") },
+      { EvalError, I18N_NOOP("Evaluation error") },
+      { RangeError, I18N_NOOP("Range error") },
+      { ReferenceError, I18N_NOOP("Reference error") },
+      { SyntaxError, I18N_NOOP("Syntax error") },
+      { TypeError, I18N_NOOP("Type error") },
+      { URIError, I18N_NOOP("URI error") },
+      { (ErrorType)0, 0 }
+  };
+
+  const char *estr = I18N_NOOP("Unknown error");
+  const ErrorStruct *estruct = errtab;
+  while (estruct->e) {
+      if (estruct->e == e) {
+	  estr = estruct->s;
+	  break;
+      }
+      estruct++;
+  }
+
+#ifndef NDEBUG
+  const char *msg = err.get("message").toString().value().ascii();
+  if (l >= 0)
+      fprintf(stderr, "JS: %s at line %d. %s\n", estr, l, msg);
+  else
+      fprintf(stderr, "JS: %s. %s\n", estr, msg);
+#endif
+
+  return err;
+}
+
+KJSO Error::create(ErrorType e, const char *m, int l)
+{
+  return KJSO(createObject(e, m, l).imp());
+}
diff --git a/WebCore/src/kdelibs/kjs/object.h b/WebCore/src/kdelibs/kjs/object.h
new file mode 100644
index 0000000..7daee7e
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/object.h
@@ -0,0 +1,640 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2001 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _KJS_OBJECT_H_
+#define _KJS_OBJECT_H_
+
+#include <stdlib.h>
+
+#include "ustring.h"
+
+/**
+ * @short Main namespace
+ */
+namespace KJS {
+
+  /**
+   * Types of classes derived from KJSO
+   */
+  enum Type { // main types
+              AbstractType = 1,
+              UndefinedType,
+	      NullType,
+	      BooleanType,
+	      NumberType,
+	      StringType,
+	      ObjectType,
+	      HostType,
+	      ReferenceType,
+              CompletionType,
+	      // extended types
+	      FunctionType,
+	      InternalFunctionType,
+	      DeclaredFunctionType,
+	      AnonymousFunctionType,
+	      ConstructorType,
+	      ActivationType
+  };
+
+  /**
+   * Property attributes.
+   */
+  enum Attribute { None       = 0,
+		   ReadOnly   = 1 << 1,
+		   DontEnum   = 1 << 2,
+		   DontDelete = 1 << 3,
+		   Internal   = 1 << 4 };
+
+  /**
+   * Types of classes derived from @ref Object.
+   */
+  enum Class { UndefClass,
+	       ArrayClass,
+	       StringClass,
+	       BooleanClass,
+	       NumberClass,
+	       ObjectClass,
+	       DateClass,
+	       RegExpClass,
+	       ErrorClass,
+	       FunctionClass };
+
+  /**
+   * Completion types.
+   */
+  enum Compl { Normal, Break, Continue, ReturnValue, Throw };
+
+  /**
+   * Error codes.
+   */
+  enum ErrorType { NoError = 0,
+		   GeneralError,
+		   EvalError,
+		   RangeError,
+		   ReferenceError,
+		   SyntaxError,
+		   TypeError,
+		   URIError };
+
+  extern const double NaN;
+  extern const double Inf;
+
+  // forward declarations
+  class Imp;
+  class Boolean;
+  class Number;
+  class String;
+  class Object;
+  struct Property;
+  class PropList;
+  class List;
+
+  /**
+   * @short Type information.
+   */
+  struct TypeInfo {
+    /**
+     * A string denoting the type name. Example: "Number".
+     */
+    const char *name;
+    /**
+     * One of the @ref KJS::Type enums.
+     */
+    Type type;
+    /**
+     * Pointer to the type information of the base class.
+     * NULL if there is none.
+     */
+    const TypeInfo *base;
+    /**
+     * Additional specifier for your own use.
+     */
+    int extra;
+    /**
+     * Reserved for future extensions (internal).
+     */
+    void *dummy;
+  };
+
+  /**
+   * @short Main base class for every KJS object.
+   */
+  class KJSO {
+    friend class ElementNode;
+  public:
+    /**
+     * Constructor.
+     */
+    KJSO();
+    /**
+     * @internal
+     */
+    KJSO(Imp *d);
+    /**
+     * Copy constructor.
+     */
+    KJSO(const KJSO &);
+    /*
+     * Assignment operator
+     */
+    KJSO& operator=(const KJSO &);
+    /**
+     * Destructor.
+     */
+    virtual ~KJSO();
+    /**
+     * @return True if this object is null, i.e. if there is no data attached
+     * to this object. Don't confuse this with the Null object.
+     */
+    bool isNull() const;
+    /**
+     * @return True if this objects is of any other value than Undefined.
+     */
+    bool isDefined() const;
+    /**
+     * @return the type of the object. One of the @ref KJS::Type enums.
+     */
+    Type type() const;
+    /**
+     * Check whether object is of a certain type
+     * @param t type to check for
+     */
+    bool isA(Type t) const { return (type() == t); }
+    /**
+     * Check whether object is of a certain type. Allows checking of
+     * host objects, too.
+     * @param type name (Number, Boolean etc.)
+     */
+    bool isA(const char *s) const;
+    /**
+     * Use this method when checking for objects. It's safer than checking
+     * for a single object type with @ref isA().
+     */
+    bool isObject() const;
+    /**
+     * Examine the inheritance structure of this object.
+     * @param t Name of the base class.
+     * @return True if object is of type t or a derived from such a type.
+     */
+    bool derivedFrom(const char *s) const;
+
+    /**
+     * @return Conversion to primitive type (Undefined, Boolean, Number
+     * or String)
+     * @param preferred Optional hint. Either StringType or NumberType.
+     */
+    KJSO toPrimitive(Type preferred = UndefinedType) const; // ECMA 9.1
+    /**
+     * @return Conversion to Boolean type.
+     */
+    Boolean toBoolean() const; // ECMA 9.2
+    /**
+     * @return Conversion to Number type.
+     */
+    Number toNumber() const; // ECMA 9.3
+    /**
+     * @return Conversion to double. 0.0 if conversion failed.
+     */
+    double round() const;
+    /**
+     * @return Conversion to Number type containing an integer value.
+     */
+    Number toInteger() const; // ECMA 9.4
+    /**
+     * @return Conversion to signed integer value.
+     */
+    int toInt32() const; // ECMA 9.5
+    /**
+     * @return Conversion to unsigned integer value.
+     */
+    unsigned int toUInt32() const; // ECMA 9.6
+    /**
+     * @return Conversion to unsigned short value.
+     */
+    unsigned short toUInt16() const; // ECMA 9.7
+    /**
+     * @return Conversion to String type.
+     */
+    String toString() const; // ECMA 9.8
+    /**
+     * @return Conversion to Object type.
+     */
+    Object toObject() const; // ECMA 9.9
+
+    // Properties
+    /**
+     * Set the internal [[Prototype]] property of this object.
+     * @param p A prototype object.
+     */
+    void setPrototype(const KJSO &p);
+    /**
+     * Set the "prototype" property of this object. Different from
+     * the internal [[Prototype]] property.
+     * @param p A prototype object.
+     */
+    void setPrototypeProperty(const KJSO &p);
+    /**
+     * @return The internal [[prototype]] property.
+     */
+    KJSO prototype() const;
+    /**
+     * The internal [[Get]] method.
+     * @return The value of property p.
+     */
+    KJSO get(const UString &p) const;
+    /**
+     * The internal [[HasProperty]] method.
+     * @param p Property name.
+     * @param recursive Indicates whether prototypes are searched as well.
+     * @return Boolean value indicating whether the object already has a
+     * member with the given name p.
+     */
+    bool hasProperty(const UString &p, bool recursive = true) const;
+    /**
+     * The internal [[Put]] method. Sets the specified property to the value v.
+     * @param p Property name.
+     * @param v Value.
+     */
+    void put(const UString &p, const KJSO& v);
+    /**
+     * The internal [[CanPut]] method.
+     * @param p Property name.
+     * @return A boolean value indicating whether a [[Put]] operation with
+     * p succeed.
+     */
+    bool canPut(const UString &p) const;
+    /**
+     * The internal [[Delete]] method. Removes the specified property from
+     * the object.
+     * @param p Property name.
+     * @return True if the property was deleted successfully or didn't exist
+     * in the first place. False if the DontDelete attribute was set.
+     */
+    bool deleteProperty(const UString &p);
+    /**
+     * Same as above put() method except the additional attribute. Right now,
+     * this only works with native types as Host Objects don't reimplement
+     * this method.
+     * @param attr One of @ref KJS::Attribute.
+     */
+    void put(const UString &p, const KJSO& v, int attr);
+    /**
+     * Convenience function for adding a Number property constructed from
+     * a double value.
+     */
+    void put(const UString &p, double d, int attr = None);
+    /**
+     * Convenience function for adding a Number property constructed from
+     * an integer value.
+     */
+    void put(const UString &p, int i, int attr = None);
+    /**
+     * Convenience function for adding a Number property constructed from
+     * an unsigned integer value.
+     */
+    void put(const UString &p, unsigned int u, int attr = None);
+
+    /**
+     * Reference method.
+     * @return Reference base if object is a reference. Throws
+     * a ReferenceError otherwise.
+     */
+    KJSO getBase() const;
+    /**
+     * Reference method.
+     * @return Property name of a reference. Null string if object is not
+     * a reference.
+     */
+    UString getPropertyName() const;
+    /**
+     * Reference method.
+     * @return Referenced value. This object if no reference.
+     */
+    KJSO getValue() const;
+    KJSO getValue();  	/* TODO: remove in next version */
+    /**
+     * Reference method. Set referenced value to v.
+     */
+    ErrorType putValue(const KJSO& v);
+
+    /**
+     * @return True if object supports @ref executeCall() method. That's the
+     * case for all objects derived from FunctionType.
+     */
+    bool implementsCall() const;
+    /**
+     * Execute function implemented via the @ref Function::execute() method.
+     *
+     * Note: check availability via @ref implementsCall() beforehand.
+     * @param thisV Object serving as the 'this' value.
+     * @param args Pointer to the list of arguments or null.
+     * @return Result of the function call.
+     */
+    KJSO executeCall(const KJSO &thisV, const List *args);
+    KJSO executeCall(const KJSO &thisV, const List *args, const List *extraScope) const;
+
+    /**
+     * Set this object's constructor.
+     */
+    void setConstructor(KJSO c);
+
+    /**
+     * @return A Pointer to the internal implementation.
+     */
+    Imp *imp() const { return rep; }
+
+#ifdef KJS_DEBUG_MEM
+    /**
+     * @internal
+     */
+    static int count;
+#endif
+  protected:
+    /**
+     * Pointer to the internal implementation.
+     */
+    Imp *rep;
+
+  private:
+    void putArrayElement(const UString &p, const KJSO &v);
+  }; // end of KJSO
+
+  /**
+   * @short Base for all implementation classes.
+   */
+  class Imp {
+    friend class KJSO;
+    friend class Collector;
+    friend class ForInNode;
+    friend class Debugger;
+  public:
+    Imp();
+  public:
+    virtual KJSO toPrimitive(Type preferred = UndefinedType) const; // ECMA 9.1
+    virtual Boolean toBoolean() const; // ECMA 9.2
+    virtual Number toNumber() const; // ECMA 9.3
+    virtual String toString() const; // ECMA 9.8
+    virtual Object toObject() const; // ECMA 9.9
+
+    // properties
+    virtual KJSO get(const UString &p) const;
+    virtual bool hasProperty(const UString &p, bool recursive = true) const;
+    virtual void put(const UString &p, const KJSO& v);
+    void put(const UString &p, const KJSO& v, int attr);
+    virtual bool canPut(const UString &p) const;
+    virtual bool deleteProperty(const UString &p);
+    virtual KJSO defaultValue(Type hint) const;
+
+    bool implementsCall() const;
+
+    /**
+     * @internal Reserved for mark & sweep garbage collection
+     */
+    virtual void mark(Imp *imp = 0L);
+    bool marked() const;
+
+    Type type() const { return typeInfo()->type; }
+    /**
+     * @return The TypeInfo struct describing this object.
+     */
+    virtual const TypeInfo* typeInfo() const { return &info; }
+
+    void setPrototype(const KJSO& p);
+    Imp* prototype() const { return proto; }
+    void setPrototypeProperty(const KJSO &p);
+    void setConstructor(const KJSO& c);
+
+    void* operator new(size_t);
+    void operator delete(void*);
+    /**
+     * @deprecated
+     */
+    void operator delete(void*, size_t);
+
+#ifdef KJS_DEBUG_MEM
+    /**
+     * @internal
+     */
+    static int count;
+#endif
+  protected:
+    virtual ~Imp();
+  private:
+    Imp(const Imp&);
+    Imp& operator=(const Imp&);
+    void putArrayElement(const UString &p, const KJSO& v);
+
+    /**
+     * Get the property names for this object. To be used by for .. in loops
+     * @return The (pointer to the) first element of a PropList, to be deleted
+     * by the caller, or 0 if there are no enumerable properties
+     */
+    PropList *propList(PropList *first = 0L, PropList *last = 0L,
+		       bool recursive = true) const;
+
+  public:
+    // reference counting mechanism
+    inline Imp* ref() { refcount++; return this; }
+    inline bool deref() { return (!--refcount); }
+    unsigned int refcount;
+
+  private:
+    Property *prop;
+    Imp *proto;
+    static const TypeInfo info;
+
+    // reserved for memory managment - currently used as flags for garbage collection
+    // (prev != 0) = marked, (next != 0) = created, (next != this) = created and gc allowed
+    Imp *prev, *next;
+    // for future extensions
+    class ImpInternal;
+    ImpInternal *internal;
+
+    void setMarked(bool m);
+    void setGcAllowed(bool a);
+    bool gcAllowed() const;
+    void setCreated(bool c);
+    bool created() const;
+  };
+
+  /**
+   * @short General implementation class for Objects
+   */
+  class ObjectImp : public Imp {
+    friend class Object;
+  public:
+    ObjectImp(Class c);
+    ObjectImp(Class c, const KJSO &v);
+    ObjectImp(Class c, const KJSO &v, const KJSO &p);
+    virtual ~ObjectImp();
+    virtual KJSO toPrimitive(Type preferred = UndefinedType) const;
+    virtual Boolean toBoolean() const;
+    virtual Number toNumber() const;
+    virtual String toString() const;
+    virtual Object toObject() const;
+
+    virtual const TypeInfo* typeInfo() const { return &info; }
+    static const TypeInfo info;
+    /**
+     * @internal Reimplemenation of @ref Imp::mark().
+     */
+    virtual void mark(Imp *imp = 0L);
+  private:
+    Class cl;
+    Imp *val;
+  };
+
+  /**
+   * @short Object class encapsulating an internal value.
+   */
+  class Object : public KJSO {
+  public:
+    Object(Imp *d);
+    Object(Class c = UndefClass);
+    Object(Class c, const KJSO& v);
+    Object(Class c, const KJSO& v, const Object& p);
+    virtual ~Object();
+    void setClass(Class c);
+    Class getClass() const;
+    void setInternalValue(const KJSO& v);
+    KJSO internalValue();
+    static Object create(Class c);
+    static Object create(Class c, const KJSO& val);
+    static Object create(Class c, const KJSO& val, const Object &p);
+    static Object dynamicCast(const KJSO &obj);
+  };
+
+  /**
+   * @short Implementation base class for Host Objects.
+   */
+  class HostImp : public Imp {
+  public:
+    HostImp();
+    virtual ~HostImp();
+    virtual const TypeInfo* typeInfo() const { return &info; }
+
+    virtual Boolean toBoolean() const;
+    virtual String toString() const;
+
+    static const TypeInfo info;
+  };
+
+  class KJScriptImp;
+  /**
+   * The Global object represents the global namespace. It holds the native
+   * objects like String and functions like eval().
+   *
+   * It also serves as a container for variables created by the user, i.e.
+   * the statement
+   * <pre>
+   *   var i = 2;
+   * </pre>
+   * will basically perform a Global::current().put("i", Number(2)); operation.
+   *
+   * @short Unique global object containing initial native properties.
+   */
+  class Global : public Object {
+    friend class KJScriptImp;
+  public:
+    /**
+     * Constructs a Global object. This is done by the interpreter once and
+     * there should be no need to create an instance on your own. Usually,
+     * you'll just want to access the current instance.
+     * For example like this:
+     * <pre>
+     * Global global(Global::current());
+     * KJSO proto = global.objectPrototype();
+     * </pre>
+     */
+    Global();
+    /**
+     * Destruct the Global object.
+     */
+    virtual ~Global();
+    /**
+     * @return A reference to the Global object belonging to the current
+     * interpreter instance.
+     */
+    static Global current();
+    /**
+     * @return A handle to Object.prototype.
+     */
+    KJSO objectPrototype() const;
+    /**
+     * @return A handle to Function.prototype.
+     */
+    KJSO functionPrototype() const;
+    /**
+     * Set a filter object that will intercept all put() and get() calls
+     * to the global object. If this object returns Undefined on get() the
+     * request will be passed on the global object.
+     * @deprecated
+     */
+    void setFilter(const KJSO &f);
+    /**
+     * Return a handle to the filter object (see @ref setFilter()).
+     * Null if no filter has been installed.
+     * @deprecated
+     */
+    KJSO filter() const;
+    /**
+     * Returns the extra user data set for this global object. Null by default.
+     * Typical usage if you need to query any info related to the currently
+     * running interpreter:
+     *
+     *    MyMainWindow *m = (MyMainWindow*)Global::current().extra();
+     */
+    void *extra() const;
+    /**
+     * Set the extra user data for this global object. It's not used by the
+     * interpreter itself and can therefore be used to bind arbitrary data
+     * to each interpreter instance.
+     */
+    void setExtra(void *e);
+  private:
+    Global(void *);
+    void init();
+    void clear();
+  };
+
+  /**
+   * @short Factory methods for error objects.
+   */
+  class Error {
+  public:
+    /**
+     * Factory method for error objects. The error will be registered globally
+     * and the execution will continue as if a "throw" statement was
+     * encountered.
+     * @param e Type of error.
+     * @param m Optional error message.
+     * @param l Optional line number.
+     */
+    static KJSO create(ErrorType e, const char *m = 0, int l = -1);
+    /**
+     * Same as above except the different return type (which is not casted
+     * here).
+     */
+    static Object createObject(ErrorType e, const char *m = 0, int l = -1);
+  };
+
+}; // namespace
+
+#endif
diff --git a/WebCore/src/kdelibs/kjs/object_object.cpp b/WebCore/src/kdelibs/kjs/object_object.cpp
new file mode 100644
index 0000000..80f98ed
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/object_object.cpp
@@ -0,0 +1,152 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "kjs.h"
+#include "operations.h"
+#include "object_object.h"
+#include "types.h"
+#include <stdio.h>
+
+using namespace KJS;
+
+ObjectObject::ObjectObject(const Object &funcProto, const Object &objProto)
+    : ConstructorImp(funcProto, 1)
+{
+  // ECMA 15.2.3.1
+  setPrototypeProperty(objProto);
+}
+
+Completion ObjectObject::execute(const List &args)
+{
+  KJSO result;
+
+  List argList;
+  if (args.isEmpty()) {
+    result = construct(argList);
+  } else {
+    KJSO arg = args[0];
+    if (arg.isA(NullType) || arg.isA(UndefinedType)) {
+      argList.append(arg);
+      result = construct(argList);
+    } else
+      result = arg.toObject();
+  }
+  return Completion(ReturnValue, result);
+}
+
+// ECMA 15.2.2
+Object ObjectObject::construct(const List &args)
+{
+  // if no arguments have been passed ...
+  if (args.isEmpty())
+    return Object::create(ObjectClass);
+
+  KJSO arg = *args.begin();
+  Object obj = Object::dynamicCast(arg);
+  if (!obj.isNull()) {
+    /* TODO: handle host objects */
+    return obj;
+  }
+
+  switch (arg.type()) {
+  case StringType:
+  case BooleanType:
+  case NumberType:
+    return arg.toObject();
+  default:
+    assert(!"unhandled switch case in ObjectConstructor");
+  case NullType:
+  case UndefinedType:
+    return Object::create(ObjectClass);
+  }
+}
+
+ObjectPrototype::ObjectPrototype()
+  : ObjectImp(ObjectClass)
+{
+  // the spec says that [[Property]] should be `null'.
+  // Not sure if Null or C's NULL is needed.
+}
+
+bool ObjectPrototype::hasProperty(const UString &p, bool recursive) const
+{
+    if ( p == "toString" || p == "valueOf" )
+        return true;
+    return /*recursive &&*/ ObjectImp::hasProperty(p, recursive);
+}
+
+KJSO ObjectPrototype::get(const UString &p) const
+{
+  if (p == "toString")
+    return Function(new ObjectProtoFunc(ToString));
+  else if (p == "valueOf")
+    return Function(new ObjectProtoFunc(ValueOf));
+  else
+    return Imp::get(p);
+}
+
+ObjectProtoFunc::ObjectProtoFunc(int i)
+  : id(i)
+{
+}
+
+// ECMA 15.2.4.2 + 15.2.4.3
+Completion ObjectProtoFunc::execute(const List &)
+{
+  Object thisObj = Object::dynamicCast(thisValue());
+
+  /* TODO: what to do with non-objects. Is this possible at all ? */
+  // Yes, this happens with Host Object at least (David)
+  if (thisObj.isNull()) {
+    UString str = "[object ";
+    str += thisValue().isNull() ? "null" : thisValue().imp()->typeInfo()->name;
+    str += "]";
+    return Completion(ReturnValue, String(str));
+  }
+
+  // valueOf()
+  if (id == ObjectPrototype::ValueOf)
+    /* TODO: host objects*/
+    return Completion(ReturnValue, thisObj);
+
+  // toString()
+  UString str;
+  switch(thisObj.getClass()) {
+  case StringClass:
+    str = "[object String]";
+    break;
+  case BooleanClass:
+    str = "[object Boolean]";
+    break;
+  case NumberClass:
+    str = "[object Number]";
+    break;
+  case ObjectClass:
+  {
+    str = "[object ";
+    str += thisValue().isNull() ? "Object" : thisValue().imp()->typeInfo()->name;
+    str += "]";
+    break;
+  }
+  default:
+    str = "[undefined object]";
+  }
+
+  return Completion(ReturnValue, String(str));
+}
diff --git a/WebCore/src/kdelibs/kjs/object_object.h b/WebCore/src/kdelibs/kjs/object_object.h
new file mode 100644
index 0000000..7f8703e
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/object_object.h
@@ -0,0 +1,53 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _OBJECT_OBJECT_H_
+#define _OBJECT_OBJECT_H_
+
+#include "object.h"
+#include "function.h"
+
+namespace KJS {
+
+  class ObjectObject : public ConstructorImp {
+  public:
+    ObjectObject(const Object &funcProto, const Object &objProto);
+    Completion execute(const List &);
+    Object construct(const List &);
+  };
+
+  class ObjectPrototype : public ObjectImp {
+  public:
+    ObjectPrototype();
+    bool hasProperty(const UString &p, bool recursive) const;
+    KJSO get(const UString &p) const;
+    enum { ToString, ValueOf };
+  };
+
+  class ObjectProtoFunc : public InternalFunctionImp {
+  public:
+    ObjectProtoFunc(int i);
+    Completion execute(const List &);
+  private:
+    int id;
+  };
+
+}; // namespace
+
+#endif
diff --git a/WebCore/src/kdelibs/kjs/operations.cpp b/WebCore/src/kdelibs/kjs/operations.cpp
new file mode 100644
index 0000000..95e6022
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/operations.cpp
@@ -0,0 +1,224 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#ifndef HAVE_FLOAT_H   /* just for !Windows */
+#define HAVE_FLOAT_H 0
+#define HAVE_FUNC__FINITE 0
+#endif
+
+#include <stdio.h>
+#include <assert.h>
+#include <math.h>
+#include <stdlib.h>
+
+#ifndef HAVE_FUNC_ISINF
+#ifdef HAVE_IEEEFP_H
+#include <ieeefp.h>
+#endif
+#endif /* HAVE_FUNC_ISINF */
+
+#if HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+#include "object.h"
+#include "types.h"
+#include "operations.h"
+
+using namespace KJS;
+
+bool KJS::isNaN(double d)
+{
+#ifdef HAVE_FUNC_ISNAN
+  return isnan(d);
+#elif defined HAVE_FLOAT_H
+  return _isnan(d) != 0;
+#else
+  return !(d == d);
+#endif
+}
+
+bool KJS::isInf(double d)
+{
+#if defined(HAVE_FUNC_ISINF)
+  return isinf(d);
+#elif HAVE_FUNC_FINITE
+  return finite(d) == 0 && d == d;
+#elif HAVE_FUNC__FINITE
+  return _finite(d) == 0 && d == d;
+#else
+  return false;
+#endif
+}
+
+// ECMA 11.9.3
+bool KJS::equal(const KJSO& v1, const KJSO& v2)
+{
+  Type t1 = v1.type();
+  Type t2 = v2.type();
+
+  if (t1 == t2) {
+    if (t1 == UndefinedType || t1 == NullType)
+      return true;
+    if (t1 == NumberType)
+      return (v1.toNumber().value() == v2.toNumber().value()); /* TODO: NaN, -0 ? */
+    if (t1 == StringType)
+      return (v1.toString().value() == v2.toString().value());
+    if (t1 == BooleanType)
+      return (v1.toBoolean().value() == v2.toBoolean().value());
+    if (t1 == HostType) {
+	KJSO h1 = v1.get("[[==]]");
+	KJSO h2 = v2.get("[[==]]");
+	if (!h1.isA(UndefinedType) && !h2.isA(UndefinedType))
+	    return equal(h1, h2);
+    }
+    return (v1.imp() == v2.imp());
+  }
+
+  // different types
+  if ((t1 == NullType && t2 == UndefinedType) || (t1 == UndefinedType && t2 == NullType))
+    return true;
+  if (t1 == NumberType && t2 == StringType) {
+    Number n2 = v2.toNumber();
+    return equal(v1, n2);
+  }
+  if ((t1 == StringType && t2 == NumberType) || t1 == BooleanType) {
+    Number n1 = v1.toNumber();
+    return equal(n1, v2);
+  }
+  if (t2 == BooleanType) {
+    Number n2 = v2.toNumber();
+    return equal(v1, n2);
+  }
+  if ((t1 == StringType || t1 == NumberType) && t2 >= ObjectType) {
+    KJSO p2 = v2.toPrimitive();
+    return equal(v1, p2);
+  }
+  if (t1 >= ObjectType && (t2 == StringType || t2 == NumberType)) {
+    KJSO p1 = v1.toPrimitive();
+    return equal(p1, v2);
+  }
+
+  return false;
+}
+
+bool KJS::strictEqual(const KJSO &v1, const KJSO &v2)
+{
+  Type t1 = v1.type();
+  Type t2 = v2.type();
+
+  if (t1 != t2)
+    return false;
+  if (t1 == UndefinedType || t1 == NullType)
+    return true;
+  if (t1 == NumberType) {
+    double n1 = v1.toNumber().value();
+    double n2 = v2.toNumber().value();
+    if (isNaN(n1) || isNaN(n2))
+      return false;
+    if (n1 == n2)
+      return true;
+    /* TODO: +0 and -0 */
+    return false;
+  } else if (t1 == StringType) {
+    return v1.toString().value() == v2.toString().value();
+  } else if (t2 == BooleanType) {
+    return v1.toBoolean().value() == v2.toBoolean().value();
+  }
+  if (v1.imp() == v2.imp())
+    return true;
+  /* TODO: joined objects */
+
+  return false;
+}
+
+int KJS::relation(const KJSO& v1, const KJSO& v2)
+{
+  KJSO p1 = v1.toPrimitive(NumberType);
+  KJSO p2 = v2.toPrimitive(NumberType);
+
+  if (p1.isA(StringType) && p2.isA(StringType))
+    return p1.toString().value() < p2.toString().value() ? 1 : 0;
+
+  Number n1 = p1.toNumber();
+  Number n2 = p2.toNumber();
+  /* TODO: check for NaN */
+  if (n1.value() == n2.value())
+    return 0;
+  /* TODO: +0, -0 and Infinity */
+  return (n1.value() < n2.value());
+}
+
+double KJS::max(double d1, double d2)
+{
+  /* TODO: check for NaN */
+  return (d1 > d2) ? d1 : d2;
+}
+
+double KJS::min(double d1, double d2)
+{
+  /* TODO: check for NaN */
+  return (d1 < d2) ? d1 : d2;
+}
+
+// ECMA 11.6
+KJSO KJS::add(const KJSO &v1, const KJSO &v2, char oper)
+{
+  KJSO p1 = v1.toPrimitive();
+  KJSO p2 = v2.toPrimitive();
+
+  if ((p1.isA(StringType) || p2.isA(StringType)) && oper == '+') {
+    String s1 = p1.toString();
+    String s2 = p2.toString();
+
+    UString s = s1.value() + s2.value();
+
+    return String(s);
+  }
+
+  Number n1 = p1.toNumber();
+  Number n2 = p2.toNumber();
+
+  if (oper == '+')
+    return Number(n1.value() + n2.value());
+  else
+    return Number(n1.value() - n2.value());
+}
+
+// ECMA 11.5
+KJSO KJS::mult(const KJSO &v1, const KJSO &v2, char oper)
+{
+  Number n1 = v1.toNumber();
+  Number n2 = v2.toNumber();
+
+  double result;
+
+  if (oper == '*')
+    result = n1.value() * n2.value();
+  else if (oper == '/')
+    result = n1.value() / n2.value();
+  else
+    result = fmod(n1.value(), n2.value());
+
+  return Number(result);
+}
diff --git a/WebCore/src/kdelibs/kjs/operations.h b/WebCore/src/kdelibs/kjs/operations.h
new file mode 100644
index 0000000..d3b0246
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/operations.h
@@ -0,0 +1,67 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _KJS_OPERATIONS_H_
+#define _KJS_OPERATIONS_H_
+
+#include "object.h"
+
+namespace KJS {
+
+  /**
+   * @return True if d is not a number (platform support required).
+   */
+  bool isNaN(double d);
+  /**
+   * @return True if d is infinite (platform support required).
+   */
+  bool isInf(double d);
+  bool equal(const KJSO& v1, const KJSO& v2);
+  bool strictEqual(const KJSO &v1, const KJSO &v2);
+  /**
+   * This operator performs an abstract relational comparision of the two
+   * arguments that can be of arbitrary type. If possible, conversions to the
+   * string or number type will take place before the comparison.
+   *
+   * @return 1 if v1 is "less-than" v2, 0 if the relation is "greater-than-or-
+   * equal". -1 if the result is undefined.
+   */
+  int relation(const KJSO& v1, const KJSO& v2);
+  double max(double d1, double d2);
+  double min(double d1, double d2);
+  /**
+   * Additive operator. Either performs an addition or substraction of v1
+   * and v2.
+   * @param oper '+' or '-' for an addition or substraction, respectively.
+   * @return The result of the operation.
+   */
+  KJSO add(const KJSO &v1, const KJSO &v2, char oper);
+  /**
+   * Multiplicative operator. Either multiplies/divides v1 and v2 or
+   * calculates the remainder from an division.
+   * @param oper '*', '/' or '%' for a multiplication, division or
+   * modulo operation.
+   * @return The result of the operation.
+   */
+  KJSO mult(const KJSO &v1, const KJSO &v2, char oper);
+
+};
+
+#endif
diff --git a/WebCore/src/kdelibs/kjs/regexp.cpp b/WebCore/src/kdelibs/kjs/regexp.cpp
new file mode 100644
index 0000000..84368e7
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/regexp.cpp
@@ -0,0 +1,68 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2001 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdio.h>
+
+#include "object.h"
+#include "regexp.h"
+
+using namespace KJS;
+
+RegExp::RegExp(const UString &p, int f)
+ : pattern(p), flags(f)
+{
+#ifdef REG_EXTENDED    
+  regcomp(&preg, p.ascii(), REG_EXTENDED);
+#else
+  regcomp(&preg, p.ascii(), 0);  
+#endif  
+  /* TODO use flags, check for errors */
+}
+
+RegExp::~RegExp()
+{
+  /* TODO: is this really okay after an error ? */
+  regfree(&preg);
+}
+
+UString RegExp::match(const UString &s, int i, int *pos)
+{
+  regmatch_t rmatch[10];
+
+  if (i < 0)
+    i = 0;
+
+  if (i > s.size() || s.isNull() ||
+      regexec(&preg, s.ascii() + i, 10, rmatch, 0)) {
+    if (pos)
+      *pos = -1;
+    return UString::null;
+  }
+
+  if (pos)
+    *pos = rmatch[0].rm_so + i;
+  return s.substr(rmatch[0].rm_so + i, rmatch[0].rm_eo - rmatch[0].rm_so);
+}
+
+bool RegExp::test(const UString &s, int)
+{
+  int r = regexec(&preg, s.ascii(), 0, 0, 0);
+
+  return r == 0;
+}
diff --git a/WebCore/src/kdelibs/kjs/regexp.h b/WebCore/src/kdelibs/kjs/regexp.h
new file mode 100644
index 0000000..9a4b2b2
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/regexp.h
@@ -0,0 +1,56 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _KJS_REGEXP_H_
+#define _KJS_REGEXP_H_
+
+#include <sys/types.h>
+
+#include "config.h"
+
+#ifdef HAVE_PCREPOSIX
+#include <pcreposix.h>
+#else  // POSIX regex - not so good...
+extern "C" { // bug with some libc5 distributions
+#include <regex.h>
+}
+#endif //HAVE_PCREPOSIX
+
+#include "ustring.h"
+
+namespace KJS {
+
+  class RegExp {
+  public:
+    enum { None, Global, IgnoreCase, Multiline };
+    RegExp(const UString &p, int f = None);
+    ~RegExp();
+    UString match(const UString &s, int i = -1, int *pos = 0L);
+    bool test(const UString &s, int i = -1);
+  private:
+    const UString &pattern;
+    int flags;
+    regex_t preg;
+
+    RegExp();
+  };
+
+}; // namespace
+
+#endif
diff --git a/WebCore/src/kdelibs/kjs/regexp_object.cpp b/WebCore/src/kdelibs/kjs/regexp_object.cpp
new file mode 100644
index 0000000..b7e6b12
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/regexp_object.cpp
@@ -0,0 +1,146 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdio.h>
+
+#include "kjs.h"
+#include "operations.h"
+#include "types.h"
+#include "internal.h"
+#include "regexp.h"
+#include "regexp_object.h"
+
+using namespace KJS;
+
+RegExpObject::RegExpObject(const Object& funcProto, const Object &regProto)
+    : ConstructorImp(funcProto, 2)
+{
+  // ECMA 15.10.5.1 RegExp.prototype
+  setPrototypeProperty(regProto);
+}
+
+// ECMA 15.9.2
+Completion RegExpObject::execute(const List &)
+{
+  return Completion(ReturnValue, Undefined());
+}
+
+// ECMA 15.9.3
+Object RegExpObject::construct(const List &args)
+{
+  /* TODO: regexp arguments */
+  String p = args[0].toString();
+  String f = args[1].toString();
+  UString flags = f.value();
+
+  RegExpImp *dat = new RegExpImp();
+  Object obj(dat); // protect from GC
+
+  bool global = (flags.find("g") >= 0);
+  bool ignoreCase = (flags.find("i") >= 0);
+  bool multiline = (flags.find("m") >= 0);
+  /* TODO: throw an error on invalid flags */
+
+  dat->put("global", Boolean(global));
+  dat->put("ignoreCase", Boolean(ignoreCase));
+  dat->put("multiline", Boolean(multiline));
+
+  dat->put("source", String(p.value()));
+  dat->put("lastIndex", 0, DontDelete | DontEnum);
+
+  dat->setRegExp(new RegExp(p.value() /* TODO flags */));
+  obj.setClass(RegExpClass);
+  obj.setPrototype(Global::current().get("[[RegExp.prototype]]"));
+
+  return obj;
+}
+
+// ECMA 15.9.4
+RegExpPrototype::RegExpPrototype(const Object& proto)
+  : ObjectImp(RegExpClass, String(""), proto)
+{
+  // The constructor will be added later in RegExpObject's constructor
+}
+
+KJSO RegExpPrototype::get(const UString &p) const
+{
+  int id = -1;
+  if (p == "exec")
+    id = RegExpProtoFunc::Exec;
+  else if (p == "test")
+    id = RegExpProtoFunc::Test;
+  else if (p == "toString")
+    id = RegExpProtoFunc::ToString;
+
+  if (id >= 0)
+    return Function(new RegExpProtoFunc(id));
+  else
+    return Imp::get(p);
+}
+
+Completion RegExpProtoFunc::execute(const List &args)
+{
+  KJSO result;
+
+  Object thisObj = Object::dynamicCast(thisValue());
+
+  if (thisObj.getClass() != RegExpClass) {
+    result = Error::create(TypeError);
+    return Completion(ReturnValue, result);
+  }
+
+  RegExp *re = static_cast<RegExpImp*>(thisObj.imp())->regExp();
+  String s;
+  KJSO lastIndex, tmp;
+  UString str;
+  int length, i;
+  switch (id) {
+  case Exec:
+  case Test:
+    s = args[0].toString();
+    length = s.value().size();
+    lastIndex = thisObj.get("lastIndex");
+    i = lastIndex.toInt32();
+    tmp = thisObj.get("global");
+    if (tmp.toBoolean().value() == false)
+      i = 0;
+    if (i < 0 || i > length) {
+      thisObj.put("lastIndex", 0);
+      result = Null();
+      break;
+    }
+    str = re->match(s.value(), i);
+    if (id == Test) {
+      result = Boolean(str.size() != 0);
+      break;
+    }
+    /* TODO complete */
+    result = String(str);
+    break;
+  case ToString:
+    s = thisObj.get("source").toString();
+    str = "/";
+    str += s.value();
+    str += "/";
+    result = String(str);
+    break;
+  }
+
+  return Completion(ReturnValue, result);
+}
diff --git a/WebCore/src/kdelibs/kjs/regexp_object.h b/WebCore/src/kdelibs/kjs/regexp_object.h
new file mode 100644
index 0000000..a5af288
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/regexp_object.h
@@ -0,0 +1,52 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _REGEXP_OBJECT_H_
+#define _REGEXP_OBJECT_H_
+
+#include "object.h"
+#include "function.h"
+
+namespace KJS {
+
+  class RegExpObject : public ConstructorImp {
+  public:
+    RegExpObject(const Object& funcProto, const Object &regProto);
+    Completion execute(const List &);
+    Object construct(const List &);
+  };
+
+  class RegExpPrototype : public ObjectImp {
+  public:
+    RegExpPrototype(const Object& proto);
+    KJSO get(const UString &p) const;
+  };
+
+  class RegExpProtoFunc : public InternalFunctionImp {
+  public:
+    RegExpProtoFunc(int i) : id(i) { }
+    Completion execute(const List &);
+    enum { Exec, Test, ToString };
+  private:
+    int id;
+  };
+
+}; // namespace
+
+#endif
diff --git a/WebCore/src/kdelibs/kjs/string_object.cpp b/WebCore/src/kdelibs/kjs/string_object.cpp
new file mode 100644
index 0000000..8e088bc
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/string_object.cpp
@@ -0,0 +1,419 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2001 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "kjs.h"
+#include "operations.h"
+#include "types.h"
+#include "regexp.h"
+#include "string_object.h"
+#include <stdio.h>
+
+using namespace KJS;
+
+StringObject::StringObject(const Object &funcProto, const Object &stringProto)
+  : ConstructorImp(funcProto, 1)
+{
+  // ECMA 15.5.3.1 String.prototype
+  setPrototypeProperty(stringProto);
+}
+
+KJSO StringObject::get(const UString &p) const
+{
+  if (p == "fromCharCode")
+    return Function(new StringObjectFunc());
+  else
+    return Imp::get(p);
+}
+
+// ECMA 15.5.1
+Completion StringObject::execute(const List &args)
+{
+  KJSO v;
+  String s;
+
+  if (args.isEmpty())
+    s = String("");
+  else {
+    v = args[0];
+    s = v.toString();
+  }
+
+  return Completion(ReturnValue, s);
+}
+
+// ECMA 15.5.2
+Object StringObject::construct(const List &args)
+{
+  String s;
+  if (args.size() > 0)
+    s = args.begin()->toString();
+  else
+    s = String("");
+
+  return Object::create(StringClass, s);
+}
+
+// ECMA 15.5.3.2 fromCharCode()
+Completion StringObjectFunc::execute(const List &args)
+{
+  UString s;
+  if (args.size()) {
+    UChar *buf = new UChar[args.size()];
+    UChar *p = buf;
+    ListIterator it = args.begin();
+    while (it != args.end()) {
+      unsigned short u = it->toUInt16();
+      *p++ = UChar(u);
+      it++;
+    }
+    s = UString(buf, args.size(), false);
+  } else
+    s = "";
+
+  return Completion(ReturnValue, String(s));
+}
+
+// ECMA 15.5.4
+StringPrototype::StringPrototype(const Object& proto)
+  : ObjectImp(StringClass, String(""), proto)
+{
+  // The constructor will be added later in StringObject's constructor
+}
+
+KJSO StringPrototype::get(const UString &p) const
+{
+  int id;
+
+  if (p == "toString")
+    id = StringProtoFunc::ToString;
+  else if (p == "valueOf")
+    id = StringProtoFunc::ValueOf;
+  else if (p == "charAt")
+    id = StringProtoFunc::CharAt;
+  else if (p == "charCodeAt")
+    id = StringProtoFunc::CharCodeAt;
+  else if (p == "indexOf")
+    id = StringProtoFunc::IndexOf;
+  else if (p == "lastIndexOf")
+    id = StringProtoFunc::LastIndexOf;
+  else if (p == "match")
+    id = StringProtoFunc::Match;
+  else if (p == "replace")
+    id = StringProtoFunc::Replace;
+  else if (p == "search")
+    id = StringProtoFunc::Search;
+  else if (p == "split")
+    id = StringProtoFunc::Split;
+  else if (p == "substr")
+    id = StringProtoFunc::Substr;
+  else if (p == "substring")
+    id = StringProtoFunc::Substring;
+  else if (p == "toLowerCase")
+    id = StringProtoFunc::ToLowerCase;
+  else if (p == "toUpperCase")
+    id = StringProtoFunc::ToUpperCase;
+#ifndef KJS_PURE_ECMA
+  else if (p == "big")
+    id = StringProtoFunc::Big;
+  else if (p == "small")
+    id = StringProtoFunc::Small;
+  else if (p == "blink")
+    id = StringProtoFunc::Blink;
+  else if (p == "bold")
+    id = StringProtoFunc::Bold;
+  else if (p == "fixed")
+    id = StringProtoFunc::Fixed;
+  else if (p == "italics")
+    id = StringProtoFunc::Italics;
+  else if (p == "strike")
+    id = StringProtoFunc::Strike;
+  else if (p == "sub")
+    id = StringProtoFunc::Sub;
+  else if (p == "sup")
+    id = StringProtoFunc::Sup;
+  else if (p == "fontcolor")
+    id = StringProtoFunc::Fontcolor;
+  else if (p == "fontsize")
+    id = StringProtoFunc::Fontsize;
+  else if (p == "anchor")
+    id = StringProtoFunc::Anchor;
+  else if (p == "link")
+    id = StringProtoFunc::Link;
+#endif
+  else
+    return Imp::get(p);
+
+  return Function(new StringProtoFunc(id));
+}
+
+StringProtoFunc::StringProtoFunc(int i)
+  : id(i)
+{
+}
+
+// ECMA 15.5.4.2 - 15.5.4.20
+Completion StringProtoFunc::execute(const List &args)
+{
+  KJSO result;
+
+  Object thisObj = Object::dynamicCast(thisValue());
+
+  // toString and valueOf are no generic function.
+  if (id == ToString || id == ValueOf) {
+    if (thisObj.isNull() || thisObj.getClass() != StringClass) {
+      result = Error::create(TypeError);
+      return Completion(ReturnValue, result);
+    }
+  }
+
+  String s2;
+  Number n, m;
+  UString u, u2, u3;
+  int pos, p0, i;
+  double d, d2;
+  KJSO v = thisObj.internalValue();
+  String s = v.toString();
+  int len = s.value().size();
+  KJSO a0 = args[0];
+  KJSO a1 = args[1];
+
+  switch (id) {
+  case ToString:
+  case ValueOf:
+    result = v.toString();
+    break;
+  case CharAt:
+    n = a0.toInteger();
+    pos = (int) n.value();
+    if (pos < 0 || pos >= len)
+      u = "";
+    else
+      u = s.value().substr(pos, 1);
+    result = String(u);
+    break;
+  case CharCodeAt:
+    n = a0.toInteger();
+    pos = (int) n.value();
+    if (pos < 0 || pos >= len)
+      d = NaN;
+    else {
+      UChar c = s.value()[pos];
+      d = (c.high() << 8) + c.low();
+    }
+    result = Number(d);
+    break;
+  case IndexOf:
+    s2 = a0.toString();
+    if (a1.isA(UndefinedType))
+      pos = 0;
+    else
+      pos = a1.toInteger().intValue();
+    d = s.value().find(s2.value(), pos);
+    result = Number(d);
+    break;
+  case LastIndexOf:
+    s2 = a0.toString();
+    if (a1.isA(UndefinedType))
+      pos = len;
+    else
+      pos = a1.toInteger().intValue();
+    d = s.value().rfind(s2.value(), pos);
+    result = Number(d);
+    break;
+  case Match:
+  case Search:
+    u = s.value();
+    if (a0.isA(ObjectType) && a0.toObject().getClass() == RegExpClass) {
+      s2 = a0.get("source").toString();
+      RegExp reg(s2.value());
+      UString mstr = reg.match(u, -1, &pos);
+      if (id == Search) {
+        result = Number(pos);
+        break;
+      }
+      if (mstr.isNull()) {
+	result = Null();
+	break;
+      }
+      /* TODO return an array, with the matches, etc. */
+      result = String(mstr);
+    } else
+    {
+      printf("Match/Search. Argument is not a RegExp - returning Undefined\n");
+      result = Undefined(); // No idea what to do here
+    }
+    break;
+  case Replace:
+    /* TODO: this is just a hack to get the most common cases going */
+    u = s.value();
+    if (a0.isA(ObjectType) && a0.toObject().getClass() == RegExpClass) {
+      s2 = a0.get("source").toString();
+      RegExp reg(s2.value());
+      UString mstr = reg.match(u, -1, &pos);
+      len = mstr.size();
+    } else {
+      s2 = a0.toString();
+      u2 = s2.value();
+      pos = u.find(u2);
+      len = u2.size();
+    }
+    if (pos == -1)
+	result = s;
+    else {
+	u3 = u.substr(0, pos) + a1.toString().value() +
+	     u.substr(pos + len);
+	result = String(u3);
+    }
+    break;
+  case Split:
+    result = Object::create(ArrayClass);
+    u = s.value();
+    i = p0 = 0;
+    d = a1.isDefined() ? a1.toInteger().intValue() : -1; // optional max number
+    if (a0.isA(ObjectType) && Object(a0.imp()).getClass() == RegExpClass) {
+      RegExp reg(a0.get("source").toString().value());
+      if (u.isEmpty() && !reg.match(u, 0).isNull()) {
+	// empty string matched by regexp -> empty array
+	result.put("length", 0);
+	break;
+      }
+      int mpos;
+      pos = 0;
+      while (1) {
+	/* TODO: back references */
+	UString mstr = reg.match(u, pos, &mpos);
+	if (mpos < 0)
+	  break;
+	pos = mpos + (mstr.isEmpty() ? 1 : mstr.size());
+	if (mpos != p0 || !mstr.isEmpty()) {
+	  result.put(UString::from(i), String(u.substr(p0, mpos-p0)));
+	  p0 = mpos + mstr.size();
+	  i++;
+	}
+      }
+    } else if (a0.isDefined()) {
+      u2 = a0.toString().value();
+      if (u2.isEmpty()) {
+	if (u.isEmpty()) {
+	  // empty separator matches empty string -> empty array
+	  put("length", 0);
+	  break;
+	} else {
+	  while (i != d && i < u.size())
+	    result.put(UString::from(i++), String(u.substr(p0++, 1)));
+	}
+      } else {
+	while (i != d && (pos = u.find(u2, p0)) >= 0) {
+	  result.put(UString::from(i), String(u.substr(p0, pos-p0)));
+	  p0 = pos + u2.size();
+	  i++;
+	}
+      }
+    }
+    // add remaining string, if any
+    if (i != d && (p0 < len || i == 0))
+      result.put(UString::from(i++), String(u.substr(p0)));
+    result.put("length", i);
+    break;
+  case Substr:
+    n = a0.toInteger();
+    m = a1.toInteger();
+    if (n.value() >= 0)
+      d = n.value();
+    else
+      d = max(len + n.value(), 0);
+    if (a1.isA(UndefinedType))
+      d2 = len - d;
+    else
+      d2 = min(max(m.value(), 0), len - d);
+    result = String(s.value().substr((int)d, (int)d2));
+    break;
+  case Substring:
+    n = a0.toInteger();
+    m = a1.toInteger();
+    d = min(max(n.value(), 0), len);
+    if (a1.isA(UndefinedType))
+      d2 = len - d;
+    else {
+      d2 = min(max(m.value(), 0), len);
+      d2 = max(d2-d, 0);
+    }
+    result = String(s.value().substr((int)d, (int)d2));
+    break;
+  case ToLowerCase:
+    u = UString(s.value());
+    for (i = 0; i < len; i++)
+      u[i] = u[i].toLower();
+    result = String(u);
+    break;
+  case ToUpperCase:
+    u = UString(s.value());
+    for (i = 0; i < len; i++)
+      u[i] = u[i].toUpper();
+    result = String(u);
+    break;
+#ifndef KJS_PURE_ECMA
+  case Big:
+    result = String("<BIG>" + s.value() + "</BIG>");
+    break;
+  case Small:
+    result = String("<SMALL>" + s.value() + "</SMALL>");
+    break;
+  case Blink:
+    result = String("<BLINK>" + s.value() + "</BLINK>");
+    break;
+  case Bold:
+    result = String("<B>" + s.value() + "</B>");
+    break;
+  case Fixed:
+    result = String("<TT>" + s.value() + "</TT>");
+    break;
+  case Italics:
+    result = String("<I>" + s.value() + "</I>");
+    break;
+  case Strike:
+    result = String("<STRIKE>" + s.value() + "</STRIKE>");
+    break;
+  case Sub:
+    result = String("<SUB>" + s.value() + "</SUB>");
+    break;
+  case Sup:
+    result = String("<SUP>" + s.value() + "</SUP>");
+    break;
+  case Fontcolor:
+    result = String("<FONT COLOR=" + a0.toString().value() + ">"
+		    + s.value() + "</FONT>");
+    break;
+  case Fontsize:
+    result = String("<FONT SIZE=" + a0.toString().value() + ">"
+		    + s.value() + "</FONT>");
+    break;
+  case Anchor:
+    result = String("<a name=" + a0.toString().value() + ">"
+		    + s.value() + "</a>");
+    break;
+  case Link:
+    result = String("<a href=" + a0.toString().value() + ">"
+		    + s.value() + "</a>");
+    break;
+#endif
+  }
+
+  return Completion(ReturnValue, result);
+}
diff --git a/WebCore/src/kdelibs/kjs/string_object.h b/WebCore/src/kdelibs/kjs/string_object.h
new file mode 100644
index 0000000..5396750
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/string_object.h
@@ -0,0 +1,66 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _STRING_OBJECT_H_
+#define _STRING_OBJECT_H_
+
+#include "object.h"
+#include "function.h"
+
+namespace KJS {
+
+  class StringObject : public ConstructorImp {
+  public:
+    StringObject(const Object &funcProto, const Object &stringProto);
+    KJSO get(const UString &p) const;
+    Completion execute(const List &);
+    Object construct(const List &);
+  };
+
+  class StringObjectFunc : public InternalFunctionImp {
+  public:
+    Completion execute(const List &);
+  };
+
+  class StringPrototype : public ObjectImp {
+  public:
+    StringPrototype(const Object& proto);
+    KJSO get(const UString &p) const;
+  };
+
+  class StringProtoFunc : public InternalFunctionImp {
+  public:
+    StringProtoFunc(int i);
+    Completion execute(const List &);
+
+    enum { ToString, ValueOf, CharAt, CharCodeAt, IndexOf, LastIndexOf,
+	   Match, Replace, Search, Slice, Split,
+	   Substr, Substring, FromCharCode, ToLowerCase, ToUpperCase
+#ifndef KJS_PURE_ECMA
+	   , Big, Small, Blink, Bold, Fixed, Italics, Strike, Sub, Sup,
+	   Fontcolor, Fontsize, Anchor, Link
+#endif
+    };
+  private:
+    int id;
+  };
+
+}; // namespace
+
+#endif
diff --git a/WebCore/src/kdelibs/kjs/test.js b/WebCore/src/kdelibs/kjs/test.js
new file mode 100644
index 0000000..f5bbf5b
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/test.js
@@ -0,0 +1,29 @@
+var i = 0;
+
+function sum(a, b)
+{
+ debug("inside test()");
+ i = i + 1;
+ debug(a);
+ debug(b);
+ return a + b;
+}
+
+s = sum(10, sum(20, 30));
+debug("s = " + s);
+debug("i = " + i);
+
+var a = new Array(11, 22, 33, 44);
+a.length = 2;
+a[4] = 'apple';
+
+for(i = 0; i != a.length; i++)
+  debug("a[" + i + "] = " + a[i]);
+
+var b = new Boolean(1==1);
+b.toString=Object.prototype.toString;
+debug("b = " + b.toString());
+
+// regular expression
+rx = /b*c/;
+debug(rx.exec("abbbcd"));
diff --git a/WebCore/src/kdelibs/kjs/testkjs.cpp b/WebCore/src/kdelibs/kjs/testkjs.cpp
new file mode 100644
index 0000000..afb04b0
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/testkjs.cpp
@@ -0,0 +1,80 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+
+#include "kjs.h"
+
+#include "object.h"
+#include "types.h"
+#include "internal.h"
+
+int main(int argc, char **argv)
+{
+  // expecting a filename
+  if (argc < 2) {
+    fprintf(stderr, "You have to specify at least one filename\n");
+    return -1;
+  }
+
+  // create interpreter
+  KJScript *kjs = new KJScript();
+
+  // add debug() function
+  kjs->enableDebug();
+
+  const int BufferSize = 100000;
+  char code[BufferSize];
+
+  bool ret = true;
+  for (int i = 1; i < argc; i++) {
+    const char *file = argv[i];
+    FILE *f = fopen(file, "r");
+    if (!f) {
+      fprintf(stderr, "Error opening %s.\n", file);
+      return -1;
+    }
+    int num = fread(code, 1, BufferSize, f);
+    code[num] = '\0';
+    if(num >= BufferSize)
+      fprintf(stderr, "Warning: File may have been too long.\n");
+
+    // run
+    ret = ret && kjs->evaluate(code);
+    if (kjs->errorType() != 0)
+      printf("%s returned: %s\n", file, kjs->errorMsg());
+    else if (kjs->returnValue())
+      printf("returned a value\n");
+
+    fclose(f);
+  }
+
+  delete kjs;
+
+#ifdef KJS_DEBUG_MEM
+  printf("List::count = %d\n", KJS::List::count);
+  assert(KJS::List::count == 0);
+  printf("Imp::count = %d\n", KJS::Imp::count);
+  assert(KJS::Imp::count == 0);
+#endif
+
+  fprintf(stderr, "OK.\n");
+  return ret;
+}
diff --git a/WebCore/src/kdelibs/kjs/types.cpp b/WebCore/src/kdelibs/kjs/types.cpp
new file mode 100644
index 0000000..682e607
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/types.cpp
@@ -0,0 +1,299 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+
+#include "kjs.h"
+#include "object.h"
+#include "types.h"
+#include "internal.h"
+#include "operations.h"
+#include "nodes.h"
+
+using namespace KJS;
+
+Undefined::Undefined() : KJSO(UndefinedImp::staticUndefined) { }
+
+Undefined::~Undefined() { }
+
+Null::Null() : KJSO(NullImp::staticNull) { }
+
+Null::~Null() { }
+
+Boolean::Boolean(bool b)
+  : KJSO(b ? BooleanImp::staticTrue : BooleanImp::staticFalse)
+{
+}
+
+Boolean::Boolean(BooleanImp *i) : KJSO(i) { }
+
+Boolean::~Boolean() { }
+
+bool Boolean::value() const
+{
+  assert(rep);
+  return ((BooleanImp*)rep)->value();
+}
+
+Number::Number(int i)
+  : KJSO(new NumberImp(static_cast<double>(i))) { }
+
+Number::Number(unsigned int u)
+  : KJSO(new NumberImp(static_cast<double>(u))) { }
+
+Number::Number(double d)
+  : KJSO(new NumberImp(d)) { }
+
+Number::Number(long int l)
+  : KJSO(new NumberImp(static_cast<double>(l))) { }
+
+Number::Number(long unsigned int l)
+  : KJSO(new NumberImp(static_cast<double>(l))) { }
+
+Number::Number(NumberImp *i)
+  : KJSO(i) { }
+
+Number::~Number() { }
+
+double Number::value() const
+{
+  assert(rep);
+  return ((NumberImp*)rep)->value();
+}
+
+int Number::intValue() const
+{
+  assert(rep);
+  return (int)((NumberImp*)rep)->value();
+}
+
+bool Number::isNaN() const
+{
+  return KJS::isNaN(((NumberImp*)rep)->value());
+}
+
+bool Number::isInf() const
+{
+  return KJS::isInf(((NumberImp*)rep)->value());
+}
+
+String::String(const UString &s) : KJSO(new StringImp(UString(s))) { }
+
+String::String(StringImp *i) : KJSO(i) { }
+
+String::~String() { }
+
+UString String::value() const
+{
+  assert(rep);
+  return ((StringImp*)rep)->value();
+}
+
+Reference::Reference(const KJSO& b, const UString &p)
+  : KJSO(new ReferenceImp(b, p))
+{
+}
+
+Reference::~Reference()
+{
+}
+
+Completion::Completion(Imp *d) : KJSO(d) { }
+
+Completion::Completion(Compl c)
+  : KJSO(new CompletionImp(c, KJSO(), UString::null))
+{
+  if (c == Throw)
+    KJScriptImp::setException(new UndefinedImp());
+}
+
+Completion::Completion(Compl c, const KJSO& v, const UString &t)
+  : KJSO(new CompletionImp(c, v, t))
+{
+  if (c == Throw)
+    KJScriptImp::setException(v.imp());
+}
+
+Completion::~Completion() { }
+
+Compl Completion::complType() const
+{
+  assert(rep);
+  return ((CompletionImp*)rep)->completion();
+}
+
+bool Completion::isValueCompletion() const
+{
+  assert(rep);
+  return !((CompletionImp*)rep)->value().isNull();
+}
+
+KJSO Completion::value() const
+{
+  assert(isA(CompletionType));
+  return ((CompletionImp*)rep)->value();
+}
+
+UString Completion::target() const
+{
+  assert(rep);
+  return ((CompletionImp*)rep)->target();
+}
+
+ListIterator::ListIterator(const List &l)
+  : node(l.hook->next)
+{
+}
+
+List::List()
+{
+#ifdef KJS_DEBUG_MEM
+  count++;
+#endif
+
+  static KJSO *null = 0;
+  if (!null)
+     null = new KJSO();
+
+  hook = new ListNode(*null, 0L, 0L);
+  hook->next = hook;
+  hook->prev = hook;
+}
+
+List::~List()
+{
+#ifdef KJS_DEBUG_MEM
+  count--;
+#endif
+
+  clear();
+  delete hook;
+}
+
+void List::append(const KJSO& obj)
+{
+  ListNode *n = new ListNode(obj, hook->prev, hook);
+  hook->prev->next = n;
+  hook->prev = n;
+}
+
+void List::prepend(const KJSO& obj)
+{
+  ListNode *n = new ListNode(obj, hook, hook->next);
+  hook->next->prev = n;
+  hook->next = n;
+}
+
+void List::removeFirst()
+{
+  erase(hook->next);
+}
+
+void List::removeLast()
+{
+  erase(hook->prev);
+}
+
+void List::remove(const KJSO &obj)
+{
+  if (obj.isNull())
+    return;
+  ListNode *n = hook->next;
+  while (n != hook) {
+    if (n->member.imp() == obj.imp()) {
+      erase(n);
+      return;
+    }
+    n = n->next;
+  }
+}
+
+void List::clear()
+{
+  ListNode *n = hook->next;
+  while (n != hook) {
+    n = n->next;
+    delete n->prev;
+  }
+
+  hook->next = hook;
+  hook->prev = hook;
+}
+
+List *List::copy() const
+{
+  List *newList = new List();
+  ListIterator e = end();
+  ListIterator it = begin();
+
+  while(it != e) {
+    newList->append(*it);
+    ++it;
+  }
+
+  return newList;
+}
+
+void List::erase(ListNode *n)
+{
+  if (n != hook) {
+    n->next->prev = n->prev;
+    n->prev->next = n->next;
+    delete n;
+  }
+}
+
+int List::size() const
+{
+  int s = 0;
+  ListNode *node = hook;
+  while ((node = node->next) != hook)
+    s++;
+
+  return s;
+}
+
+KJSO List::at(int i) const
+{
+  if (i < 0 || i >= size())
+    return Undefined();
+
+  ListIterator it = begin();
+  int j = 0;
+  while ((j++ < i))
+    it++;
+
+  return *it;
+}
+
+List *List::emptyList = 0L;
+
+const List *List::empty()
+{
+  if (!emptyList)
+    emptyList = new List;
+#ifdef KJS_DEBUG_MEM
+  else
+    count++;
+#endif
+
+
+  return emptyList;
+}
diff --git a/WebCore/src/kdelibs/kjs/types.h b/WebCore/src/kdelibs/kjs/types.h
new file mode 100644
index 0000000..c1bfac6
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/types.h
@@ -0,0 +1,355 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _TYPES_H_
+#define _TYPES_H_
+
+#include "object.h"
+
+namespace KJS {
+
+  /**
+   * @short Handle for an Undefined type.
+   */
+  class Undefined : public KJSO {
+  public:
+    Undefined();
+    virtual ~Undefined();
+  };
+
+  /**
+   * @short Handle for a Null type.
+   */
+  class Null : public KJSO {
+  public:
+    Null();
+    virtual ~Null();
+  };
+
+  class BooleanImp;
+  class NumberImp;
+  class StringImp;
+
+  /**
+   * @short Handle for a Boolean type.
+   */
+  class Boolean : public KJSO {
+    friend class BooleanImp;
+  public:
+    Boolean(bool b = false);
+    virtual ~Boolean();
+    bool value() const;
+  private:
+    Boolean(BooleanImp *i);
+  };
+
+  /**
+   * @short Handle for a Number type.
+   *
+   * Number is a handle for a number value. @ref KJSO::toPrimitive(),
+   * @ref KJSO::toBoolean(), @ref KJSO::toNumber(), @ref KJSO::toString() and
+   * @ref KJSO::toString() are re-implemented internally according to the
+   * specification.
+   *
+   * Example usage:
+   * <pre>
+   * Number a(2), b(3.0), c; // c defaults to 0.0
+   *
+   * c = a.value() * b.value(); // c will be 6.0 now
+   *
+   * String s = c.toString(); // s holds "6"
+   * </pre>
+   *
+   * Note the following implementation detail: Internally, the value is stored
+   * as a double and will be casted from and to other types when needed.
+   * This won't be noticable within a certain range of values but might produce
+   * unpredictable results when crossing these limits. In case this turns out
+   * to be a real problem for an application we might have to extend this class
+   * to behave more intelligently.
+   */
+  class Number : public KJSO {
+    friend class NumberImp;
+  public:
+    /**
+     * Construct a Number type from an integer.
+     */
+    Number(int i);
+    /**
+     * Construct a Number type from an unsigned integer.
+     */
+    Number(unsigned int u);
+    /**
+     * Construct a Number type from a double.
+     */
+    Number(double d = 0.0);
+    /**
+     * Construct a Number type from a long int.
+     */
+    Number(long int l);
+    /**
+     * Construct a Number type from a long unsigned int.
+     */
+    Number(long unsigned int l);
+    /**
+     * Destructor.
+     */
+    virtual ~Number();
+    /**
+     * @return The internally stored value.
+     */
+    double value() const;
+    /**
+     * Convenience function.
+     * @return The internally stored value converted to an int.
+     */
+    int intValue() const;
+    /**
+     * @return True is this is not a number (NaN).
+     */
+    bool isNaN() const;
+    /**
+     * @return True if Number is either +Infinity or -Infinity.
+     */
+    bool isInf() const;
+  private:
+    Number(NumberImp *i);
+  };
+
+  /**
+   * @short Handle for a String type.
+   */
+  class String : public KJSO {
+    friend class StringImp;
+  public:
+    String(const UString &s = "");
+    virtual ~String();
+    UString value() const;
+  private:
+    String(StringImp *i);
+  };
+
+  /**
+   * Completion objects are used to convey the return status and value
+   * from functions.
+   *
+   * See @ref FunctionImp::execute()
+   *
+   * @see FunctionImp
+   *
+   * @short Handle for a Completion type.
+   */
+  class Completion : public KJSO {
+  public:
+    Completion(Imp *d = 0L);
+    Completion(Compl c);
+    Completion(Compl c, const KJSO& v, const UString &t = UString::null);
+    virtual ~Completion();
+    Compl complType() const;
+    bool isValueCompletion() const;
+    KJSO value() const;
+    UString target() const;
+  };
+
+  class List;
+  class ListIterator;
+
+  /**
+   * @internal
+   */
+  class ListNode {
+    friend class List;
+    friend class ListIterator;
+    ListNode(KJSO obj, ListNode *p, ListNode *n)
+      : member(obj), prev(p), next(n) {};
+    KJSO member;
+    ListNode *prev, *next;
+  };
+
+  /**
+   * @short Iterator for @ref KJS::List objects.
+   */
+  class ListIterator {
+    friend class List;
+    ListIterator();
+    ListIterator(ListNode *n) : node(n) { }
+  public:
+    /**
+     * Construct an iterator that points to the first element of the list.
+     * @param l The list the iterator will operate on.
+     */
+    ListIterator(const List &list);
+    /**
+     * Assignment constructor.
+     */
+    ListIterator& operator=(const ListIterator &iterator)
+      { node=iterator.node; return *this; }
+    /**
+     * Copy constructor.
+     */
+    ListIterator(const ListIterator &i) : node(i.node) { }
+    /**
+     * Dereference the iterator.
+     * @return A pointer to the element the iterator operates on.
+     */
+    KJSO* operator->() const { return &node->member; }
+    //    operator KJSO* () const { return node->member; }
+    KJSO operator*() const { return node->member; }
+    /**
+     * Conversion to @ref KJS::KJSO*
+     * @return A pointer to the element the iterator operates on.
+     */
+    //    operator KJSO*() const { return node->member; }
+    /**
+     * Postfix increment operator.
+     * @return The element after the increment.
+     */
+    KJSO operator++() { node = node->next; return node->member; }
+    /**
+     * Prefix increment operator.
+     */
+    KJSO operator++(int) { const ListNode *n = node; ++*this; return n->member; }
+    /**
+     * Postfix decrement operator.
+     */
+    KJSO operator--() { node = node->prev; return node->member; }
+    /**
+     * Prefix decrement operator.
+     */
+    KJSO operator--(int) { const ListNode *n = node; --*this; return n->member; }
+    /**
+     * Compare the iterator with another one.
+     * @return True if the two iterators operate on the same list element.
+     * False otherwise.
+     */
+    bool operator==(const ListIterator &it) const { return (node==it.node); }
+    /**
+     * Check for inequality with another iterator.
+     * @return True if the two iterators operate on different list elements.
+     */
+    bool operator!=(const ListIterator &it) const { return (node!=it.node); }
+  private:
+    ListNode *node;
+  };
+
+  /**
+   * @short Native list type.
+   *
+   * List is a native ECMAScript type. List values are only used for
+   * intermediate results of expression evaluation and cannot be stored
+   * as properties of objects.
+   *
+   * The list is explicitly shared. Note that while copy() returns a deep
+   * copy of the list the referenced objects are still shared.
+   */
+  class List {
+    friend class ListIterator;
+  public:
+    /**
+     * Constructor.
+     */
+    List();
+    /**
+     * Destructor.
+     */
+    ~List();
+    /**
+     * Append an object to the end of the list.
+     *
+     * @param obj Pointer to object.
+     */
+    void append(const KJSO& obj);
+    /**
+     * Insert an object at the beginning of the list.
+     *
+     * @param obj Pointer to object.
+     */
+    void prepend(const KJSO& obj);
+    /**
+     * Remove the element at the beginning of the list.
+     */
+    void removeFirst();
+    /**
+     * Remove the element at the end of the list.
+     */
+    void removeLast();
+    /*
+     * Remove obj from list.
+     */
+    void remove(const KJSO &obj);
+    /**
+     * Remove all elements from the list.
+     */
+    void clear();
+    /**
+     * Returns a deep copy of the list. Ownership is passed to the user
+     * who is responsible for deleting the list then.
+     */
+    List *copy() const;
+    /**
+     * @return A @ref KJS::ListIterator pointing to the first element.
+     */
+    ListIterator begin() const { return ListIterator(hook->next); }
+    /**
+     * @return A @ref KJS::ListIterator pointing to the last element.
+     */
+    ListIterator end() const { return ListIterator(hook); }
+    /**
+     * @return true if the list is empty. false otherwise.
+     */
+    bool isEmpty() const { return (hook->prev == hook); }
+    /**
+     * @return the current size of the list.
+     */
+    int size() const;
+    /**
+     * Retrieve an element at an indexed position. If you want to iterate
+     * trough the whole list using @ref KJS::ListIterator will be faster.
+     *
+     * @param i List index.
+     * @return Return the element at position i. @ref KJS::Undefined if the
+     * index is out of range.
+     */
+    KJSO at(int i) const;
+    /**
+     * Equivalent to @ref at.
+     */
+    KJSO operator[](int i) const { return at(i); }
+    /**
+     * Returns a pointer to a static instance of an empty list. Useful if a
+     * function has a @ref KJS::List parameter.
+     */
+    static const List *empty();
+
+#ifdef KJS_DEBUG_MEM
+    /**
+     * @internal
+     */
+    static int count;
+#endif
+  private:
+    void erase(ListNode *n);
+    ListNode *hook;
+    static List *emptyList;
+  };
+
+}; // namespace
+
+
+#endif
diff --git a/WebCore/src/kdelibs/kjs/ustring.cpp b/WebCore/src/kdelibs/kjs/ustring.cpp
new file mode 100644
index 0000000..d547a04
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/ustring.cpp
@@ -0,0 +1,539 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
+#include "ustring.h"
+#include "operations.h"
+
+namespace KJS {
+  extern const double NaN;
+  extern const double Inf;
+};
+
+using namespace KJS;
+
+CString::CString(const char *c)
+{
+  data = new char[strlen(c)+1];
+  strcpy(data, c);
+}
+
+CString::CString(const CString &b)
+{
+  data = new char[b.size()+1];
+  strcpy(data, b.c_str());
+}
+
+CString::~CString()
+{
+  delete [] data;
+}
+
+CString &CString::append(const CString &t)
+{
+  char *n;
+  if (data) {
+    n = new char[strlen(data)+t.size()+1];
+    strcpy(n, data);
+  } else {
+    n = new char[t.size()+1];
+    n[0] = '\0';
+  }
+  strcat(n, t.c_str());
+
+  delete [] data;
+  data = n;
+
+  return *this;
+}
+
+CString &CString::operator=(const char *c)
+{
+  if (data)
+    delete [] data;
+  data = new char[strlen(c)+1];
+  strcpy(data, c);
+
+  return *this;
+}
+
+CString &CString::operator=(const CString &str)
+{
+  if (this == &str)
+    return *this;
+
+  if (data)
+    delete [] data;
+  data = new char[str.size()+1];
+  strcpy(data, str.c_str());
+
+  return *this;
+}
+
+CString &CString::operator+=(const CString &str)
+{
+  return append(str.c_str());
+}
+
+int CString::size() const
+{
+  return strlen(data);
+}
+
+bool KJS::operator==(const KJS::CString& c1, const KJS::CString& c2)
+{
+  return (strcmp(c1.c_str(), c2.c_str()) == 0);
+}
+
+UChar UChar::null;
+UString::Rep UString::Rep::null = { 0, 0, 1 };
+UString UString::null;
+static char *statBuffer = 0L;
+
+UChar::UChar(const UCharReference &c)
+#ifdef KJS_SWAPPED_CHAR
+  : lo(c.low()), hi(c.high())
+#else
+  : hi(c.high()), lo(c.low())
+#endif
+{
+}
+
+UChar UChar::toLower() const
+{
+  if (islower(lo) && hi == 0)
+    return *this;
+
+  return UChar(0, tolower(lo));
+}
+
+UChar UChar::toUpper() const
+{
+  if (isupper(lo) && hi == 0)
+    return *this;
+
+  return UChar(0, toupper(lo));
+}
+
+UCharReference& UCharReference::operator=(UChar c)
+{
+  str->detach();
+  if (offset < str->rep->len)
+    *(str->rep->dat + offset) = c;
+  /* TODO: lengthen string ? */
+  return *this;
+}
+
+UChar& UCharReference::ref() const
+{
+  if (offset < str->rep->len)
+    return *(str->rep->dat + offset);
+  else
+    return UChar::null;
+}
+
+UString::Rep *UString::Rep::create(UChar *d, int l)
+{
+  Rep *r = new Rep;
+  r->dat = d;
+  r->len = l;
+  r->rc = 1;
+
+  return r;
+}
+
+UString::UString()
+{
+  null.rep = &Rep::null;
+  attach(&Rep::null);
+}
+
+UString::UString(char c)
+{
+  rep = Rep::create(new UChar(0, c), 1);
+}
+
+UString::UString(const char *c)
+{
+  attach(&Rep::null);
+  operator=(c);
+}
+
+UString::UString(const UChar *c, int length)
+{
+  UChar *d = new UChar[length];
+  memcpy(d, c, length * sizeof(UChar));
+  rep = Rep::create(d, length);
+}
+
+UString::UString(UChar *c, int length, bool copy)
+{
+  UChar *d;
+  if (copy) {
+    d = new UChar[length];
+    memcpy(d, c, length * sizeof(UChar));
+  } else
+    d = c;
+  rep = Rep::create(d, length);
+}
+
+UString::UString(const UString &b)
+{
+  attach(b.rep);
+}
+
+UString::~UString()
+{
+  release();
+}
+
+UString UString::from(int i)
+{
+  char buf[40];
+  sprintf(buf, "%d", i);
+
+  return UString(buf);
+}
+
+UString UString::from(unsigned int u)
+{
+  char buf[40];
+  sprintf(buf, "%u", u);
+
+  return UString(buf);
+}
+
+UString UString::from(double d)
+{
+  char buf[40];
+  sprintf(buf, "%.16g", d);	// does the right thing
+  return UString(buf);
+}
+
+UString &UString::append(const UString &t)
+{
+  int l = size();
+  UChar *n = new UChar[l+t.size()];
+  memcpy(n, data(), l * sizeof(UChar));
+  memcpy(n+l, t.data(), t.size() * sizeof(UChar));
+  release();
+  rep = Rep::create(n, l + t.size());
+
+  return *this;
+}
+
+CString UString::cstring() const
+{
+  return CString(ascii());
+}
+
+char *UString::ascii() const
+{
+  if (statBuffer)
+    delete [] statBuffer;
+
+  statBuffer = new char[size()+1];
+  for(int i = 0; i < size(); i++)
+    statBuffer[i] = data()[i].lo;
+  statBuffer[size()] = '\0';
+
+  return statBuffer;
+}
+
+UString &UString::operator=(const char *c)
+{
+  release();
+  int l = c ? strlen(c) : 0;
+  UChar *d = new UChar[l];
+  for (int i = 0; i < l; i++)
+    d[i].lo = c[i];
+  rep = Rep::create(d, l);
+
+  return *this;
+}
+
+UString &UString::operator=(const UString &str)
+{
+  str.rep->ref();
+  release();
+  rep = str.rep;  
+
+  return *this;
+}
+
+UString &UString::operator+=(const UString &s)
+{
+  return append(s);
+}
+
+bool UString::is8Bit() const
+{
+  const UChar *u = data();
+  for(int i = 0; i < size(); i++, u++)
+    if (u->hi)
+      return false;
+
+  return true;
+}
+
+UChar UString::operator[](int pos) const
+{
+  if (pos >= size())
+    return UChar::null;
+
+  return ((UChar *)data())[pos];
+}
+
+UCharReference UString::operator[](int pos)
+{
+  /* TODO: boundary check */
+  return UCharReference(this, pos);
+}
+
+double UString::toDouble() const
+{
+  double d;
+
+  if (!is8Bit())
+    return NaN;
+
+  CString str = cstring();
+  const char *c = str.c_str();
+
+  // skip leading white space
+  while (isspace(*c))
+    c++;
+
+  // empty string ?
+  if (*c == '\0')
+    return 0.0;
+
+  // hex number ?
+  if (*c == '0' && (*(c+1) == 'x' || *(c+1) == 'X')) {
+    c++;
+    d = 0.0;
+    while (*(++c)) {
+      if (*c >= '0' && *c <= '9')
+	d = d * 16.0 + *c - '0';
+      else if ((*c >= 'A' && *c <= 'F') || (*c >= 'a' && *c <= 'f'))
+	d = d * 16.0 + (*c & 0xdf) - 'A' + 10.0;
+      else
+	break;
+    }
+  } else {
+    // regular number ?
+    char *end;
+    d = strtod(c, &end);
+    if (d != 0.0 || end != c) {
+      c = end;
+    } else {
+      // infinity ?
+      d = 1.0;
+      if (*c == '+')
+	c++;
+      else if (*c == '-') {
+	d = -1.0;
+	c++;
+      }
+      if (strncmp(c, "Infinity", 8) != 0)
+	return NaN;
+      d = d * Inf;
+      c += 8;
+    }
+  }
+
+  // allow trailing white space
+  while (isspace(*c))
+    c++;
+  if (*c != '\0')
+    d = NaN;
+
+  return d;
+}
+
+unsigned long UString::toULong(bool *ok) const
+{
+  double d = toDouble();
+  bool b = true;
+
+  if (isNaN(d) || d != static_cast<unsigned long>(d)) {
+    b = false;
+    d = 0;
+  }
+
+  if (ok)
+    *ok = b;
+
+  return static_cast<unsigned long>(d);
+}
+
+int UString::find(const UString &f, int pos) const
+{
+  if (isNull())
+    return -1;
+  long fsize = f.size() * sizeof(UChar);
+  if (pos < 0)
+    pos = 0;
+  const UChar *end = data() + size() - f.size();
+  for (const UChar *c = data() + pos; c <= end; c++)
+    if (!memcmp((void*)c, (void*)f.data(), fsize))
+      return (c-data());
+
+  return -1;
+}
+
+int UString::rfind(const UString &f, int pos) const
+{
+  if (isNull())
+    return -1;
+  if (pos + f.size() >= size())
+    pos = size() - f.size();
+  long fsize = f.size() * sizeof(UChar);
+  for (const UChar *c = data() + pos; c >= data(); c--) {
+    if (!memcmp((void*)c, (void*)f.data(), fsize))
+      return (c-data());
+  }
+
+  return -1;
+}
+
+UString UString::substr(int pos, int len) const
+{
+  if (isNull())
+    return UString();
+  if (pos < 0)
+    pos = 0;
+  else if (pos >= (int) size())
+    pos = size();
+  if (len < 0)
+    len = size();
+  if (pos + len >= (int) size())
+    len = size() - pos;
+
+  UChar *tmp = new UChar[len];
+  memcpy(tmp, data()+pos, len * sizeof(UChar));
+  UString result(tmp, len);
+  delete [] tmp;
+
+  return result;
+}
+
+void UString::attach(Rep *r)
+{
+  rep = r;
+  rep->ref();
+}
+
+void UString::detach()
+{
+  if (rep->rc > 1) {
+    int l = size();
+    UChar *n = new UChar[l];
+    memcpy(n, data(), l * sizeof(UChar));
+    release();
+    rep = Rep::create(n, l);
+  }
+}
+
+void UString::release()
+{
+  if (!rep->deref()) {
+    delete [] rep->dat;
+    delete rep;
+  }
+}
+
+bool KJS::operator==(const UChar &c1, const UChar &c2)
+{
+  return ((c1.lo == c2.lo) & (c1.hi == c2.hi));
+}
+
+bool KJS::operator==(const UString& s1, const UString& s2)
+{
+  if (s1.rep->len != s2.rep->len)
+    return false;
+
+  return (memcmp(s1.rep->dat, s2.rep->dat,
+		 s1.rep->len * sizeof(UChar)) == 0);
+}
+
+bool KJS::operator==(const UString& s1, const char *s2)
+{
+  if (s2 == 0L && s1.isNull())
+    return true;
+
+  if (s1.size() != (int) strlen(s2))
+    return false;
+
+  const UChar *u = s1.data();
+  while (*s2) {
+    if (u->lo != *s2 || u->hi != 0)
+      return false;
+    s2++;
+    u++;
+  }
+
+  return true;
+}
+
+bool KJS::operator==(const char *s1, const UString& s2)
+{
+  return operator==(s2, s1);
+}
+
+bool KJS::operator<(const UString& s1, const UString& s2)
+{
+  int l1 = s1.size();
+  int l2 = s2.size();
+  const UChar *c1 = s1.data();
+  const UChar *c2 = s2.data();
+  int l = 0;
+  int le = l1 < l2 ? l1 : l2;
+  while (l < le && *c1 == *c2) {
+    c1++;
+    c2++;
+    l++;
+  }
+  if (l != le)
+    return (c1->unicode() < c2->unicode());
+
+  return (l1 < l2 && !(*c1 == *c2));
+}
+
+UString KJS::operator+(const UString& s1, const UString& s2)
+{
+  UString tmp(s1);
+  tmp.append(s2);
+
+  return tmp;
+}
diff --git a/WebCore/src/kdelibs/kjs/ustring.h b/WebCore/src/kdelibs/kjs/ustring.h
new file mode 100644
index 0000000..e897a34
--- /dev/null
+++ b/WebCore/src/kdelibs/kjs/ustring.h
@@ -0,0 +1,419 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _KJS_STRING_H_
+#define _KJS_STRING_H_
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/**
+ * @internal
+ */
+namespace DOM {
+  class DOMString;
+};
+class KJScript;
+class QString;
+class QConstString;
+
+#if defined(__GNUC__)
+#define KJS_PACKED __attribute__((__packed__))
+#else
+#define KJS_PACKED
+#endif
+
+namespace KJS {
+
+  class UCharReference;
+  class UString;
+
+  /**
+   * @short Unicode character.
+   *
+   * UChar represents a 16 bit Unicode character. It's internal data
+   * representation is compatible to XChar2b and QChar. It's therefore
+   * possible to exchange data with X and Qt with shallow copies.
+   */
+  struct UChar {
+    /**
+     * Construct a character with value 0.
+     */
+    UChar();
+    /**
+     * Construct a character with the value denoted by the arguments.
+     * @param h higher byte
+     * @param l lower byte
+     */
+    UChar(unsigned char h , unsigned char l);
+    /**
+     * Construct a character with the given value.
+     * @param u 16 bit Unicode value
+     */
+    UChar(unsigned short u);
+    UChar(const UCharReference &c);
+    /**
+     * @return The higher byte of the character.
+     */
+    unsigned char high() const { return hi; }
+    /**
+     * @return The lower byte of the character.
+     */
+    unsigned char low() const { return lo; }
+    /**
+     * @return the 16 bit Unicode value of the character
+     */
+    unsigned short unicode() const { return hi << 8 | lo; }
+  public:
+    /**
+     * @return The character converted to lower case.
+     */
+    UChar toLower() const;
+    /**
+     * @return The character converted to upper case.
+     */
+    UChar toUpper() const;
+    /**
+     * A static instance of UChar(0).
+     */
+    static UChar null;
+  private:
+    friend class UCharReference;
+    friend class UString;
+    friend bool operator==(const UChar &c1, const UChar &c2);
+    friend bool operator==(const UString& s1, const char *s2);
+    friend bool operator<(const UString& s1, const UString& s2);
+#ifdef KJS_SWAPPED_CHAR
+    unsigned char lo;
+    unsigned char hi;
+#else
+    unsigned char hi;
+    unsigned char lo;
+#endif
+  } KJS_PACKED;
+
+
+#ifdef KJS_SWAPPED_CHAR // to avoid reorder warnings
+  inline UChar::UChar() : lo(0), hi(0) { }
+  inline UChar::UChar(unsigned char h , unsigned char l) : lo(l), hi(h) { }
+  inline UChar::UChar(unsigned short u) : lo(u & 0x00ff), hi(u >> 8) { }
+#else
+  inline UChar::UChar() : hi(0), lo(0) { }
+  inline UChar::UChar(unsigned char h , unsigned char l) : hi(h), lo(l) { }
+  inline UChar::UChar(unsigned short u) : hi(u >> 8), lo(u & 0x00ff) { }
+#endif
+
+  /**
+   * @short Dynamic reference to a string character.
+   *
+   * UCharReference is the dynamic counterpart of @ref UChar. It's used when
+   * characters retrieved via index from a @ref UString are used in an
+   * assignment expression (and therefore can't be treated as being const):
+   * <pre>
+   * UString s("hello world");
+   * s[0] = 'H';
+   * </pre>
+   *
+   * If that sounds confusing your best bet is to simply forget about the
+   * existance of this class and treat is as being identical to @ref UChar.
+   */
+  class UCharReference {
+    friend class UString;
+    UCharReference(UString *s, unsigned int off) : str(s), offset(off) { }
+  public:
+    /**
+     * Set the referenced character to c.
+     */
+    UCharReference& operator=(UChar c);
+    /**
+     * Same operator as above except the argument that it takes.
+     */
+    UCharReference& operator=(char c) { return operator=(UChar(c)); }
+    /**
+     * @return Unicode value.
+     */
+    unsigned short unicode() const { return ref().unicode(); }
+    /**
+     * @return Lower byte.
+     */
+    unsigned char& low() const { return ref().lo; }
+    /**
+     * @return Higher byte.
+     */
+    unsigned char& high() const { return ref().hi; }
+    /**
+     * @return Character converted to lower case.
+     */
+    UChar toLower() const { return ref().toLower(); }
+    /**
+     * @return Character converted to upper case.
+     */
+    UChar toUpper() const  { return ref().toUpper(); }
+  private:
+    // not implemented, can only be constructed from UString
+    UCharReference();
+
+    UChar& ref() const;
+    UString *str;
+    int offset;
+  };
+
+  /**
+   * @short 8 bit char based string class
+   */
+  class CString {
+  public:
+    CString() : data(0L) { }
+    CString(const char *c);
+    CString(const CString &);
+
+    ~CString();
+
+    CString &append(const CString &);
+    CString &operator=(const char *c);
+    CString &operator=(const CString &);
+    CString &operator+=(const CString &);
+
+    int size() const;
+    const char *c_str() const { return data; }
+  private:
+    char *data;
+  };
+
+  /**
+   * @short Unicode string class
+   */
+  class UString {
+    friend bool operator==(const UString&, const UString&);
+    friend class UCharReference;
+    /**
+     * @internal
+     */
+    struct Rep {
+      friend class UString;
+      friend bool operator==(const UString&, const UString&);
+      static Rep *create(UChar *d, int l);
+      inline UChar *data() const { return dat; }
+      inline int size() const { return len; }
+
+      inline void ref() { rc++; }
+      inline int deref() { return --rc; }
+
+      UChar *dat;
+      int len;
+      int rc;
+      static Rep null;
+    };
+
+  public:
+    /**
+     * Constructs a null string.
+     */
+    UString();
+    /**
+     * Constructs a string from the single character c.
+     */
+    UString(char c);
+    /**
+     * Constructs a string from a classical zero determined char string.
+     */
+    UString(const char *c);
+    /**
+     * Constructs a string from an array of Unicode characters of the specified
+     * length.
+     */
+    UString(const UChar *c, int length);
+    /**
+     * If copy is false a shallow copy of the string will be created. That
+     * means that the data will NOT be copied and you'll have to guarantee that
+     * it doesn't get deleted during the lifetime of the UString object.
+     * Behaviour defaults to a deep copy if copy is true.
+     */
+    UString(UChar *c, int length, bool copy);
+    /**
+     * Copy constructor. Makes a shallow copy only.
+     */
+    UString(const UString &);
+    /**
+     * Convenience declaration only ! You'll be on your own to write the
+     * implementation for a construction from QString.
+     *
+     * Note: feel free to contact me if you want to see a dummy header for
+     * your favourite FooString class here !
+     */
+    UString(const QString &);
+    /**
+     * Convenience declaration only ! See @ref UString(const QString&).
+     */
+    UString(const DOM::DOMString &);
+    /**
+     * Destructor. If this handle was the only one holding a reference to the
+     * string the data will be freed.
+     */
+    ~UString();
+
+    /**
+     * Constructs a string from an int.
+     */
+    static UString from(int i);
+    /**
+     * Constructs a string from an unsigned int.
+     */
+    static UString from(unsigned int u);
+    /**
+     * Constructs a string from a double.
+     */
+    static UString from(double d);
+
+    /**
+     * Append another string.
+     */
+    UString &append(const UString &);
+
+    /**
+     * @return The string converted to the 8-bit string type @ref CString().
+     */
+    CString cstring() const;
+    /**
+     * Convert the Unicode string to plain ASCII chars chopping of any higher
+     * bytes. This method should only be used for *debugging* purposes as it
+     * is neither Unicode safe nor free from side effects. In order not to
+     * waste any memory the char buffer is static and *shared* by all UString
+     * instances.
+     */
+    char *ascii() const;
+    /**
+     * @see UString(const QString&).
+     */
+    DOM::DOMString string() const;
+    /**
+     * @see UString(const QString&).
+     */
+    QString qstring() const;
+    /**
+     * @see UString(const QString&).
+     */
+    QConstString qconststring() const;
+
+    /**
+     * Assignment operator.
+     */
+    UString &operator=(const char *c);
+    /**
+     * Assignment operator.
+     */
+    UString &operator=(const UString &);
+    /**
+     * Appends the specified string.
+     */
+    UString &operator+=(const UString &s);
+
+    /**
+     * @return A pointer to the internal Unicode data.
+     */
+    const UChar* data() const { return rep->data(); }
+    /**
+     * @return True if null.
+     */
+    bool isNull() const { return (rep == &Rep::null); }
+    /**
+     * @return True if null or zero length.
+     */
+    bool isEmpty() const { return (!rep->len); }
+    /**
+     * Use this if you want to make sure that this string is a plain ASCII
+     * string. For example, if you don't want to lose any information when
+     * using @ref cstring() or @ref ascii().
+     *
+     * @return True if the string doesn't contain any non-ASCII characters.
+     */
+    bool is8Bit() const;
+    /**
+     * @return The length of the string.
+     */
+    int size() const { return rep->size(); }
+    /**
+     * Const character at specified position.
+     */
+    UChar operator[](int pos) const;
+    /**
+     * Writable reference to character at specified position.
+     */
+    UCharReference operator[](int pos);
+
+    /**
+     * Attempts an conversion to a number. Apart from floating point numbers,
+     * the algorithm will recognize hexadecimal representations (as
+     * indicated by a 0x or 0X prefix) and +/- Infinity.
+     * Returns NaN if the conversion failed.
+     */
+    double toDouble() const;
+    /**
+     * Attempts an conversion to an unsigned long integer. ok will be set
+     * according to the success.
+     */
+    unsigned long toULong(bool *ok = 0L) const;
+    /**
+     * @return Position of first occurence of f starting at position pos.
+     * -1 if the search was not successful.
+     */
+    int find(const UString &f, int pos = 0) const;
+    /**
+     * @return Position of first occurence of f searching backwards from
+     * position pos.
+     * -1 if the search was not successful.
+     */
+    int rfind(const UString &f, int pos) const;
+    /**
+     * @return The sub string starting at position pos and length len.
+     */
+    UString substr(int pos = 0, int len = -1) const;
+    /**
+     * Static instance of a null string.
+     */
+    static UString null;
+  private:
+    void attach(Rep *r);
+    void detach();
+    void release();
+    Rep *rep;
+  };
+
+  bool operator==(const UChar &c1, const UChar &c2);
+  bool operator==(const UString& s1, const UString& s2);
+  inline bool operator!=(const UString& s1, const UString& s2) {
+    return !KJS::operator==(s1, s2);
+  }
+  bool operator<(const UString& s1, const UString& s2);
+  bool operator==(const UString& s1, const char *s2);
+  inline bool operator!=(const UString& s1, const char *s2) {
+    return !KJS::operator==(s1, s2);
+  }
+  bool operator==(const char *s1, const UString& s2);
+  inline bool operator!=(const char *s1, const UString& s2) {
+    return !KJS::operator==(s1, s2);
+  }
+  bool operator==(const CString& s1, const CString& s2);
+  UString operator+(const UString& s1, const UString& s2);
+
+}; // namespace
+
+#endif

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list