Commit a50e2a7c authored by Sergio Costas's avatar Sergio Costas

Now supports crust_set_null and crust_set_not_null

parent 100a413b
......@@ -198,6 +198,13 @@ of the execution, each block pointed by global variables must be pointed by
only one global variable (it is an error to reach the end of the function
and have two or more global variables pointing to the same block).
It is possible to change the state of the global variables using
*__crust_set_null__(variable_name)* to set it to NULL, or
*__crust_set_not_null__(variable_name)* to set it to NOT_NULL. The later
is useful when a global variable in a function is known to be NOT_NULL, so
putting it at the beginning of that function will remove the undesired
messages. The former is given mainly for completion.
CRUST understand some comparisons, so this code:
if (crust_variable == NULL) {
......
......@@ -63,7 +63,7 @@ class crust(object):
TYPE_NO_CRUST = 1
TYPE_CRUST = 2
status_str = ["VALUE_UNINITIALIZED", "VALUE_NULL", "VALUE_NOT_NULL", "VALUE_NOT_NULL_OR_NULL", "VALUE_FREED", "VALUE_GLOBAL", "VALUE_FUNCTION" ]
state_str = ["VALUE_UNINITIALIZED", "VALUE_NULL", "VALUE_NOT_NULL", "VALUE_NOT_NULL_OR_NULL", "VALUE_FREED", "VALUE_GLOBAL", "VALUE_FUNCTION" ]
class VarNotFoundException(Exception):
pass
......@@ -179,7 +179,7 @@ class crust(object):
print(" Block:")
for variable in block:
print(" Variable: {:s}".format(str(variable)))
print(" status: {:s}".format(self.status_str[(block[variable]["value"])]))
print(" status: {:s}".format(self.state_str[(block[variable]["value"])]))
print(" pointer: {:d}".format(block[variable]["pointer"]))
print(" uid: {:s}".format(str(block[variable]["uid"])))
print("")
......@@ -354,7 +354,7 @@ class crust(object):
variable["uid"] = None
def _set_var_value(self, thread_status, var_name, value, line_number, force = False):
""" Set the new status of a variable """
""" Set the new state of a variable """
variable = self._find_variable(thread_status, var_name, line_number)
if variable["value"] == self.VALUE_GLOBAL:
......@@ -364,8 +364,8 @@ class crust(object):
self._add_error(thread_status, self.MSG_CRITICAL, "Trying to assign a value to the function name '{:s}' at line {:d}", str(var_name), line_number)
return
if (not force) and variable["crust"]:
status = variable["value"]
if ((status == crust.VALUE_NOT_NULL) or (status == crust.VALUE_NOT_NULL_OR_NULL)) and (not variable["borrowed"]) and (not variable["alias"]):
state = variable["value"]
if ((state == crust.VALUE_NOT_NULL) or (state == crust.VALUE_NOT_NULL_OR_NULL)) and (not variable["borrowed"]) and (not variable["alias"]):
# If this block is already assigned to another variable, it is OK
# (due to the checks in CRUST, it can be assigned to several global variables, but only to a single main variable)
found = False
......@@ -1697,6 +1697,24 @@ class crust(object):
thread_status["find_label"] = None
return self._check_return_block(tree[1:], thread_status)
if node.type == "CRUST_SET_NULL":
var_name = node.child1[0].name
var_data = self._find_variable(thread_status, var_name, node.line)
if var_data["global"]:
self._set_var_value(thread_status, var_name, self.VALUE_NULL, node.line, True)
else:
self._add_error(thread_status, self.MSG_CRITICAL, "Trying to set to NULL the state of the non-global variable '{:s}' at line {:d}", var_name, node.line)
return self._check_return_block(tree[1:], thread_status)
if node.type == "CRUST_SET_NOT_NULL":
var_name = node.child1[0].name
var_data = self._find_variable(thread_status, var_name, node.line)
if var_data["global"]:
self._set_var_value(thread_status, var_name, self.VALUE_NOT_NULL, node.line, True)
else:
self._add_error(thread_status, self.MSG_CRITICAL, "Trying to set to NOT_NULL the state of the non-global variable '{:s}' at line {:d}", var_name, node.line)
return self._check_return_block(tree[1:], thread_status)
threads = self._eval_statement(node, thread_status, True)
retvals = []
for thread in threads:
......
......@@ -68,30 +68,32 @@ class tokens(object):
321:'VA_LIST',
322:'T_EXTENSION',
323:'TYPE_SPECIFIER',
324:'CRUST_T',
325:'CRUST_BORROW',
326:'CRUST_RECYCLE',
327:'CRUST_ALIAS',
328:'CRUST_NOT_NULL',
329:'CRUST_ENABLE',
330:'CRUST_DISABLE',
331:'CRUST_FULL_ENABLE',
332:'CRUST_DEBUG',
333:'CRUST_NO_ZERO',
334:'VARIABLE_DEFINITION',
335:'T_NULL',
336:'FCONSTANT',
337:'EMPTY_DECLARATOR',
338:'FUNCTION_CALL',
339:'FUNCTION_DEFINITION',
340:'FUNCTION_DECLARATION',
341:'BRACKETS_CONTAINER',
342:'LABEL',
343:'START_BLOCK',
344:'END_BLOCK',
345:'TYPECAST',
346:'TYPENAME_IDENTIFIER',
347:'T_TYPEOF',
324:'VARIABLE_DEFINITION',
325:'T_NULL',
326:'FCONSTANT',
327:'EMPTY_DECLARATOR',
328:'FUNCTION_CALL',
329:'FUNCTION_DEFINITION',
330:'FUNCTION_DECLARATION',
331:'BRACKETS_CONTAINER',
332:'LABEL',
333:'START_BLOCK',
334:'END_BLOCK',
335:'TYPECAST',
336:'TYPENAME_IDENTIFIER',
337:'T_TYPEOF',
338:'CRUST_T',
339:'CRUST_BORROW',
340:'CRUST_RECYCLE',
341:'CRUST_ALIAS',
342:'CRUST_NOT_NULL',
343:'CRUST_ENABLE',
344:'CRUST_DISABLE',
345:'CRUST_FULL_ENABLE',
346:'CRUST_DEBUG',
347:'CRUST_NO_ZERO',
348:'CRUST_SET_NULL',
349:'CRUST_SET_NOT_NULL',
'IDENTIFIER':258,
'CONSTANT':259,
'STRING_LITERAL':260,
......@@ -158,30 +160,32 @@ class tokens(object):
'VA_LIST':321,
'T_EXTENSION':322,
'TYPE_SPECIFIER':323,
'CRUST_T':324,
'CRUST_BORROW':325,
'CRUST_RECYCLE':326,
'CRUST_ALIAS':327,
'CRUST_NOT_NULL':328,
'CRUST_ENABLE':329,
'CRUST_DISABLE':330,
'CRUST_FULL_ENABLE':331,
'CRUST_DEBUG':332,
'CRUST_NO_ZERO':333,
'VARIABLE_DEFINITION':334,
'T_NULL':335,
'FCONSTANT':336,
'EMPTY_DECLARATOR':337,
'FUNCTION_CALL':338,
'FUNCTION_DEFINITION':339,
'FUNCTION_DECLARATION':340,
'BRACKETS_CONTAINER':341,
'LABEL':342,
'START_BLOCK':343,
'END_BLOCK':344,
'TYPECAST':345,
'TYPENAME_IDENTIFIER':346,
'T_TYPEOF':347,
'VARIABLE_DEFINITION':324,
'T_NULL':325,
'FCONSTANT':326,
'EMPTY_DECLARATOR':327,
'FUNCTION_CALL':328,
'FUNCTION_DEFINITION':329,
'FUNCTION_DECLARATION':330,
'BRACKETS_CONTAINER':331,
'LABEL':332,
'START_BLOCK':333,
'END_BLOCK':334,
'TYPECAST':335,
'TYPENAME_IDENTIFIER':336,
'T_TYPEOF':337,
'CRUST_T':338,
'CRUST_BORROW':339,
'CRUST_RECYCLE':340,
'CRUST_ALIAS':341,
'CRUST_NOT_NULL':342,
'CRUST_ENABLE':343,
'CRUST_DISABLE':344,
'CRUST_FULL_ENABLE':345,
'CRUST_DEBUG':346,
'CRUST_NO_ZERO':347,
'CRUST_SET_NULL':348,
'CRUST_SET_NOT_NULL':349,
}
@staticmethod
......
......@@ -119,6 +119,9 @@ void find_close_parentheses(int);
"__crust_debug__" { return prepare_leaf(0,0.0,CRUST_DEBUG); }
"__crust_no_0__" { return prepare_leaf(0,0.0,CRUST_NO_ZERO); }
"__crust_not_null__" { return prepare_leaf(0,0.0,CRUST_NOT_NULL); }
"__crust_set_null__" { return prepare_leaf(0,0.0,CRUST_SET_NULL); }
"__crust_set_not_null__" { return prepare_leaf(0,0.0,CRUST_SET_NOT_NULL); }
{L}({L}|{D})* { return prepare_leaf(0,0.0,TYPENAME_IDENTIFIER); }
......
......@@ -48,16 +48,6 @@ void add_type_element(char *);
%token VA_LIST
%token T_EXTENSION
%token TYPE_SPECIFIER
%token CRUST_T
%token CRUST_BORROW
%token CRUST_RECYCLE
%token CRUST_ALIAS
%token CRUST_NOT_NULL
%token CRUST_ENABLE
%token CRUST_DISABLE
%token CRUST_FULL_ENABLE
%token CRUST_DEBUG
%token CRUST_NO_ZERO
%token VARIABLE_DEFINITION
%token T_NULL
%token FCONSTANT
......@@ -73,6 +63,19 @@ void add_type_element(char *);
%token TYPENAME_IDENTIFIER
%token T_TYPEOF
%token CRUST_T
%token CRUST_BORROW
%token CRUST_RECYCLE
%token CRUST_ALIAS
%token CRUST_NOT_NULL
%token CRUST_ENABLE
%token CRUST_DISABLE
%token CRUST_FULL_ENABLE
%token CRUST_DEBUG
%token CRUST_NO_ZERO
%token CRUST_SET_NULL
%token CRUST_SET_NOT_NULL
//%start translation_unit
%start start_unit
%%
......@@ -109,6 +112,8 @@ long_string_literal
$$ = $1; show_debug(__LINE__, $$, "long_string_literal");
}
postfix_expression
: primary_expression { $$ = $1; show_debug(__LINE__, $$, "postfix_expression"); }
| postfix_expression '[' expression ']' { $$ = $1; show_debug(__LINE__, $$, "postfix_expression");
......@@ -877,6 +882,18 @@ block_item
| CRUST_DISABLE { $$ = $1; show_debug(__LINE__, $$, "block_item"); }
| CRUST_FULL_ENABLE { $$ = $1; show_debug(__LINE__, $$, "block_item"); }
| CRUST_DEBUG { $$ = $1; show_debug(__LINE__, $$, "block_item"); }
| CRUST_SET_NULL '(' IDENTIFIER ')' { $$ = $1; show_debug(__LINE__, $$, "block_item");
$$->child1 = $3;
free($3->name);
$3->name = strdup($3->data);
free_tree($2);
free_tree($4); }
| CRUST_SET_NOT_NULL '(' IDENTIFIER ')' { $$ = $1; show_debug(__LINE__, $$, "block_item");
$$->child1 = $3;
free($3->name);
$3->name = strdup($3->data);
free_tree($2);
free_tree($4); }
;
expression_statement
......
This diff is collapsed.
struct crust_ts {
char var1;
int var2;
struct crust_ts *next;
};
typedef __crust_t__ struct crust_ts* crust_t;
crust_t global_var;
void function(crust_t);
void main(crust_t __crust_not_null__ var) {
global_var.var1 = var; // this is fine
__crust_debug__
}
typedef __crust_t__ unsigned char *crust_t;
crust_t var1;
void function(crust_t);
void main(crust_t __crust_not_null__ arg1) {
__crust_debug__
__crust_set_null__(var1);
__crust_debug__
var1 = arg1; // fine, and will not fail because the status of var1 is considered NULL
arg1 = NULL; // It is fine because it has been assigned to a global variable
}
typedef __crust_t__ unsigned char *crust_t;
crust_t var1;
void function(crust_t);
void main(crust_t __crust_not_null__ arg1) {
__crust_debug__
__crust_set_not_null__(var1);
__crust_debug__
var1 = arg1; // will return an error because now the status is NOT_NULL
arg1 = NULL; // It is fine because it has been assigned to a global variable
}
typedef __crust_t__ unsigned char *crust_t;
void main(void) {
crust_t var1;
__crust_set_null__(var1); // ERROR: it is not a global variable
}
typedef __crust_t__ unsigned char *crust_t;
void main(void) {
crust_t var1;
__crust_set_not_null__(var1); // ERROR: it is not a global variable
}
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