Ejemplo n.º 1
0
/* the effect of pointer indirection */
typeID ptrdown (typeID t)
{
	int *tt = open_typeID (t), *tn;
	if (tt [1] != '*' && tt [1] != '[')
		expr_error ("* not applicable");
	tn = allocaint (intlen (tt));
	tn [0] = tt [0];
	intcpy (tn + 1, tt + 2);
	return enter_type (tn);
}
Ejemplo n.º 2
0
/* given a function type return the return type */
typeID funcreturn (typeID t)
{
	int *tt = open_typeID (t), *tn, i;
	if (tt [1] != '(')
		expr_error ("bug: request return type of no function");
	for (i = 2; tt [i] != INTERNAL_ARGEND; i++);
	tn = allocaint (intlen (&tt [i]) + 2);
	tn [0] = tt [0];
	intcpy (tn + 1, tt + i + 1);
	return enter_type (tn);
}
Ejemplo n.º 3
0
/* take a function type and add the first rec* argument */
typeID makemember (typeID t, recID r)
{
	int *tt = open_typeID (t), *tn;
	if (tt [1] != '(')
		expr_error ("bug: request to makemember on no function");
	tn = allocaint (intlen (tt) + 4);
	tn [0] = tt [0];
	tn [1] = '(';
	tn [2] = pthis_of_struct (r);
	intcpy (tn + 3, tt + 2);
	return enter_type (tn);
}
Ejemplo n.º 4
0
static Eina_Bool
eval_exp(const Eolian_Expression *expr, Eolian_Expression_Mask mask,
         Eolian_Expression *out)
{
   switch (expr->type)
     {
      case EOLIAN_EXPR_INT:
      case EOLIAN_EXPR_LONG:
      case EOLIAN_EXPR_LLONG:
        {
           if (!(mask & EOLIAN_MASK_SINT))
             return expr_type_error(expr, EOLIAN_MASK_SINT, mask);
           *out = *expr;
           return EINA_TRUE;
        }
      case EOLIAN_EXPR_UINT:
      case EOLIAN_EXPR_ULONG:
      case EOLIAN_EXPR_ULLONG:
        {
           if (!(mask & EOLIAN_MASK_UINT))
             return expr_type_error(expr, EOLIAN_MASK_UINT, mask);
           *out = *expr;
           return EINA_TRUE;
        }
      case EOLIAN_EXPR_FLOAT:
      case EOLIAN_EXPR_DOUBLE:
        {
           if (!(mask & EOLIAN_MASK_FLOAT))
             return expr_type_error(expr, EOLIAN_MASK_FLOAT, mask);
           *out = *expr;
           return EINA_TRUE;
        }
      case EOLIAN_EXPR_STRING:
        {
           if (!(mask & EOLIAN_MASK_STRING))
             return expr_type_error(expr, EOLIAN_MASK_STRING, mask);
           *out = *expr;
           return EINA_TRUE;
        }
      case EOLIAN_EXPR_NULL:
        {
           if (!(mask & EOLIAN_MASK_NULL))
             return expr_type_error(expr, EOLIAN_MASK_NULL, mask);
           *out = *expr;
           return EINA_TRUE;
        }
      case EOLIAN_EXPR_CHAR:
        {
           if (!(mask & EOLIAN_MASK_CHAR))
             return expr_type_error(expr, EOLIAN_MASK_CHAR, mask);
           *out = *expr;
           return EINA_TRUE;
        }
      case EOLIAN_EXPR_BOOL:
        {
           if (!(mask & EOLIAN_MASK_BOOL))
             return expr_type_error(expr, EOLIAN_MASK_BOOL, mask);
           *out = *expr;
           return EINA_TRUE;
        }
      case EOLIAN_EXPR_NAME:
        {
           const Eolian_Variable *var = eolian_variable_constant_get_by_name
             (expr->value.s);
           const Eolian_Expression *exp = NULL;

           if (!var)
             {
                const Eolian_Type *etp;
                const Eolian_Enum_Type_Field *fl;

                /* try aliases, hoping it'll be enum */
                char *fulln = NULL, *memb = NULL;

                if (!split_enum_name(expr->value.s, &fulln, &memb))
                  return expr_error(expr, "undefined variable");

                /* assert int here, as we're clearly dealing with enum */
                if (!(mask & EOLIAN_MASK_INT))
                  return expr_type_error(expr, EOLIAN_MASK_INT, mask);

                etp = eolian_type_alias_get_by_name(fulln);
                while (etp && (etp->type == EOLIAN_TYPE_ALIAS
                            || etp->type == EOLIAN_TYPE_REGULAR))
                  etp = eolian_type_base_type_get(etp);

                if (!etp) etp = eolian_type_enum_get_by_name(fulln);
                if (!etp || etp->type != EOLIAN_TYPE_ENUM)
                  {
                     free(fulln);
                     return expr_error(expr, "undefined variable");
                  }

                fl = eolian_type_enum_field_get(etp, memb);
                if (fl) exp = eolian_type_enum_field_value_get(fl, EINA_TRUE);
                free(fulln);

                if (!exp)
                  return expr_error(expr, "invalid enum field");
             }
           else
             exp = var->value;

           if (!exp)
             return expr_error(expr, "undefined variable");

           return eval_exp(exp, mask, out);
        }
      case EOLIAN_EXPR_UNARY:
        return eval_unary(expr, mask, out);
      case EOLIAN_EXPR_BINARY:
        return eval_binary(expr, mask, out);
      default:
        assert(EINA_FALSE);
        return EINA_FALSE;
     }

   return EINA_TRUE;
}
Ejemplo n.º 5
0
ast_result_t pass_expr(ast_t** astp, pass_opt_t* options)
{
  typecheck_t* t = &options->check;
  ast_t* ast = *astp;
  bool r = true;

  switch(ast_id(ast))
  {
    case TK_NOMINAL:    r = expr_nominal(options, astp); break;
    case TK_FVAR:
    case TK_FLET:
    case TK_PARAM:      r = expr_field(options, ast); break;
    case TK_NEW:
    case TK_BE:
    case TK_FUN:        r = expr_fun(options, ast); break;
    case TK_SEQ:        r = expr_seq(ast); break;
    case TK_VAR:
    case TK_LET:        r = expr_local(t, ast); break;
    case TK_BREAK:      r = expr_break(t, ast); break;
    case TK_CONTINUE:   r = expr_continue(t, ast); break;
    case TK_RETURN:     r = expr_return(options, ast); break;
    case TK_IS:
    case TK_ISNT:       r = expr_identity(options, ast); break;
    case TK_ASSIGN:     r = expr_assign(options, ast); break;
    case TK_CONSUME:    r = expr_consume(t, ast); break;
    case TK_RECOVER:    r = expr_recover(ast); break;
    case TK_DOT:        r = expr_dot(options, astp); break;
    case TK_TILDE:      r = expr_tilde(options, astp); break;
    case TK_QUALIFY:    r = expr_qualify(options, astp); break;
    case TK_CALL:       r = expr_call(options, astp); break;
    case TK_IF:         r = expr_if(options, ast); break;
    case TK_WHILE:      r = expr_while(options, ast); break;
    case TK_REPEAT:     r = expr_repeat(options, ast); break;
    case TK_TRY_NO_CHECK:
    case TK_TRY:        r = expr_try(options, ast); break;
    case TK_MATCH:      r = expr_match(options, ast); break;
    case TK_CASES:      r = expr_cases(ast); break;
    case TK_CASE:       r = expr_case(options, ast); break;
    case TK_TUPLE:      r = expr_tuple(ast); break;
    case TK_ARRAY:      r = expr_array(options, astp); break;
    case TK_REFERENCE:  r = expr_reference(options, astp); break;
    case TK_THIS:       r = expr_this(options, ast); break;
    case TK_TRUE:
    case TK_FALSE:      r = expr_literal(options, ast, "Bool"); break;
    case TK_ERROR:      r = expr_error(ast); break;
    case TK_COMPILER_INTRINSIC:
                        r = expr_compiler_intrinsic(t, ast); break;
    case TK_POSITIONALARGS:
    case TK_NAMEDARGS:
    case TK_NAMEDARG:
    case TK_UPDATEARG:  ast_inheritflags(ast); break;
    case TK_AMP:        r = expr_addressof(options, ast); break;
    case TK_DONTCARE:   r = expr_dontcare(ast); break;

    case TK_INT:
      // Integer literals can be integers or floats
      make_literal_type(ast);
      break;

    case TK_FLOAT:
      make_literal_type(ast);
      break;

    case TK_STRING:
      if(ast_id(ast_parent(ast)) == TK_PACKAGE)
        return AST_OK;

      r = expr_literal(options, ast, "String");
      break;

    case TK_FFICALL:
      return expr_ffi(options, ast);

    default: {}
  }

  if(!r)
  {
    assert(get_error_count() > 0);
    return AST_ERROR;
  }

  // Can't use ast here, it might have changed
  symtab_t* symtab = ast_get_symtab(*astp);

  if(symtab != NULL && !symtab_check_all_defined(symtab))
    return AST_ERROR;

  return AST_OK;
}