[gen] More work ZPT->PX.

This commit is contained in:
Gaetan Delannay 2013-08-21 12:35:30 +02:00
parent 2e9a832463
commit 34e3a3083e
31 changed files with 3287 additions and 3067 deletions

View file

@ -77,11 +77,25 @@ class BufferAction:
dumpTb=dumpTb)
self.buffer.evaluate(result, context)
def _evalExpr(self, expr, context):
'''Evaluates p_expr with p_context. p_expr can contain an error expr,
in the form "someExpr|errorExpr". If it is the case, if the "normal"
expr raises an error, the "error" expr is evaluated instead.'''
if '|' not in expr:
res = eval(expr, context)
else:
expr, errorExpr = expr.rsplit('|', 1)
try:
res = eval(expr, context)
except Exception:
res = eval(errorExpr, context)
return res
def evaluateExpression(self, result, context, expr):
'''Evaluates expression p_expr with the current p_context. Returns a
tuple (result, errorOccurred).'''
try:
res = eval(expr, context)
res = self._evalExpr(expr, context)
error = False
except Exception, e:
res = None
@ -169,7 +183,10 @@ class ForAction(BufferAction):
self.iter = iter # Name of the iterator variable used in the each loop
def initialiseLoop(self, context, elems):
'''Initialises information about the loop, before entering into it.'''
'''Initialises information about the loop, before entering into it. It
is possible that this loop overrides an outer loop whose iterator
has the same name. This method returns a tuple
(loop, outerOverriddenLoop).'''
# The "loop" object, made available in the POD context, contains info
# about all currently walked loops. For every walked loop, a specific
# object, le'ts name it curLoop, accessible at getattr(loop, self.iter),
@ -195,11 +212,17 @@ class ForAction(BufferAction):
context['loop'] = Object()
try:
total = len(elems)
except:
except Exception:
total = 0
curLoop = Object(length=total)
# Does this loop overrides an outer loop whose iterator has the same
# name ?
outerLoop = None
if hasattr(context['loop'], self.iter):
outerLoop = getattr(context['loop'], self.iter)
# Put this loop in the global object "loop".
setattr(context['loop'], self.iter, curLoop)
return curLoop
return curLoop, outerLoop
def do(self, result, context, elems):
'''Performs the "for" action. p_elems is the list of elements to
@ -229,7 +252,7 @@ class ForAction(BufferAction):
if not elems:
result.dumpElement(Cell.OD.elem)
# Enter the "for" loop.
loop = self.initialiseLoop(context, elems)
loop, outerLoop = self.initialiseLoop(context, elems)
i = -1
for item in elems:
i += 1
@ -277,11 +300,13 @@ class ForAction(BufferAction):
context[self.iter] = ''
for i in range(nbOfMissingCellsLastLine):
self.buffer.evaluate(result, context, subElements=False)
# Delete the object representing info about the current loop.
# Delete the current loop object and restore the overridden one if any.
try:
delattr(context['loop'], self.iter)
except AttributeError:
pass
if outerLoop:
setattr(context['loop'], self.iter, outerLoop)
# Restore hidden variable if any
if hasHiddenVariable:
context[self.iter] = hiddenVariable

View file

@ -19,6 +19,7 @@ import re
from xml.sax.saxutils import quoteattr
from appy.shared.xml_parser import xmlPrologue, escapeXml
from appy.pod import PodError
from appy.shared.utils import Traceback
from appy.pod.elements import *
from appy.pod.actions import IfAction, ElseAction, ForAction, VariablesAction, \
NullAction

View file

@ -74,17 +74,32 @@ class Table(PodElement):
class Expression(PodElement):
'''Represents a Python expression that is found in a pod or px.'''
OD = None
def __init__(self, pyExpr, pod):
# The Python expression
self.expr = pyExpr.strip()
self.pod = pod # True if I work for pod, False if I work for px.
# Must we, when evaluating the expression, escape XML special chars
# or not?
if self.expr.startswith(':'):
self.expr = self.expr[1:]
self.escapeXml = False
def extractInfo(self, py):
'''Within p_py, several elements can be included:
- the fact that XML chars must be escaped or not (leading ":")
- the "normal" Python expression,
- an optional "error" expression, that is evaluated when the normal
expression raises an exception.
This method return a tuple (escapeXml, normaExpr, errorExpr).'''
# Determine if we must escape XML chars or not.
escapeXml = True
if py.startswith(':'):
py = py[1:]
escapeXml = False
# Extract normal and error expression
if '|' not in py:
expr = py
errorExpr = None
else:
self.escapeXml = True
expr, errorExpr = py.rsplit('|', 1)
expr = expr.strip()
errorExpr = errorExpr.strip()
return escapeXml, expr, errorExpr
def __init__(self, py, pod):
# Extract parts from expression p_py.
self.escapeXml, self.expr, self.errorExpr = self.extractInfo(py.strip())
self.pod = pod # True if I work for pod, False if I work for px.
if self.pod:
# pod-only: store here the expression's true result (before being
# converted to a string).
@ -98,6 +113,18 @@ class Expression(PodElement):
# self.result and self.evaluated are not used by PX, because they
# are not thread-safe.
def _eval(self, context):
'''Evaluates self.expr with p_context. If self.errorExpr is defined,
evaluate it if self.expr raises an error.'''
if self.errorExpr:
try:
res = eval(self.expr, context)
except Exception:
res = eval(self.errorExpr, context)
else:
res = eval(self.expr, context)
return res
def evaluate(self, context):
'''Evaluates the Python expression (self.expr) with a given
p_context, and returns the result. More precisely, it returns a
@ -114,8 +141,7 @@ class Expression(PodElement):
# with another context.
self.evaluated = False
else:
# Evaluates the Python expression
res = eval(self.expr, context)
res = self._eval(context)
# pod-only: cache the expression result.
if self.pod: self.result = res
# Converts the expr result to a string that can be inserted in the

File diff suppressed because it is too large Load diff