Commit 3d0fabb8 authored by Sergio Costas's avatar Sergio Costas

Merge branch 'acceleration_2'

parents a0904278 b561ff18
......@@ -87,6 +87,7 @@ class crust(object):
self.next = None
self.intval = 0
self.floatval = 0.0
self.uid = None
def copy(self):
retval = crust.AST_node()
......@@ -120,6 +121,7 @@ class crust(object):
self.debug = []
self.print_debug = do_print_debug
self.id_counter = 0
self.expoints = {}
with open(headerpath, "r") as header:
do_process = False
......@@ -243,6 +245,9 @@ class crust(object):
if data is not None:
if (name == "type"):
data = tokens.tokens.get_token(data)
if data == "END_BLOCK":
newnode.uid = self.id_counter
self.id_counter += 1
elif isinstance(data, bytes):
data = data.decode("utf8")
elif isinstance(data, POINTER(self.AST_leaf)):
......@@ -1358,6 +1363,8 @@ class crust(object):
thread_status["debug_level"] = 0
thread_status["loop_level"] = 0
thread_status["find_label"] = None
# delete all the old expoints, because each function is processed independently
self.expoints = {}
if tree[0].type == "START_BLOCK":
tree = tree[1:] # the variable block has been already added
blocks = [ (tree, thread_status) ]
......@@ -1368,7 +1375,8 @@ class crust(object):
blocks = blocks[1:]
if current_block[0] is not None:
retval = self._process_block2(current_block[0], current_block[1])
blocks = retval + blocks
if retval is not None:
blocks = retval + blocks
else:
if (current_block[1]["returned_something"] is None) and (current_block[1]["return_is_crust"] is not None):
self._add_error(current_block[1], self.MSG_ERROR, "Function '{:s}' expects a return value, but the code exited without it", function_name)
......@@ -1439,6 +1447,42 @@ class crust(object):
self._add_error(thread_status, self.MSG_ERROR, "Memory block '{:s}', initialized at line {:d}, is still in use at exit point in line {:d}", variable, init_line, line)
def _compare_status(self, ex_point, status):
""" Gets the current status and compares it with all the previous status in the same execution point.
If the current status has been already found, it returns TRUE. If not, it will be stored and will return FALSE
Parameters:
ex_point: the execution point UID
status: the status to compare
Returns:
TRUE if the status has been already checked; FALSE if not
"""
current_vars = status["variables"][0]
if not ex_point in self.expoints:
self.expoints[ex_point] = [ current_vars.copy() ]
return False
for old_expoint in self.expoints[ex_point]:
if len(old_expoint) != len(current_vars):
continue
is_equal = True
for element in old_expoint:
if not element in current_vars:
is_equal = False
break
for item in old_expoint[element]:
if old_expoint[element][item] != current_vars[element][item]:
is_equal = False
break
if not is_equal:
break
if is_equal:
return True
self.expoints[ex_point].append(current_vars.copy())
return False
def _process_block2(self, tree, thread_status):
node = tree[0]
......@@ -1480,6 +1524,9 @@ class crust(object):
if (len(thread_status["variables"]) == 1):
# if we are at the end of the function, check the global variables
self._check_global_vars(thread_status, node.line)
else:
if self._compare_status(node.uid, thread_status):
return None
return self._check_return_block(tree[1:], thread_status)
if node.type == "EMPTY_DECLARATOR":
......
Markdown is supported
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