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"; } } } }
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); }