/* %Z%%M% %I% %E% */

/*
 * Copyright (c) 1990, 1991, 1992, 1995 by Wayne C. Gramlich.
 * All rights reserved.
 *
 * Permission to use, copy, modify, distribute, and sell this software
 * for any purpose is hereby granted without fee provided that the above
 * copyright notice and this permission are retained.  The author makes
 * no representations about the suitability of this software for any purpose.
 * It is provided "as is" without express or implied warranty.
 */

/* This file contains a routine for printing out a routine object: */

#ifndef GEN_DEFS_H
#include "gen_defs.h"
#endif

#ifndef ROUTINE_DEFS_H
#include "routine_defs.h"
#endif

#ifndef STATEMENT_EXPORTS_H
#include "statement_exports.h"
#endif

#ifndef TYPE_DEFS_H
#include "type_defs.h"
#endif

#ifndef VAR_EXPORTS_H
#include "var_exports.h"
#endif

#ifndef VECTOR_DEFS_H
#include "vector_defs.h"
#endif

/* 
 * routine_print(routine, gen)
 *	This routine will print "routine" to "gen".
 */
void
routine_print(
	Routine		routine,
	Gen		gen)
{
	Type_needs	needs;
	Stdio		out_file;
	Type_need	type_need;
	Signal		signal;
	Vec(Signal)	signals;

	out_file = gen->out_file;
	gen_out(gen, "routine %s%@ %s\n",
		routine->name, routine->type_ref,
		(routine->is_procedure) ? "procedure" : "iterator");

	if (!vec_empty(Routine_type, routine->routine_types)) {
		Routine_type	routine_type;
		Vec(Routine_type) routine_types;

		gen_out(gen, "%\troutine_type\n", 1);
		routine_types = routine->routine_types;
		VEC_LOOP(Routine_type, routine_types, routine_type) {
			gen_out(gen, "%\t%s ", 2, routine_type->name);
			type_proto_print(routine_type->type_proto,
					 3, out_file);
		}
	}
	vars_keyword_print(routine->takes, out_file, "takes");
	type_refs_keyword_print(routine->yields, out_file, "yields", 1);
	if (type_refs_is_empty(routine->returns)) {
		gen_out(gen, "%\treturns_nothing\n", 1);
	} else {
		type_refs_keyword_print(routine->returns,
					gen->out_file, "returns", 1);
	}
	signals = routine->signals;
	if (!vec_empty(Signal, signals)) {
		gen_out(gen, "%\tsignals\n", 1);
		VEC_LOOP(Signal, signals, signal) {
			gen_out(gen, "%\t%s", 2, signal->name);
			if (!type_refs_is_empty(signal->args)) {
				gen_out(gen, "(");
				type_refs_print(signal->args, out_file);
				gen_out(gen, ")");
			}
			gen_out(gen, "\n");
		}
	}
	needs = routine->needs;
	if (!type_needs_is_empty(needs)) {
		gen_out(gen, "%\tneeds\n", 1);
		VEC_LOOP(Type_need, needs, type_need) {
			type_need_print(type_need, 2, out_file);
		}
	}
	vars_keyword_print(routine->vars, out_file, "vars");
	if (routine->external == (Str)0) {
		statement_list_print(routine->statements, out_file, 1);
	} else {
		gen_out(gen, "%\texternal %s\n", 1, routine->external);
	}
	gen_out(gen, "\n");
}

