Exemplo n.º 1
0
static void
gen_expr(tree *expr)
{
  struct variable *var;

  switch(expr->tag) {
  case node_arg:
    var = get_global(ARG_NAME(expr));
    codegen_load_file(expr, var);
    break;
  case node_call:
    analyze_call(expr, true, codegen_size);    
    break;
  case node_constant:
    LOAD_CONSTANT(expr->value.constant, codegen_size);
    break;
  case node_symbol:
    var = get_global(SYM_NAME(expr));
    if (var->tag == sym_const) {
      LOAD_CONSTANT(var->value, codegen_size); 
    } else {
      codegen_load_file(expr, var);
    }
    break;
  case node_unop:
    gen_unop_expr(expr);
    break;
  case node_binop:
    if (expr->value.binop.op == op_assign) {
      analyze_error(expr, "assign operator = should be equal operator ==");
    } else if ((expr->value.binop.op == op_lsh) ||
               (expr->value.binop.op == op_rsh)) {
      /* for shifts it is best to calculate the left side first */
      gen_binop_expr(expr->value.binop.op,
                     expr->value.binop.p1,
                     expr->value.binop.p0);
    } else {
      /* for all others calculate the right side first */
      gen_binop_expr(expr->value.binop.op,
                     expr->value.binop.p0,
                     expr->value.binop.p1);
    }
    break;
  default:
    assert(0);
  }

}
Exemplo n.º 2
0
static void
gen_binop_expr(enum node_op op, tree *p0, tree *p1)
{
  char *reg1 = NULL;
  char *reg2 = NULL;
  struct variable *var;

  gen_expr(p1);

  if (p0->tag == node_call) {
    reg1 = codegen_get_temp(codegen_size);
    STORE_FILE(reg1, codegen_size, 0, false);
    analyze_call(p0, true, codegen_size);    
    CODEGEN(op, codegen_size, false, 0, reg1);
  } else if (p0->tag == node_constant) {
    CODEGEN(op, codegen_size, true, p0->value.constant, NULL);
  } else if (p0->tag == node_symbol) { 
    var = get_global(SYM_NAME(p0));
    if (var->tag == sym_const) {
      CODEGEN(op, codegen_size, true, var->value, NULL);
    } else if (SYM_OFST(p0)) {
      /* it is a complex expression, so save temp data */
      reg1 = codegen_get_temp(codegen_size);
      reg2 = codegen_get_temp(codegen_size);
      STORE_FILE(reg1, codegen_size, 0, false);
      codegen_load_file(p0, var);
      STORE_FILE(reg2, codegen_size, 0, false);
      LOAD_FILE(reg1, codegen_size, 0, false);
      CODEGEN(op, codegen_size, false, 0, reg2);
    } else {
      CODEGEN(op, codegen_size, false, 0, var->name);
    }
  } else {
    /* it is a complex expression so save temp data */
    reg1 = codegen_get_temp(codegen_size);
    STORE_FILE(reg1, codegen_size, 0, false);
    gen_expr(p0);
    CODEGEN(op, codegen_size, false, 0, reg1);
  }

  if (reg1)
    free(reg1);
  if (reg2)
    free(reg2);

}
Exemplo n.º 3
0
static void analyze_expr(short priority, short op_main)
{
	short op, op_curr, op_not;
	short prio;
	short nparam;

	inc_level();

	op_curr = op_main;
	op_not = RS_NONE;
	nparam = (op_main == RS_NONE || op_main == RS_UNARY) ? 0 : 1;

	if (PATTERN_is(*current, RS_NEW))
		THROW("Cannot use NEW operator there");

READ_OPERAND:

	//analyze_expr_check_first(op_curr);

	analyze_single(op_curr);
	nparam++;

	if (nparam > MAX_PARAM_OP)
		THROW("Expression too complex. Too many operands");

READ_OPERATOR:

	if (!PATTERN_is_reserved(*current))
		goto OPERATOR_END;

	op = PATTERN_index(*current);

	if (!RES_is_operator(op))
		goto OPERATOR_END;

	if (op == RS_AND || op == RS_OR)
		if (PATTERN_is(current[1], RS_IF))
			goto OPERATOR_END;

	current++;
	
	if (op == RS_NOT && PATTERN_is_reserved(*current))
	{
		op_not = PATTERN_index(*current);
		if (RES_is_operator(op_not) && RES_can_have_not_before(op_not))
		{
			op = op_not + 1;
			current++;
		}
	}
	
	if (priority)
		prio = priority;
	else if (op_curr == RS_NONE)
		prio = 0;
	else
		prio = RES_priority(op_curr);

	if (op_curr == RS_NONE)
	{
		if (RES_is_binary(op) || RES_is_n_ary(op))
		{
			op_curr = op;
			goto READ_OPERAND;
		}
	}

	if (op_curr == op)
	{
		if (!(RES_is_binary(op) && nparam == 2))
			goto READ_OPERAND;
	}

	if (RES_priority(op) > prio)
	{
		if (op == RS_LSQR)
			analyze_array();
		else if (op == RS_LBRA)
			analyze_call();
		else
			analyze_expr(RES_priority(op), op);

		goto READ_OPERATOR;
	}

	if (RES_priority(op) == prio)
	{
		add_operator(op_curr, nparam);

		if (op == RS_LSQR)
		{
			analyze_array();
			goto READ_OPERATOR;
		}
		else if (op == RS_LBRA)
		{
			analyze_call();
			goto READ_OPERATOR;
		}
		else
		{
			if (RES_is_only(op_curr) || RES_is_only(op))
				THROW("Ambiguous expression. Please use brackets");

			nparam = 1;
			op_curr = op;
			goto READ_OPERAND;
		}
	}

	if (RES_priority(op) < prio)
	{
		if ((op_main != RS_NONE) || (priority > 0))
		{
			add_operator(op_curr, nparam);
			current--;
			if (op_not != RS_NONE)
				current--;
			goto END;
		}

		add_operator(op_curr, nparam);

		if (op == RS_LSQR)
		{
			analyze_array();
			nparam = 1;
			op_curr = op_main;
			goto READ_OPERATOR;
		}
		else if (op == RS_LBRA)
		{
			analyze_call();
			nparam = 1;
			op_curr = op_main;
			goto READ_OPERATOR;
		}
		else
		{
			nparam = 1;
			op_curr = op;
			goto READ_OPERAND;
		}
	}

	dec_level();
	return;

OPERATOR_END:

	add_operator(op_curr, nparam);

END:

	dec_level();
	return;

}