示例#1
0
void Canonicalizer::do_ArrayLength    (ArrayLength*     x) {
  NewArray* array = x->array()->as_NewArray();
  if (array != NULL && array->length() != NULL) {
    Constant* length = array->length()->as_Constant();
    if (length != NULL) {
      // do not use the Constant itself, but create a new Constant
      // with same value Otherwise a Constant is live over multiple
      // blocks without being registered in a state array.
      assert(length->type()->as_IntConstant() != NULL, "array length must be integer");
      set_constant(length->type()->as_IntConstant()->value());
    }
  } else {
    LoadField* lf = x->array()->as_LoadField();
    if (lf != NULL) {
      ciField* field = lf->field();
      if (field->is_constant() && field->is_static()) {
        // final static field
        ciObject* c = field->constant_value().as_object();
        if (c->is_array()) {
          ciArray* array = (ciArray*) c;
          set_constant(array->length());
        }
      }
    }
  }
}
// This piece of code expands all the \newcolumntype commands
// There is a special case: nct_size=0,  case where nothing is 
// defined, and nothing has to be done. Otherwise, we loop over all
// characters. If there is one substitution, we try again.
// If for some reason, the character is invalid, we remove it from the table.
void token_ns::expand_nct(TokenList&L)
{
  bool action = true;
  if(the_parser.tracing_commands())
    the_log << lg_start << "array preamble at start: " << L << "\n";
  if(!new_array_object.has_a_nct()) return;
  int max_iter = max_newcolumn_loops;
  while(action) {
    action = false;
    max_iter--;
    if(max_iter<=0) {
      the_parser.parse_error("array preamble expansion: Infinite loop?");
      return;
    }
    for(int i=1;i<int(nb_newcolumn);i++) {
      uchar c = i;
      if(!new_array_object.nct_exists(c)) continue;
      Token T = new_array_object.nct_token(c);
      int n = the_parser.nct_aux(T);
      if(n==-1) {
	new_array_object.remove_a_type(c);
	continue;
      }
      if(expand_nct(L,T,n,c,max_iter)) {
	action = true;
	if(the_parser.tracing_commands())
	  the_log << "array preamble after " << c << ": " << L << "\n";
      }
    }
  }
}
示例#3
0
void Canonicalizer::do_ArrayLength    (ArrayLength*     x) {
  NewArray*  na;
  Constant*  ct;
  LoadField* lf;

  if ((na = x->array()->as_NewArray()) != NULL) {
    // New arrays might have the known length.
    // Do not use the Constant itself, but create a new Constant
    // with same value Otherwise a Constant is live over multiple
    // blocks without being registered in a state array.
    Constant* length;
    if (na->length() != NULL &&
        (length = na->length()->as_Constant()) != NULL) {
      assert(length->type()->as_IntConstant() != NULL, "array length must be integer");
      set_constant(length->type()->as_IntConstant()->value());
    }

  } else if ((ct = x->array()->as_Constant()) != NULL) {
    // Constant arrays have constant lengths.
    ArrayConstant* cnst = ct->type()->as_ArrayConstant();
    if (cnst != NULL) {
      set_constant(cnst->value()->length());
    }

  } else if ((lf = x->array()->as_LoadField()) != NULL) {
    ciField* field = lf->field();
    if (field->is_static_constant()) {
      assert(PatchALot || ScavengeRootsInCode < 2, "Constant field loads are folded during parsing");
      ciObject* c = field->constant_value().as_object();
      if (!c->is_null_object()) {
        set_constant(c->as_array()->length());
      }
    }
  }
}
void Canonicalizer::do_ArrayLength    (ArrayLength*     x) {
  NewArray* array = x->array()->as_NewArray();
  if (array != NULL && array->length() != NULL) {
    Constant* length = array->length()->as_Constant();
    if (length != NULL) {
      set_canonical(length);
    }
  }
}
// This is \begin{tabular}. Should be in an environment (not necessarily)
void Parser::T_start_tabular (subtypes c)
{
  Istring x = the_names[c==zero_code ? np_tabular : np_tabular_star];
  if(the_stack.is_float())
    leave_v_mode();
  else if(the_stack.is_frame(np_fbox)) {}
  else
    leave_h_mode();
  hash_table.eval_let_local("par","@empty");
  the_stack.push1(x,np_table);
  the_stack.add_att_to_last(np_rend,np_inline);
  Xid id = the_stack.get_xid();
  if(c!=0) { // case of tabular*
    Token T = cur_tok;
    TokenList L = mac_arg();
    ScaledInt tab_width = dimen_from_list(T,L);
    if(!tab_width.null())
      id.add_attribute(the_names[np_tab_width],the_main->SH.find_scaled(tab_width));
    get_token();  // eat the relax
    if(!cur_cmd_chr.is_relax()) back_input();
  }
  {
    int pos = get_ctb_opt(false); // Lamport does not mention c, who cares
    if(pos) id.add_attribute(the_names[np_vpos], the_names[pos]);
  }
  new_array_object.run(id,true);
  the_stack.set_array_mode(); // Is the mode ok ?
  start_a_row(-1);
}
// Implements \newcolumntype{C}[opt]{body}
// as \newcommand\cmd[opt]{body}
// Here \cmd is some internal name, stored in nct_tok[C]
void Parser::T_newcolumn_type()
{
  TokenList L = mac_arg();
  uint c = 0; 
  if(L.empty()) parse_error("Empty argument to \\newcolumntype");
  else if(L.size() != 1)
    parse_error("More than one token in argument to \\newcolumntype");
  else {
    if(L.front().is_a_char())
      c = L.front().char_val().get_value();
    if(!(c>0 && c<nb_newcolumn)) {
      parse_error("Argument to \\newcolumntype is not a 7bit character");
      c= 0;
    }
  }
  Buffer& B = hash_table.my_buffer();
  B.reset();
  B.push_back("newcolumtype@");
  B.push_back(uchar(c)); // special hack if c=0 !
  cur_tok = hash_table.locate(B);
  new_array_object.add_a_type(c,cur_tok);
  back_input();
  get_new_command(rd_always,false); // definition is local
}
// If started is true, we have already started one
void Parser::start_a_cell(bool started)
{
  if(!started) {
    the_stack.push_pop_cell(push_only);
    push_level(bt_cell);
  }
  remove_initial_space_and_back_input();
  symcodes S = cur_cmd_chr.get_cmd();
  if(S==unimp_cmd && cur_cmd_chr.get_chr()==omit_code) {
    get_token();
    the_stack.mark_omit_cell();
  } else if(S==end_cmd) { // has to be \end{tabular}
    the_stack.mark_omit_cell();
  } else if(S==multicolumn_cmd) {
    the_stack.mark_omit_cell();
    get_token();
    unprocessed_xml.remove_last_space();
    Xid cid = the_stack.get_top_id();
    new_array_object.run(cid,false);
  } else {
    TokenList L= the_stack.get_u_or_v(true);
    back_input(L);
  }
}
void Parser::boot_NAO()
{
  new_array_object.boot(this);
}