static void select_move(Node node, Symbol type_name) /*;select_move*/ { if (is_simple_type(type_name)) { if ((N_KIND(node) != as_null && is_simple_name(node) && !is_renaming(N_UNQ(node))) || (N_KIND(node) == as_selector || N_KIND(node) == as_index || N_KIND(node) == as_all)) { gen_address(node); gen_k(I_INDIRECT_MOVE, kind_of(type_name)); } else { gen_value(node); gen_k(I_MOVE, kind_of(type_name)); } } else { if (is_array_type(type_name)) { gen_value(node); gen(I_ARRAY_MOVE); } else { gen_value(node); gen_s(I_RECORD_MOVE, type_name); } } }
std::vector<gde::geom::core::line_segment> gen_segments(std::size_t num_segments, std::pair<double, double> x_interval, std::pair<double, double> y_interval, double min_length, double max_length) { // output segment list std::vector<gde::geom::core::line_segment> segments; // reserve memory for #num_segments segments.reserve(num_segments); // generates a variable of type line_segment gde::geom::core::line_segment segment; // define the points p1 and p2 of each segment for(int i = 0; i < num_segments; ++i) { // generates the first point of the segment in the interval segment.p1.x = gen_value(x_interval.first, x_interval.second - max_length); segment.p1.y = gen_value(y_interval.first, y_interval.second - max_length); // the second segment point is constrained to min_length and max_length segment.p2.x = gen_value(segment.p1.x + min_length, segment.p1.x + max_length); segment.p2.y = gen_value(segment.p1.y + min_length, segment.p1.y + max_length); segments.push_back(segment); } return segments; }
int main(int argc,char** argv) { if(argc<3) { printf("usage %s <length> <num> \n",argv[0]); exit(-1); } FILE* bash=fopen("bash.dat","w+"); FILE* python=fopen("py.dat","w+"); int num=atoi(argv[2]); int length=atoi(argv[1]); set_exe_name(" bg_expr "); srand(time(NULL)); int i=0; for(;i<num;i++) { gen_value(buf_l,length); gen_value(buf_r,length); bash_write(bash," div "); python_write(python," / "); } fclose(bash); fclose(python); return 0; }
void select_assign(Node var_node, Node expr_node, Symbol type_name) /*;select_assign*/ { Symbol var_name, expr_name; var_name = N_UNQ(var_node); expr_name = N_UNQ(expr_node); if (is_simple_type(type_name) && is_simple_name(var_node) && !is_renaming(var_name) ) { if ((is_simple_name(expr_node) && N_KIND(expr_node) != as_null && !is_renaming(expr_name)) || (N_KIND(expr_node) == as_selector || N_KIND(expr_node) == as_index || N_KIND(expr_node) == as_all)) { gen_address(expr_node); gen_ks(I_INDIRECT_POP, kind_of(type_name), var_name); } else { gen_value(expr_node); gen_ks(I_POP, kind_of(type_name), var_name); } } else { gen_address(var_node); select_move(expr_node, type_name); } }
/* * Accumulate a value to a tuple. */ void gen_integer(struct value *gen, int i) { struct value val; value_integer_set(&val, i); gen_value(gen, &val); }
void GenTree::gen_array( const ArrayDecl *ad ) { ListElement *iter = ad->begin(); while( iter != 0 ) { const Value *val = (const Value *) iter->data(); gen_value( val ); iter = iter->next(); if( iter != 0 ) m_out->writeString( ", " ); } }
void GenTree::gen_dict( const DictDecl *ad ) { if( ad->empty() ) { m_out->writeString( " =>" ); return; } ListElement *iter = ad->begin(); while( iter != 0 ) { DictDecl::pair *pair = (DictDecl::pair *) iter->data(); const Value *key = pair->first; const Value *value = pair->second; gen_value( key ); m_out->writeString( "=>" ); gen_value( value ); iter = iter->next(); if( iter != 0 ) m_out->writeString( ", " ); } }
/* * Generate a reference to a label into the tuple, for instance as the * immediate argument of a branch instruction. If the label parameter * is NULL, this will generate and return a forward reference which * should be resolved by subsequently passing it to gen_define_label(). */ void gen_gen_label_ref(struct value *gen, struct value *gen_label) { struct value *bp; struct value next; int global_pos; assert(gen_label != NULL); if (value_is_null(gen_label)) { /* Not yet allocated, so allocate a new undefined one. */ gen_label_new(gen_label); } global_pos = value_tuple_fetch_integer(gen_label, GEN_LABEL_GLOBAL_POS); if (global_pos != 0) { /* Already defined, so just use it. */ gen_integer(gen, global_pos); return; } /* * The label is newly allocated, or at least has not been defined * yet. So, we remember that we will need to backpatch here in the * future (by adding an entry to the label's backpatch list) and, * for now, generate a NULL in its slot. */ value_copy(&next, value_tuple_fetch(gen_label, GEN_LABEL_NEXT)); bp = value_tuple_fetch(gen_label, GEN_LABEL_NEXT); gen_label_new(bp); value_tuple_store(bp, GEN_LABEL_TUPLE, value_tuple_fetch(gen, GEN_CURRENT_TUPLE)); value_tuple_store(bp, GEN_LABEL_LOCAL_POS, value_tuple_fetch(gen, GEN_LOCAL_POS)); value_tuple_store(bp, GEN_LABEL_GLOBAL_POS, value_tuple_fetch(gen, GEN_GLOBAL_POS)); value_tuple_store(bp, GEN_LABEL_NEXT, &next); gen_value(gen, &VNULL); }
/* Object evaluation */ void gen_address(Node node) /*;gen_address*/ { /* * This procedure generates code for the o_expressions * or, in other words, the left-handsides. */ Node pre_node, array_node, range_node, lbd_node, ubd_node, record_node, field_node, id_node; Symbol node_name, type_name, record_name, record_type, field_name, comp_type, proc_name, return_type; int f_off, bse, off, nk; Fortup ft1; #ifdef TRACE if (debug_flag) gen_trace_node("GEN_ADDRESS", node); #endif while (N_KIND(node) == as_insert) { FORTUP(pre_node=(Node), N_LIST(node), ft1); compile(pre_node); ENDFORTUP(ft1); node = N_AST1(node); } node_name = N_UNQ(node); if (is_simple_name(node)) { type_name = get_type(node); if (is_renaming(node_name)) gen_ks(I_PUSH, mu_addr, node_name); else gen_s(I_PUSH_EFFECTIVE_ADDRESS, node_name); /* Arrays are treated in a different manner, depending on their */ /* nature: parameters, constants, variables... */ if (is_array_type(type_name)) { if (is_formal_parameter(node_name)) { type_name = assoc_symbol_get(node_name, FORMAL_TEMPLATE); } gen_s(I_PUSH_EFFECTIVE_ADDRESS, type_name); } } else { switch (nk = N_KIND(node)) { case as_raise: compile(node); break; case as_index: gen_subscript(node); break; case as_slice: array_node = N_AST1(node); range_node = N_AST2(node); /*range_name = N_UNQ(range_node); -- never used ds 7-8-85 */ /* Note: case of type simple name changed into range attribute */ /* by expander */ if (N_KIND(range_node) == as_attribute) { gen_attribute(range_node); } else { /* range */ lbd_node = N_AST1(range_node); ubd_node = N_AST2(range_node); gen_value(lbd_node); gen_value(ubd_node); } if (N_KIND(array_node) == as_attribute) { gen_attribute(array_node); } else { gen_address(array_node); } gen(I_ARRAY_SLICE); break; case as_selector: record_node = N_AST1(node); field_node = N_AST2(node); record_name = N_UNQ(record_node); record_type = get_type(record_node); field_name = N_UNQ(field_node); f_off = FIELD_OFFSET(field_name); if (f_off >= 0 && ((! has_discriminant(record_type)) || NATURE(field_name) == na_discriminant)){ if (is_simple_name(record_node) && !(is_renaming(record_name)) && is_global(record_name)) { reference_of(record_name); bse = REFERENCE_SEGMENT; off = REFERENCE_OFFSET; /* The SETL version has generate(I_PUSH_IMMEDIATE, mu_addr, * ref, field_name); * which we translate as (I_PUSH_EFFECTIVE_ADDRESS ... * ref = [bse, off+f_off]; * Replace use of explicit ref by PUSH_IMMEDIATE */ /* gen_rc(I_PUSH_IMMEDIATE, explicit_ref_new(bse, * off+f_off), ""); */ gen_kv(I_PUSH_IMMEDIATE, mu_word, int_const(bse)); gen_kv(I_PUSH_IMMEDIATE, mu_word, int_const(off+f_off)); } else { gen_address(record_node); if (f_off != 0 ) { gen_ki(I_ADD_IMMEDIATE, mu_word, f_off); } } if (is_array_type(comp_type=TYPE_OF(field_name))) { gen_s(I_PUSH_EFFECTIVE_ADDRESS, comp_type); } } else { gen_address(record_node); gen_s(I_PUSH_EFFECTIVE_ADDRESS, record_type); /* translating following assuming field_name is comment part of *-- instruction ds 7-5-86 * gen_i(I_SELECT, FIELD_NUMBER(field_name), field_name); */ gen_i(I_SELECT, (int) FIELD_NUMBER(field_name)); } break; case as_all: id_node = N_AST1(node); gen_value(id_node); if (is_array_type(N_TYPE(node))) gen_k(I_DEREF, mu_dble); break; case as_call: id_node = N_AST1(node); proc_name = N_UNQ(id_node); return_type = TYPE_OF(proc_name); gen_kc(I_DUPLICATE, kind_of(return_type), "place holder"); compile(node); /* processed from now as a procedure call */ break; case as_un_op: gen_unary(node); break; case as_op: gen_binary(node); break; case as_string_ivalue: gen_value(node); break; default: compiler_error_k("GEN_ADDRESS called with kind ", node); } } }
void gen_subscript(Node node) /*;gen_subscript*/ { Symbol comp_type; Node index_name, array_node; Node index_list_node, subscript; Tuple index_type_list, subscripts, tup; Symbol array_name, array_type; int optimized; int index, seg, offset; Fortup ft1; #ifdef TRACE if (debug_flag) gen_trace_node("GEN_SUBSCRIPT", node); #endif array_node = N_AST1(node); index_list_node = N_AST2(node); array_name = N_UNQ(array_node); array_type = get_type(array_node); tup = SIGNATURE(array_type); index_type_list = (Tuple) tup[1]; comp_type = (Symbol) tup[2]; /* need tup_copy since subscripts used in tup_fromb below */ subscripts = tup_copy(N_LIST(index_list_node)); /* * Before applying the brute force method of the 'do-it-all' instruction * "subscript", which can solve any case, some optimizations will be * attempted. * * First, we try to compute the address of the indexed element directly, * when subscripts are immediate values and the index check can be done * at compile time: */ if ((Symbol)index_type_list[1] == symbol_none) { optimized = FALSE; } else if (!(is_unconstrained(array_type))) { index = compute_index(subscripts, index_type_list); optimized = index != -1; if (optimized) { if (has_static_size(comp_type)) { index = index * size_of(comp_type); if (is_simple_name(array_node) && !is_renaming(array_name) ) { if (is_global(array_name)) { reference_of(array_name); seg = REFERENCE_SEGMENT; offset = REFERENCE_OFFSET; /*gen_todo(I_PUSH_EFFECTIVE_ADDRESS,[seg, offset+index], * array_name + '(" + str(get_ivalue(subscripts(1))) * +/ [', '+str(get_ivalue(subscripts(i))): * i in [2..#subscripts] ] * + ")' ); */ gen_rc(I_PUSH_EFFECTIVE_ADDRESS, explicit_ref_new(seg, offset+index), ""); } else { gen_s(I_PUSH_EFFECTIVE_ADDRESS, array_name); if (index != 0) gen_kic(I_ADD_IMMEDIATE, mu_word, index, "offset"); } } else { gen_address(array_node); gen_ks(I_DISCARD_ADDR, 1, array_type); if (index != 0) gen_ki(I_ADD_IMMEDIATE, mu_word, index); } } else { optimized = FALSE; } } } else { optimized = FALSE; } /* * Nothing worked, we are left with the worse case, solved by the * "subscript" instruction */ if (!optimized) { FORTUP( index_name=(Node), index_type_list, ft1); subscript = (Node) tup_fromb(subscripts); gen_value(subscript) ; ENDFORTUP(ft1); gen_address(array_node); gen(I_SUBSCRIPT); } if (is_array_type(comp_type)) { gen_s(I_PUSH_EFFECTIVE_ADDRESS, comp_type); } }
void gen_loop(Node node) /*;gen_loop*/ { /* Generate loop stratements */ Node id_node, iter_node, stmt_node, while_cond_node, var_node, exp1_node, exp2_node; Symbol label_name, start_loop, start_while, end_while, var_name, end_for, for_body, for_start, void_loop; int end_inst; int kind_var; int needs_check; Const val1, val2; #ifdef TRACE if (debug_flag) gen_trace_node("GEN_LOOP", node); #endif id_node = N_AST1(node); iter_node = N_AST2(node); stmt_node = N_AST3(node); if (id_node != OPT_NODE) { label_name = N_UNQ(id_node); labelmap_put(label_name, LABEL_STATIC_DEPTH, (char *) CURRENT_LEVEL); next_local_reference(label_name); gen_s(I_SAVE_STACK_POINTER, label_name); } if (iter_node == OPT_NODE) { /* simple loop */ start_loop = new_unique_name("loop"); gen_s(I_LABEL, start_loop); compile(stmt_node); gen_s(I_JUMP, start_loop ); if (id_node != OPT_NODE) gen_s(I_LABEL, label_name); } else if (N_KIND(iter_node) == as_while) { /* while loop */ while_cond_node = N_AST1(iter_node); start_while = new_unique_name("start_while"); end_while = new_unique_name("end_while"); gen_sc(I_JUMP, end_while, "Test better at end of loop"); gen_s(I_LABEL, start_while); compile(stmt_node); gen_s(I_LABEL, end_while); gen_condition(while_cond_node, start_while, TRUE); if (id_node != OPT_NODE) gen_s(I_LABEL, label_name); } else { /* for loop */ var_node = N_AST1(iter_node); exp1_node = N_AST2(iter_node); exp2_node = N_AST3(iter_node); var_name = N_UNQ(var_node); next_local_reference(var_name); kind_var = kind_of(TYPE_OF(var_name)); val1 = get_ivalue(exp1_node); val2 = get_ivalue(exp2_node); end_inst = ((N_KIND(iter_node) == as_for)) ? I_END_FOR_LOOP : I_END_FORREV_LOOP; /* Static null range already checked by expander */ if (val1->const_kind != CONST_OM && val2->const_kind != CONST_OM && get_ivalue_int(exp1_node) == get_ivalue_int(exp2_node)) { /* Loop executed only once, remove loop */ gen_value(exp1_node); gen_k(I_CREATE_COPY, kind_var); gen_s(I_UPDATE_AND_DISCARD, var_name); compile(stmt_node); if (id_node != OPT_NODE) gen_s(I_LABEL, label_name); gen_s(I_PUSH_EFFECTIVE_ADDRESS, var_name); gen(I_UNCREATE); } else { needs_check = (val1->const_kind == CONST_OM || val2->const_kind == CONST_OM ); if (N_KIND(iter_node) == as_for) { gen_value(exp2_node); if (needs_check) { gen_k(I_DUPLICATE, kind_var); } gen_value(exp1_node); if (needs_check) { gen_k(I_DUPLICATE, kind_var); } } else { gen_value(exp1_node); if (needs_check) { gen_k(I_DUPLICATE, kind_var); } gen_value(exp2_node); if (needs_check) { gen_k(I_DUPLICATE, kind_var); } } for_start = new_unique_name("for_start"); for_body = new_unique_name("for_body"); end_for = new_unique_name("end_for"); if (needs_check) { void_loop = new_unique_name("void"); gen_k(I_CREATE_COPY, kind_var); gen_s(I_UPDATE_AND_DISCARD, var_name); gen_k(I_COMPARE, kind_var); if (N_KIND(iter_node) == as_for) { gen_s(I_JUMP_IF_GREATER_OR_EQUAL, for_start); } else { gen_s(I_JUMP_IF_LESS_OR_EQUAL, for_start); } gen_ks(I_POP, kind_var, var_name); gen_s(I_JUMP, void_loop); gen_s(I_LABEL, for_start); gen_s(I_PUSH_EFFECTIVE_ADDRESS, var_name); } else { /* loop executed at least once, no need for check */ gen_k(I_CREATE_COPY, kind_var); gen_s(I_UPDATE, var_name); } gen_s(I_LABEL, for_body); compile(stmt_node); gen_s(I_LABEL, end_for); gen_ks(end_inst, kind_var, for_body ); if (id_node != OPT_NODE) { gen_s(I_LABEL, label_name); } if (needs_check) { gen_s(I_LABEL, void_loop); } gen_s(I_PUSH_EFFECTIVE_ADDRESS, var_name); gen(I_UNCREATE); } /* static null loop */ } }
void gen_condition(Node node, Symbol destination, int branch_cond) /*;gen_condition*/ { /* IMPORTANT WARNING: destination is where to go when expression is * equal to branch_cond */ /* These maps are realized in procedures immediately following. * const * jump_false_code = { * ['=', I_JUMP_IF_FALSE], * ['!=', I_JUMP_IF_TRUE], * ['<', I_JUMP_IF_GREATER_OR_EQUAL], * ['>', I_JUMP_IF_LESS_OR_EQUAL], * ['<=', I_JUMP_IF_GREATER], * ['>=', I_JUMP_IF_LESS] }, * * jump_true_code = { * ['=', I_JUMP_IF_TRUE], * ['<', I_JUMP_IF_LESS], * ['>', I_JUMP_IF_GREATER], * ['<=', I_JUMP_IF_LESS_OR_EQUAL], * ['>=', I_JUMP_IF_GREATER_OR_EQUAL] }; */ Tuple tup; Node opnode, args, op1, op2; Symbol opcode, optype; #ifdef TRACE if (debug_flag) gen_trace_node("GEN_CONDITION", node); #endif if (N_KIND(node) == as_op) { opnode = N_AST1(node); args = N_AST2(node); opcode = N_UNQ(opnode); if (opcode == symbol_eq || opcode == symbol_ne || opcode == symbol_lt || opcode == symbol_gt || opcode == symbol_le || opcode == symbol_ge){ tup = N_LIST(args); op1 = (Node) tup[1]; op2 = (Node) tup[2]; gen_value(op1); gen_value(op2); optype = get_type(op1); if (is_simple_type(optype)) { if (is_float_type(optype)) gen_k(I_FLOAT_COMPARE, kind_of(optype)); else gen_k(I_COMPARE, kind_of(optype)); } else { if (is_record_type(optype)) { gen_s(I_PUSH_EFFECTIVE_ADDRESS, optype); } if (is_array_type(optype) && (opcode != symbol_eq) && (opcode != symbol_ne)) { gen(I_COMPARE_ARRAYS); } else { gen(I_COMPARE_STRUC); } } } else { gen_value(node); opcode = symbol_eq; } } else { gen_value(node); opcode = symbol_eq; } if (branch_cond) gen_s(jump_true_code(opcode), destination); else gen_s(jump_false_code(opcode), destination); }
void GenTree::generate( const Statement *cmp, const char *specifier, bool sameline, int depth ) { if ( ! sameline ) { String line; line.writeNumber( (int64) cmp->line() ); int pos = 0; while (pos + line.length() < 5 ) { pos ++; m_out->writeString( " " ); } m_out->writeString( line + " : " ); for (int i = 0; i < depth; i++ ) m_out->writeString( " " ); } if ( specifier != 0 ) { m_out->writeString( specifier ); m_out->writeString( " " ); } switch( cmp->type() ) { case Statement::t_none: m_out->writeString( "(placeholder none statement)\n" ); break; case Statement::t_break: m_out->writeString( "BREAK\n" ); break; case Statement::t_continue: m_out->writeString( "CONTINUE" ); if( static_cast< const StmtContinue *>( cmp )->dropping() ) m_out->writeString( " DROPPING" ); m_out->writeString( "\n" ); break; case Statement::t_launch: m_out->writeString( "LAUNCH " ); gen_value( static_cast< const StmtExpression *>( cmp )->value() ); m_out->writeString( "\n" ); break; case Statement::t_autoexp: m_out->writeString( "AUTOEXPR " ); gen_value( static_cast< const StmtExpression *>( cmp )->value() ); m_out->writeString( "\n" ); break; case Statement::t_return: m_out->writeString( "RETURN " ); gen_value( static_cast< const StmtExpression *>( cmp )->value() ); m_out->writeString( "\n" ); break; case Statement::t_fordot: m_out->writeString( "FORDOT " ); gen_value( static_cast< const StmtExpression *>( cmp )->value() ); m_out->writeString( "\n" ); break; case Statement::t_raise: m_out->writeString( "RAISE " ); gen_value( static_cast< const StmtExpression *>( cmp )->value() ); m_out->writeString( "\n" ); break; case Statement::t_give: { const StmtGive *give = static_cast< const StmtGive *>( cmp ); m_out->writeString( "GIVE " ); gen_array( give->attributes() ); m_out->writeString( " to " ); gen_array( give->objects() ); m_out->writeString( "\n" ); } break; case Statement::t_self_print: { const StmtSelfPrint *sp = static_cast< const StmtSelfPrint *>( cmp ); m_out->writeString( "FAST PRINT " ); gen_array( sp->toPrint() ); m_out->writeString( "\n" ); } break; case Statement::t_if: { m_out->writeString( "IF " ); const StmtIf *sif = static_cast< const StmtIf *>( cmp ); gen_value( sif->condition() ); m_out->writeString( "\n" ); gen_block( sif->children(), depth ); const Statement *stmt = sif->elifChildren().front(); while( stmt != 0 ) { generate( stmt, 0, false, depth + 1 ); stmt = static_cast<const Statement *>(stmt->next()); } gen_block( sif->elseChildren(), depth, "ELSE" ); } break; case Statement::t_select: case Statement::t_switch: { if ( cmp->type() == Statement::t_switch ) m_out->writeString( "SWITCH " ); else m_out->writeString( "SELECT " ); const StmtSwitch *sw = static_cast< const StmtSwitch *>( cmp ); gen_value( sw->switchItem() ); m_out->writeString( "\n" ); // generates the switch lists MapIterator iter; // generatest the switch integer list if ( !sw->intCases().empty() ) { m_out->writeString( "INT cases " ); iter = sw->intCases().begin(); while( iter.hasCurrent() ) { Value *first = *(Value **) iter.currentKey(); uint32 second = *(uint32 *) iter.currentValue(); String temp; temp.writeNumber( (int64) second ); gen_value( first ); m_out->writeString( "->" + temp + "; " ); iter.next(); } m_out->writeString( "\n" ); } if ( !sw->rngCases().empty() ) { m_out->writeString( "RANGE cases " ); iter = sw->rngCases().begin(); while( iter.hasCurrent() ) { Value *first = *(Value **) iter.currentKey(); uint32 second = *(uint32 *) iter.currentValue(); String temp; temp.writeNumber( (int64) second ); gen_value( first ); m_out->writeString( "->" + temp + "; " ); iter.next(); } m_out->writeString( "\n" ); } if ( !sw->strCases().empty() ) { m_out->writeString( "STRING cases " ); iter = sw->strCases().begin(); while( iter.hasCurrent() ) { Value *first = *(Value **) iter.currentKey(); uint32 second = *(uint32 *) iter.currentValue(); String temp; temp.writeNumber( (int64) second ); gen_value( first ); m_out->writeString( "->" + temp + "; " ); iter.next(); } m_out->writeString( "\n" ); } if ( !sw->objCases().empty() ) { m_out->writeString( "Symbol cases " ); iter = sw->objCases().begin(); while( iter.hasCurrent() ) { Value *first = *(Value **) iter.currentKey(); uint32 second = *(uint32 *) iter.currentValue(); String temp; temp.writeNumber( (int64) second ); gen_value( first ); m_out->writeString( "->" + temp + "; " ); iter.next(); } m_out->writeString( "\n" ); } // generates the blocks int blockId = 0; const Statement *stmt = sw->blocks().front(); while( stmt != 0 ) { String blockStr; blockStr.writeNumber( (int64) blockId ); if( blockId == sw->nilBlock() ) m_out->writeString( "CASE BLOCK (NIL)" + blockStr + "\n" ); else m_out->writeString( "CASE BLOCK " + blockStr + "\n" ); generate( stmt, 0, false, depth + 1 ); stmt = static_cast<const Statement *>(stmt->next()); blockId ++ ; } if ( ! sw->defaultBlock().empty() ) { m_out->writeString( "DEFAULT BLOCK\n" ); gen_block( sw->defaultBlock(), depth + 1 ); } } break; case Statement::t_case: { //m_out->writeString( "CASE \n" ); const StmtCaseBlock *scase = static_cast< const StmtCaseBlock *>( cmp ); gen_block( scase->children(), depth ); } break; case Statement::t_catch: { //m_out->writeString( "CASE \n" ); const StmtCatchBlock *scase = static_cast< const StmtCatchBlock *>( cmp ); if ( scase->intoValue() != 0 ) { m_out->writeString( "CATCH into " ); gen_value( scase->intoValue() ); m_out->writeString( "\n" ); } else m_out->writeString( "CATCH witout into\n" ); gen_block( scase->children(), depth ); } break; case Statement::t_elif: { m_out->writeString( "ELIF " ); const StmtElif *selif = static_cast< const StmtElif *>( cmp ); gen_value( selif->condition() ); m_out->writeString( "\n" ); gen_block( selif->children(), depth ); } break; case Statement::t_while: { const StmtWhile *wh = static_cast< const StmtWhile *>( cmp ); m_out->writeString( "WHILE " ); gen_value( wh->condition() ); m_out->writeString( "\n" ); gen_block( wh->children(), depth ); } break; case Statement::t_loop: { const StmtLoop *wh = static_cast< const StmtLoop *>( cmp ); m_out->writeString( "LOOP " ); m_out->writeString( "\n" ); gen_block( wh->children(), depth ); if( wh->condition() != 0 ) { m_out->writeString( "END LOOP WHEN " ); gen_value( wh->condition() ); m_out->writeString( "\n" ); } else m_out->writeString( "END\n" ); } break; case Statement::t_global: { m_out->writeString( "GLOBAL " ); const StmtGlobal *sglobal = static_cast< const StmtGlobal *>( cmp ); ListElement *iter = sglobal->getSymbols().begin(); while ( iter != 0 ) { Symbol *sym = (Symbol *) iter->data(); m_out->writeString( sym->name() + ", " ); iter = iter->next(); } m_out->writeString( "\n" ); } break; case Statement::t_forin: { m_out->writeString( "FOR-IN " ); const StmtForin *sfor = static_cast< const StmtForin *>( cmp ); gen_array( sfor->dest() ); m_out->writeString( " IN " ); gen_value( sfor->source() ); m_out->writeString( "\n" ); gen_block( sfor->children(), depth ); gen_block( sfor->firstBlock(), depth, "FORFIRST" ); gen_block( sfor->middleBlock(), depth, "FORMIDDLE" ); gen_block( sfor->lastBlock(), depth, "FORLAST" ); } break; case Statement::t_try: { m_out->writeString( "TRY\n" ); const StmtTry *stry = static_cast< const StmtTry *>( cmp ); gen_block( stry->children(), depth ); // generatest the switch integer list if ( ! stry->intCases().empty() ) { m_out->writeString( "TYPE ID CATCHES " ); MapIterator iter = stry->intCases().begin(); while( iter.hasCurrent() ) { Value *first = *(Value **) iter.currentKey(); uint32 second = *(uint32 *) iter.currentValue(); String temp; temp.writeNumber( (int64) second ); gen_value( first ); m_out->writeString( "->" + temp + "; " ); iter.next(); } m_out->writeString( "\n" ); } // Generates the switch symbol list if ( ! stry->objCases().empty() ) { m_out->writeString( "SYMBOL CATCHES " ); MapIterator iter = stry->objCases().begin(); while( iter.hasCurrent() ) { Value *first = *(Value **) iter.currentKey(); uint32 second = *(uint32 *) iter.currentValue(); String temp; temp.writeNumber( (int64) second ); gen_value( first ); m_out->writeString( "->" + temp + "; " ); iter.next(); } m_out->writeString( "\n" ); } // generates the blocks int blockId = 0; const Statement *stmt = stry->handlers().front(); while( stmt != 0 ) { String blockStr; blockStr.writeNumber( (int64) blockId ); m_out->writeString( "HANDLER BLOCK " + blockStr + "\n" ); generate( stmt, 0, false, depth + 1 ); stmt = static_cast<const Statement *>( stmt->next() ); blockId ++ ; } if ( stry->defaultHandler() != 0 ) { m_out->writeString( "DEFAULT HANDLER" ); if ( stry->defaultHandler()->intoValue() != 0 ) { m_out->writeString( " into " ); gen_value( stry->defaultHandler()->intoValue() ); } m_out->writeString( "\n" ); gen_block( stry->defaultHandler()->children(), depth + 1 ); } } break; case Statement::t_propdef: { m_out->writeString( "PROPDEF " ); const StmtVarDef *spd = static_cast< const StmtVarDef *>( cmp ); m_out->writeString( *spd->name() ); m_out->writeString( "=" ); gen_value( spd->value() ); m_out->writeString( "\n" ); } break; default: m_out->writeString( "????\n" ); } }
void GenTree::gen_expression( const Expression *exp ) { String name; int type = 0; switch( exp->type() ) { case Expression::t_optimized: gen_value( exp->first() ); return; case Expression::t_neg: type = 0; name = "-"; break; case Expression::t_bin_not: type = 0; name = "!"; break; case Expression::t_strexpand: type = 0; name = "@"; break; case Expression::t_indirect: type = 0; name = "#"; break; case Expression::t_not: type = 0; name = "not"; break; case Expression::t_pre_inc: type = 0; name = "++"; break; case Expression::t_pre_dec: type = 0; name = "--"; break; case Expression::t_eval: type = 0; name = "^*"; break; case Expression::t_oob: type = 0; name = "^+"; break; case Expression::t_deoob: type = 0; name = "^-"; break; case Expression::t_isoob: type = 0; name = "^?"; break; case Expression::t_xoroob: type = 0; name = "^!"; break; case Expression::t_post_inc: type = 1; name = "++"; break; case Expression::t_post_dec: type = 1; name = "--"; break; case Expression::t_bin_and: type = 2; name = "&"; break; case Expression::t_bin_or: type = 2; name = "|"; break; case Expression::t_bin_xor: type = 2; name = "^"; break; case Expression::t_shift_left: type = 2; name = "<<"; break; case Expression::t_shift_right: type = 2; name = ">>"; break; case Expression::t_plus: type = 2; name = "+"; break; case Expression::t_minus: type = 2; name = "-"; break; case Expression::t_times: type = 2; name = "*"; break; case Expression::t_divide: type = 2; name = "/"; break; case Expression::t_modulo: type = 2; name = "%"; break; case Expression::t_power: type = 2; name = "**"; break; case Expression::t_gt: type = 2; name = ">"; break; case Expression::t_ge: type = 2; name = ">="; break; case Expression::t_lt: type = 2; name = "<"; break; case Expression::t_le: type = 2; name = "<="; break; case Expression::t_eq: type = 2; name = "="; break; case Expression::t_exeq: type = 2; name = "eq"; break; case Expression::t_neq: type = 2; name = "!="; break; case Expression::t_has: type = 2; name = "has"; break; case Expression::t_hasnt: type = 2; name = "hasnt"; break; case Expression::t_in: type = 2; name = "in"; break; case Expression::t_notin: type = 2; name = "notin"; break; case Expression::t_provides: type = 2; name = "provides"; break; case Expression::t_or: type = 2; name = "or"; break; case Expression::t_and: type = 2; name = "and"; break; case Expression::t_iif: type = 3; break; case Expression::t_assign: type = 4; name = " = "; break; case Expression::t_fbind: type = 4; name = " | "; break; case Expression::t_aadd: type = 4; name = " += "; break; case Expression::t_asub: type = 4; name = " -= "; break; case Expression::t_amul: type = 4; name = " *= "; break; case Expression::t_adiv: type = 4; name = " /= "; break; case Expression::t_amod: type = 4; name = " %= "; break; case Expression::t_apow: type = 4; name = " *= "; break; case Expression::t_aband: type = 4; name = " &= "; break; case Expression::t_abor: type = 4; name = " |= "; break; case Expression::t_abxor: type = 4; name = " ^= "; break; case Expression::t_ashl: type = 4; name = " <<= "; break; case Expression::t_ashr: type = 4; name = " >>= "; break; case Expression::t_array_access: type = 5; break; case Expression::t_array_byte_access: type = 10; break; case Expression::t_obj_access: type = 6; break; case Expression::t_funcall: case Expression::t_inherit: type = 7; break; case Expression::t_lambda: type = 8; break; default: return; } switch( type ) { case 0: m_out->writeString( " " + name + " " ); gen_value( exp->first() ); break; case 1: gen_value( exp->first() ); m_out->writeString( " " + name + " " ); break; case 2: m_out->writeString( "(" ); gen_value( exp->first() ); m_out->writeString( " " + name + " " ); gen_value( exp->second() ); m_out->writeString( " )" ); break; case 3: m_out->writeString( "(" ); gen_value( exp->first() ); m_out->writeString( " ? (" ); gen_value( exp->second() ); m_out->writeString( " ):(" ); gen_value( exp->third() ); m_out->writeString( " ))" ); break; case 4: m_out->writeString( "( " ); gen_value( exp->first() ); m_out->writeString( name ); gen_value( exp->second() ); m_out->writeString( " )" ); break; case 5: gen_value( exp->first() ); m_out->writeString( "[ " ); gen_value( exp->second() ); m_out->writeString( " ]" ); break; case 6: gen_value( exp->first() ); m_out->writeString( "." ); gen_value( exp->second() ); break; case 7: gen_value( exp->first() ); m_out->writeString( "(" ); if( exp->second() != 0 ) gen_array( exp->second()->asArray() ); m_out->writeString( " )" ); break; case 8: m_out->writeString( exp->first()->asSymbol()->name() ); if( exp->second() != 0 ) { m_out->writeString( " closure (" ); gen_array( exp->second()->asArray() ); m_out->writeString( " )" ); } break; case 10: gen_value( exp->first() ); m_out->writeString( "[ *" ); gen_value( exp->second() ); m_out->writeString( " ]" ); break; } }
void GenTree::gen_value( const Value *val ) { if ( val == 0 ) { m_out->writeString( "(null)" ); return; } switch( val->type() ) { case Value::t_nil: m_out->writeString( "nil" ); break; case Value::t_unbound: m_out->writeString( "unbound" ); break; case Value::t_imm_bool: m_out->writeString( val->asBool() ? "true": "false" ); break; case Value::t_imm_integer: { String intStr; intStr.writeNumber( val->asInteger() ); m_out->writeString( intStr ); } break; case Value::t_imm_string: { String temp; val->asString()->escape( temp ); m_out->writeString( "\"" + temp + "\"" ); } break; case Value::t_lbind: { m_out->writeString( "&" + *val->asLBind() ); } break; case Value::t_imm_num: { String numStr; numStr.writeNumber( val->asInteger() ); m_out->writeString( numStr ); } break; case Value::t_range_decl: m_out->writeString( "[" ); gen_value( val->asRange()->rangeStart() ); m_out->writeString( ":" ); if ( ! val->asRange()->isOpen() ) { gen_value( val->asRange()->rangeEnd() ) ; if ( val->asRange()->rangeStep() != 0 ) { m_out->writeString( ":" ); gen_value( val->asRange()->rangeStep() ); } } m_out->writeString( "]" ); break; case Value::t_symbol: m_out->writeString( val->asSymbol()->name() ); break; case Value::t_self: m_out->writeString( "self" ); break; case Value::t_fself: m_out->writeString( "fself" ); break; case Value::t_array_decl: m_out->writeString( "Array: [ " ); gen_array( val->asArray() ); m_out->writeString( " ]" ); break; case Value::t_dict_decl: m_out->writeString( "Dict: [" ); gen_dict( val->asDict() ); m_out->writeString( " ]" ); break; case Value::t_byref: m_out->writeString( "$" ); gen_value( val->asReference() ); break; case Value::t_expression: gen_expression( val->asExpr() ); break; default: break; } }