Commit de5492c0 authored by Sergio Costas's avatar Sergio Costas

Now accepts multiassignments ( a=b=5 )

parent 68d32111
......@@ -418,6 +418,15 @@ class crusty(object):
newstatus = vardata["status"]
self._set_var_value(var_container,assignment.name,self.STATUS_FREED,assignment.line,True,True)
return [ (newstatus, self._copy_container(var_container), retval_type, assignment.name) ]
elif assignment.type == "=":
varname = assignment.child1[0].name
var_defined = self._find_variable(var_container,varname,assignment.line)
options = self._eval_assignment(assignment.child2,var_container,function_container)
newoptions = []
for option in options:
retval = self._check_assignment(var_defined,[option],varname,assignment,None,0,function_container)
newoptions.append( (option[0],retval,option[2],option[3]) )
return newoptions
else:
print("assignment type unknown '{:s}' at line {:d}".format(assignment.type,assignment.line))
return [ (self.STATUS_NOT_NULL_OR_NULL, self._copy_container(var_container), self.TYPE_NO_MATTER, assignment.name) ]
......@@ -538,6 +547,36 @@ class crusty(object):
self._process_block(node.child1,tmpvars, function_container)
def _check_assignment(self,var_defined,options,varname,node,tree,counter,function_container):
this_is_crust = self.TYPE_CRUST if ((var_defined["properties"] & self.PROPERTY_CRUST_VARIABLE) != 0) else self.TYPE_NO_CRUST
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 (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 (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:
self._add_error(self.MSG_CRITICAL,"Assigning a non-crust value to the crust variable '{:s}' at line {:d}",error_element[2],error_element[3])
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:
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)
return var_container
def _process_block(self, tree, var_container, function_container):
for counter in range(len(tree)):
......@@ -559,54 +598,21 @@ class crusty(object):
continue
if node.type == "EMPTY_DECLARATOR":
continue
if (node.type == "VARIABLE_DEFINITION") or (node.type == "="):
do_assignment = False
if node.type == "VARIABLE_DEFINITION":
if not node.t_typedef:
varname = node.name
var_defined = {"properties":self._get_variable_properties(node,False), "status":crusty.STATUS_UNINITIALIZED, "init_line": None, "pointer": node.pointer, "enum": False }
var_container[0][node.name] = var_defined
if node.assignment is not None:
var_defined["init_line"] = node.line
options = self._eval_assignment(node.assignment,var_container,function_container)
do_assignment = True
else:
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)
do_assignment = True
if do_assignment:
this_is_crust = self.TYPE_CRUST if ((var_defined["properties"] & self.PROPERTY_CRUST_VARIABLE) != 0) else self.TYPE_NO_CRUST
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 (option[2] != this_is_crust):
if this_is_crust == self.TYPE_CRUST:
if option[3] is None:
self._add_error(self.MSG_CRITICAL,"Assigning a non-crust value to the crust variable '{:s}' at line {:d}",varname,node.line)
else:
self._add_error(self.MSG_CRITICAL,"Assigning the non-crust variable '{:s}' to the crust variable '{:s}' at line {:d}",option[3],varname,node.line)
else:
if option[3] is None:
self._add_error(self.MSG_CRITICAL,"Assigning a crust pointer to the non-crust variable '{:s}' at line {:d}",varname,node.line)
else:
self._add_error(self.MSG_CRITICAL,"Assigning the crust pointer '{:s}' to the non-crust variable '{:s}' at line {:d}",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 (options[0][2] != this_is_crust):
if this_is_crust == self.TYPE_CRUST:
if options[0][3] is None:
self._add_error(self.MSG_CRITICAL,"Assigning a non-crust value to the crust variable '{:s}' at line {:d}",varname,node.line)
else:
self._add_error(self.MSG_CRITICAL,"Assigning the non-crust variable '{:s}' to the crust variable '{:s}' at line {:d}",options[0][3],varname,node.line)
else:
if options[0][3] is None:
self._add_error(self.MSG_CRITICAL,"Assigning a crust pointer to the non-crust variable '{:s}' at line {:d}",varname,node.line)
else:
self._add_error(self.MSG_CRITICAL,"Assigning the crust pointer '{:s}' to the non-crust variable '{:s}' at line {:d}",options[0][3],varname,node.line)
var_container = options[0][1]
self._set_var_value(var_container,varname,options[0][0],node.line)
if node.type == "VARIABLE_DEFINITION":
if not node.t_typedef:
varname = node.name
var_defined = {"properties":self._get_variable_properties(node,False), "status":crusty.STATUS_UNINITIALIZED, "init_line": None, "pointer": node.pointer, "enum": False }
var_container[0][node.name] = var_defined
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
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,tree,counter,function_container)
continue
if node.type == "FUNCTION_CALL":
function_params = self._find_function(function_container,node.name,node.line)
......
This diff is collapsed.
typedef __crust_t__ unsigned char *crust_t;
void main() {
crust_t a,b;
a = b = 5;
}
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