[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
r5518 - in trunk/gnue-common/src/logic: . adapters adapters/ECMAscript
From: |
johannes |
Subject: |
r5518 - in trunk/gnue-common/src/logic: . adapters adapters/ECMAscript |
Date: |
Fri, 26 Mar 2004 03:47:33 -0600 (CST) |
Author: johannes
Date: 2004-03-26 03:47:32 -0600 (Fri, 26 Mar 2004)
New Revision: 5518
Added:
trunk/gnue-common/src/logic/adapters/
trunk/gnue-common/src/logic/adapters/python.py
Removed:
trunk/gnue-common/src/logic/adapters/python/
Modified:
trunk/gnue-common/src/logic/adapters/Base.py
trunk/gnue-common/src/logic/adapters/ECMAscript/Adapter.py
Log:
Restructuring of language engine stuff (to be continued ...)
Copied: trunk/gnue-common/src/logic/adapters (from rev 5517,
trunk/gnue-common/src/logic/language)
Modified: trunk/gnue-common/src/logic/adapters/Base.py
===================================================================
--- trunk/gnue-common/src/logic/language/Base.py 2004-03-26 00:57:14 UTC
(rev 5517)
+++ trunk/gnue-common/src/logic/adapters/Base.py 2004-03-26 09:47:32 UTC
(rev 5518)
@@ -16,150 +16,183 @@
# write to the Free Software Foundation, Inc., 59 Temple Place
# - Suite 330, Boston, MA 02111-1307, USA.
#
-# Copyright 2003-2004 Free Software Foundation
+# Copyright 2001-2004 Free Software Foundation
#
-#
-# FILE:
-# Base.py
-#
-# DESCRIPTION:
-# Provides a way to execute arbitrary code in a given environment
-#
-# NOTES:
-#
+# $Id: $
-from gnue.common.logic.NamespaceCore import NamespaceFunction, NamespaceElement
-from gnue.common.utils.FileUtils import dyn_import
+import sys
+import traceback
+import string
-######
-#
-# We have three types of classes to access:
-#
-# LanguageEngine: the Language Engine, which has to be loaded just once
-# (it can possibly loaded twice if more security is needed)
-#
-# ExecutionContext: Environmet where the code is executed.
-# if you need to reload/change global values just
-# create a new context
-#
-# VirtualMethod: A method of an object which provides an pointer to
-# the execution context (python: self, ECMAscript: this)
-#
-# VirtualAttribute: An attribute of an object
-#
+from gnue.common.logic.language import ImplementationError
+from gnue.common.logic.NamespaceCore import NamespaceElement, NamespaceFunction
-class LangIfError(StandardError):
- pass
-class LangIfCompileError(LangIfError):
- pass
+# =============================================================================
+# Base class for LanguageAdapters
+# =============================================================================
-class LangIfRuntimeError(LangIfError):
- pass
+class BaseLanguageAdapter:
+ """
+ This is the base class for language adapters. A language adapter has to
+ provide a public function for creation of new execution contexts.
+ """
-class LanguageEngine:
- def __init__(self):
- pass
+ # ---------------------------------------------------------------------------
+ # Create and return a new execution context
+ # ---------------------------------------------------------------------------
- def createNewContext(self):
- return ExecutionContext(None)
+ def createNewContext (self):
+ """
+ Abstract: Create a new execution context.
+ """
+ raise ImplementationError, (self.__class__, 'createNewContext ()')
-class ExecutionContext:
-
- def __init__(self, runtime):
- self._runtime=runtime
- self._shortname = "unknown_executioncontext"
- self._description = "There is no description provided."
- ######
- #
- # Namespace creation
- #
- # add python objects, procedures and attributes to the global namespace
- #
- # helper function to reuse the GObj Namespace,
- # define global namespace ('global' directive in python)
- def defineNamespace(self, ns, globalns=0):
- for name in ns.keys():
- if name!=None:
- # just add Namespace elements/functions
- if isinstance(ns[name], NamespaceFunction):
- self.bindFunction(name, ns[name])
-
- if isinstance(ns[name], NamespaceElement):
- self.bindObject(name, ns[name])
+# =============================================================================
+# Base class for execution contexts
+# =============================================================================
- def bindObject(self, name, object, klass=None):
- pass
+class BaseExecutionContext:
+ """
+ An execution context provides an environment where code can be transformed
+ and executed.
+ """
- def bindFunction(self, name, object):
- pass
+ # ---------------------------------------------------------------------------
+ # Constructor
+ # ---------------------------------------------------------------------------
- #####
- #
- # build virtual methods, attributs and functions and add to the namespace
- #
-
- def buildMethod(self, name, code, parameter):
- # name has to be the name of a global accesible object
- return VirtualMethod(self, name, code, parameter)
-
- def buildAttribute(self, name, value):
- # name has to be the name of a global accesible object
- return VirtualAttribute(self, name, value)
+ def __init__ (self, runtime = None):
+ self._runtime = runtime
+ self.shortname = "unknown_executioncontext"
+ self.description = "There is no description provided"
- def buildFunction(self, name, code, parameter):
- return VirtualFunction(self, name, code, parameter)
- #####
- #
- # a possibility to set Description o
- #
+ # ---------------------------------------------------------------------------
+ # Merge a namespace into the execution contexts namespace
+ # ---------------------------------------------------------------------------
- def setDescription(self, shortname, description):
- self._shortname = shortname
- self._description = description
+ def defineNamespace (self, addNS, asGlobal = False):
+ """
+ Merge the given namespace @addNS into the execution context. This function
+ is doing this using bindFunction () and bindObject () depeding on the
+ namespace elements type.
+ """
+ for (name, value) in addNS.items ():
+ if name is not None:
+ if isinstance (value, NamespaceFunction):
+ self.bindFunction (name, value, asGlobal)
+ if isinstance (value, NamespaceElement):
+ self.bindObject (name, value, asGlobal)
+
+
+ # ---------------------------------------------------------------------------
+ # Bind an object into the contexts namespace using the given name
+ # ---------------------------------------------------------------------------
+
+ def bindObject (self, name, aObject, asGlobal = False):
+ """
+ Abstract: A descendant overrides this function to bind a given object into
+ the local or global namespace.
+ """
+ raise ImplementationError, (self.__class__, 'bindObject ()')
+
+
+ # ---------------------------------------------------------------------------
+ # Bind a function into the contexts namespace using the given name
+ # ---------------------------------------------------------------------------
+
+ def bindFunction (self, name, aFunction, asGlobal = False):
+ """
+ Abstract: A descendant overrides this function to bind a given function
+ with into the local or global namespace.
+ """
+ raise ImplementationError, (self.__class__, 'bindFunction ()')
+
+
+ # ---------------------------------------------------------------------------
+ # Create a new function instance
+ # ---------------------------------------------------------------------------
+
+ def buildFunction (self, name, code, parameters = {}):
+ """
+ Abstract: Create a new instance of a virtual function and prepare it's
+ code.
+ """
+ raise ImplementationError, (self.__class__, 'buildFunction ()')
+
+
+
+# =============================================================================
+# Base class of a virtual function
+# =============================================================================
+
class VirtualFunction:
- def __init__(self, context, name, code, parameter):
- self._code = code
- self._context = context
- self._name = name
- self._parameter= parameter
-
- def compile(self):
- pass
+ """
+ This is the base class of virtual functions. Such an instance must be able to
+ prepare a sourcecode and to execute it.
+ """
- def execute(self, *args, **params):
- pass
-
- def __call__(self, *args, **params):
- return apply(self.execute,args,params)
-
-class VirtualMethod(VirtualFunction):
- def rebind(self, obj, name):
- pass
+ # ---------------------------------------------------------------------------
+ # Constructor
+ # ---------------------------------------------------------------------------
-class VirtualAttribute:
- def __init__(self, context, name, value):
- self._context = context
- self._name = name
- self._value = value
-
- def get(self):
- return self._value
+ def __init__ (self, context, name, code, parameters):
+ self._context = context
+ self._name = name
+ self._code = code
+ self._parameters = parameters
+ self._prepare ()
- def set(self,value):
- self._value = value
+ # ---------------------------------------------------------------------------
+ # Execute the function using the given arguments
+ # ---------------------------------------------------------------------------
-def loadLanguageEngine(language):
- try:
- adapter = dyn_import('gnue.common.logic.language.%s.Adapter' \
- % language)
- except ImportError:
- GDebug.printMesg(0, "Language %s not implemented" % self.language)
- sys.exit()
+ def execute (self, *args, **params):
+ """
+ Execute the function using the given arguments. A descendant must override
+ this function.
+ """
+ raise ImplementationError, (self.__class__, 'execute ()')
- return adapter.LanguageEngine()
+
+
+ # ---------------------------------------------------------------------------
+ # redirect a call of an instance to the execute () function.
+ # ---------------------------------------------------------------------------
+
+ def __call__ (self, *args, **params):
+ """
+ If an instance gets called, redirect this call to the execute () function.
+ """
+ return apply (self.execute, args, params)
+
+
+ # ---------------------------------------------------------------------------
+ # Prepare the given source code
+ # ---------------------------------------------------------------------------
+
+ def _prepare (self):
+ """
+ This function gets called on constructing an instance at could be used by a
+ descendant to prepare the sourcecode, i.e. compile it.
+ """
+ pass
+
+
+ # ---------------------------------------------------------------------------
+ # Put info for current exception into a string
+ # ---------------------------------------------------------------------------
+
+ def _traceback (self, count):
+ """
+ Returns the complete traceback of the current exception as a string, where
+ the first @count lines of the traceback are hidden.
+ """
+ lines = traceback.format_exception (*sys.exc_info ())
+ del lines [1:count + 1]
+ return string.join (lines, '')
Property changes on: trunk/gnue-common/src/logic/adapters/Base.py
___________________________________________________________________
Name: svn:keywords
+ svn:Id
Modified: trunk/gnue-common/src/logic/adapters/ECMAscript/Adapter.py
===================================================================
--- trunk/gnue-common/src/logic/language/ECMAscript/Adapter.py 2004-03-26
00:57:14 UTC (rev 5517)
+++ trunk/gnue-common/src/logic/adapters/ECMAscript/Adapter.py 2004-03-26
09:47:32 UTC (rev 5518)
@@ -56,10 +56,10 @@
# namespace creation (global namespace)
#
- def bindObject(self, name, object, klass=None):
- if klass!=None:
- self._cx.bind_class(klass)
- self._cx.bind_object(name, object)
+ def bindObject (self, name, aObject, aClass = None):
+ if aClass != None:
+ self._cx.bind_class (aClass)
+ self._cx.bind_object (name, aObject)
def bindFunction(self, name, object):
self._cx.bind_callable(name, object)
Copied: trunk/gnue-common/src/logic/adapters/python.py (from rev 5517,
trunk/gnue-common/src/logic/language/python/Adapter.py)
===================================================================
--- trunk/gnue-common/src/logic/language/python/Adapter.py 2004-03-26
00:57:14 UTC (rev 5517)
+++ trunk/gnue-common/src/logic/adapters/python.py 2004-03-26 09:47:32 UTC
(rev 5518)
@@ -0,0 +1,208 @@
+#
+# This file is part of GNU Enterprise.
+#
+# GNU Enterprise 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.
+#
+# GNU Enterprise 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 program; see the file COPYING. If not,
+# write to the Free Software Foundation, Inc., 59 Temple Place
+# - Suite 330, Boston, MA 02111-1307, USA.
+#
+# Copyright 2001-2004 Free Software Foundation
+#
+# $Id: $
+
+from string import join
+from copy import copy
+
+import gnue.common.logic.language
+from gnue.common.logic.language.adapters import Base
+
+# =============================================================================
+# Implementation of a language adapter for python
+# =============================================================================
+
+class LanguageAdapter (Base.BaseLanguageAdapter):
+ """
+ Implementation of a language engine for python
+ """
+
+ # ---------------------------------------------------------------------------
+ # Create a new execution context
+ # ---------------------------------------------------------------------------
+
+ def createNewContext (self):
+ """
+ Create a python execution context
+ """
+ return PythonExecutionContext ()
+
+
+# =============================================================================
+# Python Execution Context
+# =============================================================================
+
+class PythonExecutionContext (Base.BaseExecutionContext):
+ """
+ This class implements an ExecutionContext for Python.
+ """
+
+ # ---------------------------------------------------------------------------
+ # Constructor
+ # ---------------------------------------------------------------------------
+
+ def __init__ (self, runtime = None):
+ BaseExecutionContext.__init__ (self, runtime)
+
+ self._globalNS = {}
+ self._localNS = {}
+
+
+ # ---------------------------------------------------------------------------
+ # Replace the local or global namespace
+ # ---------------------------------------------------------------------------
+
+ def defineNamespace (self, addNS, asGlobal = False):
+ """
+ This function replaces the local or global namespace with @addNS.
+ """
+ if asGlobal:
+ self._globalNS = addNS
+ else:
+ self._localNS = addNS
+
+
+ # ---------------------------------------------------------------------------
+ # Add an object to the namespace
+ # ---------------------------------------------------------------------------
+
+ def bindObject (self, name, aObject, asGlobal = False):
+ """
+ Add @aObject as @name to the local or global namespace.
+ """
+ if asGlobal:
+ self._globalNS [name] = aObject
+ else:
+ self._localNS [name] = aObject
+
+
+ # ---------------------------------------------------------------------------
+ # Add a function to the namespace
+ # ---------------------------------------------------------------------------
+
+ def bindFunction (self, name, aFunction, asGlobal = False):
+ """
+ Add @aFunction as @name to the local or global namespace.
+ """
+ if asGlobal:
+ self._globalNS [name] = aFunction
+ else:
+ self._localNS [name] = aFunction
+
+
+ # ---------------------------------------------------------------------------
+ # Create a function
+ # ---------------------------------------------------------------------------
+
+ def buildFunction (self, name, code, parameters = {}):
+ return PythonFunction (self, name, code, parameters)
+
+
+# =============================================================================
+# This class implements a virtual function using python
+# =============================================================================
+
+class PythonFunction (Base.VirtualFunction):
+ """
+ Implementation of a virtual function using Python.
+ """
+
+ # ---------------------------------------------------------------------------
+ # Prepare a python function
+ # ---------------------------------------------------------------------------
+
+ def _prepare (self):
+ """
+ Preparing a sourcecode for python means compiling. This function compiles
+ the code.
+ """
+ # if name has invalid characters, we won't use it as function name
+ if 1 in [c in self._name for c in " ."]:
+ self.funcName = "tempCode"
+ else:
+ self.funcName = self._name
+
+ paramlist = join (['__namespace'] + self._parameters.keys (), ", ")
+ text = self._code.rstrip ()
+
+ try:
+ tabPos = text.find ('\t')
+ if tabPos > -1:
+ raise gException, \
+ u_("Sourcecode contains tab character at position %d") % tabPos
+
+
+ # get the indentation level of the first line
+ indent = 0
+ for line in text.splitlines ():
+ if len (line.strip ()) and line.lstrip () [0] != "#":
+ indent = len (line) - len (line.lstrip ())
+ break
+
+ # add the functions header
+ revisedCode = "# -*- coding: utf-8 -*-\n"
+ revisedCode += "def %s (%s):\n" % (self.funcName, paramlist)
+
+ # add the namespace transformation loop
+ revisedCode += " for __add in __namespace.keys ():\n"
+ revisedCode += " exec '%s = __namespace [\"%s\"]' % (__add, __add)\n"
+ revisedCode += " del __add, __namespace\n\n"
+
+ # add the original code
+ for line in text.splitlines ():
+ revisedCode += " %s\n" % line [indent:]
+
+ # and finalize the function by a call to it
+ revisedCode += " pass\n\n"
+ revisedCode += "__result = %s (%s)\n" % (self.funcName, paramlist)
+
+ self._compiled = compile (revisedCode.encode ('utf-8'),
+ '<%s>' % self._context.shortname.encode ('utf-8'), 'exec')
+
+ except:
+ raise language.CompileError, self._traceback (1)
+
+
+ # ---------------------------------------------------------------------------
+ # Execute the function
+ # ---------------------------------------------------------------------------
+
+ def execute (self, *args, **params):
+ """
+ This function creates a local namespace as a copy from the execution
+ context's local namespace, adds all parameters to this namespace and
+ executes the code.
+ """
+ try:
+ localNS = copy (self._context._localNS)
+ localNS.update (params)
+ localNS ['__namespace'] = localNS
+
+ exec self._compiled in self._context._globalNS, localNS
+
+ if localNS.has_key ('__result'):
+ return localNS ['__result']
+ else:
+ return None
+
+
+ except:
+ raise language.RuntimeError, self._traceback (1)
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- r5518 - in trunk/gnue-common/src/logic: . adapters adapters/ECMAscript,
johannes <=