Commit 0a481405 authored by dbarbera's avatar dbarbera
Browse files

Merge branch 'master' into llvm

Conflicts:
	tests/regression/test12/Makefile
parents a906a059 7784ec59
......@@ -704,6 +704,9 @@ def _primary_variable(prim):
sep=sep, name=prim.value[0])
if prim.op_minus:
ada_string = '(-{})'.format(ada_string)
if prim.exprType.__name__ == 'for_range':
# Ada iterator in FOR loops is an Integer - we must cast to 64 bits
ada_string = u'Interfaces.Integer_64({})'.format(ada_string)
return [], ada_string, []
......
......@@ -15,6 +15,7 @@
This module is managing the Copy and Paste functions.
"""
import traceback
import logging
from itertools import chain
import PySide
......@@ -143,10 +144,22 @@ def paste_floating_objects(scene):
symbols.append(new_item)
# Insert the new state at click coordinates
Renderer.add_to_scene(new_item, scene)
for each in chain(text_areas, labels, procedures, processes):
LOG.debug('PASTE TA/LAB/PROC')
for each in chain(text_areas, labels):
LOG.debug('PASTE Text Area/Label')
new_item = Renderer.render(each, scene, states=states)
symbols.append(new_item)
for each in chain(procedures, processes):
LOG.debug('PASTE Process/Procedure')
new_item = Renderer.render(each, scene, states=states)
symbols.append(new_item)
new_item.nested_scene = scene.create_subscene(
type(new_item).__name__.lower())
# Render recursively, creating any required scene
try:
new_item.nested_scene.render_everything(each.content)
except TypeError as err:
LOG.debug(str(err))
if start:
start, = start
LOG.debug('PASTE START')
......
......@@ -252,11 +252,15 @@ class Channel(Connection):
def end_point(self):
''' Compute connection end point - redefined function '''
# Arrow always bumps at the screen edge
view = self.scene().views()[0]
view_pos = view.mapToScene(
try:
view = self.scene().views()[0]
view_pos = view.mapToScene(
view.viewport().geometry()).boundingRect().topLeft()
scene_pos_x = self.mapFromScene(view_pos).x()
return QPointF(scene_pos_x, self.start_point.y())
scene_pos_x = self.mapFromScene(view_pos).x()
return QPointF(scene_pos_x, self.start_point.y())
except IndexError:
# In case there is no view (e.g. Export PNG from cmd line)
return QPointF(self.start_point.x() - 50, self.start_point.y())
class Controlpoint(QGraphicsPathItem, object):
......
......@@ -47,6 +47,7 @@ def add_to_scene(item, scene):
if type(item) in scene.allowed_symbols:
scene.addItem(item)
else:
#print type(item), scene.allowed_symbols, scene.context
raise TypeError('This symbol does not fit the current scene')
......@@ -129,10 +130,10 @@ def _automaton(ast, scene):
new_state = render(state, scene=scene, states=ast.states,
terminators=ast.parent.terminators)
if new_state.nested_scene:
if str(new_state).lower() in nested_states:
if unicode(new_state).lower() in nested_states:
new_state.nested_scene = None
else:
nested_states.append(str(new_state).lower())
nested_states.append(unicode(new_state).lower())
except TypeError:
# Discard terminators (see _state function for explanation)
pass
......
......@@ -585,6 +585,8 @@ class Symbol(QObject, QGraphicsPathItem, object):
def __str__(self):
''' Print the text inside the symbol '''
import traceback
print traceback.print_stack()
raise TypeError('Use unicode() not str()')
#return str(self.text) or 'no_name'
......
......@@ -751,6 +751,9 @@ class Procedure(object):
self.comment = None
# Set of symbols contained in the procedure (type Automaton)
self.content = Automaton(parent=self)
# input/output signal lists - unused but for context information
self.input_signals = []
self.output_signals = []
class Process(object):
......
......@@ -1366,7 +1366,7 @@ def expression(root, context):
elif isinstance(expr, (ogAST.ExprMod, ogAST.ExprRem)):
attrs = {'Min': right.Min, 'Max': right.Max}
expr.exprType = type('Mod', (basic,), attrs)
except ValueError:
except (ValueError, AttributeError):
errors.append('Check that all your numerical data types have '
'a range constraint')
......@@ -2533,7 +2533,7 @@ def outputbody(root, context):
warnings.extend(warn)
elif child.type == lexer.TO:
pass
# TODO: better support of TO primitive
# TODO: better support of TO primitive
else:
warnings.append('Unsupported output body type:' +
str(child.type))
......@@ -3298,7 +3298,16 @@ def parseSingleElement(elem='', string=''):
assert(elem in ('input_part', 'output', 'decision', 'alternative_part',
'terminator_statement', 'label', 'task', 'procedure_call', 'end',
'text_area', 'state', 'start', 'procedure', 'floating_label',
'connect_part', 'process_definition'))
'connect_part', 'process_definition', 'proc_start', 'state_start'))
# Create a dummy context, needed to place context data
if elem == 'proc_start':
elem = 'start'
context = ogAST.Procedure()
elif elem == 'state_start':
elem = 'start'
context = ogAST.CompositeState()
else:
context = ogAST.Process()
LOG.debug('Parsing string: ' + string + ' with elem ' + elem)
parser = parser_init(string=string)
parser_ptr = getattr(parser, elem)
......@@ -3318,12 +3327,12 @@ def parseSingleElement(elem='', string=''):
root = r.tree
root.token_stream = parser.getTokenStream()
backend_ptr = eval(elem)
# Create a dummy process, needed to place context data
context = ogAST.Process()
try:
t, semantic_errors, warnings = backend_ptr(
root=root, parent=None, context=context)
except AttributeError:
except AttributeError as err:
print str(err)
print (traceback.format_exc())
# Syntax checker has no visibility on variables and types
# so we have to discard exceptions sent by e.g. find_variable
pass
......
......@@ -389,7 +389,7 @@ class SDL_Scene(QtGui.QGraphicsScene, object):
def all_nested_scenes(self):
''' Return all nested scenes, recursively '''
for each in self.visible_symb:
if each.nested_scene and isinstance(each, SDL_Scene):
if each.nested_scene and isinstance(each.nested_scene, SDL_Scene):
yield each.nested_scene
for sub in each.nested_scene.all_nested_scenes:
yield sub
......@@ -406,15 +406,21 @@ class SDL_Scene(QtGui.QGraphicsScene, object):
# XXX - should be set when entering the process
self.process_name = ast.processName
# Render top-level items and their children:
for each in Renderer.render(content, dest_scene):
G_SYMBOLS.add(each)
try:
# Render top-level items and their children:
for each in Renderer.render(content, dest_scene):
G_SYMBOLS.add(each)
except TypeError as err:
LOG.error(traceback.format_exc())
# Render nested scenes, recursively:
for each in (item for item in dest_scene.visible_symb
if item.nested_scene):
subscene = SDL_Scene(context=each.__class__.__name__.lower())
subscene.messages_window = self.messages_window
subscene = \
self.create_subscene(each.__class__.__name__.lower())
#subscene = SDL_Scene(context=each.__class__.__name__.lower())
#subscene.messages_window = self.messages_window
subscene.name = unicode(each)
recursive_render(each.nested_scene.content, subscene)
each.nested_scene = subscene
......@@ -633,9 +639,9 @@ class SDL_Scene(QtGui.QGraphicsScene, object):
Clipboard.copy(self.selected_symbols())
except TypeError as error_msg:
try:
self.messages_window.addItem(str(error_msg))
self.messages_window.addItem(unicode(error_msg))
except AttributeError:
LOG.error(str(error_msg))
LOG.error(unicode(error_msg))
raise
def cut_selected_symbols(self):
......@@ -662,7 +668,11 @@ class SDL_Scene(QtGui.QGraphicsScene, object):
try:
new_items = Clipboard.paste(parent_item, self)
except TypeError as error_msg:
self.messages_window.addItem(str(error_msg))
LOG.error(str(error_msg))
try:
self.messages_window.addItem(str(error_msg))
except AttributeError:
pass
else:
self.undo_stack.beginMacro('Paste')
for item in new_items:
......@@ -685,28 +695,6 @@ class SDL_Scene(QtGui.QGraphicsScene, object):
self.undo_stack.endMacro()
self.refresh()
# def get_pr_string(self):
# ''' Parse the graphical items and returns a PR string '''
# pr_data = deque()
# for each in self.processes:
# pr_data.append(each.PR())
#
# for item in chain(self.texts, self.procs, self.start):
# pr_data.append(item.PR())
# for item in self.floating_labels:
# pr_data.append(item.PR_floating())
# composite = set(self.composite_states.keys())
# for item in self.states:
# if item.is_composite():
# try:
# composite.remove(unicode(item).lower())
# pr_data.appendleft(item.parse_composite_state())
# except KeyError:
# pass
# pr_data.append(item.PR_state())
#
# return list(pr_data)
def sdl_to_statechart(self):
''' Create a graphviz representation of the SDL model '''
pr_raw = Pr.parse_scene(self)
......@@ -723,7 +711,7 @@ class SDL_Scene(QtGui.QGraphicsScene, object):
def export_branch_to_picture(self, symbol, filename, doc_format):
''' Save a symbol and its followers to a file '''
temp_scene = SDL_Scene()
temp_scene = SDL_Scene(context=self.context)
temp_scene.messages_window = self.messages_window
self.clearSelection()
symbol.select()
......@@ -746,8 +734,10 @@ class SDL_Scene(QtGui.QGraphicsScene, object):
# Save in multiple files
index = 0
for item in self.floating_symb:
self.export_branch_to_picture(item, filename + str(index),
doc_format)
name = '{}-{}'.format(filename, str(index))
LOG.info('Saving {ext} file: {name}.{ext}'
.format(ext=doc_format, name=name))
self.export_branch_to_picture(item, name, doc_format)
index += 1
if filename.split('.')[-1] != doc_format:
......@@ -756,12 +746,16 @@ class SDL_Scene(QtGui.QGraphicsScene, object):
self.clearSelection()
self.clear_focus()
# Copy in a different scene to get the smallest rectangle
other_scene = SDL_Scene()
other_scene = SDL_Scene(context=self.context)
other_scene.messages_window = self.messages_window
other_scene.setBackgroundBrush(QtGui.QBrush())
for each in self.floating_symb:
each.select()
self.copy_selected_symbols()
try:
self.copy_selected_symbols()
except AttributeError as err:
LOG.debug(str(traceback.format_exc()))
LOG.error(str(err))
other_scene.paste_symbols()
each.select(False)
rect = other_scene.sceneRect()
......@@ -986,6 +980,14 @@ class SDL_Scene(QtGui.QGraphicsScene, object):
pprint.pprint(selection.__dict__, None, 2, 1)
code.interact('type your command:', local=locals())
def create_subscene(self, context):
''' Create a new SDL scene, e.g. for nested symbols '''
subscene = SDL_Scene(context=context)
subscene.messages_window = self.messages_window
return subscene
def place_symbol(self, item_type, parent, pos=None):
''' Draw a symbol on the scene '''
item = item_type()
......@@ -1003,11 +1005,10 @@ class SDL_Scene(QtGui.QGraphicsScene, object):
# When creating a new decision, add two default answers
self.place_symbol(item_type=DecisionAnswer, parent=item)
self.place_symbol(item_type=DecisionAnswer, parent=item)
elif item_type in (Procedure, State):
# Create a sub-scene for the procedure or nested state
subscene = SDL_Scene(context=item_type.__name__.lower())
subscene.messages_window = self.messages_window
item.nested_scene = subscene
elif item_type in (Procedure, State, Process):
# Create a sub-scene for clickable symbols
item.nested_scene = \
self.create_subscene(item_type.__name__.lower())
self.clearSelection()
self.clear_focus()
......@@ -1242,9 +1243,8 @@ class SDL_View(QtGui.QGraphicsView, object):
item.double_click()
ctx = unicode(item.__class__.__name__.lower())
if not isinstance(item.nested_scene, SDL_Scene):
subscene = SDL_Scene(context=ctx)
subscene.messages_window = self.messages_window
item.nested_scene = subscene
item.nested_scene = \
self.scene().create_subscene(context=ctx)
self.go_down(item.nested_scene,
name=ctx + u' ' + unicode(item))
else:
......@@ -1389,7 +1389,7 @@ class SDL_View(QtGui.QGraphicsView, object):
else:
self.load_file(filenames)
def isModelClean(self):
def is_model_clean(self):
''' Check recursively if anything has changed in any scene '''
if self.parent_scene:
scene = self.parent_scene[0][0]
......@@ -1420,7 +1420,7 @@ class SDL_View(QtGui.QGraphicsView, object):
def new_diagram(self):
''' If model state is clean, reset current diagram '''
if not self.isModelClean():
if not self.is_model_clean():
# If changes occured since last save, pop up a window
if not self.propose_to_save():
return False
......@@ -1717,7 +1717,7 @@ class OG_MainWindow(QtGui.QMainWindow, object):
# pylint: disable=C0103
def closeEvent(self, event):
''' Close main application '''
if not self.view.isModelClean():
if not self.view.is_model_clean():
if not self.view.propose_to_save():
event.ignore()
return
......@@ -1796,9 +1796,9 @@ def parse(files):
LOG.info('Checking ' + str(files))
ast, warnings, errors = ogParser.parse_pr(files=files)
LOG.info(
'Parsing complete. Summary, found %d warnings and %d errors' % (len(warnings), len(errors))
)
LOG.info('Parsing complete. '
'Summary, found {} warnings and {} errors'
.format(len(warnings), len(errors)))
for warning in warnings:
LOG.warning(warning[0])
for error in errors:
......@@ -1828,11 +1828,14 @@ def generate(process, options):
LOG.error('LLVM IR generation failed')
def export(process, options):
def export(ast, options):
''' Export process '''
# Qt must be initialized before using SDL_Scene
init_qt()
# Initialize the clipboard
Clipboard.CLIPBOARD = SDL_Scene(context='clipboard')
export_fmt = []
if options.png:
export_fmt.append('png')
......@@ -1843,15 +1846,37 @@ def export(process, options):
if not export_fmt:
return
name = process.processName
scene = SDL_Scene(context='process')
scene.render_everything(process)
# Update connections, placements:
process, = ast.processes
try:
syst, = ast.systems
block, = syst.blocks
if block.processes[0].referenced:
LOG.debug('Process is referenced, fixing')
block.processes = [process]
except ValueError:
# No System/Block hierarchy, creating single block
block = ogAST.Block()
block.processes = [process]
scene = SDL_Scene(context='block')
scene.render_everything(block)
# Update connections, placements
scene.refresh()
for doc_fmt in export_fmt:
LOG.info('Saving {ext} file: {name}.{ext}'.format(ext=doc_fmt, name=name))
scene.export_img(name, doc_format=doc_fmt, split=options.split)
scenes = [scene]
for each in set(scene.all_nested_scenes):
if any(each.visible_symb):
scenes.append(each)
for idx, diagram in enumerate(scenes):
for doc_fmt in export_fmt:
name = '{}-{}-{}-{}'.format(str(idx),
process.processName,
diagram.context,
diagram.name or 'main')
LOG.info('Saving {ext} file: {name}.{ext}'
.format(ext=doc_fmt, name=name))
diagram.export_img(name, doc_format=doc_fmt, split=options.split)
def cli(options):
......@@ -1867,7 +1892,7 @@ def cli(options):
return 1
if options.png or options.pdf or options.svg:
export(ast.processes[0], options)
export(ast, options)
if options.toAda or options.llvm:
if not errors:
......@@ -1879,7 +1904,7 @@ def cli(options):
def init_qt():
''' Initialize QT '''
''' Initialize Qt '''
app = QtGui.QApplication.instance()
if app is None:
app = QtGui.QApplication(sys.argv)
......
......@@ -846,6 +846,7 @@ class ProcedureStart(Start):
# Define reserved keywords for the syntax highlighter
blackbold = SDL_BLACKBOLD
redbold = SDL_REDBOLD
common_name = 'proc_start'
def set_shape(self, width, height):
''' Compute the polygon to fit in width, height '''
......@@ -863,6 +864,7 @@ class StateStart(Start):
''' Composite states can have several named START symbols '''
has_text_area = True
is_singleton = False
common_name = 'state_start'
def __unicode__(self):
''' Return the state entry point '''
......
......@@ -16,9 +16,13 @@ test-llvm:
llc trafficlight.ll
gcc -c trafficlight.s
test-export:
../../../opengeode.py --png --pdf --svg trafficlight.pr system_structure.pr
../../../opengeode.py --png --pdf --svg --split trafficlight.pr system_structure.pr
coverage:
coverage run -p ../../../opengeode.py trafficlight.pr system_structure.pr --toAda
clean:
rm -rf *.adb *.ads *.pyc runSpark.sh spark.idx *.o *.ali gnat.cfg examiner \
bin *.wrn *.gpr testcase *.ll *.s
bin *.wrn *.gpr testcase *.ll *.s *.pdf *.svg *.png
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment