Commit 7bbce441 authored by Sergio Costas's avatar Sergio Costas

Moved the loop outside the function that checks the current statement. This...

Moved the loop outside the function that checks the current statement. This allows to fully remove all recursion, thus preventing failures in case of too much deep recursion.
parent c2310236
......@@ -429,7 +429,7 @@ class crusty(object):
options = self._eval_assignment(assignment.child2,var_container,function_container)
newoptions = []
for option in options:
retval = self._check_assignment(var_defined,[option],varname,assignment.child1[0],None,0,function_container)
retval = self._check_assignment(var_defined,option,varname,assignment.child1[0],None,function_container)
newoptions.append( (option[0],retval,option[2],option[3]) )
return newoptions
else:
......@@ -560,7 +560,7 @@ class crusty(object):
self._process_block(node.child1,tmpvars, function_container)
def _check_assignment(self,var_defined,options,varname,node,tree,counter,function_container):
def _check_assignment(self,var_defined,option,varname,node,tree,function_container):
this_is_crust = self.TYPE_CRUST if self._check_variable_properties(var_defined, self.PROPERTY_CRUST_VARIABLE) else self.TYPE_NO_CRUST
if self._check_variable_properties(var_defined,self.PROPERTY_ARRAY):
......@@ -568,16 +568,9 @@ class crusty(object):
if self._check_variable_properties(var_defined,self.PROPERTY_STRUCT) and (node.right is not None):
this_is_crust = self.TYPE_NO_MATTER
error_list = []
if len(options) > 1:
for option in options[1:]:
# create a new "execution thread" for each possible assignment value
if (option[2] != self.TYPE_NO_MATTER) and (this_is_crust != self.TYPE_NO_MATTER) and (option[2] != this_is_crust):
error_list.append( (this_is_crust,option[3],varname,node.line) )
newvar_container = option[1]
self._set_var_value(newvar_container,varname,option[0],node.line)
self._process_block(tree[counter+1:],newvar_container,function_container)
if (options[0][2] != self.TYPE_NO_MATTER) and (this_is_crust != self.TYPE_NO_MATTER) and (options[0][2] != this_is_crust):
error_list.append( (this_is_crust,options[0][3],varname,node.line) )
for error_element in error_list:
if error_element[0] == self.TYPE_CRUST:
if error_element[1] is None:
......@@ -585,36 +578,53 @@ class crusty(object):
else:
self._add_error(self.MSG_CRITICAL,"Assigning the non-crust variable '{:s}' to the crust variable '{:s}' at line {:d}",error_element[1],error_element[2],error_element[3])
else:
if options[0][3] is None:
if option[3] is None:
self._add_error(self.MSG_CRITICAL,"Assigning a crust pointer to the non-crust variable '{:s}' at line {:d}",error_element[2],error_element[3])
else:
self._add_error(self.MSG_CRITICAL,"Assigning the crust pointer '{:s}' to the non-crust variable '{:s}' at line {:d}",error_element[1],error_element[2],error_element[3])
var_container = options[0][1]
self._set_var_value(var_container,varname,options[0][0],node.line)
var_container = option[1]
self._set_var_value(var_container,varname,option[0],node.line)
return var_container
def _check_return_block(self,tree,var_container):
if len(tree) == 0:
return [(None,None)]
else:
return [(tree,var_container)]
def _process_block(self, tree, var_container, function_container):
for counter in range(len(tree)):
node = tree[counter]
blocks = [ (tree,var_container) ]
while len(blocks) > 0:
current_block = blocks[0]
blocks = blocks[1:]
if current_block[0] is not None:
retval = self._process_block2(current_block[0],current_block[1],function_container)
blocks += retval
def _process_block2(self, tree, var_container, function_container):
node = tree[0]
if (node.type == "TYPE_SPECIFIER"):
if (node.enum_data is not None):
self._process_enum(node,var_container)
continue
return self._check_return_block(tree[1:],var_container)
if node.type == "CRUSTY_DEBUG":
print("Debug: '{:s}'".format(str(var_container)))
continue
return self._check_return_block(tree[1:],var_container)
if node.type == "START_BLOCK":
# append a new block for the variables created inside this block
var_container.insert(0,{})
continue
return self._check_return_block(tree[1:],var_container)
if node.type == "END_BLOCK":
# remove the last block of variables
var_container = var_container[1:]
continue
return self._check_return_block(tree[1:],var_container)
if node.type == "EMPTY_DECLARATOR":
continue
return self._check_return_block(tree[1:],var_container)
if node.type == "VARIABLE_DEFINITION":
if not node.t_typedef:
varname = node.name
......@@ -623,24 +633,35 @@ class crusty(object):
if node.assignment is not None:
var_defined["init_line"] = node.line
options = self._eval_assignment(node.assignment,var_container,function_container)
var_container = self._check_assignment(var_defined,options,varname,node,tree,counter,function_container)
continue
retvals = []
for option in options:
new_var_container = self._check_assignment(var_defined,option,varname,node,tree,function_container)
retvals += self._check_return_block(tree[1:],new_var_container)
return retvals
else:
return self._check_return_block(tree[1:],var_container)
if node.type == "=":
varname = node.child1[0].name
var_defined = self._find_variable(var_container,varname,node.line)
options = self._eval_assignment(node.child2,var_container,function_container)
var_container = self._check_assignment(var_defined,options,varname,node.child1[0],tree,counter,function_container)
continue
retvals = []
for option in options:
new_var_container = self._check_assignment(var_defined,option,varname,node.child1[0],tree,function_container)
retvals += self._check_return_block(tree[1:],new_var_container)
return retvals
if node.type == "FUNCTION_CALL":
function_params = self._find_function(function_container,node.name,node.line)
if ((function_params[0][0] & self.PROPERTY_CRUST_VARIABLE) != 0) and (function_params[0][1] == 1):
self._add_error(self.MSG_ERROR,"Calling the function '{:s}' at line {:d}, but ignoring the crust-type return value",node.name,node.line)
options = self._eval_function_call(node,var_container,function_container)
if len(options) > 1:
for option in options[1:]:
self._process_block(tree[counter+1:],option[1],function_container)
var_container = options[0][1]
continue
retvals = []
for option in options:
retvals += self._check_return_block(tree[1:],option[1])
return retvals
#if node.type == "IF":
#retvals = self._eval_condition(node.condition,var_container,function_container)
#continue
# if node.type == "FOR":
# print("Tipo: {:s}; Nombre: {:s}".format(str(node.type),str(node.name)))
# b1,b2 = lib.get_next_block(tree[counter+1:])
......@@ -651,3 +672,4 @@ class crusty(object):
#
# break
print("Tipo: {:s}; Nombre: {:s}".format(str(node.type),str(node.name)))
return self._check_return_block(tree[1:],var_container)
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