Beispiel #1
0
void gen_statement(tree_t *t) {
  int local_if_label;
  int local_while_label;
  int local_for_label;
  int num_args;

  if (t->type == ARRAY || t->right->type == ARRAY || t->left->type == ARRAY) {
    yyerror("Array access not supported");
  }

  switch(t->type) {
  case ASSIGNOP:
    // Generate code for expression
    gen_label(t->right, 1);
    gen_expression(t->right);
    fprintf(yyout, "\tmovl\t%%ebx, %%eax\n");
    
    // If this is actually a return statement, then return with correct value in %eax
    if(!strcmp(t->left->attribute.variable->name, top_scope->curr->name)) 
      fprintf(yyout, "\tjmp\tsubprog%send\n", top_scope->curr->name);
    else {
      // Generate code for assignment
      gen_assignment(t->left);
    }

    break;
  case IF:
    local_if_label = if_label++;
    
    //Generate code for expression
    gen_label(t->left, 1);
    gen_expression(t->left);

    //Compare and jump accordingly
    fprintf(yyout, "\tcmpl\t$1, %%ebx\n\tjge\tiftrue%d\n", local_if_label);

    //Generate code for else first
    if (t->right->right != NULL) {
      gen_statement(t->right->right);
      fprintf(yyout, "\tjmp\tifend%d\n", local_if_label);
    }
    
    //Generate code for true section
    fprintf(yyout, "iftrue%d:\n", local_if_label);
    gen_statement(t->right->left);
    fprintf(yyout, "ifend%d:\n", local_if_label);

    break;
  case WHILE:
    local_while_label = while_label++;

    //Plant label for beginning of loop
    fprintf(yyout, "beginwhile%d:\n", local_while_label);
    
    //Generate code for expression
    gen_label(t->left, 1);
    gen_expression(t->left);

    //Compare and jump to end if needed
    fprintf(yyout, "\tcmpl\t$0, %%ebx\n\tje\tendwhile%d\n", local_while_label);

    //Generate code for statements
    gen_statement(t->right);
    fprintf(yyout, "\tjmp\tbeginwhile%d\n", local_while_label);
    fprintf(yyout, "endwhile%d:\n", local_while_label);

    break;
  case PROCEDURE:
    if (!strcmp(t->left->attribute.variable->name, "read"))
      gen_read(t->right);
    else if (!strcmp(t->left->attribute.variable->name, "write"))
      gen_write(t->right);
    else if (t->right != NULL) {
      // push arguments on the stack
      num_args = gen_expression_list(t->right); 
      fprintf(yyout, "\tcall\tsubprog%s\n", t->left->attribute.variable->name);

      // move the top of the stack below args
      fprintf(yyout, "\taddl\t$%d, %%esp\n", 4*num_args); 
    }
    else {
      fprintf(yyout, "\tcall\tsubprog%s\n", t->left->attribute.variable->name);
    }
    
    break;
  case COMMA:
    // Generate left and right statements
    if (t->left->type == ARRAY || t->right->type == ARRAY)
      yyerror("Array access not supported");
    else {
      gen_statement(t->left);
      gen_statement(t->right);
    }
    break;
  case FOR:
    local_for_label = for_label++;

    // Generate assignment
    gen_statement(t->left->left);

    //Plant label for beginning
    fprintf(yyout, "forloop%d:\n", local_for_label);

    // Generate expression for TO value
    gen_label(t->left->right, 1);
    gen_expression(t->left->right);

    //Compare and jump to end if needed
    if (t->left->left->left->attribute.variable->local_or_parameter == LOCAL)
      fprintf(yyout, "\tcmpl\t-%i(%%ebp), %%ebx\n\tjl\tforend%d\n",
	      t->left->left->left->attribute.variable->offset, local_for_label);
    else
      fprintf(yyout, "\tcmpl\t-%i(%%ebp), %%ebx\n\tjl\tforend%d\n",
	      t->left->left->left->attribute.variable->offset, local_for_label); 

    //Generate code for statements
    gen_statement(t->right);

    //Increment, jump to top then plant end label
    fprintf(yyout, "\tincl\t-%i(%%ebp)\n\tjmp\tforloop%d\nforend%d:\n", 
	    t->left->left->left->attribute.variable->offset,
	    local_for_label, local_for_label);

    break;
  default:
    fprintf(stderr, "TYPE: %d\n", t->type);
    yywarn("Statement not supported");
    break;
  }
}
Beispiel #2
0
static void gen_statement( qli_nod* node, qli_req* request)
{
/**************************************
 *
 *	g e n _ s t a t e m e n t
 *
 **************************************
 *
 * Functional description
 *	Generate BLR for statement.
 *
 **************************************/
	if (request)
		CHECK_RLB(request->req_blr);

	switch (node->nod_type)
	{
	case nod_abort:
		if (node->nod_count)
			gen_expression(node->nod_arg[0], 0);
		return;

	case nod_assign:
		gen_assignment(node, request);
		return;

	case nod_commit_retaining:
		return;

	case nod_erase:
		gen_erase(node, request);
		return;

	case nod_for:
	case nod_report_loop:
		gen_for(node, request);
		return;

	case nod_list:
	    {
	        qli_nod** ptr = node->nod_arg;
			for (const qli_nod* const* const end = ptr + node->nod_count; ptr < end; ++ptr)
			{
				gen_statement(*ptr, request);
			}
			return;
		}

	case nod_modify:
		gen_modify(node); //, request);
		return;

	case nod_output:
		gen_statement(node->nod_arg[e_out_statement], request);
		return;

	case nod_print:
		gen_print_list(node->nod_arg[e_prt_list], request);
		return;

	case nod_repeat:
		gen_statement(node->nod_arg[e_rpt_statement], request);
		return;

	case nod_report:
		gen_report(node, request);
		return;

	case nod_store:
		gen_store(node, request);
		return;

	case nod_if:
		gen_if(node, request);
		return;

	default:
		ERRQ_bugcheck(354);			// Msg354 gen_statement: not yet implemented
	}
}