ref: remove unused loop checker
This commit is contained in:
@@ -26,7 +26,6 @@ add_executable(fzc
|
||||
src/compiler/utils/fzl_linked.c
|
||||
src/compiler/utils/fzl_options.c
|
||||
src/compiler/utils/fzl_ctable.c
|
||||
src/compiler/checkers/fzl_loop_check.c
|
||||
src/compiler/analyzer/utility.c
|
||||
src/compiler/analyzer/context.c
|
||||
src/compiler/analyzer/an_assign.c
|
||||
|
||||
@@ -1,229 +0,0 @@
|
||||
#include <common/fzl_opcodes.h>
|
||||
#include <common/fzl_types.h>
|
||||
#include <compiler/fzl_parser.h>
|
||||
#include <compiler/fzl_walker.h>
|
||||
#include <compiler/utils/fzl_const_pool.h>
|
||||
#include <compiler/utils/fzl_symtable.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
ssize_t check_top;
|
||||
fzl_nodetype_t check_tree[256];
|
||||
|
||||
// Ghost walk AST tree (w/o adding opcodes) to check if
|
||||
// variable used in condition is changed
|
||||
void ghost_walk_changed(fzl_node_t *node, bool *changed, fzl_sym_t *sym)
|
||||
{
|
||||
if (!node || !changed || *changed)
|
||||
return;
|
||||
|
||||
check_tree[check_top++] = node->type;
|
||||
|
||||
switch (node->type)
|
||||
{
|
||||
case FZL_NODETYPE_BREAK:
|
||||
case FZL_NODETYPE_DECLARATION:
|
||||
case FZL_NODETYPE_CONSTRUCT:
|
||||
case FZL_NODETYPE_CLASS:
|
||||
case FZL_NODETYPE_FUNCTION:
|
||||
case FZL_NODETYPE_LITERAL:
|
||||
break;
|
||||
|
||||
case FZL_NODETYPE_UNARY_PLUS:
|
||||
case FZL_NODETYPE_UNARY_MINUS:
|
||||
case FZL_NODETYPE_NOT:
|
||||
ghost_walk_changed(node->unary_op.operand, changed, sym);
|
||||
break;
|
||||
|
||||
case FZL_NODETYPE_ADD:
|
||||
case FZL_NODETYPE_SUB:
|
||||
case FZL_NODETYPE_MUL:
|
||||
case FZL_NODETYPE_DIV:
|
||||
case FZL_NODETYPE_POW:
|
||||
case FZL_NODETYPE_MOD:
|
||||
case FZL_NODETYPE_OR:
|
||||
case FZL_NODETYPE_AND:
|
||||
case FZL_NODETYPE_EQUAL:
|
||||
case FZL_NODETYPE_NEQUAL:
|
||||
case FZL_NODETYPE_LESS:
|
||||
case FZL_NODETYPE_LESS_EQUAL:
|
||||
case FZL_NODETYPE_GREATER:
|
||||
case FZL_NODETYPE_GREATER_EQUAL:
|
||||
case FZL_NODETYPE_ASSIGN:
|
||||
ghost_walk_changed(node->binary_op.left, changed, sym);
|
||||
ghost_walk_changed(node->binary_op.right, changed, sym);
|
||||
break;
|
||||
|
||||
case FZL_NODETYPE_FIELD:
|
||||
ghost_walk_changed(node->memb.parent, changed, sym);
|
||||
ghost_walk_changed(node->memb.field, changed, sym);
|
||||
break;
|
||||
|
||||
case FZL_NODETYPE_RETURN:
|
||||
ghost_walk_changed(node->ret.value, changed, sym);
|
||||
break;
|
||||
|
||||
case FZL_NODETYPE_CONDITIONAL:
|
||||
ghost_walk_changed(node->cond.condition, changed, sym);
|
||||
ghost_walk_changed(node->cond.true_block, changed, sym);
|
||||
ghost_walk_changed(node->cond.else_block, changed, sym);
|
||||
break;
|
||||
|
||||
case FZL_NODETYPE_LOOP:
|
||||
ghost_walk_changed(node->loop.cond, changed, sym);
|
||||
ghost_walk_changed(node->loop.step, changed, sym);
|
||||
ghost_walk_changed(node->loop.body, changed, sym);
|
||||
break;
|
||||
|
||||
case FZL_NODETYPE_BLOCK:
|
||||
for (size_t i = 0; i < node->list.entry_count; i++)
|
||||
ghost_walk_changed(node->list.entries[i], changed, sym);
|
||||
break;
|
||||
|
||||
case FZL_NODETYPE_CALL:
|
||||
ghost_walk_changed(node->call.callee, changed, sym);
|
||||
for (size_t i = 0; i < node->call.args_count; i++)
|
||||
ghost_walk_changed(node->call.args[i], changed, sym);
|
||||
break;
|
||||
|
||||
case FZL_NODETYPE_IDENTIFIER:
|
||||
if (strcmp(node->token->value, sym->name) == 0)
|
||||
{
|
||||
*changed = true;
|
||||
}
|
||||
|
||||
if (*changed)
|
||||
{
|
||||
*changed = false;
|
||||
for (ssize_t i = check_top - 1; i >= 0; i--)
|
||||
{
|
||||
fzl_nodetype_t cur_t = check_tree[i];
|
||||
if (cur_t == FZL_NODETYPE_ADD || cur_t == FZL_NODETYPE_SUB ||
|
||||
cur_t == FZL_NODETYPE_MUL || cur_t == FZL_NODETYPE_DIV ||
|
||||
cur_t == FZL_NODETYPE_POW || cur_t == FZL_NODETYPE_MOD ||
|
||||
cur_t == FZL_NODETYPE_UNARY_MINUS)
|
||||
{
|
||||
*changed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
check_tree[--check_top] = 0;
|
||||
}
|
||||
|
||||
// Whether value changed in loop body
|
||||
bool value_is_changed(fzl_node_t *node, fzl_sym_t *sym)
|
||||
{
|
||||
if (!node || !sym)
|
||||
return false;
|
||||
|
||||
bool changed = false;
|
||||
check_top = 0;
|
||||
memset(check_tree, 0, sizeof(check_tree));
|
||||
ghost_walk_changed(node, &changed, sym);
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
// Try to find symbol in loop condition node
|
||||
bool retrieve_cond_sym(fzl_walker_t *walker, fzl_node_t *node, fzl_sym_t *sym)
|
||||
{
|
||||
if (!walker || !node)
|
||||
return false;
|
||||
|
||||
switch (node->type)
|
||||
{
|
||||
case FZL_NODETYPE_BREAK:
|
||||
case FZL_NODETYPE_BLOCK:
|
||||
case FZL_NODETYPE_CALL:
|
||||
case FZL_NODETYPE_LITERAL:
|
||||
case FZL_NODETYPE_CONDITIONAL:
|
||||
case FZL_NODETYPE_FUNCTION:
|
||||
case FZL_NODETYPE_RETURN:
|
||||
case FZL_NODETYPE_CLASS:
|
||||
case FZL_NODETYPE_FIELD:
|
||||
case FZL_NODETYPE_CONSTRUCT:
|
||||
case FZL_NODETYPE_LOOP:
|
||||
case FZL_NODETYPE_ASSIGN:
|
||||
case FZL_NODETYPE_DECLARATION:
|
||||
return false;
|
||||
|
||||
case FZL_NODETYPE_UNARY_MINUS:
|
||||
case FZL_NODETYPE_UNARY_PLUS:
|
||||
case FZL_NODETYPE_NOT:
|
||||
return retrieve_cond_sym(walker, node->unary_op.operand, sym);
|
||||
|
||||
case FZL_NODETYPE_ADD:
|
||||
case FZL_NODETYPE_SUB:
|
||||
case FZL_NODETYPE_MUL:
|
||||
case FZL_NODETYPE_DIV:
|
||||
case FZL_NODETYPE_POW:
|
||||
case FZL_NODETYPE_MOD:
|
||||
case FZL_NODETYPE_AND:
|
||||
case FZL_NODETYPE_OR:
|
||||
case FZL_NODETYPE_LESS:
|
||||
case FZL_NODETYPE_LESS_EQUAL:
|
||||
case FZL_NODETYPE_GREATER:
|
||||
case FZL_NODETYPE_GREATER_EQUAL:
|
||||
case FZL_NODETYPE_EQUAL:
|
||||
case FZL_NODETYPE_NEQUAL:
|
||||
if (retrieve_cond_sym(walker, node->binary_op.left, sym))
|
||||
return true;
|
||||
if (retrieve_cond_sym(walker, node->binary_op.right, sym))
|
||||
return true;
|
||||
return false;
|
||||
|
||||
case FZL_NODETYPE_IDENTIFIER:
|
||||
{
|
||||
bool exists;
|
||||
for (ssize_t i = walker->sym_top - 1; i >= 0; i--)
|
||||
{
|
||||
if ((exists = fzl_symt_get(walker->syms[i], (char *)node->token->value,
|
||||
sym)))
|
||||
break;
|
||||
}
|
||||
return exists;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for infinite loop
|
||||
bool is_infinite_loop(fzl_walker_t *walker, fzl_node_t *node, size_t start_ip,
|
||||
size_t end_ip)
|
||||
{
|
||||
if (!walker)
|
||||
return false;
|
||||
|
||||
end_ip = (end_ip >= walker->op_count) ? (walker->op_count - 1) : end_ip;
|
||||
|
||||
fzl_sym_t sym;
|
||||
bool sym_exists = retrieve_cond_sym(walker, node->loop.cond, &sym);
|
||||
if (sym_exists)
|
||||
{
|
||||
if (sym.type >= FZL_TYPE_INT8)
|
||||
{
|
||||
bool value_changed = value_is_changed(node, &sym);
|
||||
if (value_changed)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// At least has jump outside
|
||||
for (size_t i = start_ip; i <= end_ip; i++)
|
||||
{
|
||||
if (walker->ops[i] != FZL_OPCODE_JMP)
|
||||
continue;
|
||||
|
||||
size_t jump_ip = walker->ops[++i];
|
||||
if (jump_ip >= end_ip)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user