// Copiado do analisador semântico
// TODO: refatorar...
int jvmcodegen::compute_type(const ast::node_ptr &expr)
{
    switch (expr->type) {
        case ast::call_node: {
            auto curr_scope = m_stack.top();
            auto sym = curr_scope->get(ast::to_call(expr)->name);
            if (!sym.is_valid())
                return -1;
            return sym.type & ~types::function;
        }
        case ast::variable_node: {
            auto curr_scope = m_stack.top();
            auto sym = curr_scope->get(ast::to_variable(expr)->name);
            if (!sym.is_valid())
                return -1;
            return sym.type;
        }
        case ast::integer_node:
            return types::integer;
        case ast::string_node:
            return types::string;
        case ast::type_node:
            return ast::to_type(expr)->type_id;
        case ast::op_logical_node: {
            auto op = ast::to_op_logical(expr);
            int lhs_type = compute_type(op->left);
            int rhs_type = compute_type(op->right);
            if (lhs_type == types::integer && rhs_type == types::integer)
                return types::integer;
            return -1;
        }
        case ast::op_arithm_node: {
            auto op = ast::to_op_arithm(expr);
            int lhs_type = compute_type(op->left);
            int rhs_type = compute_type(op->right);
            if (lhs_type == types::integer && rhs_type == types::integer)
                return types::integer;
            return -1;
        }
        default: return -1;
    }
}
示例#2
0
bool ClassContainer::read_type(UmlTypeSpec & typespec, Class ** cl) {
  QCString s = Lex::read_word();
  
  if (s.isEmpty()) {
    Lex::premature_eof();
    return FALSE;
  }
    
  compute_type(s, typespec, cl);
  
  return TRUE;
}
void jvmcodegen::gen_write_stmt(const ast::node_ptr &node)
{
    auto write = ast::to_write_stmt(node);

    m_out << fmt::sprintf("getstatic java/lang/System/out Ljava/io/PrintStream;\n");
    int type = compute_type(write->expr);
    gen_node(write->expr);
    if (type == types::string) {
        m_out << fmt::sprintf("invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V\n");
    } else if (type == types::integer) {
        m_out << fmt::sprintf("invokevirtual java/io/PrintStream/print(I)V\n");
    }
}
void jvmcodegen::gen_return_stmt(const ast::node_ptr &node)
{
    auto ret = ast::to_return_stmt(node);
    gen_node(ret->expr);
    int type = compute_type(ret->expr);
    if (type == types::integer) {
        m_out << fmt::sprintf("ireturn\n");
    } else if (type == types::voidt) {
        m_out << fmt::sprintf("return\n");
    } else if (type == types::string) {
        m_out << fmt::sprintf("areturn\n");
    }
}
 // Of what type is this field?
 ciType* type() { return (_type == NULL) ? compute_type() : _type; }
示例#6
0
/* Parse the FORMAT string and populate the specification array stored
   at the address ARGSPECS_ADDR.  The caller has provided enough space
   to store up to MAX_ARGSPECS in that buffer.  The function may
   however ignore the provided buffer and malloc a larger one.  On
   success the addrrss of that larger buffer will be stored at
   ARGSPECS_ADDR.  The actual number of specifications will be
   returned at R_ARGSPECS_COUNT. */
static int
parse_format (const char *format,
              argspec_t *argspecs_addr, size_t max_argspecs,
              size_t *r_argspecs_count)
{
  const char *s;
  argspec_t argspecs = *argspecs_addr;
  argspec_t arg;
  size_t argcount = 0;

  if (!format)
    goto leave_einval;

  for (; *format; format++)
    {
      unsigned int flags;
      int width, precision;
      lenmod_t lenmod;
      conspec_t conspec;
      int arg_pos, width_pos, precision_pos;

      if (*format != '%')
        continue;
      s = ++format;
      if (!*s)
        goto leave_einval;
      if (*s == '%')
        continue; /* Just a quoted percent.  */

      /* First check whether there is a positional argument.  */
      arg_pos = 0; /* No positional argument given.  */
      if (*s >= '1' && *s <= '9')
        {
          const char *save_s = s;

          arg_pos = (*s++ - '0');
          for (; *s >= '0' && *s <= '9'; s++)
            arg_pos = 10*arg_pos + (*s - '0');
          if (arg_pos < 0)
            goto leave_einval; /* Overflow during conversion.  */
          if (*s == '$')
            s++;
          else
            {
              arg_pos = 0;
              s = save_s;
            }
        }

      /* Parse the flags.  */
      flags = 0;
      for ( ; *s; s++)
        {
          switch (*s)
            {
            case '\'': flags |= FLAG_GROUPING; break;
            case '-': flags |= FLAG_LEFT_JUST; break;
            case '+': flags |= FLAG_PLUS_SIGN; break;
            case ' ': flags |= FLAG_SPACE_PLUS; break;
            case '#': flags |= FLAG_ALT_CONV; break;
            case '0': flags |= FLAG_ZERO_PAD; break;
            default:
              goto flags_parsed;
            }
        }
    flags_parsed:

      /* Parse the field width.  */
      width_pos = 0;
      if (*s == '*')
        {
          width = STAR_FIELD_VALUE;
          s++;
          /* If we have a positional argument, another one might also
             be used to give the position of the star's value. */
          if (arg_pos && *s >= '1' && *s <= '9')
            {
              width_pos = (*s++ - '0');
              for (; *s >= '0' && *s <= '9'; s++)
                width_pos = 10*width_pos + (*s - '0');
              if (width_pos < 1)
                goto leave_einval; /* Overflow during conversion.  */
              if (*s != '$')
                goto leave_einval; /* Not followed by $.  */
              s++;
            }
        }
      else if ( *s >= '0' && *s <= '9')
        {
          width = (*s++ - '0');
          for (; *s >= '0' && *s <= '9'; s++)
            {
              if (!width && *s == '0')
                goto leave_einval; /* Leading zeroes are not allowed.
                                      Fixme: check what other
                                      implementations do. */
              width = 10*width + (*s - '0');
            }
          if (width < 0)
            goto leave_einval; /* Overflow during conversion.  */
        }
      else
        width = NO_FIELD_VALUE;

      /* Parse the precision.  */
      precision_pos = 0;
      precision = NO_FIELD_VALUE;
      if (*s == '.')
        {
          int ignore_value = (s[1] == '-');

          s++;
          if (*s == '*')
            {
              precision = STAR_FIELD_VALUE;
              s++;
              /* If we have a positional argument, another one might also
                 be used to give the position of the star's value. */
              if (arg_pos && *s >= '1' && *s <= '9')
                {
                  precision_pos = (*s++ - '0');
                  for (; *s >= '0' && *s <= '9'; s++)
                    precision_pos = 10*precision_pos + (*s - '0');
                  if (precision_pos < 1)
                    goto leave_einval; /* Overflow during conversion.  */
                  if (*s != '$')
                    goto leave_einval; /* Not followed by $.  */
                  s++;
                }
            }
          else if ( *s >= '0' && *s <= '9')
            {
              precision = (*s++ - '0');
              for (; *s >= '0' && *s <= '9'; s++)
                {
                  if (!precision && *s == '0')
                    goto leave_einval; /* Leading zeroes are not allowed.
                                          Fixme: check what other
                                          implementations do. */
                  precision = 10*precision + (*s - '0');
                }
              if (precision < 0)
                goto leave_einval; /* Overflow during conversion.  */
            }
          else
            precision = 0;
          if (ignore_value)
            precision = NO_FIELD_VALUE;
        }

      /* Parse the length modifiers.  */
      switch (*s)
        {
        case 'h':
          if (s[1] == 'h')
            {
              lenmod = LENMOD_CHAR;
              s++;
            }
          else
            lenmod = LENMOD_SHORT;
          s++;
          break;
        case 'l':
          if (s[1] == 'l')
            {
              lenmod = LENMOD_LONGLONG;
              s++;
            }
          else
            lenmod = LENMOD_LONG;
          s++;
          break;
        case 'j': lenmod = LENMOD_INTMAX; s++; break;
        case 'z': lenmod = LENMOD_SIZET; s++; break;
        case 't': lenmod = LENMOD_PTRDIFF; s++; break;
        case 'L': lenmod = LENMOD_LONGDBL; s++; break;
        default:  lenmod = LENMOD_NONE; break;
        }

      /* Parse the conversion specifier.  */
      switch (*s)
        {
        case 'd':
        case 'i': conspec = CONSPEC_DECIMAL; break;
        case 'o': conspec = CONSPEC_OCTAL; break;
        case 'u': conspec = CONSPEC_UNSIGNED; break;
        case 'x': conspec = CONSPEC_HEX; break;
        case 'X': conspec = CONSPEC_HEX_UP; break;
        case 'f': conspec = CONSPEC_FLOAT; break;
        case 'F': conspec = CONSPEC_FLOAT_UP; break;
        case 'e': conspec = CONSPEC_EXP; break;
        case 'E': conspec = CONSPEC_EXP_UP; break;
        case 'g': conspec = CONSPEC_F_OR_G; break;
        case 'G': conspec = CONSPEC_F_OR_G_UP; break;
        case 'a': conspec = CONSPEC_HEX_EXP; break;
        case 'A': conspec = CONSPEC_HEX_EXP_UP; break;
        case 'c': conspec = CONSPEC_CHAR; break;
        case 's': conspec = CONSPEC_STRING; break;
        case 'p': conspec = CONSPEC_POINTER; break;
        case 'n': conspec = CONSPEC_BYTES_SO_FAR; break;
        case 'C': conspec = CONSPEC_CHAR; lenmod = LENMOD_LONG; break;
        case 'S': conspec = CONSPEC_STRING; lenmod = LENMOD_LONG; break;
        case 'm': conspec = CONSPEC_STRERROR; arg_pos = -1; break;
        default: conspec = CONSPEC_UNKNOWN;
        }

      /* Save the args. */
      if (argcount >= max_argspecs)
        {
          /* We either need to allocate a new array instead of the
             caller provided one or realloc the array.  Instead of
             using realloc we allocate a new one and release the
             original one then. */
          size_t n, newmax;
          argspec_t newarg;

          newmax = max_argspecs + ARGSPECS_BUMP_VALUE;
          if (newmax <= max_argspecs)
            goto leave_einval;  /* Too many arguments. */
          newarg = calloc (newmax, sizeof *newarg);
          if (!newarg)
            goto leave;
          for (n=0; n < argcount; n++)
            newarg[n] = argspecs[n];
          if (argspecs != *argspecs_addr)
            free (argspecs);
          argspecs = newarg;
          max_argspecs = newmax;
        }

      arg = argspecs + argcount;
      arg->length = s - format + 2;
      arg->flags = flags;
      arg->width = width;
      arg->precision = precision;
      arg->lenmod = lenmod;
      arg->conspec = conspec;
      arg->arg_pos = arg_pos;
      arg->width_pos = width_pos;
      arg->precision_pos = precision_pos;
      compute_type (arg);
      argcount++;
      format = s;
    }

  *argspecs_addr = argspecs;
  *r_argspecs_count = argcount;
  return 0; /* Success.  */

 leave_einval:
  errno = EINVAL;
 leave:
  if (argspecs != *argspecs_addr)
    free (argspecs);
  *argspecs_addr = NULL;
  return -1;
}
示例#7
0
bool ClassContainer::read_type(UmlTypeSpec & typespec, Class ** cl, 
			       const QValueList<FormalParameterList> & tmplts,
			       QValueList<UmlTypeSpec> * actuals,
			       QCString & str_actuals, QCString s,
			       UmlClass ** first_actual_class, QCString & def,
			       QCString & genericname) {
  str_actuals = 0;
  if (actuals != 0)
    actuals->clear();
  
  if (s.isEmpty() && (s = Lex::read_word()).isEmpty()) {
    Lex::premature_eof();
    return FALSE;
  }
    
  QCString path; // type without <..>
  QCString type; // real type form
  bool internal_template = FALSE;	// true if type is ...<...>...
  int pfixdef_length = 0;		// generic form including first class
  int first_actual_class_length = 0;	// first class's name length
  
  genericname = s;
  
  for (;;) {
    internal_template = (path != type);
    
    path += s;
    type += s;
    
    s = Lex::read_word();
  
    if (s != "<")
      break;
    
    type += s;
    str_actuals = s;
    
    // read <...>
    do {
      Lex::mark();
      
      int level = 0;
      QCString firstword;	// first element in current actual
      int pfixlen = 0;		// type length including firstword
      
      for (;;) {
	s = Lex::read_word(TRUE);
	
	if (s == ",") {
	  if (level == 0)
	    break;
	}
	else if (s == ">") {
	  if (level-- == 0)
	    break;
	}
	else if (s == "]")
	  level -= 1;
	else if ((s == "<") || (s == "["))
	  level += 1;
	else if (s.isEmpty()) {
	  Lex::premature_eof();
	  return FALSE;
	}
	else if (firstword.isEmpty()) {
	  firstword = s;
	  pfixlen = type.length() + Lex::region().length();
	}
      }
      
      QCString e = Lex::region();
      
      type += e;
      str_actuals += e;

      if (actuals != 0) {
	UmlTypeSpec t;
	
	e.resize(e.length()); // remove , or >
	e = e.stripWhiteSpace();
	if (! e.isEmpty())
	  compute_type(e, t, tmplts);
	if (actuals != 0)
	  actuals->append(t);
      }
      else if ((first_actual_class != 0) &&
	       (*first_actual_class == 0) && 
	       !firstword.isEmpty()) {
	UmlTypeSpec t;
	
	compute_type(firstword, t, tmplts);
	if (t.type != 0) {
	  *first_actual_class = t.type;
	  first_actual_class_length = firstword.length();
	  pfixdef_length = pfixlen - first_actual_class_length;
	}
      }
    } while (s == ",");
    
    s = Lex::read_word();
    if (s.isEmpty() || (*s != '.'))
      break;
    str_actuals = 0;
    if (actuals != 0)
      actuals->clear();
  }
  
  if (! s.isEmpty())
    Lex::unread_word(s);
  
  compute_type(path, typespec, tmplts, cl);
  if (typespec.type != 0) {
    if (internal_template)
      // typespec.type stay unchanged
      typespec.explicit_type = type;
  }
  else if ((first_actual_class != 0) && (*first_actual_class != 0)) {
    def = type.left(pfixdef_length) + "${type}" + 
      type.mid(pfixdef_length+first_actual_class_length);
  }
  else
    // path may be not good
    typespec.explicit_type = type;
  
  return TRUE;
}