mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Merge branch 'master' of https://github.com/cbhaley/calibre
This commit is contained in:
commit
b9a64085e9
@ -397,9 +397,6 @@ class TemplateDialog(QDialog, Ui_TemplateDialog):
|
|||||||
self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setText(_('&OK'))
|
self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setText(_('&OK'))
|
||||||
self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setText(_('&Cancel'))
|
self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setText(_('&Cancel'))
|
||||||
|
|
||||||
self.textbox.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
|
|
||||||
self.textbox.customContextMenuRequested.connect(self.show_context_menu)
|
|
||||||
|
|
||||||
self.color_copy_button.clicked.connect(self.color_to_clipboard)
|
self.color_copy_button.clicked.connect(self.color_to_clipboard)
|
||||||
self.filename_button.clicked.connect(self.filename_button_clicked)
|
self.filename_button.clicked.connect(self.filename_button_clicked)
|
||||||
self.icon_copy_button.clicked.connect(self.icon_to_clipboard)
|
self.icon_copy_button.clicked.connect(self.icon_to_clipboard)
|
||||||
@ -443,6 +440,9 @@ class TemplateDialog(QDialog, Ui_TemplateDialog):
|
|||||||
self.set_up_font_boxes()
|
self.set_up_font_boxes()
|
||||||
self.toggle_button.clicked.connect(self.toggle_button_pressed)
|
self.toggle_button.clicked.connect(self.toggle_button_pressed)
|
||||||
self.remove_all_button.clicked.connect(self.remove_all_button_pressed)
|
self.remove_all_button.clicked.connect(self.remove_all_button_pressed)
|
||||||
|
|
||||||
|
self.load_button.clicked.connect(self.load_template)
|
||||||
|
self.save_button.clicked.connect(self.save_template)
|
||||||
# Now geometry
|
# Now geometry
|
||||||
try:
|
try:
|
||||||
geom = gprefs.get('template_editor_dialog_geometry', None)
|
geom = gprefs.get('template_editor_dialog_geometry', None)
|
||||||
@ -451,15 +451,6 @@ class TemplateDialog(QDialog, Ui_TemplateDialog):
|
|||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def show_context_menu(self, point):
|
|
||||||
m = self.textbox.createStandardContextMenu()
|
|
||||||
m.addSeparator()
|
|
||||||
ca = m.addAction(_('Load template from file'))
|
|
||||||
ca.triggered.connect(self.load_template)
|
|
||||||
ca = m.addAction(_('Save template to file'))
|
|
||||||
ca.triggered.connect(self.store_template)
|
|
||||||
m.exec_(self.textbox.mapToGlobal(point))
|
|
||||||
|
|
||||||
def load_template(self):
|
def load_template(self):
|
||||||
filename = choose_files(self, 'template_dialog_save_templates',
|
filename = choose_files(self, 'template_dialog_save_templates',
|
||||||
_('Load template from file'),
|
_('Load template from file'),
|
||||||
@ -470,7 +461,7 @@ class TemplateDialog(QDialog, Ui_TemplateDialog):
|
|||||||
with open(filename[0], 'r') as f:
|
with open(filename[0], 'r') as f:
|
||||||
self.textbox.setPlainText(f.read())
|
self.textbox.setPlainText(f.read())
|
||||||
|
|
||||||
def store_template(self):
|
def save_template(self):
|
||||||
filename = choose_save_file(self, 'template_dialog_save_templates',
|
filename = choose_save_file(self, 'template_dialog_save_templates',
|
||||||
_('Save template to file'),
|
_('Save template to file'),
|
||||||
filters=[
|
filters=[
|
||||||
|
@ -330,6 +330,12 @@ you the value as well as all the local variables</p></string>
|
|||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>The template program text</string>
|
<string>The template program text</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>1</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0">
|
<item row="3" column="0">
|
||||||
@ -523,7 +529,7 @@ you the value as well as all the local variables</p></string>
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="font_name_label">
|
<widget class="QLabel" name="font_name_label">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Current font:</string>
|
<string>Font:</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="buddy">
|
<property name="buddy">
|
||||||
<cstring>font_box</cstring>
|
<cstring>font_box</cstring>
|
||||||
@ -557,6 +563,41 @@ you the value as well as all the local variables</p></string>
|
|||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="24" column="3">
|
<item row="24" column="3">
|
||||||
|
<layout class="QHBoxLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QFrame" name="frame">
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::VLine</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Raised</enum>
|
||||||
|
</property>
|
||||||
|
<property name="lineWidth">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="load_button">
|
||||||
|
<property name="text">
|
||||||
|
<string>Lo&ad</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Load the template from a file</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="save_button">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Save</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Save the template in a file</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
@ -566,6 +607,8 @@ you the value as well as all the local variables</p></string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
<item row="25" column="0" colspan="4">
|
<item row="25" column="0" colspan="4">
|
||||||
<widget class="QFrame">
|
<widget class="QFrame">
|
||||||
<property name="frameShape">
|
<property name="frameShape">
|
||||||
|
@ -41,19 +41,23 @@ class Node(object):
|
|||||||
NODE_BINARY_ARITHOP = 19
|
NODE_BINARY_ARITHOP = 19
|
||||||
NODE_UNARY_ARITHOP = 20
|
NODE_UNARY_ARITHOP = 20
|
||||||
NODE_PRINT = 21
|
NODE_PRINT = 21
|
||||||
NODE_LINE_NUMBER = 22
|
|
||||||
|
|
||||||
def __init__(self, line_number, name):
|
def __init__(self, line_number, name):
|
||||||
self.line_number = line_number
|
self.my_line_number = line_number
|
||||||
self.my_node_name = name
|
self.my_node_name = name
|
||||||
|
|
||||||
|
@property
|
||||||
def node_name(self):
|
def node_name(self):
|
||||||
return self.my_node_name
|
return self.my_node_name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def line_number(self):
|
||||||
|
return self.my_line_number
|
||||||
|
|
||||||
|
|
||||||
class IfNode(Node):
|
class IfNode(Node):
|
||||||
def __init__(self, line_number, condition, then_part, else_part):
|
def __init__(self, line_number, condition, then_part, else_part):
|
||||||
Node.__init__(self, line_number, 'IF')
|
Node.__init__(self, line_number, 'if ...')
|
||||||
self.node_type = self.NODE_IF
|
self.node_type = self.NODE_IF
|
||||||
self.condition = condition
|
self.condition = condition
|
||||||
self.then_part = then_part
|
self.then_part = then_part
|
||||||
@ -62,7 +66,7 @@ class IfNode(Node):
|
|||||||
|
|
||||||
class ForNode(Node):
|
class ForNode(Node):
|
||||||
def __init__(self, line_number, variable, list_field_expr, separator, block):
|
def __init__(self, line_number, variable, list_field_expr, separator, block):
|
||||||
Node.__init__(self, line_number, 'FOR')
|
Node.__init__(self, line_number, 'for ...:')
|
||||||
self.node_type = self.NODE_FOR
|
self.node_type = self.NODE_FOR
|
||||||
self.variable = variable
|
self.variable = variable
|
||||||
self.list_field_expr = list_field_expr
|
self.list_field_expr = list_field_expr
|
||||||
@ -72,7 +76,7 @@ class ForNode(Node):
|
|||||||
|
|
||||||
class AssignNode(Node):
|
class AssignNode(Node):
|
||||||
def __init__(self, line_number, left, right):
|
def __init__(self, line_number, left, right):
|
||||||
Node.__init__(self, line_number, 'ASSIGN')
|
Node.__init__(self, line_number, 'assign to ' + left)
|
||||||
self.node_type = self.NODE_ASSIGN
|
self.node_type = self.NODE_ASSIGN
|
||||||
self.left = left
|
self.left = left
|
||||||
self.right = right
|
self.right = right
|
||||||
@ -80,7 +84,7 @@ class AssignNode(Node):
|
|||||||
|
|
||||||
class FunctionNode(Node):
|
class FunctionNode(Node):
|
||||||
def __init__(self, line_number, function_name, expression_list):
|
def __init__(self, line_number, function_name, expression_list):
|
||||||
Node.__init__(self, line_number, 'FUNCTION CALL')
|
Node.__init__(self, line_number, function_name + '()')
|
||||||
self.node_type = self.NODE_FUNC
|
self.node_type = self.NODE_FUNC
|
||||||
self.name = function_name
|
self.name = function_name
|
||||||
self.expression_list = expression_list
|
self.expression_list = expression_list
|
||||||
@ -88,7 +92,7 @@ class FunctionNode(Node):
|
|||||||
|
|
||||||
class CallNode(Node):
|
class CallNode(Node):
|
||||||
def __init__(self, line_number, function, expression_list):
|
def __init__(self, line_number, function, expression_list):
|
||||||
Node.__init__(self, line_number, 'TEMPLATE CALL')
|
Node.__init__(self, line_number, 'call template: ' + function)
|
||||||
self.node_type = self.NODE_CALL
|
self.node_type = self.NODE_CALL
|
||||||
self.function = function
|
self.function = function
|
||||||
self.expression_list = expression_list
|
self.expression_list = expression_list
|
||||||
@ -96,28 +100,28 @@ class CallNode(Node):
|
|||||||
|
|
||||||
class ArgumentsNode(Node):
|
class ArgumentsNode(Node):
|
||||||
def __init__(self, line_number, expression_list):
|
def __init__(self, line_number, expression_list):
|
||||||
Node.__init__(self, line_number, 'ARGUMENTS')
|
Node.__init__(self, line_number, 'arguments()')
|
||||||
self.node_type = self.NODE_ARGUMENTS
|
self.node_type = self.NODE_ARGUMENTS
|
||||||
self.expression_list = expression_list
|
self.expression_list = expression_list
|
||||||
|
|
||||||
|
|
||||||
class GlobalsNode(Node):
|
class GlobalsNode(Node):
|
||||||
def __init__(self, line_number, expression_list):
|
def __init__(self, line_number, expression_list):
|
||||||
Node.__init__(self, line_number, 'GLOBALS')
|
Node.__init__(self, line_number, 'globals()')
|
||||||
self.node_type = self.NODE_GLOBALS
|
self.node_type = self.NODE_GLOBALS
|
||||||
self.expression_list = expression_list
|
self.expression_list = expression_list
|
||||||
|
|
||||||
|
|
||||||
class SetGlobalsNode(Node):
|
class SetGlobalsNode(Node):
|
||||||
def __init__(self, line_number, expression_list):
|
def __init__(self, line_number, expression_list):
|
||||||
Node.__init__(self, line_number, 'SET_GLOBALS')
|
Node.__init__(self, line_number, 'set_globals()')
|
||||||
self.node_type = self.NODE_SET_GLOBALS
|
self.node_type = self.NODE_SET_GLOBALS
|
||||||
self.expression_list = expression_list
|
self.expression_list = expression_list
|
||||||
|
|
||||||
|
|
||||||
class StringCompareNode(Node):
|
class StringCompareNode(Node):
|
||||||
def __init__(self, line_number, operator, left, right):
|
def __init__(self, line_number, operator, left, right):
|
||||||
Node.__init__(self, line_number, 'COMPARE STRING')
|
Node.__init__(self, line_number, 'comparision: ' + operator)
|
||||||
self.node_type = self.NODE_COMPARE_STRING
|
self.node_type = self.NODE_COMPARE_STRING
|
||||||
self.operator = operator
|
self.operator = operator
|
||||||
self.left = left
|
self.left = left
|
||||||
@ -126,7 +130,7 @@ class StringCompareNode(Node):
|
|||||||
|
|
||||||
class NumericCompareNode(Node):
|
class NumericCompareNode(Node):
|
||||||
def __init__(self, line_number, operator, left, right):
|
def __init__(self, line_number, operator, left, right):
|
||||||
Node.__init__(self, line_number, 'COMPARE NUMBERS')
|
Node.__init__(self, line_number, 'comparison: ' + operator)
|
||||||
self.node_type = self.NODE_COMPARE_NUMERIC
|
self.node_type = self.NODE_COMPARE_NUMERIC
|
||||||
self.operator = operator
|
self.operator = operator
|
||||||
self.left = left
|
self.left = left
|
||||||
@ -135,7 +139,7 @@ class NumericCompareNode(Node):
|
|||||||
|
|
||||||
class LogopBinaryNode(Node):
|
class LogopBinaryNode(Node):
|
||||||
def __init__(self, line_number, operator, left, right):
|
def __init__(self, line_number, operator, left, right):
|
||||||
Node.__init__(self, line_number, 'BINARY LOGICAL OP')
|
Node.__init__(self, line_number, 'binary operator: ' + operator)
|
||||||
self.node_type = self.NODE_BINARY_LOGOP
|
self.node_type = self.NODE_BINARY_LOGOP
|
||||||
self.operator = operator
|
self.operator = operator
|
||||||
self.left = left
|
self.left = left
|
||||||
@ -144,7 +148,7 @@ class LogopBinaryNode(Node):
|
|||||||
|
|
||||||
class LogopUnaryNode(Node):
|
class LogopUnaryNode(Node):
|
||||||
def __init__(self, line_number, operator, expr):
|
def __init__(self, line_number, operator, expr):
|
||||||
Node.__init__(self, line_number, 'UNARY LOGICAL OP')
|
Node.__init__(self, line_number, 'unary operator: ' + operator)
|
||||||
self.node_type = self.NODE_UNARY_LOGOP
|
self.node_type = self.NODE_UNARY_LOGOP
|
||||||
self.operator = operator
|
self.operator = operator
|
||||||
self.expr = expr
|
self.expr = expr
|
||||||
@ -152,7 +156,7 @@ class LogopUnaryNode(Node):
|
|||||||
|
|
||||||
class NumericBinaryNode(Node):
|
class NumericBinaryNode(Node):
|
||||||
def __init__(self, line_number, operator, left, right):
|
def __init__(self, line_number, operator, left, right):
|
||||||
Node.__init__(self, line_number, 'BINARY ARITHMETIC OP')
|
Node.__init__(self, line_number, 'binary operator: ' + operator)
|
||||||
self.node_type = self.NODE_BINARY_ARITHOP
|
self.node_type = self.NODE_BINARY_ARITHOP
|
||||||
self.operator = operator
|
self.operator = operator
|
||||||
self.left = left
|
self.left = left
|
||||||
@ -161,7 +165,7 @@ class NumericBinaryNode(Node):
|
|||||||
|
|
||||||
class NumericUnaryNode(Node):
|
class NumericUnaryNode(Node):
|
||||||
def __init__(self, line_number, operator, expr):
|
def __init__(self, line_number, operator, expr):
|
||||||
Node.__init__(self, line_number, 'UNARY ARITHMETIC OP')
|
Node.__init__(self, line_number, 'unary operator: '+ operator)
|
||||||
self.node_type = self.NODE_UNARY_ARITHOP
|
self.node_type = self.NODE_UNARY_ARITHOP
|
||||||
self.operator = operator
|
self.operator = operator
|
||||||
self.expr = expr
|
self.expr = expr
|
||||||
@ -169,28 +173,28 @@ class NumericUnaryNode(Node):
|
|||||||
|
|
||||||
class ConstantNode(Node):
|
class ConstantNode(Node):
|
||||||
def __init__(self, line_number, value):
|
def __init__(self, line_number, value):
|
||||||
Node.__init__(self, line_number, 'CONSTANT')
|
Node.__init__(self, line_number, 'constant: ' + value)
|
||||||
self.node_type = self.NODE_CONSTANT
|
self.node_type = self.NODE_CONSTANT
|
||||||
self.value = value
|
self.value = value
|
||||||
|
|
||||||
|
|
||||||
class VariableNode(Node):
|
class VariableNode(Node):
|
||||||
def __init__(self, line_number, name):
|
def __init__(self, line_number, name):
|
||||||
Node.__init__(self, line_number, 'VARIABLE')
|
Node.__init__(self, line_number, 'variable: ' + name)
|
||||||
self.node_type = self.NODE_RVALUE
|
self.node_type = self.NODE_RVALUE
|
||||||
self.name = name
|
self.name = name
|
||||||
|
|
||||||
|
|
||||||
class FieldNode(Node):
|
class FieldNode(Node):
|
||||||
def __init__(self, line_number, expression):
|
def __init__(self, line_number, expression):
|
||||||
Node.__init__(self, line_number, 'FIELD FUNCTION')
|
Node.__init__(self, line_number, 'field()')
|
||||||
self.node_type = self.NODE_FIELD
|
self.node_type = self.NODE_FIELD
|
||||||
self.expression = expression
|
self.expression = expression
|
||||||
|
|
||||||
|
|
||||||
class RawFieldNode(Node):
|
class RawFieldNode(Node):
|
||||||
def __init__(self, line_number, expression, default=None):
|
def __init__(self, line_number, expression, default=None):
|
||||||
Node.__init__(self, line_number, 'RAW_FIELD FUNCTION')
|
Node.__init__(self, line_number, 'raw_field()')
|
||||||
self.node_type = self.NODE_RAW_FIELD
|
self.node_type = self.NODE_RAW_FIELD
|
||||||
self.expression = expression
|
self.expression = expression
|
||||||
self.default = default
|
self.default = default
|
||||||
@ -198,14 +202,14 @@ class RawFieldNode(Node):
|
|||||||
|
|
||||||
class FirstNonEmptyNode(Node):
|
class FirstNonEmptyNode(Node):
|
||||||
def __init__(self, line_number, expression_list):
|
def __init__(self, line_number, expression_list):
|
||||||
Node.__init__(self, line_number, 'FIRST_NON_EMPTY FUNCTION')
|
Node.__init__(self, line_number, 'first_non_empty()')
|
||||||
self.node_type = self.NODE_FIRST_NON_EMPTY
|
self.node_type = self.NODE_FIRST_NON_EMPTY
|
||||||
self.expression_list = expression_list
|
self.expression_list = expression_list
|
||||||
|
|
||||||
|
|
||||||
class ContainsNode(Node):
|
class ContainsNode(Node):
|
||||||
def __init__(self, line_number, arguments):
|
def __init__(self, line_number, arguments):
|
||||||
Node.__init__(self, line_number, 'CONTAINS FUNCTION')
|
Node.__init__(self, line_number, 'contains()')
|
||||||
self.node_type = self.NODE_CONTAINS
|
self.node_type = self.NODE_CONTAINS
|
||||||
self.value_expression = arguments[0]
|
self.value_expression = arguments[0]
|
||||||
self.test_expression = arguments[1]
|
self.test_expression = arguments[1]
|
||||||
@ -215,17 +219,11 @@ class ContainsNode(Node):
|
|||||||
|
|
||||||
class PrintNode(Node):
|
class PrintNode(Node):
|
||||||
def __init__(self, line_number, arguments):
|
def __init__(self, line_number, arguments):
|
||||||
Node.__init__(self, line_number, 'PRINT')
|
Node.__init__(self, line_number, 'print')
|
||||||
self.node_type = self.NODE_PRINT
|
self.node_type = self.NODE_PRINT
|
||||||
self.arguments = arguments
|
self.arguments = arguments
|
||||||
|
|
||||||
|
|
||||||
class LineNumberNode(Node):
|
|
||||||
def __init__(self, line_number):
|
|
||||||
Node.__init__(self, line_number, 'LINE NUMBER')
|
|
||||||
self.node_type = self.NODE_LINE_NUMBER
|
|
||||||
|
|
||||||
|
|
||||||
class _Parser(object):
|
class _Parser(object):
|
||||||
LEX_OP = 1
|
LEX_OP = 1
|
||||||
LEX_ID = 2
|
LEX_ID = 2
|
||||||
@ -513,7 +511,6 @@ class _Parser(object):
|
|||||||
while True:
|
while True:
|
||||||
while self.token_is_newline():
|
while self.token_is_newline():
|
||||||
self.line_number += 1
|
self.line_number += 1
|
||||||
expr_list.append(LineNumberNode(self.line_number))
|
|
||||||
self.consume()
|
self.consume()
|
||||||
if self.token_is_eof():
|
if self.token_is_eof():
|
||||||
break
|
break
|
||||||
@ -529,7 +526,7 @@ class _Parser(object):
|
|||||||
line_number = self.line_number
|
line_number = self.line_number
|
||||||
condition = self.top_expr()
|
condition = self.top_expr()
|
||||||
if not self.token_is_then():
|
if not self.token_is_then():
|
||||||
self.error(_("Missing 'then' in if statement"))
|
self.error(_("Expected '%s' in '%s' statement")%('then', 'if'))
|
||||||
self.consume()
|
self.consume()
|
||||||
then_part = self.expression_list()
|
then_part = self.expression_list()
|
||||||
if self.token_is_elif():
|
if self.token_is_elif():
|
||||||
@ -540,17 +537,18 @@ class _Parser(object):
|
|||||||
else:
|
else:
|
||||||
else_part = None
|
else_part = None
|
||||||
if not self.token_is_fi():
|
if not self.token_is_fi():
|
||||||
self.error(_("Missing 'fi' in if statement"))
|
self.error(_("Expected '%s' in '%s' statement")%('fi', 'if'))
|
||||||
self.consume()
|
self.consume()
|
||||||
return IfNode(line_number, condition, then_part, else_part)
|
return IfNode(line_number, condition, then_part, else_part)
|
||||||
|
|
||||||
def for_expression(self):
|
def for_expression(self):
|
||||||
|
line_number = self.line_number
|
||||||
self.consume()
|
self.consume()
|
||||||
if not self.token_is_id():
|
if not self.token_is_id():
|
||||||
self.error(_("Missing identifier in for statement"))
|
self.error(_("Expected identifier in '%s' statement")%'for')
|
||||||
variable = self.token()
|
variable = self.token()
|
||||||
if not self.token_is_in():
|
if not self.token_is_in():
|
||||||
self.error(_("Missing 'in' in for statement"))
|
self.error(_("Expected '%s' in '%s' statement")%('in', 'for'))
|
||||||
self.consume()
|
self.consume()
|
||||||
list_expr = self.top_expr()
|
list_expr = self.top_expr()
|
||||||
if self.token_is_separator():
|
if self.token_is_separator():
|
||||||
@ -559,13 +557,13 @@ class _Parser(object):
|
|||||||
else:
|
else:
|
||||||
separator = None
|
separator = None
|
||||||
if not self.token_op_is_colon():
|
if not self.token_op_is_colon():
|
||||||
self.error(_("Missing colon (':') in for statement"))
|
self.error(_("Expected colon in '%s' statement")%'for')
|
||||||
self.consume()
|
self.consume()
|
||||||
block = self.expression_list()
|
block = self.expression_list()
|
||||||
if not self.token_is_rof():
|
if not self.token_is_rof():
|
||||||
self.error(_("Missing 'rof' in for statement"))
|
self.error(_("Expected '%s' in '%s' statement")%('rof', 'for'))
|
||||||
self.consume()
|
self.consume()
|
||||||
return ForNode(self.line_number, variable, list_expr, separator, block)
|
return ForNode(line_number, variable, list_expr, separator, block)
|
||||||
|
|
||||||
def top_expr(self):
|
def top_expr(self):
|
||||||
return self.or_expr()
|
return self.or_expr()
|
||||||
@ -644,7 +642,7 @@ class _Parser(object):
|
|||||||
self.consume()
|
self.consume()
|
||||||
rv = self.expression_list()
|
rv = self.expression_list()
|
||||||
if not self.token_op_is_rparen():
|
if not self.token_op_is_rparen():
|
||||||
self.error(_('Missing )'))
|
self.error(_("Expected a right parenthesis"))
|
||||||
self.consume()
|
self.consume()
|
||||||
return rv
|
return rv
|
||||||
if self.token_is_if():
|
if self.token_is_if():
|
||||||
@ -652,19 +650,20 @@ class _Parser(object):
|
|||||||
if self.token_is_for():
|
if self.token_is_for():
|
||||||
return self.for_expression()
|
return self.for_expression()
|
||||||
if self.token_is_id():
|
if self.token_is_id():
|
||||||
|
line_number = self.line_number
|
||||||
id_ = self.token()
|
id_ = self.token()
|
||||||
# We have an identifier. Check if it is a field reference
|
# We have an identifier. Check if it is a field reference
|
||||||
if len(id_) > 1 and id_[0] == '$':
|
if len(id_) > 1 and id_[0] == '$':
|
||||||
if id_[1] == '$':
|
if id_[1] == '$':
|
||||||
return RawFieldNode(self.line_number, ConstantNode(self.line_number, id_[2:]))
|
return RawFieldNode(line_number, ConstantNode(self.line_number, id_[2:]))
|
||||||
return FieldNode(self.line_number, ConstantNode(self.line_number, id_[1:]))
|
return FieldNode(line_number, ConstantNode(self.line_number, id_[1:]))
|
||||||
# Determine if it is a function
|
# Determine if it is a function
|
||||||
if not self.token_op_is_lparen():
|
if not self.token_op_is_lparen():
|
||||||
if self.token_op_is_equals():
|
if self.token_op_is_equals():
|
||||||
# classic assignment statement
|
# classic assignment statement
|
||||||
self.consume()
|
self.consume()
|
||||||
return AssignNode(self.line_number, id_, self.top_expr())
|
return AssignNode(line_number, id_, self.top_expr())
|
||||||
return VariableNode(self.line_number, id_)
|
return VariableNode(line_number, id_)
|
||||||
|
|
||||||
# We have a function.
|
# We have a function.
|
||||||
# Check if it is a known one. We do this here so error reporting is
|
# Check if it is a known one. We do this here so error reporting is
|
||||||
@ -682,17 +681,17 @@ class _Parser(object):
|
|||||||
break
|
break
|
||||||
self.consume()
|
self.consume()
|
||||||
if self.token() != ')':
|
if self.token() != ')':
|
||||||
self.error(_('Missing closing parenthesis'))
|
self.error(_("Expected a closing right parenthesis for function call"))
|
||||||
if id_ == 'field' and len(arguments) == 1:
|
if id_ == 'field' and len(arguments) == 1:
|
||||||
return FieldNode(self.line_number, arguments[0])
|
return FieldNode(line_number, arguments[0])
|
||||||
if id_ == 'raw_field' and (len(arguments) in (1, 2)):
|
if id_ == 'raw_field' and (len(arguments) in (1, 2)):
|
||||||
return RawFieldNode(self.line_number, *arguments)
|
return RawFieldNode(line_number, *arguments)
|
||||||
if id_ == 'test' and len(arguments) == 3:
|
if id_ == 'test' and len(arguments) == 3:
|
||||||
return IfNode(self.line_number, arguments[0], (arguments[1],), (arguments[2],))
|
return IfNode(line_number, arguments[0], (arguments[1],), (arguments[2],))
|
||||||
if id_ == 'first_non_empty' and len(arguments) > 0:
|
if id_ == 'first_non_empty' and len(arguments) > 0:
|
||||||
return FirstNonEmptyNode(self.line_number, arguments)
|
return FirstNonEmptyNode(line_number, arguments)
|
||||||
if (id_ == 'assign' and len(arguments) == 2 and arguments[0].node_type == Node.NODE_RVALUE):
|
if (id_ == 'assign' and len(arguments) == 2 and arguments[0].node_type == Node.NODE_RVALUE):
|
||||||
return AssignNode(self.line_number, arguments[0].name, arguments[1])
|
return AssignNode(line_number, arguments[0].name, arguments[1])
|
||||||
if id_ == 'arguments' or id_ == 'globals' or id_ == 'set_globals':
|
if id_ == 'arguments' or id_ == 'globals' or id_ == 'set_globals':
|
||||||
new_args = []
|
new_args = []
|
||||||
for arg_list in arguments:
|
for arg_list in arguments:
|
||||||
@ -701,23 +700,23 @@ class _Parser(object):
|
|||||||
self.error(_("Parameters to '{}' must be "
|
self.error(_("Parameters to '{}' must be "
|
||||||
"variables or assignments").format(id_))
|
"variables or assignments").format(id_))
|
||||||
if arg.node_type == Node.NODE_RVALUE:
|
if arg.node_type == Node.NODE_RVALUE:
|
||||||
arg = AssignNode(self.line_number, arg.name, ConstantNode(self.line_number, ''))
|
arg = AssignNode(line_number, arg.name, ConstantNode(self.line_number, ''))
|
||||||
new_args.append(arg)
|
new_args.append(arg)
|
||||||
if id_ == 'arguments':
|
if id_ == 'arguments':
|
||||||
return ArgumentsNode(self.line_number, new_args)
|
return ArgumentsNode(line_number, new_args)
|
||||||
if id_ == 'set_globals':
|
if id_ == 'set_globals':
|
||||||
return SetGlobalsNode(self.line_number, new_args)
|
return SetGlobalsNode(line_number, new_args)
|
||||||
return GlobalsNode(self.line_number, new_args)
|
return GlobalsNode(line_number, new_args)
|
||||||
if id_ == 'contains' and len(arguments) == 4:
|
if id_ == 'contains' and len(arguments) == 4:
|
||||||
return ContainsNode(self.line_number, arguments)
|
return ContainsNode(line_number, arguments)
|
||||||
if id_ == 'print':
|
if id_ == 'print':
|
||||||
return PrintNode(self.line_number, arguments)
|
return PrintNode(line_number, arguments)
|
||||||
if id_ in self.func_names and not self.funcs[id_].is_python:
|
if id_ in self.func_names and not self.funcs[id_].is_python:
|
||||||
return self.call_expression(id_, arguments)
|
return self.call_expression(id_, arguments)
|
||||||
cls = self.funcs[id_]
|
cls = self.funcs[id_]
|
||||||
if cls.arg_count != -1 and len(arguments) != cls.arg_count:
|
if cls.arg_count != -1 and len(arguments) != cls.arg_count:
|
||||||
self.error(_('Incorrect number of arguments for function {0}').format(id_))
|
self.error(_('Incorrect number of arguments for function {0}').format(id_))
|
||||||
return FunctionNode(self.line_number, id_, arguments)
|
return FunctionNode(line_number, id_, arguments)
|
||||||
elif self.token_is_constant():
|
elif self.token_is_constant():
|
||||||
# String or number
|
# String or number
|
||||||
return ConstantNode(self.line_number, self.token())
|
return ConstantNode(self.line_number, self.token())
|
||||||
@ -726,8 +725,8 @@ class _Parser(object):
|
|||||||
|
|
||||||
|
|
||||||
class _Interpreter(object):
|
class _Interpreter(object):
|
||||||
def error(self, message):
|
def error(self, message, line_number):
|
||||||
m = _('Interpreter: {0} - line number {1}').format(message, self.line_number)
|
m = _('Interpreter: {0} - line number {1}').format(message, line_number)
|
||||||
raise ValueError(m)
|
raise ValueError(m)
|
||||||
|
|
||||||
def program(self, funcs, parent, prog, val, is_call=False, args=None,
|
def program(self, funcs, parent, prog, val, is_call=False, args=None,
|
||||||
@ -735,7 +734,6 @@ class _Interpreter(object):
|
|||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.parent_kwargs = parent.kwargs
|
self.parent_kwargs = parent.kwargs
|
||||||
self.parent_book = parent.book
|
self.parent_book = parent.book
|
||||||
self.line_number = 1
|
|
||||||
self.funcs = funcs
|
self.funcs = funcs
|
||||||
self.locals = {'$':val}
|
self.locals = {'$':val}
|
||||||
self.global_vars = global_vars if isinstance(global_vars, dict) else {}
|
self.global_vars = global_vars if isinstance(global_vars, dict) else {}
|
||||||
@ -746,21 +744,16 @@ class _Interpreter(object):
|
|||||||
self.break_reporter = None
|
self.break_reporter = None
|
||||||
|
|
||||||
if is_call:
|
if is_call:
|
||||||
return self.do_node_call(CallNode(self.line_number, prog, None), args=args)
|
return self.do_node_call(CallNode(1, prog, None), args=args)
|
||||||
return self.expression_list(prog)
|
return self.expression_list(prog)
|
||||||
|
|
||||||
def call_break_reporter(self, txt, val, line_number=None):
|
def call_break_reporter(self, txt, val, line_number):
|
||||||
self.real_break_reporter(txt, val, self.locals,
|
self.real_break_reporter(txt, val, self.locals, line_number)
|
||||||
line_number if line_number else self.line_number)
|
|
||||||
|
|
||||||
def expression_list(self, prog):
|
def expression_list(self, prog):
|
||||||
val = ''
|
val = ''
|
||||||
for p in prog:
|
for p in prog:
|
||||||
val = self.expr(p)
|
val = self.expr(p)
|
||||||
if (self.break_reporter and
|
|
||||||
p.node_type != Node.NODE_LINE_NUMBER and
|
|
||||||
p.node_type != Node.NODE_IF):
|
|
||||||
self.break_reporter(p.node_name(), val)
|
|
||||||
return val
|
return val
|
||||||
|
|
||||||
INFIX_STRING_COMPARE_OPS = {
|
INFIX_STRING_COMPARE_OPS = {
|
||||||
@ -777,9 +770,14 @@ class _Interpreter(object):
|
|||||||
try:
|
try:
|
||||||
left = self.expr(prog.left)
|
left = self.expr(prog.left)
|
||||||
right = self.expr(prog.right)
|
right = self.expr(prog.right)
|
||||||
return ('1' if self.INFIX_STRING_COMPARE_OPS[prog.operator](left, right) else '')
|
res = '1' if self.INFIX_STRING_COMPARE_OPS[prog.operator](left, right) else ''
|
||||||
|
if (self.break_reporter):
|
||||||
|
self.break_reporter(prog.node_name, res, prog.line_number)
|
||||||
|
return res
|
||||||
except:
|
except:
|
||||||
self.error(_('Error during string comparison. Operator {0}').format(prog.operator))
|
self.error(
|
||||||
|
_('Error during string comparison. Operator {0}').format(prog.operator),
|
||||||
|
prog.line_number)
|
||||||
|
|
||||||
INFIX_NUMERIC_COMPARE_OPS = {
|
INFIX_NUMERIC_COMPARE_OPS = {
|
||||||
"==#": lambda x, y: x == y,
|
"==#": lambda x, y: x == y,
|
||||||
@ -799,32 +797,40 @@ class _Interpreter(object):
|
|||||||
try:
|
try:
|
||||||
left = self.float_deal_with_none(self.expr(prog.left))
|
left = self.float_deal_with_none(self.expr(prog.left))
|
||||||
right = self.float_deal_with_none(self.expr(prog.right))
|
right = self.float_deal_with_none(self.expr(prog.right))
|
||||||
return '1' if self.INFIX_NUMERIC_COMPARE_OPS[prog.operator](left, right) else ''
|
res = '1' if self.INFIX_NUMERIC_COMPARE_OPS[prog.operator](left, right) else ''
|
||||||
|
if (self.break_reporter):
|
||||||
|
self.break_reporter(prog.node_name, res, prog.line_number)
|
||||||
|
return res
|
||||||
except:
|
except:
|
||||||
self.error(_('Value used in comparison is not a number. Operator {0}').format(prog.operator))
|
self.error(
|
||||||
|
_('Value used in comparison is not a number. Operator {0}').format(prog.operator),
|
||||||
|
prog.line_number)
|
||||||
|
|
||||||
def do_node_if(self, prog):
|
def do_node_if(self, prog):
|
||||||
line_number = prog.line_number
|
line_number = prog.line_number
|
||||||
test_part = self.expr(prog.condition)
|
test_part = self.expr(prog.condition)
|
||||||
if self.break_reporter:
|
if self.break_reporter:
|
||||||
self.break_reporter('if: condition', test_part, line_number=line_number)
|
self.break_reporter("'if': condition value", test_part, line_number)
|
||||||
if test_part:
|
if test_part:
|
||||||
v = self.expression_list(prog.then_part)
|
v = self.expression_list(prog.then_part)
|
||||||
if self.break_reporter:
|
if self.break_reporter:
|
||||||
self.break_reporter('if: then part', v, line_number=line_number)
|
self.break_reporter("'if': then-block value", v, line_number)
|
||||||
return v
|
return v
|
||||||
elif prog.else_part:
|
elif prog.else_part:
|
||||||
v = self.expression_list(prog.else_part)
|
v = self.expression_list(prog.else_part)
|
||||||
if self.break_reporter:
|
if self.break_reporter:
|
||||||
self.break_reporter('if: else part', v, line_number=line_number)
|
self.break_reporter("'if': else-block value", v, line_number)
|
||||||
return v
|
return v
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def do_node_rvalue(self, prog):
|
def do_node_rvalue(self, prog):
|
||||||
try:
|
try:
|
||||||
|
if (self.break_reporter):
|
||||||
|
self.break_reporter(prog.node_name, self.locals[prog.name], prog.line_number)
|
||||||
return self.locals[prog.name]
|
return self.locals[prog.name]
|
||||||
except:
|
except:
|
||||||
self.error(_('Unknown identifier {0}').format(prog.name))
|
self.error(_('Unknown identifier {0}').format(prog.name),
|
||||||
|
prog.line_number)
|
||||||
|
|
||||||
def do_node_func(self, prog):
|
def do_node_func(self, prog):
|
||||||
args = list()
|
args = list()
|
||||||
@ -834,8 +840,11 @@ class _Interpreter(object):
|
|||||||
# Evaluate the function.
|
# Evaluate the function.
|
||||||
id_ = prog.name.strip()
|
id_ = prog.name.strip()
|
||||||
cls = self.funcs[id_]
|
cls = self.funcs[id_]
|
||||||
return cls.eval_(self.parent, self.parent_kwargs,
|
res = cls.eval_(self.parent, self.parent_kwargs,
|
||||||
self.parent_book, self.locals, *args)
|
self.parent_book, self.locals, *args)
|
||||||
|
if (self.break_reporter):
|
||||||
|
self.break_reporter(prog.node_name, res, prog.line_number)
|
||||||
|
return res
|
||||||
|
|
||||||
def do_node_call(self, prog, args=None):
|
def do_node_call(self, prog, args=None):
|
||||||
if args is None:
|
if args is None:
|
||||||
@ -849,53 +858,78 @@ class _Interpreter(object):
|
|||||||
self.locals['*arg_'+ str(dex)] = v
|
self.locals['*arg_'+ str(dex)] = v
|
||||||
val = self.expression_list(prog.function)
|
val = self.expression_list(prog.function)
|
||||||
self.locals = saved_locals
|
self.locals = saved_locals
|
||||||
|
if (self.break_reporter):
|
||||||
|
self.break_reporter(prog.node_name, val, prog.line_number)
|
||||||
return val
|
return val
|
||||||
|
|
||||||
def do_node_arguments(self, prog):
|
def do_node_arguments(self, prog):
|
||||||
for dex, arg in enumerate(prog.expression_list):
|
for dex, arg in enumerate(prog.expression_list):
|
||||||
self.locals[arg.left] = self.locals.get('*arg_'+ str(dex), self.expr(arg.right))
|
self.locals[arg.left] = self.locals.get('*arg_'+ str(dex), self.expr(arg.right))
|
||||||
|
if (self.break_reporter):
|
||||||
|
self.break_reporter(prog.node_name, '', prog.line_number)
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def do_node_globals(self, prog):
|
def do_node_globals(self, prog):
|
||||||
res = ''
|
res = ''
|
||||||
for arg in prog.expression_list:
|
for arg in prog.expression_list:
|
||||||
res = self.locals[arg.left] = self.global_vars.get(arg.left, self.expr(arg.right))
|
res = self.locals[arg.left] = self.global_vars.get(arg.left, self.expr(arg.right))
|
||||||
|
if (self.break_reporter):
|
||||||
|
self.break_reporter(prog.node_name, res, prog.line_number)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def do_node_set_globals(self, prog):
|
def do_node_set_globals(self, prog):
|
||||||
res = ''
|
res = ''
|
||||||
for arg in prog.expression_list:
|
for arg in prog.expression_list:
|
||||||
res = self.global_vars[arg.left] = self.locals.get(arg.left, self.expr(arg.right))
|
res = self.global_vars[arg.left] = self.locals.get(arg.left, self.expr(arg.right))
|
||||||
|
if (self.break_reporter):
|
||||||
|
self.break_reporter(prog.node_name, res, prog.line_number)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def do_node_constant(self, prog):
|
def do_node_constant(self, prog):
|
||||||
|
if (self.break_reporter):
|
||||||
|
self.break_reporter(prog.node_name, prog.value, prog.line_number)
|
||||||
return prog.value
|
return prog.value
|
||||||
|
|
||||||
def do_node_field(self, prog):
|
def do_node_field(self, prog):
|
||||||
try:
|
try:
|
||||||
name = self.expr(prog.expression)
|
name = self.expr(prog.expression)
|
||||||
try:
|
try:
|
||||||
return self.parent.get_value(name, [], self.parent_kwargs)
|
res = self.parent.get_value(name, [], self.parent_kwargs)
|
||||||
|
if (self.break_reporter):
|
||||||
|
self.break_reporter(prog.node_name, res, prog.line_number)
|
||||||
|
return res
|
||||||
except:
|
except:
|
||||||
self.error(_('Unknown field {0}').format(name))
|
self.error(_('Unknown field {0}').format(name),
|
||||||
|
prog.line_number)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
raise e
|
raise e
|
||||||
except:
|
except:
|
||||||
self.error(_('Unknown field {0}').format('internal parse error'))
|
self.error(_('Unknown field {0}').format('internal parse error'),
|
||||||
|
prog.line_number)
|
||||||
|
|
||||||
def do_node_raw_field(self, prog):
|
def do_node_raw_field(self, prog):
|
||||||
try:
|
try:
|
||||||
name = self.expr(prog.expression)
|
name = self.expr(prog.expression)
|
||||||
res = getattr(self.parent_book, name, None)
|
res = getattr(self.parent_book, name, None)
|
||||||
if res is None and prog.default is not None:
|
if res is None and prog.default is not None:
|
||||||
return self.expr(prog.default)
|
res = self.expr(prog.default)
|
||||||
|
if (self.break_reporter):
|
||||||
|
self.break_reporter(prog.node_name, res, prog.line_number)
|
||||||
|
return res
|
||||||
if res is not None:
|
if res is not None:
|
||||||
if isinstance(res, list):
|
if isinstance(res, list):
|
||||||
fm = self.parent_book.metadata_for_field(name)
|
fm = self.parent_book.metadata_for_field(name)
|
||||||
if fm is None:
|
if fm is None:
|
||||||
return ', '.join(res)
|
res = ', '.join(res)
|
||||||
return fm['is_multiple']['list_to_ui'].join(res)
|
else:
|
||||||
return unicode_type(res)
|
res = fm['is_multiple']['list_to_ui'].join(res)
|
||||||
|
else:
|
||||||
|
res = unicode_type(res)
|
||||||
|
else:
|
||||||
|
res = unicode_type(res) # Should be the string "None"
|
||||||
|
if (self.break_reporter):
|
||||||
|
self.break_reporter(prog.node_name, res, prog.line_number)
|
||||||
|
return res
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
raise e
|
raise e
|
||||||
except:
|
except:
|
||||||
@ -904,15 +938,22 @@ class _Interpreter(object):
|
|||||||
def do_node_assign(self, prog):
|
def do_node_assign(self, prog):
|
||||||
t = self.expr(prog.right)
|
t = self.expr(prog.right)
|
||||||
self.locals[prog.left] = t
|
self.locals[prog.left] = t
|
||||||
|
if (self.break_reporter):
|
||||||
|
self.break_reporter(prog.node_name, t, prog.line_number)
|
||||||
return t
|
return t
|
||||||
|
|
||||||
def do_node_first_non_empty(self, prog):
|
def do_node_first_non_empty(self, prog):
|
||||||
for expr in prog.expression_list:
|
for expr in prog.expression_list:
|
||||||
if v := self.expr(expr):
|
if v := self.expr(expr):
|
||||||
|
if (self.break_reporter):
|
||||||
|
self.break_reporter(prog.node_name, v, prog.line_number)
|
||||||
return v
|
return v
|
||||||
|
if (self.break_reporter):
|
||||||
|
self.break_reporter(prog.node_name, '', prog.line_number)
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def do_node_for(self, prog):
|
def do_node_for(self, prog):
|
||||||
|
line_number = prog.line_number
|
||||||
try:
|
try:
|
||||||
separator = ',' if prog.separator is None else self.expr(prog.separator)
|
separator = ',' if prog.separator is None else self.expr(prog.separator)
|
||||||
v = prog.variable
|
v = prog.variable
|
||||||
@ -923,26 +964,33 @@ class _Interpreter(object):
|
|||||||
res = [r.strip() for r in res.split(separator) if r.strip()]
|
res = [r.strip() for r in res.split(separator) if r.strip()]
|
||||||
ret = ''
|
ret = ''
|
||||||
if self.break_reporter:
|
if self.break_reporter:
|
||||||
self.break_reporter(_("'for' value list"), separator.join(res))
|
self.break_reporter("'for' list value", separator.join(res), line_number)
|
||||||
for x in res:
|
for x in res:
|
||||||
self.locals[v] = x
|
self.locals[v] = x
|
||||||
ret = self.expression_list(prog.block)
|
ret = self.expression_list(prog.block)
|
||||||
return ret
|
if (self.break_reporter):
|
||||||
|
self.break_reporter("'for' block value", ret, line_number)
|
||||||
elif self.break_reporter:
|
elif self.break_reporter:
|
||||||
self.break_reporter(_("'for' value list"), '')
|
# Shouldn't get here
|
||||||
|
self.break_reporter("'for' list value", '', line_number)
|
||||||
self.error(_('The field {0} is not a list').format(f))
|
ret = ''
|
||||||
|
return ret
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
raise e
|
raise e
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.error(_('Unhandled exception {0}').format(e))
|
self.error(_('Unhandled exception {0}').format(e), line_number)
|
||||||
|
|
||||||
def do_node_contains(self, prog):
|
def do_node_contains(self, prog):
|
||||||
v = self.expr(prog.value_expression)
|
v = self.expr(prog.value_expression)
|
||||||
t = self.expr(prog.test_expression)
|
t = self.expr(prog.test_expression)
|
||||||
if re.search(t, v, flags=re.I):
|
if re.search(t, v, flags=re.I):
|
||||||
return self.expr(prog.match_expression)
|
res = self.expr(prog.match_expression)
|
||||||
return self.expr(prog.not_match_expression)
|
else:
|
||||||
|
res = self.expr(prog.not_match_expression)
|
||||||
|
if (self.break_reporter):
|
||||||
|
self.break_reporter(prog.node_name, res, prog.line_number)
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
LOGICAL_BINARY_OPS = {
|
LOGICAL_BINARY_OPS = {
|
||||||
'and': lambda self, x, y: self.expr(x) and self.expr(y),
|
'and': lambda self, x, y: self.expr(x) and self.expr(y),
|
||||||
@ -951,9 +999,14 @@ class _Interpreter(object):
|
|||||||
|
|
||||||
def do_node_logop(self, prog):
|
def do_node_logop(self, prog):
|
||||||
try:
|
try:
|
||||||
return ('1' if self.LOGICAL_BINARY_OPS[prog.operator](self, prog.left, prog.right) else '')
|
res = ('1' if self.LOGICAL_BINARY_OPS[prog.operator](self, prog.left, prog.right) else '')
|
||||||
|
if (self.break_reporter):
|
||||||
|
self.break_reporter(prog.node_name, res, prog.line_number)
|
||||||
|
return res
|
||||||
except:
|
except:
|
||||||
self.error(_('Error during operator evaluation. Operator {0}').format(prog.operator))
|
self.error(
|
||||||
|
_('Error during operator evaluation. Operator {0}').format(prog.operator),
|
||||||
|
prog.line_number)
|
||||||
|
|
||||||
LOGICAL_UNARY_OPS = {
|
LOGICAL_UNARY_OPS = {
|
||||||
'not': lambda x: not x,
|
'not': lambda x: not x,
|
||||||
@ -962,9 +1015,14 @@ class _Interpreter(object):
|
|||||||
def do_node_logop_unary(self, prog):
|
def do_node_logop_unary(self, prog):
|
||||||
try:
|
try:
|
||||||
expr = self.expr(prog.expr)
|
expr = self.expr(prog.expr)
|
||||||
return ('1' if self.LOGICAL_UNARY_OPS[prog.operator](expr) else '')
|
res = ('1' if self.LOGICAL_UNARY_OPS[prog.operator](expr) else '')
|
||||||
|
if (self.break_reporter):
|
||||||
|
self.break_reporter(prog.node_name, res, prog.line_number)
|
||||||
|
return res
|
||||||
except:
|
except:
|
||||||
self.error(_('Error during operator evaluation. Operator {0}').format(prog.operator))
|
self.error(
|
||||||
|
_('Error during operator evaluation. Operator {0}').format(prog.operator),
|
||||||
|
prog.line_number)
|
||||||
|
|
||||||
ARITHMETIC_BINARY_OPS = {
|
ARITHMETIC_BINARY_OPS = {
|
||||||
'+': lambda x, y: x + y,
|
'+': lambda x, y: x + y,
|
||||||
@ -977,9 +1035,14 @@ class _Interpreter(object):
|
|||||||
try:
|
try:
|
||||||
answer = self.ARITHMETIC_BINARY_OPS[prog.operator](float(self.expr(prog.left)),
|
answer = self.ARITHMETIC_BINARY_OPS[prog.operator](float(self.expr(prog.left)),
|
||||||
float(self.expr(prog.right)))
|
float(self.expr(prog.right)))
|
||||||
return unicode_type(answer if modf(answer)[0] != 0 else int(answer))
|
res = unicode_type(answer if modf(answer)[0] != 0 else int(answer))
|
||||||
|
if (self.break_reporter):
|
||||||
|
self.break_reporter(prog.node_name, res, prog.line_number)
|
||||||
|
return res
|
||||||
except:
|
except:
|
||||||
self.error(_('Error during arithmetic operator evaluation. Operator {0}').format(prog.operator))
|
self.error(
|
||||||
|
_('Error during operator evaluation. Operator {0}').format(prog.operator),
|
||||||
|
prog.line_number)
|
||||||
|
|
||||||
ARITHMETIC_UNARY_OPS = {
|
ARITHMETIC_UNARY_OPS = {
|
||||||
'+': lambda x: x,
|
'+': lambda x: x,
|
||||||
@ -989,9 +1052,14 @@ class _Interpreter(object):
|
|||||||
def do_node_unary_arithop(self, prog):
|
def do_node_unary_arithop(self, prog):
|
||||||
try:
|
try:
|
||||||
expr = self.ARITHMETIC_UNARY_OPS[prog.operator](float(self.expr(prog.expr)))
|
expr = self.ARITHMETIC_UNARY_OPS[prog.operator](float(self.expr(prog.expr)))
|
||||||
return unicode_type(expr if modf(expr)[0] != 0 else int(expr))
|
res = unicode_type(expr if modf(expr)[0] != 0 else int(expr))
|
||||||
|
if (self.break_reporter):
|
||||||
|
self.break_reporter(prog.node_name, res, prog.line_number)
|
||||||
|
return res
|
||||||
except:
|
except:
|
||||||
self.error(_('Error during arithmetic operator evaluation. Operator {0}').format(prog.operator))
|
self.error(
|
||||||
|
_('Error during operator evaluation. Operator {0}').format(prog.operator),
|
||||||
|
prog.line_number)
|
||||||
|
|
||||||
def do_node_print(self, prog):
|
def do_node_print(self, prog):
|
||||||
res = []
|
res = []
|
||||||
@ -1000,10 +1068,6 @@ class _Interpreter(object):
|
|||||||
print(res)
|
print(res)
|
||||||
return res[0] if res else ''
|
return res[0] if res else ''
|
||||||
|
|
||||||
def do_node_line_number(self, prog):
|
|
||||||
self.line_number = prog.line_number
|
|
||||||
return ''
|
|
||||||
|
|
||||||
NODE_OPS = {
|
NODE_OPS = {
|
||||||
Node.NODE_IF: do_node_if,
|
Node.NODE_IF: do_node_if,
|
||||||
Node.NODE_ASSIGN: do_node_assign,
|
Node.NODE_ASSIGN: do_node_assign,
|
||||||
@ -1026,7 +1090,6 @@ class _Interpreter(object):
|
|||||||
Node.NODE_BINARY_ARITHOP: do_node_binary_arithop,
|
Node.NODE_BINARY_ARITHOP: do_node_binary_arithop,
|
||||||
Node.NODE_UNARY_ARITHOP: do_node_unary_arithop,
|
Node.NODE_UNARY_ARITHOP: do_node_unary_arithop,
|
||||||
Node.NODE_PRINT: do_node_print,
|
Node.NODE_PRINT: do_node_print,
|
||||||
Node.NODE_LINE_NUMBER: do_node_line_number,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def expr(self, prog):
|
def expr(self, prog):
|
||||||
@ -1039,7 +1102,7 @@ class _Interpreter(object):
|
|||||||
except:
|
except:
|
||||||
if (DEBUG):
|
if (DEBUG):
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
self.error(_('Internal error evaluating an expression'))
|
self.error(_('Internal error evaluating an expression'), prog.line_number)
|
||||||
|
|
||||||
|
|
||||||
class TemplateFormatter(string.Formatter):
|
class TemplateFormatter(string.Formatter):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user