// $Id: Scope.h,v 1.16 2003/09/01 23:43:03 vern Exp $
//
// Copyright (c) 1995, 1996, 1997, 1998, 1999, 2001, 2002
//      The Regents of the University of California.  All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that: (1) source code distributions
// retain the above copyright notice and this paragraph in its entirety, (2)
// distributions including binary code include the above copyright notice and
// this paragraph in its entirety in the documentation or other materials
// provided with the distribution, and (3) all advertising materials mentioning
// features or use of this software display the following acknowledgement:
// ``This product includes software developed by the University of California,
// Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
// the University nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

#ifndef scope_h
#define scope_h

#include <string>

#include "Dict.h"
#include "Obj.h"
#include "BroList.h"

class ID;
class BroType;
class ListVal;

declare(PDict,ID);

class Scope : public BroObj {
public:
	Scope(ID* id);
	~Scope();

	ID* Lookup(const char* name) const	{ return local->Lookup(name); }
	void Insert(const char* name, ID* id)	{ local->Insert(name, id); }

	ID* ScopeID() const		{ return scope_id; }
	BroType* ReturnType() const	{ return return_type; }

	int Length() const		{ return local->Length(); }
	PDict(ID)* Vars() const		{ return local; }

	ID* GenerateTemporary(const char* name);

	// Returns the list of variables needing initialization, and
	// removes it from this Scope.
	id_list* GetInits();

	// Adds a variable to the list.
	void AddInit(ID* id)		{ inits->append(id); }

	void Describe(ODesc* d) const;

protected:
	ID* scope_id;
	BroType* return_type;
	PDict(ID)* local;
	id_list* inits;
};

extern const char* GLOBAL_MODULE_NAME;

extern string extract_module_name(const char* name);
extern string normalized_module_name(const char* module_name); // w/o ::

// concatenates module_name::var_name unless var_name is already fully
// qualified, in which case it is returned unmodified.
extern string make_full_var_name(const char* module_name, const char* var_name);

extern bool in_debug;

// If no_global is true, don't search in the default "global" namespace.
extern ID* lookup_ID(const char* name, const char* module,
			bool no_global = false);
extern ID* install_ID(const char* name, const char* module_name,
			bool is_global, bool is_export);

extern void push_scope(ID* id);
extern void push_existing_scope(Scope* scope);

// Returns the one popped off; it's not deleted.
extern Scope* pop_scope();
extern Scope* current_scope();
extern Scope* global_scope();

// Current module (identified by its name).
extern string current_module;

#endif
