Beispiel #1
0
Block* find_block_that_exit_point_will_reach(Term* term)
{
    ca_assert(is_exit_point(term));

    Block* block = term->owningBlock;

    // 'return' exits to nearest major block.
    if (term->function == FUNCS.return_func) {
        while (is_minor_block(block)) {
            Block* parent = get_parent_block(block);
            if (parent == NULL)
                return block;

            block = parent;
        }
        return block;
    }

    // 'case_condition_bool' exits the current if-block.
    if (term->function == FUNCS.case_condition_bool)
        return get_parent_block(term->owningBlock);

    // Otherwise, exit to nearest for-loop.
    while (!is_for_loop(block) && !is_while_loop(block)) {
        Block* parent = get_parent_block(block);
        if (parent == NULL)
            return block;

        block = parent;
    }
    return block;
}
Beispiel #2
0
Block* find_enclosing_loop(Block* block)
{
    while (true) {
        if (block == NULL)
            return NULL;

        if (is_while_loop(block) || is_for_loop(block))
            return block;

        if (is_major_block(block))
            return NULL;

        block = get_parent_block(block);
    }
    return NULL;
}
Beispiel #3
0
void start_for_loop(caStack* stack, bool enableLoopOutput)
{
    Frame* frame = top_frame(stack);
    Branch* contents = frame->branch;

    // Check if top frame actually contains a for-loop (it might be using the #zero branch)
    if (!is_for_loop(contents))
        return;

    // Initialize the loop index
    set_int(get_frame_register(frame, for_loop_find_index(contents)), 0);

    if (enableLoopOutput) {
        // Initialize output value
        set_int(get_frame_register(frame, for_loop_find_output_index(contents)), 0);
        caValue* listInput = circa_input(stack, 0);
        set_list(get_frame_register_from_end(frame, 0), list_length(listInput));
    }

    // Interpreter will run the contents of the branch
}
Beispiel #4
0
bool is_loop(Block* block)
{
    return is_for_loop(block) || is_while_loop(block);
}
Beispiel #5
0
void emit_stmt(ivl_scope_t scope, ivl_statement_t stmt)
{
      switch(ivl_statement_type(stmt)) {
	case IVL_ST_NOOP:
	      /* If this is a statement termination then just finish the
	       * statement, otherwise print an empty begin/end pair. */
	    if (single_indent) {
		  single_indent = 0;
		  fprintf(vlog_out, ";\n");
	    } else {
		  fprintf(vlog_out, "%*cbegin\n", get_indent(), ' ');
		  fprintf(vlog_out, "%*cend\n", get_indent(), ' ');
	    }
	    break;
	case IVL_ST_ALLOC:
	      /* This statement is only used with an automatic task so we
	       * can safely skip it. The automatic task definition will
	       * generate an appropriate error message.*/
	    break;
	case IVL_ST_ASSIGN:
	    emit_stmt_assign(scope, stmt);
	    break;
	case IVL_ST_ASSIGN_NB:
	    emit_stmt_assign_nb(scope, stmt);
	    break;
	case IVL_ST_BLOCK:
	    if (ivl_stmt_block_scope(stmt)) {
		  emit_stmt_block_named(scope, stmt);
	    } else {
		  if (is_delayed_or_event_assign(scope, stmt)) break;
		  if (is_for_loop(scope, stmt)) break;
		  if (is_repeat_event_assign(scope, stmt)) break;
		  if (is_wait(scope, stmt)) break;
		  if (is_utask_call_with_args(scope, stmt)) break;
		  emit_stmt_block(scope, stmt);
	    }
	    break;
	case IVL_ST_CASE:
	case IVL_ST_CASER:
	case IVL_ST_CASEX:
	case IVL_ST_CASEZ:
	    emit_stmt_case(scope, stmt);
	    break;
	case IVL_ST_CASSIGN:
	    emit_stmt_cassign(scope, stmt);
	    break;
	case IVL_ST_CONDIT:
	    emit_stmt_condit(scope, stmt);
	    break;
	case IVL_ST_DEASSIGN:
	    emit_stmt_deassign(scope, stmt);
	    break;
	case IVL_ST_DELAY:
	    emit_stmt_delay(scope, stmt);
	    break;
	case IVL_ST_DELAYX:
	    emit_stmt_delayx(scope, stmt);
	    break;
	case IVL_ST_DISABLE:
	    emit_stmt_disable(scope, stmt);
	    break;
	case IVL_ST_FORCE:
	    emit_stmt_force(scope, stmt);
	    break;
	case IVL_ST_FOREVER:
	    emit_stmt_forever(scope, stmt);
	    break;
	case IVL_ST_FORK:
	    if (ivl_stmt_block_scope(stmt)) {
		  emit_stmt_fork_named(scope, stmt);
	    } else {
		  emit_stmt_fork(scope, stmt);
	    }
	    break;
	case IVL_ST_FREE:
	      /* This statement is only used with an automatic task so we
	       * can safely skip it. The automatic task definition will
	       * generate an appropriate error message.*/
	    break;
	case IVL_ST_RELEASE:
	    emit_stmt_release(scope, stmt);
	    break;
	case IVL_ST_REPEAT:
	    emit_stmt_repeat(scope, stmt);
	    break;
	case IVL_ST_STASK:
	    emit_stmt_stask(scope, stmt);
	    break;
	case IVL_ST_TRIGGER:
	    emit_stmt_trigger(scope, stmt);
	    break;
	case IVL_ST_UTASK:
	    emit_stmt_utask(scope, stmt);
	    break;
	case IVL_ST_WAIT:
	    emit_stmt_wait(scope, stmt);
	    break;
	case IVL_ST_WHILE:
	    emit_stmt_while(scope, stmt);
	    break;
	default:
	    fprintf(vlog_out, "%*c<unknown>;\n", get_indent(), ' ');
	    fprintf(stderr, "%s:%u: vlog95 error: Unknown statement "
	                    "type (%d).\n",
	                    ivl_stmt_file(stmt),
	                    ivl_stmt_lineno(stmt),
	                    (int)ivl_statement_type(stmt));
	    vlog_errors += 1;
	    break;
      }
}