fixed bug with being to aggressive
- Is now more flexible - Added resolve constant relationsmain
parent
e29492f7f8
commit
2734cdb176
|
@ -12,6 +12,10 @@ tree_print(node_t* root, stem head);
|
||||||
|
|
||||||
static void destroy_subtree ( node_t *discard );
|
static void destroy_subtree ( node_t *discard );
|
||||||
|
|
||||||
|
static void prune_children(node_t **simplified, node_t *root);
|
||||||
|
static void resolve_constant_expressions(node_t **simplified, node_t *root);
|
||||||
|
static void flatten(node_t **simplified, node_t *root);
|
||||||
|
|
||||||
|
|
||||||
/* External interface */
|
/* External interface */
|
||||||
void
|
void
|
||||||
|
@ -154,18 +158,71 @@ destroy_subtree ( node_t *discard )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
flatten(node_t **simplified, node_t *root)
|
||||||
|
{
|
||||||
|
/* This will flatten left-expanded lists */
|
||||||
|
if (!root)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Do this recursivly */
|
||||||
|
for (int i = 0; i < root->n_children; i++)
|
||||||
|
flatten(&root->children[i], root->children[i]);
|
||||||
|
|
||||||
|
node_t **new_children, *result = root;
|
||||||
|
switch (root->type)
|
||||||
|
{
|
||||||
|
case GLOBAL_LIST:
|
||||||
|
case STATEMENT_LIST:
|
||||||
|
case PRINT_LIST:
|
||||||
|
case EXPRESSION_LIST:
|
||||||
|
case VARIABLE_LIST:
|
||||||
|
case DECLARATION_LIST:
|
||||||
|
// Check if node have more than two children
|
||||||
|
if (root->n_children < 2)
|
||||||
|
break;
|
||||||
|
|
||||||
|
result = root->children[0];
|
||||||
|
result->n_children++;
|
||||||
|
|
||||||
|
// Realloc the array of children to the new size
|
||||||
|
if (!(new_children = realloc(result->children, result->n_children * sizeof(node_t*))))
|
||||||
|
break;
|
||||||
|
// if successs, insert the new array
|
||||||
|
result->children = new_children;
|
||||||
|
|
||||||
|
// Insert child at the end
|
||||||
|
result->children[result->n_children - 1] = root->children[1];
|
||||||
|
|
||||||
|
node_finalize(root);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
*simplified = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
prune_children(node_t **simplified, node_t *root)
|
prune_children(node_t **simplified, node_t *root)
|
||||||
{
|
{
|
||||||
if (!root)
|
if (!root)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* Do this recursivly */
|
||||||
|
for (int i = 0; i < root->n_children; i++)
|
||||||
|
prune_children(&root->children[i], root->children[i]);
|
||||||
|
|
||||||
node_t *result = root;
|
node_t *result = root;
|
||||||
switch (root->type)
|
switch (root->type)
|
||||||
{
|
{
|
||||||
|
case PROGRAM:
|
||||||
case GLOBAL:
|
case GLOBAL:
|
||||||
//case ARGUMENT_LIST: // For this to work, need to change order of operations
|
//case ARGUMENT_LIST: // For this to work, need to change order of operations
|
||||||
//case PARAMETER_LIST: // For this to work, need to change order of operations
|
//case PARAMETER_LIST: // For this to work, need to change order of operations
|
||||||
|
//case VARIABLE_LIST:
|
||||||
|
//case EXPRESSION_LIST:
|
||||||
|
case DECLARATION:
|
||||||
case STATEMENT:
|
case STATEMENT:
|
||||||
case PRINT_ITEM:
|
case PRINT_ITEM:
|
||||||
case PRINT_STATEMENT:
|
case PRINT_STATEMENT:
|
||||||
|
@ -189,6 +246,10 @@ resolve_constant_expressions(node_t **simplified, node_t *root)
|
||||||
if (!root)
|
if (!root)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* Do this recursivly */
|
||||||
|
for (int i = 0; i < root->n_children; i++)
|
||||||
|
resolve_constant_expressions(&root->children[i], root->children[i]);
|
||||||
|
|
||||||
if (root->type != EXPRESSION)
|
if (root->type != EXPRESSION)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -239,6 +300,7 @@ resolve_constant_expressions(node_t **simplified, node_t *root)
|
||||||
|
|
||||||
switch (*(char*)root->data)
|
switch (*(char*)root->data)
|
||||||
{
|
{
|
||||||
|
/* Assignments */
|
||||||
case '|': *lhs |= *rhs; break;
|
case '|': *lhs |= *rhs; break;
|
||||||
case '^': *lhs ^= *rhs; break;
|
case '^': *lhs ^= *rhs; break;
|
||||||
case '&': *lhs &= *rhs; break;
|
case '&': *lhs &= *rhs; break;
|
||||||
|
@ -258,57 +320,80 @@ resolve_constant_expressions(node_t **simplified, node_t *root)
|
||||||
*simplified = result;
|
*simplified = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
flatten(node_t **simplified, node_t *root)
|
resolve_constant_relations( node_t** simplified, node_t* root)
|
||||||
{
|
{
|
||||||
/* This will flatten left-expanded lists */
|
|
||||||
if (!root)
|
if (!root)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
node_t **new_children, *result = root;
|
/* Do this recursivly */
|
||||||
switch (root->type)
|
for (int i = 0; i < root->n_children; i++)
|
||||||
{
|
resolve_constant_relations(&root->children[i], root->children[i]);
|
||||||
case GLOBAL_LIST:
|
|
||||||
case STATEMENT_LIST:
|
if (root->type != RELATION)//|| root->type != RELATION)
|
||||||
case PRINT_LIST:
|
return;
|
||||||
case EXPRESSION_LIST:
|
|
||||||
case VARIABLE_LIST:
|
node_t *result = root;
|
||||||
case DECLARATION_LIST:
|
|
||||||
// Check if node have more than two children
|
if (root->n_children != 2)
|
||||||
if (root->n_children < 2)
|
return;
|
||||||
break;
|
|
||||||
|
// Both children must be constant numbers
|
||||||
|
if (root->children[0]->type != NUMBER_DATA ||
|
||||||
|
root->children[1]->type != NUMBER_DATA)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Check if children does not contain null pointers
|
||||||
|
if (!root->children[0]->data)
|
||||||
|
return;
|
||||||
|
if (!root->children[1]->data)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Check if data field is not null pointer
|
||||||
|
if (!root->data)
|
||||||
|
return;
|
||||||
|
|
||||||
result = root->children[0];
|
result = root->children[0];
|
||||||
result->n_children++;
|
int64_t
|
||||||
|
*lhs = result->data,
|
||||||
|
*rhs = root->children[1]->data;
|
||||||
|
|
||||||
// Realloc the array of children to the new size
|
switch (*(char*)root->data)
|
||||||
if (!(new_children = realloc(result->children, result->n_children * sizeof(node_t*))))
|
{
|
||||||
break;
|
/* Relations */
|
||||||
// if successs, insert the new array
|
case '=': *lhs = (*lhs == *rhs); break;
|
||||||
result->children = new_children;
|
case '<': *lhs = (*lhs < *rhs); break;
|
||||||
|
case '>': *lhs = (*lhs > *rhs); break;
|
||||||
// Insert child at the end
|
|
||||||
result->children[result->n_children - 1] = root->children[1];
|
|
||||||
|
|
||||||
node_finalize(root);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
node_finalize(root->children[1]);
|
||||||
|
node_finalize(root);
|
||||||
|
|
||||||
*simplified = result;
|
*simplified = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
simplify_tree ( node_t **simplified, node_t *root )
|
simplify_tree ( node_t **simplified, node_t *root )
|
||||||
{
|
{
|
||||||
if (!root)
|
if (!root)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (int i = 0; i < root->n_children; i++)
|
//for (int i = 0; i < root->n_children; i++)
|
||||||
simplify_tree(&root->children[i], root->children[i]);
|
// simplify_tree(&root->children[i], root->children[i]);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Each of the functions do their operations recursivly.
|
||||||
|
This opens up for a lot more flexibility, like removing
|
||||||
|
variable list after it is flatten
|
||||||
|
*/
|
||||||
|
flatten(&root, root);
|
||||||
prune_children(&root, root);
|
prune_children(&root, root);
|
||||||
resolve_constant_expressions(&root, root);
|
resolve_constant_expressions(&root, root);
|
||||||
flatten(&root, root);
|
|
||||||
|
// The following is experimental, will resolve the constant relations
|
||||||
|
resolve_constant_relations(&root, root);
|
||||||
|
|
||||||
*simplified = root;
|
*simplified = root;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue