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

/*
 * Copyright (c) 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.
 */

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

#ifndef HEAP_EXPORTS_H
#include "heap_exports.h"
#endif

#ifndef LINT_H
#include "lint.h"
#endif

#ifndef MSG_EXPORTS_H
#include "msg_exports.h"
#endif

#ifndef OUT_EXPORTS_H
#include "out_exports.h"
#endif

#ifndef PARSER_DEFS_H
#include "parser_defs.h"
#endif

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

#ifndef TABLE_EXPORTS_H
#include "table_exports.h"
#endif

#ifndef TOKEN_DEFS_H
#include "token_defs.h"
#endif

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

#ifndef UNIX_ASSERT_H
#include "unix_assert.h"
#endif

#ifndef VAR_DEFS_H
#include "var_defs.h"
#endif

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

LOCAL void		vars_print(Vars, Stdio, int);

/*
 * var routines:
 */

/*
 * var_parse(parser)
 *	This routine will parse and return a variable definition.
 */
Var
var_parse(
	Parser		parser)
{
	Token		token;
	Var		var;

	var = heap_allocate(parser->heap, Var);
	token = parser_symbol_parse(parser);
	var->position = token->position;
	var->name = token->value.symbol;
	var->type_ref = type_ref_parse(parser);
	var->comment = parser_eol_read(parser);
	return var;
}

/*
 * var_print(var, out_file, indent)
 *	This routine will print "var" to "out_file" indented by "indent".
 */
void
var_print(
	Var		var,
	Stdio		out_file,
	int		indent)
{
	out(out_file, "%\t%s %r\n", indent, var->name, var->type_ref);
}

/*
 * Vars routines:
 */

/* 
 * vars_keyword_print(vars, out_file, keyword)
 *	This routine will print each variable in "vars" to "out_file" preceeded
 *	by "keyword".
 */
void
vars_keyword_print(
	Vars		vars,
	Stdio		out_file,
	Str		keyword)
{
	if (!vec_empty(Var, vars)) {
		out(out_file, "%\t%s\n", 1, keyword);
		vars_print(vars, out_file, 2);
	}
}

/*
 * vars_parse(parser, routine)
 *	This routine will parse and return an indented list of varaibles.
 */
Vars
vars_parse(
	Parser		parser,
	Routine		routine)
{
	Var		var;
	Var_table	var_table;
	Vars		vars;

	vars = (Vars)parser_indented_list_parse(parser,
						(Parser_routine)var_parse,
						"Empty variable list");
	var_table = routine->var_table;
	VEC_LOOP(Var, vars, var) {
		if (table_insert(Str, Var, var_table, var->name, var)) {
			msg_out(parser->msg, var->position,
				"Duplicate argument/variable");
		}
	}
	return vars;
}

/* 
 * vars_print(vars, out_file, indent)
 *	This routine will print each variable in "vars" to "out_file"
 *	indentd by "indent".
 */
LOCAL void
vars_print(
	Vars		vars,
	Stdio		out_file,
	int		indent)
{
	Var		var;

	VEC_LOOP(Var, vars, var) {
		var_print(var, out_file, indent);
	}
}

/*
 * vars_to_type_refs(vars, type_tables)
 *	This routine will return the type reference list associated with "vars"
 *	allocated using "type_tables".
 */
Type_refs
vars_to_type_refs(
	Vars		vars,
	Type_tables	type_tables)
{
	Type_refs	type_refs;
	Var		var;

	type_refs = type_refs_empty_create(type_tables);
	VEC_LOOP(Var, vars, var) {
		type_refs = type_refs_append(type_refs, var->type_ref,
					     type_tables);
	}
	return type_refs;
}

