Exemplo n.º 1
0
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);
		}
	}
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
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);
	}
}
Exemplo n.º 5
0
/*
 * 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);
}
Exemplo n.º 6
0
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( ", " );
   }
}
Exemplo n.º 7
0
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( ", " );
   }
}
Exemplo n.º 8
0
/*
 * 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);
}
Exemplo n.º 9
0
/* 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);
		}
	}
}
Exemplo n.º 10
0
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);
	}
}
Exemplo n.º 11
0
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 */
	}
}
Exemplo n.º 12
0
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);
}
Exemplo n.º 13
0
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" );
   }
}
Exemplo n.º 14
0
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;
   }
}
Exemplo n.º 15
0
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;
   }
}