/* $XConsortium: gen-hdr.cxx,v 1.5 94/11/08 20:57:08 matt Exp $ */
/*
 * Copyright (c) 1992-1993 Silicon Graphics, Inc.
 * Copyright (c) 1993 Fujitsu, Ltd.
 *
 * Permission to use, copy, modify, distribute, and sell this software and 
 * its documentation for any purpose is hereby granted without fee, provided
 * that (i) the above copyright notices and this permission notice appear in
 * all copies of the software and related documentation, and (ii) the names of
 * Silicon Graphics and Fujitsu may not be used in any advertising or
 * publicity relating to the software without the specific, prior written
 * permission of Silicon Graphics and Fujitsu.
 *
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
 *
 * IN NO EVENT SHALL SILICON GRAPHICS OR FUJITSU BE LIABLE FOR
 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
 * OF THIS SOFTWARE.
 */

/*
 * Generate header file
 */

#include "generator.h"

Boolean ExprImpl::generate(Generator*) { return false; }

/*
 * Generate a list of expressions using the given function
 * on each expression.  Return true if any of the functions
 * return true.
 */

Boolean ExprImpl::generate_list(
    ExprList* list, Boolean (Expr::*func)(Generator*), Generator* g,
    const char* sep, const char* trail
) {
    Boolean b = false;
    if (list != nil) {
	long n = g->counter();
	g->counter(0);
	Boolean need_sep = false;
	Expr* e;
	for (ListItr(ExprList) i(*list); i.more(); i.next()) {
	    if (need_sep && sep != nil) {
		g->emit(sep);
	    }
	    e = i.cur();
	    need_sep = (e->*func)(g);
	    b |= need_sep;
	    g->count(+1);
	}
	if (need_sep && trail != nil) {
	    g->emit(trail);
	}
    }
    return b;
}

Boolean RootExpr::generate(Generator* g) {
    SourcePosition* p = g->handler()->position();
    String* s = nil;
    if (p != nil) {
	s = p->filename();
    }
    g->emit_edit_warning(s);
    if (defs_ != nil) {
	g->need_sep(false);
	put_list(defs_, &RootExpr::put_decls, g);
	if (!g->cdecls()) {
	    put_list(defs_, &RootExpr::put_inlines, g);
	}
    }
    if (g->begin_file(g->stubfile())) {
	g->emit_edit_warning(s);
	g->emit_stub_includes();
	g->need_sep(false);
	put_list(defs_, &RootExpr::put_stubs, g);
	g->end_file();
    }
    if (g->begin_file(g->serverfile())) {
	g->emit_edit_warning(s);
	g->emit_server_includes();
	g->need_sep(false);
	put_list(defs_, &RootExpr::put_server, g);
	g->end_file();
    }
    g->flush();
    return false;
}

Boolean RootExpr::put_list(
    ExprList* list, Boolean (*func)(Generator*, Expr*), Generator* g
) {
    Boolean b = false;
    if (list != nil) {
	/*
	 * The separator semantics are a bit different here
	 * than in ExprImpl::generate_list because we must check
	 * each expression individually to see if it needs
	 * a trailing semi-colon.  The reason is that some
	 * declarations (e.g., structs) need semi-colons because
	 * they can also be used as types for members, while
	 * interfaces don't need trailing semi-colons.
	 */
	g->indirect(false);
	for (ListItr(ExprList) i(*list); i.more(); i.next()) {
	    if (g->need_sep(false)) {
		g->emit("\n");
	    }
	    Expr* e = i.cur();
	    if (e->set_source(g)) {
		b = (*func)(g, e);
		if (b) {
		    g->emit(";\n");
		    g->need_sep(true);
		}
	    }
	}
    }
    return b;
}

Boolean RootExpr::put_decls(Generator* g, Expr* e) {
    return e->generate(g);
}

Boolean RootExpr::put_inlines(Generator* g, Expr* e) {
    Symbol* s = e->symbol();
    if (s != nil) {
	Module* m = s->module();
	if (m != nil) {
	    g->enter_scope(m->block());
	    put_list(m->defs(), &RootExpr::put_inlines, g);
	    g->leave_scope();
	}
    }
    return /* no semi-colon */ false;
}

Boolean RootExpr::put_stubs(Generator* g, Expr* e) {
    Boolean b = false;
    Symbol* s = e->symbol();
    if (s != nil) {
	InterfaceDef* i;
	e = nil;
	switch (s->tag()) {
	case Symbol::sym_module:
	    b = s->module()->generate_types(g);
	    break;
	case Symbol::sym_interface:
	    i = s->interface();
	    if (i->info()->generated_body) {
		i->put_init(g);
		i->generate_extern_stubs(g);
		if (g->request() != nil) {
		    i->put_type_dii(g);
		} else {
		    i->put_type(g);
		}
		i->generate_stub(g);
		i->generate_types(g);
		g->need_sep(true);
	    }
	    break;
	case Symbol::sym_struct:
	    e = s->struct_tag();
	    break;
	case Symbol::sym_union:
	    e = s->union_tag();
	    break;
	case Symbol::sym_sequence:
	    e = s->sequence_type();
	    break;
	}
	if (e != nil) {
	    e->generate_extern_stubs(g);
	    if (e->generate_types(g)) {
		g->need_sep(true);
	    }
	}
    }
    return b;
}

Boolean RootExpr::put_server(Generator* g, Expr* e) {
    Boolean b = false;
    Symbol* s = e->symbol();
    if (s != nil) {
	Module* m;
	InterfaceDef* i;
	switch (s->tag()) {
	case Symbol::sym_module:
	    m = s->module();
	    g->enter_scope(m->block());
	    b = put_list(m->defs(), &RootExpr::put_server, g);
	    g->leave_scope();
	    break;
	case Symbol::sym_interface:
	    i = s->interface();
	    if (i->info()->generated_body) {
		i->generate_extern_stubs(g);
		i->put_receive(g);
		g->need_sep(true);
	    }
	    break;
	}
    }
    return b;
}

/*
 * Generate header declaration for a module.  Currently, we use
 * a class for the scoping.  This should be changed to generate
 * C++ namespaces if/when supported by the compiler.
 */

Boolean Module::generate(Generator* g) {
    Boolean b = false;
    Boolean cdecls = g->cdecls();
    if (!cdecls) {
	b = true;
	g->emit("class %I {\npublic:\n%i", ident_->string());
    }
    g->enter_scope(block_);
    b |= RootExpr::put_list(defs_, &RootExpr::put_decls, g);
    g->leave_scope();
    if (!cdecls) {
	b = true;
	g->emit("%u}");
	g->need_sep(/* newline separator */ true);
    }
    return b;
}

Boolean InterfaceDef::generate(Generator* g) {
    String* s = ident_->string();
    Boolean b = g->indirect();
    g->indirect(false);
    if (!info_->generated_decl) {
	put_forward_decl(g);
	if (!forward_) {
	    g->emit("\n");
	}
	info_->generated_decl = true;
    }
    if (!forward_) {
	put_hdr(g);
	if (g->stubclass() != nil) {
	    put_stub_hdr(g);
	}
	info_->generated_body = true;
    }
    g->need_sep(/* newline separator */ true);
    g->indirect(b);
    return /* no semicolon */ false;
}

void InterfaceDef::put_forward_decl(Generator* g) {
    String* s = ident_->string();
    Boolean has_super = g->superclass() != nil;
    if (g->cdecls()) {
	if (has_super) {
	    g->emit("typedef %S%p %_%I, %_%I%p;\n", s);
	} else {
	    g->emit("typedef void* %_%I, %_%I%p;\n", s);
	}
    } else {
	g->emit("class %I;\n", s);
	g->emit("typedef %I* %I%p;\n", s);
	g->emit("typedef %I%p %I_in;\n", s);
	g->emit("typedef %I%p %I_out, %I_inout;\n", s);
	g->emit("typedef %I%p %I_return;\n", s);
	g->emit("class %I%r;\n", s);
    }
}

void InterfaceDef::put_hdr(Generator* g) {
    String* s = ident_->string();
    const char* super = g->superclass();
    Boolean is_superclass = super != nil && *s == super;
    Boolean cdecls = g->cdecls();
    if (!cdecls) {
	if (g->stubclass() != nil) {
	    g->emit("extern %S%p _%_%I%C_create(%O*);\n\n", s);
	}
	g->emit("class %I", s);
	if (supertypes_ != nil) {
	    g->emit(" : public ");
	    Boolean save = g->interface_is_ref(false);
	    generate_list(supertypes_, &Expr::generate, g, ", public ");
	    g->interface_is_ref(save);
	} else if (super != nil && !is_superclass) {
	    g->emit(" : public %S");
	}
	if (is_superclass) {
	    g->emit(" {\npublic");
	} else {
	    g->emit(" {\nprotected");
	}
	g->emit(":\n%i%I();\n", s);
	g->emit("virtual ~%I();\n%u", s);
	g->emit("public:\n%i");
	if (super != nil) {
	    g->emit("%I%p _obj() { return this; };\n", s);
	    g->emit(
		"static %I%p  _return_ref(%I_return r) { return r; }\n\n", s
	    );
	    g->emit("virtual void* _this();\n");
	    if (g->metaclass() != nil) {
		g->emit("virtual %MId _tid();\n\n");
		g->emit("static %I%p _narrow(%S%p);\n", s);
		g->emit("static %I%p _duplicate(%I%p obj) {\n%i", s);
		g->emit("return (%I%p)", s);
		put_cast_down(g);
		g->emit("_%S__duplicate(", s);
		put_cast_up(g);
		g->emit("obj, %c);\n%u}\n", s);
	    }
	}
    }
    g->enter_scope(info_->block);
    generate_list(defs_, &Expr::generate, g, ";\n", ";\n");
    g->leave_scope();
    g->emit_transcriptions(true);
    if (!cdecls) {
	if (is_superclass) {
	    g->emit("%uprivate:\n%i%I(const %I&);\n", s);
	    g->emit("void operator =(const %I&);\n", s);
	}
	g->emit("%u};\n\n");
	put_managed_hdr(g);
    }
}

/*
 * Generate a cast up/down the current interface's ancestors.
 * The cast does NOT include this interface, as the exact format of
 * that may vary depending on the current scope.
 */

void InterfaceDef::put_cast_up(Generator* g) {
    if (supertypes_ != nil) {
	InterfaceDef* p = supertypes_->item(0)->symbol()->interface();
	if (p != nil) {
	    p->put_cast_up(g);
	    if (supertypes_->count() > 1) {
		g->emit("(%F%p)", nil, p);
	    }
	}
    }
}

void InterfaceDef::put_cast_down(Generator* g) {
    InterfaceDef* p;
    for (InterfaceDef* i = this; i->supertypes_ != nil; i = p) {
	p = i->supertypes_->item(0)->symbol()->interface();
	if (p != nil && i->supertypes_->count() > 1) {
	    g->emit("(%F%p)", nil, p);
	}
    }
}

/*
 * Generate a call to release an object reference.  Need to cast the
 * pointer up to the base type.
 */

void InterfaceDef::put_release(Generator* g) {
    g->emit("_%S__release(");
    put_cast_up(g);
    g->emit("_obj_);");
}

/*
 * Generate a class that manages an object reference pointer.
 */

void InterfaceDef::put_managed_hdr(Generator* g) {
    String* s = ident_->string();
    g->emit("class %I%r {\nprotected:\n%i%I%p _obj_;\n%upublic:\n%i", s);

    /* default constructor */
    g->emit("%I%r() { _obj_ = 0; };\n", s);

    /* constructor from pointer ref */
    g->emit("%I%r(%I%p p) { _obj_ = p; }\n", s);

    /* copy constructor */
    g->emit("%I%r(const %I%r& r) {\n%i", s);
    g->emit("_obj_ = %I::_duplicate(r._obj_);\n%u}\n", s);

    /* destructor */
    g->emit("~%I%r() { ", s);
    put_release(g);
    g->emit(" }\n\n");

    /* assignment from pointer ref */
    g->emit("%I%r& operator =(%I%p p) {\n%i", s);
    put_release(g);
    g->emit("\n_obj_ = %I::_duplicate(p);\n", s);
    g->emit("return *this;\n%u}\n");

    /* assignment */
    g->emit("%I%r& operator =(const %I%r& r) {\n%i", s);
    put_release(g);
    g->emit("\n_obj_ = %I::_duplicate(r._obj_);\n", s);
    g->emit("return *this;\n%u}\n\n");

    /* explicit conversion */
    g->emit("%I%p _obj() const { return _obj_; }\n", s);
    g->emit("%I%p& _out() { return _obj_; }\n", s);

    /* implicit conversion */
    g->emit("operator %I%p() const { return _obj_; }\n", s);

    /* indirection with arrow */
    g->emit("%I%p operator ->() const { return _obj_; }\n", s);

    g->emit("%u};\n");

    g->emit("\ninline %I%r _tmp(%I%p p) { return %I%r(p); }\n", s);
}

Boolean Accessor::generate(Generator* g) {
    if (g->qualify()) {
	Boolean b = g->interface_is_ref(false);
	g->emit("%E%?", nil, qualifier_);
	g->interface_is_ref(b);
    }
    g->emit("%I", string_);
    if (symbol_->actual_type()->tag() == Symbol::sym_interface) {
	g->emit("%P");
    }
    return true;
}

Boolean Constant::generate(Generator* g) {
    String* s = ident_->string();
    if (g->cdecls()) {
	g->emit("#define %_%I %E\n", s, value_);
	return /* no trailing semi-colon */ false;
    } else {
	g->emit("static const %F %I", s, type_);
	Scope* b = symbol_->scope();
	if (b == nil || b->name == nil) {
	    g->emit(" = %E", nil, value_);
	}
    }
    return true;
}

Boolean Unary::generate(Generator* g) {
    g->emit_op(op_);
    g->emit("(");
    expr_->generate(g);
    g->emit(")");
    return true;
}

Boolean Binary::generate(Generator* g) {
    g->emit("(");
    left_->generate(g);
    g->emit(")");
    g->emit_op(op_);
    g->emit("(");
    right_->generate(g);
    g->emit(")");
    return true;
}

Boolean TypeName::generate(Generator* g) {
    if (!seq_) {
	if (g->varying()) {
	    switch (type_->symbol()->tag()) {
	    case Symbol::sym_interface:
	    case Symbol::sym_typedef:
	    case Symbol::sym_string:
		g->emit("typedef %E ", nil, type_);
		break;
	    default:
		g->emit("%E;\ntypedef %N ", nil, type_);
		break;
	    }
	} else {
	    g->emit("typedef %E ", nil, type_);
	}
	generate_list(declarators_, &Expr::generate, g, ", ");
	return true;
    } else {
	return type_->generate(g);
    }
}

Boolean UnsignedType::generate(Generator* g) {
    Symbol* s = symbol_;
    if (s->tag() == Symbol::sym_typedef) {
	TypeName* t = s->typename();
	if (t->type() == nil) {
	    /* builtin */
	    g->emit("%I", t->mapping());
	    return true;
	}
    }
    return false;
}

Boolean Declarator::generate(Generator* g) {
    g->emit_declarator_ident(ident_);
    if (subscripts_ != nil && g->is_array_decl()) {
	g->emit("[");
	generate_list(subscripts_, &Expr::generate, g, "][");
	g->emit("]");
    }
    return true;
}

Boolean StructDecl::generate(Generator* g) {
    String* s = ident_->string();
    g->emit("struct %I {", s);
    if (members_ != nil) {
	g->emit("\n%i");
	generate_list(members_, &Expr::generate, g, ";\n");
	g->emit(";\n%u");
    } else {
	g->emit(" ");
    }
    g->emit("}");
    return true;
}

Boolean StructMember::generate(Generator* g) {
    g->emit("%E ", nil, type_);
    generate_list(declarators_, &Expr::generate, g, ", ");
    return true;
}

Boolean UnionDecl::generate(Generator* g) {
    String* s = ident_->string();
    if (g->varying()) {
	g->emit("class %I {\npublic:\n%i", s);
    } else {
	g->emit("struct %I {\n%i", s);
    }
    g->emit("%E _d", nil, type_);
    if (!g->cdecls()) {
	g->emit("_");
    }
    g->emit(";\nunion _U {\n%i");
    for (ListItr(CaseList) c(*cases_); c.more(); c.next()) {
	c.cur()->generate(g);
	g->emit(";\n");
    }
    Boolean v = varying();
    if (v) {
	g->emit("void* __init_;\n");
    }
    g->emit("%u} _u;\n");
    if (g->varying()) {
	g->emit("\n%I();\n", s);
	g->emit("%I(const %I& _u) { *this = _u; }\n", s);
	g->emit("~%I() { ", s);
	if (v) {
	    g->emit("_free(); ");
	}
	g->emit("}\n");
	g->emit("%I& operator =(const %I&);\n\n", s);
	g->emit("const %F _d() const { return _d_; }\n", nil, type_);
	g->emit("void _d(%F);\n", nil, type_);
	g->emit("%F& _d() { return _d_; }\n", nil, type_);
	for (ListItr(CaseList) i(*cases_); i.more(); i.next()) {
	    g->emit("\n");
	    generate_access_hdr(g, i.cur());
	}
	if (v) {
	    g->emit("\nvoid _free();\n");
	}
    }
    g->emit("%u}");
    return true;
}

void UnionDecl::generate_access_hdr(Generator* g, CaseElement* c) {
    UnionMember* u = c->element();
    Expr* t = u->type();
    Expr* e = u->declarators()->item(0);
    Boolean v = t->varying();
    Boolean addr = g->addr_type(t);
    if (addr) {
	g->emit("const ");
    }
    g->emit("%F", nil, t);
    if (addr) {
	g->emit("&");
    }
    g->emit(" %E() const { return ", nil, e);
    if (v) {
	g->emit("*");
    }
    g->emit("_u.%E; }\n", nil, e);

    g->emit("void %E(", nil, e);
    if (addr) {
	g->emit("const ");
    }
    g->emit("%F", nil, t);
    if (addr) {
	g->emit("&");
    }
    g->emit(");\n");

    g->emit("%F& ", nil, t);
    g->emit("%E();\n", nil, e);
}

Boolean CaseElement::generate(Generator* g) {
    return element_->generate(g);
}

Boolean UnionMember::generate(Generator* g) {
    Expr* e = declarators_->item(0);
    g->emit("%E", nil, type_);
    if (g->varying() && type_->varying()) {
	g->emit("*");
    }
    g->emit(" %E", nil, e);
    return true;
}

Boolean CaseLabel::generate(Generator* g) {
    return value_->generate(g);
}

Boolean DefaultLabel::generate(Generator*) {
    /* do not output anything */
    return true;
}

Boolean EnumDecl::generate(Generator* g) {
    g->emit("enum %I {\n%i", ident_->string());
    generate_list(members_, &Expr::generate, g, ", %b");
    g->emit("%u\n}");
    return true;
}

Boolean Enumerator::generate(Generator* g) {
    return ident_->generate(g);
}

Boolean SequenceDecl::generate(Generator* g) {
    if (g->varying()) {
	g->emit("class %N {\npublic:\n%ilong _maximum, _length; ", nil, this);
	g->emit("%E* _buffer;\n\n", nil, type_);
	g->emit("%N() { _maximum = _length = 0; _buffer = 0; }\n", nil, this);
	g->emit("%N(long m, long n, ", nil, this);
	g->emit("%E* e) {\n%i", nil, type_);
	g->emit("_maximum = m; _length = n; _buffer = e;\n%u}\n");
	g->emit("%N(const %N& _s) { _buffer = 0; *this = _s; }\n", nil, this);
	g->emit("%N& operator =(const %N&);\n", nil, this);
	g->emit("~%N() { delete [] _buffer; }\n", nil, this);
	g->emit("%u}");
    } else {
	g->emit("struct %N {\n%ilong _maximum, _length; ", nil, this);
	g->emit("%E* _buffer;\n%u}", nil, type_);
    }
    return true;
}

Boolean StringDecl::generate(Generator* g) {
    if (g->varying()) {
	g->emit("string");
    } else {
	g->emit("char*");
    }
    return true;
}

Boolean ExceptDecl::generate(Generator* g) {
    String* s = ident_->string();
    g->emit("class %I : public %U {\npublic:\n%i", s);
    g->emit("enum { _index = ");
    g->emit_integer(index_);
    g->emit(", _code = ");
    long ihash = symbol_->scope()->name->hash();
    g->emit_integer(((ihash & 0xfffff) << 6) + index_);
    g->emit(" };\n");
    g->emit("%I();\n", s);
    if (members_ != nil) {
	g->emit("%I(", s);
	generate_list(members_, &Expr::generate, g, ", ");
	g->emit(");\n", s);
    }
    g->emit("static %I* _cast(const %x*);\n\n", s);
    g->emit("void _put(%B&) const;\n");
    g->emit("static %x* _get(%B&);\n", s);
    if (members_ != nil) {
	g->emit("\n");
	generate_list(members_, &Expr::generate, g, ";\n");
	g->emit(";\n");
    }
    g->emit("%u}");
    return true;
}

/*
 * Still need to handle attributes (oneway) and context.
 */

Boolean Operation::generate(Generator* g) {
    if (g->cdecls()) {
	g->emit("extern %Y ", nil, type_);
	g->emit("%_%N(%~%p, ", nil, this);
	g->emit_param_decls(params_, Generator::emit_env_formals);
	g->emit(")");
    } else {
	String* s = ident_->string();
	g->emit("virtual ");
	Boolean ref = g->interface_is_ref(false);
	g->emit("%E", nil, type_);
	if (g->actual_type(type_)->tag() == Symbol::sym_interface) {
	    g->emit("_return");
	}
	g->interface_is_ref(ref);
	g->emit(" %I(", s);
	g->emit_param_decls(params_, Generator::emit_env_formals);
	g->emit(")%=");
    }
    return true;
}

/*
 * Generate a parameter declaration.  The basic idea for "in" parameters
 * is that primitive types (char, short, long) and object pointers
 * are passed by value, while structured types (string, sequence, struct)
 * are passed by const reference.  For "inout" or "out" parameters,
 * everything is passed non-const reference.  Arrays are the strange case,
 * as they are passed by "value pointer" meaning the mode looks like
 * by-value but is really by-reference.
 */

const char* param_tag[4] = { "?", "in", "out", "inout" };

Boolean Parameter::generate(Generator* g) {
    Boolean f = g->formals();
    Boolean a = g->array_decl(f);
    Symbol::Tag t = g->actual_type(type_)->tag();
    Boolean in_param = (attr_ == ExprKit::in_param);
    if (f) {
	Boolean cdecls = g->cdecls();
	Boolean addr = g->addr_type(type_);
	if (!cdecls && in_param && addr) {
	    g->emit("const ");
	}
	Boolean ref = g->interface_is_ref(false);
	g->emit(cdecls ? "%Y" : "%E", nil, type_);
	if (t == Symbol::sym_interface) {
	    g->emit("_");
	    g->emit(param_tag[attr_]);
	}
	g->interface_is_ref(ref);
	if (addr || (!in_param && t != Symbol::sym_array)) {
	    g->emit(cdecls ? "*" : "&");
	}
	g->emit("%o");
    }
    declarator_->generate(g);
    g->array_decl(a);
    return true;
}

Boolean IdentifierImpl::generate(Generator* g) {
    Symbol* s = symbol_;
    if (s != nil && s->tag() == Symbol::sym_typedef) {
	TypeName* t = s->typename();
	if (t->type() == nil) {
	    /* builtin type */
	    g->emit("%I", t->mapping());
	    return true;
	}
    }
    g->emit("%I", value_);
    if (symbol_ != nil && symbol_->tag() == Symbol::sym_interface) {
	g->emit("%P");
    }
    return true;
}

Boolean BooleanLiteral::generate(Generator* g) {
    g->emit_integer(value_ ? 1 : 0);
    return true;
}

Boolean IntegerLiteral::generate(Generator* g) {
    g->emit_integer(value_);
    return true;
}

Boolean FloatLiteral::generate(Generator* g) {
    g->emit_float(value_);
    return true;
}

Boolean StringLiteral::generate(Generator* g) {
    g->emit("\"%I\"", value_);
    return true;
}

Boolean CharLiteral::generate(Generator* g) {
    g->emit("\'");
    g->emit_char(value_);
    g->emit("\'");
    return true;
}

Boolean ExprImpl::set_source(Generator* g) {
    return g->is_source();
}

Boolean IdentifierImpl::set_source(Generator* g) {
    return g->is_source();
}

Boolean SrcPos::set_source(Generator* g) {
    SourcePosition* p = position();
    if (p == nil) {
	/* this shouldn't happen? */
	return false;
    }
    g->set_source(p);
    return true;
}

Boolean SrcPos::generate(Generator* g) {
    SourcePosition* p = position();
    FileName name = p->filename();
    LineNumber n = p->lineno();
    if (g->is_source()) {
	if (g->need_ifndef()) {
	    g->emit_ifndef(name);
	    g->emit_includes();
	} else {
	    g->emit_endif(name);
	}
    } else if (n == 1) {
	g->emit_include(name);
    }
    return /* no semi-colon */ false;
}

/*
 * Generate the name for an expression; this for type expressions.
 */

Boolean ExprImpl::generate_name(Generator*) { return false; }
Boolean IdentifierImpl::generate_name(Generator* g) { return generate(g); }

Boolean Accessor::generate_name(Generator* g) {
    SequenceDecl* s = g->actual_type(this)->sequence_type();
    if (s != nil) {
	return s->generate_name(g);
    }
    g->emit("%I", string_);
    if (symbol_->actual_type()->tag() == Symbol::sym_interface) {
	g->emit("%P");
    }
    return true;
}

Boolean InterfaceDef::generate_name(Generator* g) {
    g->emit("%I", ident_->string());
    return true;
}

Boolean Operation::generate_name(Generator* g) {
    g->emit("%I", ident_->string());
    return true;
}

Boolean AttrOp::generate_name(Generator* g) {
    const char* fmt = (params_ == nil) ? "_get_%I" : "_set_%I";
    g->emit(fmt, ident_->string());
    return true;
}

Boolean TypeName::generate_name(Generator* g) {
    return (type_ == nil) ? generate(g) : type_->generate_name(g);
}

Boolean UnsignedType::generate_name(Generator* g) { return generate(g); }

Boolean StructDecl::generate_name(Generator* g) {
    g->emit("%I", ident_->string());
    return true;
}

Boolean UnionDecl::generate_name(Generator* g) {
    g->emit("%I", ident_->string());
    return true;
}

Boolean SequenceDecl::generate_name(Generator* g) {
    if (name_ != nil) {
	name_->generate(g);
    } else {
	g->emit("_%NSeq", nil, type_);
	if (id_ > 1) {
	    g->emit_integer(id_);
	}
    }
    return true;
}

Boolean Declarator::generate_name(Generator* g) {
    g->emit("%I", ident_->string());
    return true;
}

Boolean StringDecl::generate_name(Generator* g) { return generate(g); }
