Esempio n. 1
0
static void gen_assignment( qli_nod* node, qli_req* request)
{
/**************************************
 *
 *	g e n _ a s s i g n m e n t
 *
 **************************************
 *
 * Functional description
 *	Generate an assignment statement.
 *
 **************************************/
	qli_nod* from = node->nod_arg[e_asn_from];

	// Handle a local expression locally

	if (node->nod_flags & NOD_local)
	{
		gen_expression(from, 0);
		return;
	}

	// Generate a remote assignment

	qli_rlb* rlb = CHECK_RLB(request->req_blr);

	STUFF(blr_assignment);
	qli_nod* target = node->nod_arg[e_asn_to];

	// If we are referencing a parameter of another request, compile
	// the request first, the make a reference.  Otherwise, just compile
	// the expression in the context of this request

	const qli_nod* reference = target->nod_arg[e_fld_reference];
	if (reference)
	{
		gen_expression(from, 0);
		gen_parameter(reference->nod_import, request);
	}
	else
		gen_expression(from, request);

	qli_nod* validation = node->nod_arg[e_asn_valid];
	if (validation)
		gen_expression(validation, 0);

	gen_expression(target, request);
}
Esempio n. 2
0
static void gen_sort( qli_nod* node, qli_req* request, const UCHAR operatr)
{
/**************************************
 *
 *	g e n _ s o r t
 *
 **************************************
 *
 * Functional description
 *	Generate sort or reduced clause.
 *
 **************************************/
	qli_rlb* rlb = CHECK_RLB(request->req_blr);

	STUFF(operatr);
	STUFF(node->nod_count);

	request->req_flags |= REQ_project;
	qli_nod** ptr = node->nod_arg;
	for (qli_nod** const end = ptr + node->nod_count * 2; ptr < end; ptr += 2)
	{
		if (operatr == blr_sort)
			STUFF(ptr[1] ? blr_descending : blr_ascending);
		gen_expression(ptr[0], request);
	}
	request->req_flags &= ~REQ_project;
}
Esempio n. 3
0
static void gen_map(qli_map* map, qli_req* request)
{
/**************************************
 *
 *	g e n _ m a p
 *
 **************************************
 *
 * Functional description
 *	Generate a value map for a record selection expression.
 *
 **************************************/
	qli_map* temp;

	qli_rlb* rlb = CHECK_RLB(request->req_blr);

	USHORT count = 0;
	for (temp = map; temp; temp = temp->map_next)
	{
		if (temp->map_node->nod_type != nod_function)
			temp->map_position = count++;
	}

	STUFF(blr_map);
	STUFF_WORD(count);

	for (temp = map; temp; temp = temp->map_next)
	{
		if (temp->map_node->nod_type != nod_function)
		{
			STUFF_WORD(temp->map_position);
			gen_expression(temp->map_node, request);
		}
	}
}
Esempio n. 4
0
static void gen_if( qli_nod* node, qli_req* request)
{
/**************************************
 *
 *	g e n _ i f
 *
 **************************************
 *
 * Functional description
 *	Generate code for an IF statement.  Depending
 *	on the environment, this may be either a QLI
 *	context IF or a database context IF.
 *
 **************************************/

	// If the statement is local to QLI, force the sub- statements/expressions to be local also.
	// If not local, generate BLR.

	if (node->nod_flags & NOD_local)
	{
		gen_expression(node->nod_arg[e_if_boolean], 0);
		gen_statement(node->nod_arg[e_if_true], request);
		if (node->nod_arg[e_if_false])
			gen_statement(node->nod_arg[e_if_false], request);
	}
	else
	{
	    // probably the var is irrelevant, but not the function call,
	    // as it makes sure there's enough room.
		qli_rlb* rlb = CHECK_RLB(request->req_blr);
		STUFF(blr_if);
		gen_expression(node->nod_arg[e_if_boolean], request);
		STUFF(blr_begin);
		gen_statement(node->nod_arg[e_if_true], request);
		STUFF(blr_end);
		if (node->nod_arg[e_if_false])
		{
			STUFF(blr_begin);
			gen_statement(node->nod_arg[e_if_false], request);
			STUFF(blr_end);
		}
		else
			STUFF(blr_end);
	}
}
Esempio n. 5
0
int gen_expression_list(tree_t *t) {
  if(t->type == COMMA) {
    return gen_expression_list(t->left) + gen_expression_list(t->right);
  }
  else {
    gen_label(t, 1);	
    gen_expression(t);
    fprintf(yyout, "\tpushl\t%s\n", stack_top(registers));
    return 1;
  }
}
Esempio n. 6
0
static void gen_field( qli_nod* node, qli_req* request)
{
/**************************************
 *
 *	g e n _ f i e l d
 *
 **************************************
 *
 * Functional description
 *	Compile BLR to handle a field reference.  Things varying
 *	substantially depend on whether the field reference spans
 *	requests or not.
 *
 **************************************/
	// If there isn't a request specified, this is a reference.

	if (!request)
		return;

	qli_rlb* rlb = CHECK_RLB(request->req_blr);

	const qli_fld* field = (qli_fld*) node->nod_arg[e_fld_field];
	const qli_ctx* context = (qli_ctx*) node->nod_arg[e_fld_context];

	// If the field referenced is in this request, just generate a field reference.

	if (context->ctx_request == request)
	{
		qli_nod* args = node->nod_arg[e_fld_subs];
		if (args)
			STUFF(blr_index);
		STUFF(blr_fid);
		STUFF(context->ctx_context);
		STUFF_WORD(field->fld_id);
		if (args)
		{
			STUFF(args->nod_count);
			qli_nod** ptr = args->nod_arg;
			for (const qli_nod* const* const end = ptr + args->nod_count; ptr < end; ++ptr)
			{
				gen_expression(*ptr, request);
			}
		}
		return;
	}

	// The field is in a different request.  Make a parameter reference instead.

	gen_parameter(node->nod_export, request);
}
Esempio n. 7
0
static void gen_print_list( qli_nod* list, qli_req* request)
{
/**************************************
 *
 *	g e n _ p r i n t _ l i s t
 *
 **************************************
 *
 * Functional description
 *	Generate BLR for a print list.
 *
 **************************************/
	qli_nod** ptr = list->nod_arg;
	for (const qli_nod* const* const end = ptr + list->nod_count; ptr < end; ptr++)
	{
		qli_print_item* item = (qli_print_item*) *ptr;
		if (item->itm_type == item_value)
			gen_expression(item->itm_value, request);
	}
}
Esempio n. 8
0
static void gen_control_break( qli_brk* control, qli_req* request)
{
/**************************************
 *
 *	g e n _ c o n t r o l _ b r e a k
 *
 **************************************
 *
 * Functional description
 *	Process report writer control breaks.
 *
 **************************************/

	for (; control; control = control->brk_next)
	{
		if (control->brk_field)
			gen_expression((qli_nod*) control->brk_field, request);
		if (control->brk_line)
			gen_print_list((qli_nod*) control->brk_line, request);
	}
}
Esempio n. 9
0
void gen_expression(tree_t *t) {
  char *reg;

  // If the tree is actually a function, then take care of it here.
  if (t->type == FUNCTION) {
    // Push the arguments on the stack and call the function
    int num_args = gen_expression_list(t->right);
    fprintf(yyout, "\tcall\tsubprog%s\n", t->left->attribute.variable->name);

    // Move the top of the stack back down below the arguments
    fprintf(yyout, "\taddl\t$%d, %%esp\n", 4*num_args);

    // Move the answer to the top of the register stack
    fprintf(yyout, "\tmovl\t%%eax, %s\n", stack_top(registers));
  }

  // Case 0:
  else if (t->right == NULL && t->left == NULL && t->label == 1) {
    if (t->type == ID ) {
	fprintf(yyout, "\tmovl\t%s, %s\n", find_variable(t), stack_top(registers));
    }
    else if (t->type == INUM) {
      fprintf(yyout, "\tmovl\t$%i, %s\n", t->attribute.ival, 
	      stack_top(registers));
    }
    else {
      yywarn("Type not supported");
    }
  }
  else {
    // Case 1:
    if (t->right->label == 0) {
      // Go to left
      gen_expression(t->left);

      if (t->right->type == ID) {
	  gen_op(t, find_variable(t->right), stack_top(registers));
      }
      else if (t->right->type == INUM) {
        sprintf(buff1, "$%i", t->right->attribute.ival);
	  gen_op(t, buff1, stack_top(registers));
      }
      else {
	  yywarn("Type not supported");
      }
    }
    // Case 2:
    else if (t->left->label >= 1 && t->right->label > t->left->label && t->left->label < NUM_REG) {
      stack_swap(registers);
      gen_expression(t->right);
      reg = pop(registers);
      gen_expression(t->left);
      
      gen_op(t, reg, stack_top(registers));

   	push(registers, reg);
	stack_swap(registers);
    }
    // Case 3:
    else if (t->right->label >= 1 && t->left->label >= t->right->label && t->right->label < NUM_REG) {
	gen_expression(t->left);
      reg = pop(registers);
      gen_expression(t->right);
      
      gen_op(t, stack_top(registers), reg);
      push(registers, reg);
    }
    // Case 4:
    else {
      yywarn("Temporaries not yet implemented");
    }
  }
}
Esempio n. 10
0
static void gen_expression(qli_nod* node, qli_req* request)
{
/**************************************
 *
 *	g e n _ e x p r e s s i o n
 *
 **************************************
 *
 * Functional description
 *	Generate the BLR for a boolean or value expression.
 *
 **************************************/
	USHORT operatr = 0;
	qli_rlb* rlb = 0;

	if (node->nod_flags & NOD_local)
	{
		request = NULL;
		//return;
	}
	else if (request)
		rlb = CHECK_RLB(request->req_blr);

	switch (node->nod_type)
	{
	case nod_any:
		gen_any(node, request);
		return;

	case nod_unique:
		if (request)
		{
			STUFF(blr_unique);
			gen_rse(node->nod_arg[e_any_rse], request);
		}
		return;

	case nod_constant:
		if (request)
			gen_literal(&node->nod_desc, request);
		return;

	case nod_field:
		gen_field(node, request);
		return;

	case nod_format:
		gen_expression(node->nod_arg[e_fmt_value], request);
		return;

	case nod_map:
		{
			qli_map* map = (qli_map*) node->nod_arg[e_map_map];
			const qli_ctx* context = (qli_ctx*) node->nod_arg[e_map_context];
			if (context->ctx_request != request && map->map_node->nod_type == nod_field)
			{
				gen_field(map->map_node, request);
				return;
			}
			STUFF(blr_fid);
			STUFF(context->ctx_context);
			STUFF_WORD(map->map_position);
			return;
		}

	case nod_eql:
		operatr = blr_eql;
		break;

	case nod_neq:
		operatr = blr_neq;
		break;

	case nod_gtr:
		operatr = blr_gtr;
		break;

	case nod_geq:
		operatr = blr_geq;
		break;

	case nod_leq:
		operatr = blr_leq;
		break;

	case nod_lss:
		operatr = blr_lss;
		break;

	case nod_containing:
		operatr = blr_containing;
		break;

	case nod_matches:
		operatr = blr_matching;
		break;

	case nod_sleuth:
		operatr = blr_matching2;
		break;

	case nod_like:
		operatr = (node->nod_count == 2) ? blr_like : blr_ansi_like;
		break;

	case nod_starts:
		operatr = blr_starting;
		break;

	case nod_missing:
		operatr = blr_missing;
		break;

	case nod_between:
		operatr = blr_between;
		break;

	case nod_and:
		operatr = blr_and;
		break;

	case nod_or:
		operatr = blr_or;
		break;

	case nod_not:
		operatr = blr_not;
		break;

	case nod_add:
		operatr = blr_add;
		break;

	case nod_subtract:
		operatr = blr_subtract;
		break;

	case nod_multiply:
		operatr = blr_multiply;
		break;

	case nod_divide:
		operatr = blr_divide;
		break;

	case nod_negate:
		operatr = blr_negate;
		break;

	case nod_concatenate:
		operatr = blr_concatenate;
		break;

	case nod_substr:
		operatr = blr_substring;
		break;

	case nod_function:
		gen_function(node, request);
		return;

	case nod_agg_average:
	case nod_agg_count:
	case nod_agg_max:
	case nod_agg_min:
	case nod_agg_total:

	case nod_average:
	case nod_count:
	case nod_max:
	case nod_min:
	case nod_total:
	case nod_from:
		gen_statistical(node, request);
		return;

	case nod_rpt_average:
	case nod_rpt_count:
	case nod_rpt_max:
	case nod_rpt_min:
	case nod_rpt_total:

	case nod_running_total:
	case nod_running_count:
		if (node->nod_arg[e_stt_value])
			gen_expression(node->nod_arg[e_stt_value], request);
		if (node->nod_export)
			gen_parameter(node->nod_export, request);
		request = NULL;
		break;

	case nod_prompt:
	case nod_variable:
		if (node->nod_export)
			gen_parameter(node->nod_export, request);
		return;

	case nod_edit_blob:
	case nod_reference:
		return;

	case nod_null:
		operatr = blr_null;
		break;

	case nod_user_name:
		operatr = blr_user_name;
		break;

	case nod_upcase:
		operatr = blr_upcase;
		break;

	case nod_lowcase:
		operatr = blr_lowcase;
		break;

	default:
		if (request && node->nod_export)
		{
			gen_parameter(node->nod_export, request);
			return;
		}
		ERRQ_bugcheck(353);			// Msg353 gen_expression: not understood
	}

	if (request)
	{
		rlb = CHECK_RLB(request->req_blr);
		STUFF(operatr);
	}

	qli_nod** ptr = node->nod_arg;
	for (qli_nod** const end = ptr + node->nod_count; ptr < end; ptr++)
		gen_expression(*ptr, request);

	if (!node->nod_desc.dsc_address && node->nod_desc.dsc_length)
		CMP_alloc_temp(node);
}
Esempio n. 11
0
static void gen_for( qli_nod* node, qli_req* request)
{
/**************************************
 *
 *	g e n _ f o r
 *
 **************************************
 *
 * Functional description
 *	Generate BLR for a FOR loop, included synchronization messages.
 *
 **************************************/

	// If there is a request associated with the statement, prepare to
	// generate BLR.  Otherwise assume that a request is alrealdy initialized.

	if (node->nod_arg[e_for_request])
	{
		request = (qli_req*) node->nod_arg[e_for_request];
		gen_request(request);
	}

	qli_rlb* rlb = CHECK_RLB(request->req_blr);

	// If the statement requires an end of file marker, build a BEGIN/END around
	// the whole statement.

	const qli_msg* message = (qli_msg*) node->nod_arg[e_for_receive];
	if (message)
		STUFF(blr_begin);

	// If there is a message to be sent, build a receive for it

	if (node->nod_arg[e_for_send])
		gen_send_receive((qli_msg*) node->nod_arg[e_for_send], blr_receive);

	// Generate the FOR loop proper.

	STUFF(blr_for);
	gen_rse(node->nod_arg[e_for_rse], request);
	STUFF(blr_begin);

	// If data is to be received (included EOF), build a send

	const qli_par* eof = 0;
	dsc desc;
	USHORT value;

	if (message)
	{
		gen_send_receive(message, blr_send);
		STUFF(blr_begin);

		// Build assigments for all values referenced.

		for (const qli_par* parameter = message->msg_parameters; parameter;
			parameter = parameter->par_next)
		{
			if (parameter->par_value)
			{
				STUFF(blr_assignment);
				gen_expression(parameter->par_value, request);
				gen_parameter(parameter, request);
			}
		}

		// Next, make a FALSE for the end of file parameter

		eof = (qli_par*) node->nod_arg[e_for_eof];
		desc.dsc_dtype = dtype_short;
		desc.dsc_length = sizeof(SSHORT);
		desc.dsc_scale = 0;
		desc.dsc_sub_type = 0;
		desc.dsc_address = (UCHAR*) &value;
		QLI_validate_desc(desc);

		STUFF(blr_assignment);
		value = FALSE;
		gen_literal(&desc, request);
		gen_parameter(eof, request);

		STUFF(blr_end);
	}

	// Build  the body of the loop.

	const qli_msg* continuation = request->req_continue;
	if (continuation)
	{
		STUFF(blr_label);
		const USHORT label = request->req_label++;
		STUFF(label);
		STUFF(blr_loop);
		STUFF(blr_select);
		gen_send_receive(continuation, blr_receive);
		STUFF(blr_leave);
		STUFF(label);
	}

	qli_nod* sub = node->nod_arg[e_for_statement];
	gen_statement(sub, request);

	STUFF(blr_end);

	if (continuation)
		STUFF(blr_end);

	// Finish off by building a SEND to indicate end of file

	if (message)
	{
		gen_send_receive(message, blr_send);
		STUFF(blr_assignment);
		value = TRUE;
		gen_literal(&desc, request);
		gen_parameter(eof, request);
		STUFF(blr_end);
	}

	// If this is our request, compile it.

	if (node->nod_arg[e_for_request])
		gen_compile(request);
}
Esempio n. 12
0
void gen_statements(char* method_name, is_node* node, prog_env* prog)
{
    char* expr;
    char* type;
    is_node* aux;
    int glob;
    int if_else_c;
    
    while(node != NULL)
    {
        switch (node->type)
        {
            case VarDecl:
                aux = node->child->next;
                while(aux != NULL)
                {
                    printf("\t%%%s = alloca %s\n", aux->id, gen_code_type(gen_type[node->child->type]));
                    aux = aux->next;
                }
                break;
                
            case CompoundStat:
                break;
                
            case IfElse:
                expr = gen_expression(method_name, node->child, prog);
                
                if_else_c = 0;
                printf("%%if_%d = icmp eq i1 1 , %s\n", if_else_c, expr);
                printf("br i1 %%if_%d, label %%then_%d, label %%else_%d \n", if_else_c, if_else_c, if_else_c); // then else true false ??
                
                

                
                /*
                %ifcond = icmp eq i32 %v1, %v2
                br i1 %ifcond , label %then , label %else
                    
                then :
                    %calltmp = add i32 %v1, %v2
                    br label %ifcont
                else :
                    %calltmp1 = mul i32 %v1, %v2
                    br label %ifcont
                ifcont :
                    %iftmp = phi i32 [ %calltmp , %then ] , [ %calltmp1 , %else ]
                    ret i32 %iftmp
                */
                
                /*
                 contaIfElse++;
                 int tmp = contaIfElse;
                 
                 printf("%%if%d = icmp eq i1 1 , %s\n",tmp,GeraExp(stm->filho,semanticTree,methodName));
                 printf("br i1 %%if%d, label %%true%d, label %%false%d \n",tmp,tmp,tmp);
                 printf("true%d:\n",tmp);
                 
                 if(stm->filho->next->nodeType!=Null){
                 GeraStatement(stm->filho->next,semanticTree,methodName);
                 }
                 printf("br label %%count%d\n",tmp);
                 
                 
                 printf("false%d:\n",tmp);
                 if(stm->filho->next->next->nodeType!=Null){
                 GeraStatement(stm->filho->next->next,semanticTree,methodName);
                 printf("br label %%count%d\n",tmp);
                 }
                 else{
                 printf("br label %%count%d\n",tmp);
                 }
                 printf("count%d:\n",tmp );
                */
                break;
            
            case Print:
                // verificar tipo
                if(node->child->type == Id)
                    type = get_type(node->child->id, prog, method_name);
                else
                    type = gen_code_type(gen_type[node->child->type]);
                
                if(strcmp(type, "i32") == 0) // inteiro
                {
                    expr = gen_expression(method_name, node->child, prog);
                    counter++;
                    printf("\t%%%d = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @str, i32 0, i32 0), i32 %s)\n", counter, expr);
                    
                } else  // boolean
                {
                    expr = gen_expression(method_name, node->child, prog);
                    if_c++;
                    // comparar o boolean com 1
                    printf("\t%%ifcond_%d = icmp eq i1 1 , %s\n", if_c, expr);
                    // se true vai para then, caso contrario vai para else
                    printf("\tbr i1 %%ifcond_%d, label %%then_%d, label %%else_%d\n", if_c, if_c, if_c);
                    
                    // se true, imprimir true
                    printf("\tthen_%d:\n", if_c);
                    counter++;
					printf("\t%%%d = load i8** @.true\n", counter);
					printf("\t%%%d = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str2, i32 0, i32 0), i8* %%%d)\n", counter + 1, counter);
					printf("\tbr label %%ifcount_%d\n", if_c);
                    counter++;
                    
                    // se false, imprimir false
                    printf("\telse_%d:\n", if_c);
					printf("\t%%%d = load i8** @.false\n", ++counter);
					printf("\t%%%d = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str2, i32 0, i32 0), i8* %%%d)\n", counter + 1, counter);
					printf("\tbr label %%ifcount_%d\n", if_c);
                    counter++;
                    
					printf("\tifcount_%d:\n", if_c);
                }
                break;
                
            case Return:
                break;
                
            case Store:
                glob = verifyGlobal(node->child->id, prog, method_name);
                type = get_type(node->child->id, prog, method_name);
                expr = gen_expression(method_name, node->child->next, prog);
                
                if (!glob) // global
                    printf("\tstore %s %s, %s* %%%s\n", type, expr, type, node->child->id);
                else // local
                    printf("\tstore %s %s, %s* @%s\n", type, expr, type, node->child->id);
                break;
                
            case StoreArray:
                break;
                
            case While:
                break;
                
            default:
                break;
        }
        node = node->next;
    }
}
Esempio n. 13
0
static void gen_rse( qli_nod* node, qli_req* request)
{
/**************************************
 *
 *	g e n _ r s e
 *
 **************************************
 *
 * Functional description
 *	Generate a record selection expression.
 *
 **************************************/

	qli_rlb* rlb = CHECK_RLB(request->req_blr);

	if ((nod_t) (IPTR) node->nod_arg[e_rse_join_type] == nod_nothing)
		STUFF(blr_rse);
	else
		STUFF(blr_rs_stream);
	STUFF(node->nod_count);

	// Check for aggregate case
	qli_nod* list;
	qli_ctx* context = (qli_ctx*) node->nod_arg[e_rse_count];

	if (context->ctx_sub_rse)
	{
		STUFF(blr_aggregate);
		STUFF(context->ctx_context);
		gen_rse(context->ctx_sub_rse, request);
		STUFF(blr_group_by);
		if (list = node->nod_arg[e_rse_group_by])
		{
			request->req_flags |= REQ_group_by;
			STUFF(list->nod_count);
			qli_nod** ptr = list->nod_arg;
			for (const qli_nod* const* const end = ptr + list->nod_count; ptr < end; ++ptr)
			{
				gen_expression(*ptr, request);
			}
			request->req_flags &= ~REQ_group_by;
		}
		else
			STUFF(0);
		gen_map(context->ctx_map, request);
		if (list = node->nod_arg[e_rse_having])
		{
			STUFF(blr_boolean);
			gen_expression(list, request);
		}
		if (list = node->nod_arg[e_rse_sort])
			gen_sort(list, request, blr_sort);
		STUFF(blr_end);
		return;
	}

	// Make relation clauses for all relations

	qli_nod** ptr = &node->nod_arg[e_rse_count];
	for (const qli_nod* const* const end = ptr + node->nod_count; ptr < end; ++ptr)
	{
		context = (qli_ctx*) *ptr;
		if (context->ctx_stream)
			gen_rse(context->ctx_stream, request);
		else
		{
			const qli_rel* relation = context->ctx_relation;
			STUFF(blr_rid);
			STUFF_WORD(relation->rel_id);
			STUFF(context->ctx_context);
		}
	}

	// Handle various clauses

	if (list = node->nod_arg[e_rse_first])
	{
		STUFF(blr_first);
		gen_expression(list, request);
	}

	if (list = node->nod_arg[e_rse_boolean])
	{
		STUFF(blr_boolean);
		gen_expression(list, request);
	}

	if (list = node->nod_arg[e_rse_sort])
		gen_sort(list, request, blr_sort);

	if (list = node->nod_arg[e_rse_reduced])
		gen_sort(list, request, blr_project);

	const nod_t join_type = (nod_t) (IPTR) node->nod_arg[e_rse_join_type];
	if (join_type != nod_nothing && join_type != nod_join_inner)
	{
		STUFF(blr_join_type);
		switch (join_type)
		{
		case nod_join_left:
			STUFF(blr_left);
			break;
		case nod_join_right:
			STUFF(blr_right);
			break;
		default:
			STUFF(blr_full);
		}
	}

	STUFF(blr_end);
}
Esempio n. 14
0
static void gen_function( qli_nod* node, qli_req* request)
{
/**************************************
 *
 *	g e n _ f u n c t i o n
 *
 **************************************
 *
 * Functional description
 *	Generate blr for a function reference.
 *
 **************************************/
	qli_req* new_request;
	qli_rlb* rlb;

	// If there is a request associated with the statement, prepare to
	// generate BLR.  Otherwise assume that a request is already initialized.

	if (request && (request->req_flags & (REQ_project | REQ_group_by)))
	{
		new_request = NULL;
		rlb = CHECK_RLB(request->req_blr);
	}
	else if (new_request = (qli_req*) node->nod_arg[e_fun_request])
	{
		request = new_request;
		gen_request(request);
		const qli_msg* receive = (qli_msg*) node->nod_arg[e_fun_send];
		if (receive)
			gen_send_receive(receive, blr_receive);
		const qli_msg* send = (qli_msg*) node->nod_arg[e_fun_receive];
		gen_send_receive(send, blr_send);
		rlb = CHECK_RLB(request->req_blr);
		STUFF(blr_assignment);
	}
	else
		rlb = CHECK_RLB(request->req_blr);

	// Generate function body

	STUFF(blr_function);
	qli_fun* function = (qli_fun*) node->nod_arg[e_fun_function];
	qli_symbol* symbol = function->fun_symbol;
	STUFF(symbol->sym_length);
	for (const UCHAR* p = (UCHAR*) symbol->sym_string; *p;)
		STUFF(*p++);

	// Generate function arguments

	qli_nod* args = node->nod_arg[e_fun_args];
	STUFF(args->nod_count);

    qli_nod** ptr = args->nod_arg;
	for (const qli_nod* const* const end = ptr + args->nod_count; ptr < end; ptr++)
		gen_expression(*ptr, request);

	if (new_request)
	{
		gen_parameter(node->nod_import, request);
		gen_compile(request);
	}
}
Esempio n. 15
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
	}
}
Esempio n. 16
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;
  }
}
Esempio n. 17
0
static void gen_statistical( qli_nod* node, qli_req* request)
{
/**************************************
 *
 *	g e n _ s t a t i s t i c a l
 *
 **************************************
 *
 * Functional description
 *	Generate the BLR for a statistical expresionn.
 *
 **************************************/
	USHORT operatr;

	switch (node->nod_type)
	{
	case nod_average:
		operatr = blr_average;
		break;

	case nod_count:
		// count2
		// operatr = node->nod_arg [e_stt_value] ? blr_count2 : blr_count;
		operatr = blr_count;
		break;

	case nod_max:
		operatr = blr_maximum;
		break;

	case nod_min:
		operatr = blr_minimum;
		break;

	case nod_total:
		operatr = blr_total;
		break;

	case nod_agg_average:
		operatr = blr_agg_average;
		break;

	case nod_agg_count:
		// count2
		// operatr = node->nod_arg [e_stt_value] ? blr_agg_count2 : blr_agg_count;
		operatr = blr_agg_count;
		break;

	case nod_agg_max:
		operatr = blr_agg_max;
		break;

	case nod_agg_min:
		operatr = blr_agg_min;
		break;

	case nod_agg_total:
		operatr = blr_agg_total;
		break;

	case nod_from:
		operatr = node->nod_arg[e_stt_default] ? blr_via : blr_from;
		break;

	default:
		ERRQ_bugcheck(355);			// Msg355 gen_statistical: not understood
	}

	// If there is a request associated with the statement, prepare to
	// generate BLR.  Otherwise assume that a request is alrealdy initialized.

	qli_rlb* rlb;
	qli_req* new_request = (qli_req*) node->nod_arg[e_stt_request];
	if (new_request)
	{
		request = new_request;
		gen_request(request);
		const qli_msg* receive = (qli_msg*) node->nod_arg[e_stt_send];
		if (receive)
			gen_send_receive(receive, blr_receive);
		const qli_msg* send = (qli_msg*) node->nod_arg[e_stt_receive];
		gen_send_receive(send, blr_send);
		rlb = CHECK_RLB(request->req_blr);
		STUFF(blr_assignment);
	}
	else
		rlb = CHECK_RLB(request->req_blr);

	STUFF(operatr);

	if (node->nod_arg[e_stt_rse])
		gen_rse(node->nod_arg[e_stt_rse], request);

	// count 2
	// if (node->nod_arg [e_stt_value])

	if (node->nod_arg[e_stt_value] && node->nod_type != nod_agg_count)
		gen_expression(node->nod_arg[e_stt_value], request);

	if (node->nod_arg[e_stt_default])
		gen_expression(node->nod_arg[e_stt_default], request);

	if (new_request)
	{
		gen_parameter(node->nod_import, request);
		gen_compile(request);
	}
}
Esempio n. 18
0
char* gen_expression(char* method_name, is_node* expr, prog_env* prog)
{
    char* expr_type;
    char* expr_type1;
    int glob;
    char *c = (char*) malloc(sizeof(char*));
    
    switch (expr->type)
    {
        case Call:
            break;
            
        case Or:
            break;
            
        case And:
            break;
            
        case Not:
            break;
            
        case Eq:
            break;
            
        case Neq:
            break;
            
        case Lt:
            break;
            
        case Gt:
            break;
            
        case Leq:
            break;
            
        case Geq:
            break;
            
        case Add:
            expr_type = gen_expression(method_name, expr->child, prog);
            expr_type1 = gen_expression(method_name, expr->child->next, prog);
            printf("\t%%%d = add i32 %s,%s\n", ++counter, expr_type, expr_type1);
            sprintf(c, "%%%d", counter);
            return c;
            break;
            
        case Sub:
            break;
            
        case Mul:
            break;
            
        case Div:
            break;
            
        case Mod:
            break;
            
        case Plus:
            break;
            
        case Minus:
            break;
            
        case Length:
            c = (char*) malloc(sizeof(char*));
			counter++;
			printf("\t%%%d = sub i32 %%.argc, 1\n", counter);
			sprintf(c, "%%%d", counter);
			return c;
            break;
            
        case LoadArray:
            break;
            
        case NewInt:
            break;
            
        case NewBool:
            break;
            
        case ParseArgs:
            counter++;
            printf("\t%%%d = getelementptr inbounds i8** %%.argv, i64 %d\n", counter, atoi(expr->child->next->id) + 1);
            printf("\t%%%d = load i8** %%%d\n", counter + 1, counter);
            counter += 2;
            printf("\t%%%d = call i32 @atoi(i8* %%%d)\n", counter, counter - 1);
            c = (char* ) malloc(sizeof(char*));
            sprintf(c, "%%%d", counter);
            return c;
            break;
            
        case IntLit:
            c = (char*) malloc(sizeof(char*));
            int hexa;
            hexa = strtol(expr->id, NULL, 0);
            sprintf(c, "%d", hexa);
            return c;
			break;
            
        case BoolLit:
            if(strcmp(expr->id, "true") == 0)
                return "1";
            else
                return "0";
            break;
            
        case Id:
            glob = verifyGlobal(expr->id, prog, method_name);
            expr_type = get_type(expr->id, prog, method_name); // tipo do Id
            counter++;
            sprintf(c, "%%%d", counter);
            if(!glob)
                printf("\t%%%d = load %s* %%%s\n", counter, expr_type, expr->id);
            else
                printf("\t%%%d = load %s* @%s\n",counter, expr_type, expr->id);
            return c;
            break;
            
        default:
            break;
    }
    return "erro";
}
Esempio n. 19
0
void GenTree::gen_value( const Value *val )
{
   if ( val == 0 ) {
      m_out->writeString( "(null)" );
      return;
   }

   switch( val->type() )
   {
      case Value::t_nil: m_out->writeString( "nil" ); break;
      case Value::t_unbound: m_out->writeString( "unbound" ); break;
      case Value::t_imm_bool:
            m_out->writeString( val->asBool() ? "true": "false" );
      break;

      case Value::t_imm_integer: {
         String intStr;
         intStr.writeNumber( val->asInteger() );
         m_out->writeString( intStr );
      }
      break;
      case Value::t_imm_string:
      {
         String temp;
         val->asString()->escape( temp );
         m_out->writeString( "\"" + temp + "\"" );
      }
      break;

      case Value::t_lbind:
      {
         m_out->writeString( "&" + *val->asLBind() );
      }
      break;

      case Value::t_imm_num: {
         String numStr;
         numStr.writeNumber( val->asInteger() );
         m_out->writeString( numStr );
      }
      break;

      case Value::t_range_decl:
         m_out->writeString( "[" );
         gen_value( val->asRange()->rangeStart() );
         m_out->writeString( ":" );
         if ( ! val->asRange()->isOpen() )
         {
            gen_value(  val->asRange()->rangeEnd() ) ;
            if ( val->asRange()->rangeStep() != 0 )
            {
               m_out->writeString( ":" );
               gen_value(  val->asRange()->rangeStep() );
            }

         }
         m_out->writeString( "]" );
      break;

      case Value::t_symbol: m_out->writeString( val->asSymbol()->name() ); break;
      case Value::t_self: m_out->writeString( "self" ); break;
      case Value::t_fself: m_out->writeString( "fself" ); break;
      case Value::t_array_decl:
         m_out->writeString( "Array: [ " );
            gen_array( val->asArray() );
         m_out->writeString( " ]" );
      break;

      case Value::t_dict_decl:
         m_out->writeString( "Dict: [" );
            gen_dict( val->asDict() );
         m_out->writeString( " ]" );
      break;

      case Value::t_byref:
         m_out->writeString( "$" );
         gen_value( val->asReference() );
      break;

      case Value::t_expression:
         gen_expression( val->asExpr() );
      break;

      default:
         break;
   }
}