diff options
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/Makefile | 2 | ||||
-rw-r--r-- | cpp/src/Slice/Grammer.y | 450 | ||||
-rw-r--r-- | cpp/src/Slice/Makefile | 59 | ||||
-rw-r--r-- | cpp/src/Slice/OutputUtil.cpp | 182 | ||||
-rw-r--r-- | cpp/src/Slice/OutputUtil.h | 83 | ||||
-rw-r--r-- | cpp/src/Slice/Parser.cpp | 973 | ||||
-rw-r--r-- | cpp/src/Slice/Parser.h | 545 | ||||
-rw-r--r-- | cpp/src/Slice/Scanner.l | 197 | ||||
-rw-r--r-- | cpp/src/Slice/dummyinclude/unistd.h | 4 | ||||
-rw-r--r-- | cpp/src/slice2cpp/GenCPlusPlus.cpp | 1519 | ||||
-rw-r--r-- | cpp/src/slice2cpp/GenCPlusPlus.h | 233 | ||||
-rw-r--r-- | cpp/src/slice2cpp/GenCPlusPlusUtil.cpp | 250 | ||||
-rw-r--r-- | cpp/src/slice2cpp/GenCPlusPlusUtil.h | 41 | ||||
-rw-r--r-- | cpp/src/slice2cpp/Main.cpp | 192 | ||||
-rw-r--r-- | cpp/src/slice2cpp/Makefile | 31 |
15 files changed, 4760 insertions, 1 deletions
diff --git a/cpp/src/Makefile b/cpp/src/Makefile index e0fc1bcbfc4..4d0f2d26b55 100644 --- a/cpp/src/Makefile +++ b/cpp/src/Makefile @@ -12,7 +12,7 @@ top_srcdir = .. include $(top_srcdir)/config/Make.rules -SUBDIRS = library compiler +SUBDIRS = library slice $(EVERYTHING):: @for subdir in $(SUBDIRS); \ diff --git a/cpp/src/Slice/Grammer.y b/cpp/src/Slice/Grammer.y new file mode 100644 index 00000000000..bc08de10d2d --- /dev/null +++ b/cpp/src/Slice/Grammer.y @@ -0,0 +1,450 @@ +%{ + +// ********************************************************************** +// +// Copyright (c) 2001 +// MutableRealms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#include <Parser.h> + +using namespace std; +using namespace IceLang; + +void +yyerror(const char* s) +{ + parser -> error(s); +} + +%} + +%token ICE_SCOPE_DELIMITOR +%token ICE_MODULE +%token ICE_CLASS +%token ICE_LOCAL +%token ICE_EXTENDS +%token ICE_THROWS +%token ICE_VOID +%token ICE_BOOL +%token ICE_BYTE +%token ICE_SHORT +%token ICE_INT +%token ICE_LONG +%token ICE_FLOAT +%token ICE_DOUBLE +%token ICE_STRING +%token ICE_WSTRING +%token ICE_OBJECT +%token ICE_VECTOR +%token ICE_IDENTIFIER +%token ICE_OP_IDENTIFIER + +%% + +// ---------------------------------------------------------------------- +start +// ---------------------------------------------------------------------- +: definitions +{ +} +; + +// ---------------------------------------------------------------------- +definitions +// ---------------------------------------------------------------------- +: definition ';' definitions +{ +} +| definition +{ + yyerror("`;' missing after definition"); +} +| +{ +} +| error ';' +{ + yyerrok; +} +; + +// ---------------------------------------------------------------------- +definition +// ---------------------------------------------------------------------- +: module +{ +} +| class +{ +} +| class_decl +{ +} +| vector +{ +} +; + +// ---------------------------------------------------------------------- +exports +// ---------------------------------------------------------------------- +: export ';' exports +{ +} +| export +{ + yyerror("`;' missing after definition"); +} +| +{ +} +| error ';' +{ + yyerrok; +} +; + +// ---------------------------------------------------------------------- +export +// ---------------------------------------------------------------------- +: operation +{ +} +| data_member +{ +} +; + +// ---------------------------------------------------------------------- +module +// ---------------------------------------------------------------------- +: ICE_MODULE ICE_IDENTIFIER +{ + String_ptr ident = String_ptr::dynamicCast($2); + Container_ptr cont = parser -> currentContainer(); + Module_ptr module = cont -> createModule(ident -> v); + parser -> pushContainer(module); +} +'{' definitions '}' +{ + parser -> popContainer(); +} +; + +// ---------------------------------------------------------------------- +class +// ---------------------------------------------------------------------- +: ICE_CLASS ICE_IDENTIFIER extends +{ + String_ptr ident = String_ptr::dynamicCast($2); + Container_ptr cont = parser -> currentContainer(); + ClassDef_ptr base = ClassDef_ptr::dynamicCast($3); + ClassDef_ptr derived = cont -> createClassDef(ident -> v, base, false); + parser -> pushContainer(derived); +} +'{' exports '}' +{ + parser -> popContainer(); +} +| ICE_LOCAL ICE_CLASS ICE_IDENTIFIER extends +{ + String_ptr ident = String_ptr::dynamicCast($3); + Container_ptr cont = parser -> currentContainer(); + ClassDef_ptr base = ClassDef_ptr::dynamicCast($4); + ClassDef_ptr derived = cont -> createClassDef(ident -> v, base, true); + parser -> pushContainer(derived); +} +'{' exports '}' +{ + parser -> popContainer(); +} +; + +// ---------------------------------------------------------------------- +class_decl +// ---------------------------------------------------------------------- +: ICE_CLASS ICE_IDENTIFIER +{ + String_ptr ident = String_ptr::dynamicCast($2); + Container_ptr cont = parser -> currentContainer(); + ClassDecl_ptr cl = cont -> createClassDecl(ident -> v, false); +} +| ICE_LOCAL ICE_CLASS ICE_IDENTIFIER +{ + String_ptr ident = String_ptr::dynamicCast($3); + Container_ptr cont = parser -> currentContainer(); + ClassDecl_ptr cl = cont -> createClassDecl(ident -> v, true); +} +; + +// ---------------------------------------------------------------------- +extends +// ---------------------------------------------------------------------- +: ICE_EXTENDS scoped_name +{ + String_ptr scoped = String_ptr::dynamicCast($2); + Container_ptr cont = parser -> currentContainer(); + vector<Type_ptr> types = cont -> lookupType(scoped -> v); + if(types.empty()) + YYERROR; // Can't continue, jump to next yyerrok + ClassDecl_ptr cl = ClassDecl_ptr::dynamicCast(types[0]); + if(!cl) + { + string msg = "`"; + msg += scoped -> v; + msg += "' is not a class"; + yyerror(msg.c_str()); + $$ = 0; + } + else + { + ClassDef_ptr def = cl -> definition(); + if(!def) + { + string msg = "`"; + msg += scoped -> v; + msg += "' has been declared but not defined"; + yyerror(msg.c_str()); + $$ = 0; + } + else + { + $$ = def; + } + } +} +| +{ + $$ = 0; +} +; + +// ---------------------------------------------------------------------- +operation +// ---------------------------------------------------------------------- +: return_type ICE_OP_IDENTIFIER parameters output_parameters ')' throws +{ + Type_ptr returnType = Type_ptr::dynamicCast($1); + String_ptr name = String_ptr::dynamicCast($2); + Parameters_ptr inParms = Parameters_ptr::dynamicCast($3); + Parameters_ptr outParms = Parameters_ptr::dynamicCast($4); + Throws_ptr throws = Throws_ptr::dynamicCast($6); + ClassDef_ptr cl = ClassDef_ptr::dynamicCast(parser -> currentContainer()); + cl -> createOperation(name -> v, returnType, inParms -> v, outParms -> v, + throws -> v); +} + +// ---------------------------------------------------------------------- +parameters +// ---------------------------------------------------------------------- +: type ICE_IDENTIFIER ',' parameters +{ + Type_ptr type = Type_ptr::dynamicCast($1); + String_ptr ident = String_ptr::dynamicCast($2); + Parameters_ptr parms = Parameters_ptr::dynamicCast($4); + parms -> v.push_front(make_pair(type, ident -> v)); + $$ = parms; +} +| type ICE_IDENTIFIER +{ + Type_ptr type = Type_ptr::dynamicCast($1); + String_ptr ident = String_ptr::dynamicCast($2); + Parameters_ptr parms = new Parameters; + parms -> v.push_front(make_pair(type, ident -> v)); + $$ = parms; +} +| +{ + $$ = new Parameters; +} +; + +// ---------------------------------------------------------------------- +output_parameters +// ---------------------------------------------------------------------- +: ';' parameters +{ + $$ = $2 +} +| +{ + $$ = new Parameters; +} + +// ---------------------------------------------------------------------- +throws +// ---------------------------------------------------------------------- +: ICE_THROWS throw_list +{ + $$ = $2; +} +| +{ + $$ = new Throws; +} +; + +// ---------------------------------------------------------------------- +throw_list +// ---------------------------------------------------------------------- +: type ',' throw_list +{ + Type_ptr type = Type_ptr::dynamicCast($1); + Throws_ptr throws = Throws_ptr::dynamicCast($3); + throws -> v.push_front(type); + $$ = throws; +} +| type +{ + Type_ptr type = Type_ptr::dynamicCast($1); + Throws_ptr throws = new Throws; + throws -> v.push_front(type); + $$ = throws; +} +; + +// ---------------------------------------------------------------------- +data_member +// ---------------------------------------------------------------------- +: type ICE_IDENTIFIER +{ + Type_ptr type = Type_ptr::dynamicCast($1); + String_ptr ident = String_ptr::dynamicCast($2); + ClassDef_ptr cl = ClassDef_ptr::dynamicCast(parser -> currentContainer()); + cl -> createDataMember(ident -> v, type); +} +; + +// ---------------------------------------------------------------------- +type +// ---------------------------------------------------------------------- +: ICE_BYTE +{ + $$ = parser -> builtin(Builtin::KindByte); +} +| ICE_BOOL +{ + $$ = parser -> builtin(Builtin::KindBool); +} +| ICE_SHORT +{ + $$ = parser -> builtin(Builtin::KindShort); +} +| ICE_INT +{ + $$ = parser -> builtin(Builtin::KindInt); +} +| ICE_LONG +{ + $$ = parser -> builtin(Builtin::KindLong); +} +| ICE_FLOAT +{ + $$ = parser -> builtin(Builtin::KindFloat); +} +| ICE_DOUBLE +{ + $$ = parser -> builtin(Builtin::KindDouble); +} +| ICE_STRING +{ + $$ = parser -> builtin(Builtin::KindString); +} +| ICE_WSTRING +{ + $$ = parser -> builtin(Builtin::KindWString); +} +| ICE_OBJECT +{ + $$ = parser -> builtin(Builtin::KindObject); +} +| ICE_OBJECT '*' +{ + $$ = parser -> builtin(Builtin::KindObjectProxy); +} +| ICE_LOCAL ICE_OBJECT +{ + $$ = parser -> builtin(Builtin::KindLocalObject); +} +| scoped_name +{ + String_ptr scoped = String_ptr::dynamicCast($1); + Container_ptr cont = parser -> currentContainer(); + vector<Type_ptr> types = cont -> lookupType(scoped -> v); + if(types.empty()) + YYERROR; // Can't continue, jump to next yyerrok + $$ = types[0]; +} +| scoped_name '*' +{ + String_ptr scoped = String_ptr::dynamicCast($1); + Container_ptr cont = parser -> currentContainer(); + vector<Type_ptr> types = cont -> lookupType(scoped -> v); + if(types.empty()) + YYERROR; // Can't continue, jump to next yyerrok + for(vector<Type_ptr>::iterator p = types.begin(); + p != types.end(); + ++p) + { + ClassDecl_ptr cl = ClassDecl_ptr::dynamicCast(*p); + assert(cl); // TODO: Only classes can be passed as proxy + *p = new Proxy(cl); + } + $$ = types[0]; +} +; + +// ---------------------------------------------------------------------- +return_type +// ---------------------------------------------------------------------- +: ICE_VOID +{ + $$ = 0; +} +| type +{ + $$ = $1; +} +; + +// ---------------------------------------------------------------------- +vector +// ---------------------------------------------------------------------- +: ICE_VECTOR '<' type '>' ICE_IDENTIFIER +{ + String_ptr ident = String_ptr::dynamicCast($5); + Type_ptr type = Type_ptr::dynamicCast($3); + Container_ptr cont = parser -> currentContainer(); + cont -> createVector(ident -> v, type); +} +; + +// ---------------------------------------------------------------------- +scoped_name +// ---------------------------------------------------------------------- +: ICE_IDENTIFIER +{ + $$ = $1; +} +| ICE_SCOPE_DELIMITOR ICE_IDENTIFIER +{ + String_ptr ident = String_ptr::dynamicCast($2); + ident -> v = "::" + ident -> v; + $$ = ident; +} +| scoped_name ICE_SCOPE_DELIMITOR ICE_IDENTIFIER +{ + String_ptr scoped = String_ptr::dynamicCast($1); + String_ptr ident = String_ptr::dynamicCast($3); + scoped -> v += "::"; + scoped -> v += ident -> v; + $$ = scoped; +} +; + +%% diff --git a/cpp/src/Slice/Makefile b/cpp/src/Slice/Makefile new file mode 100644 index 00000000000..2b008268867 --- /dev/null +++ b/cpp/src/Slice/Makefile @@ -0,0 +1,59 @@ +# ********************************************************************** +# +# Copyright (c) 2001 +# MutableRealms, Inc. +# Huntsville, AL, USA +# +# All Rights Reserved +# +# ********************************************************************** + +top_srcdir = ../../.. + +BASE = libSlice.so +VERSIONED_BASE = $(BASE).$(VERSION) + +NAME = $(top_srcdir)/lib/$(BASE) +VERSIONED_NAME = $(top_srcdir)/lib/$(VERSIONED_BASE) + +TARGETS = $(NAME) $(VERSIONED_NAME) + +OBJS = Shared.o \ + Scanner.o \ + Grammer.o \ + Parser.o \ + OutputUtil.o + +SRCS = $(OBJS:.o=.cpp) + +include $(top_srcdir)/config/Make.rules + +$(VERSIONED_NAME): $(OBJS) + rm -f $@ + $(CXX) $(CXXFLAGS) $(BASELDFLAGS) -shared -o $@ $(OBJS) + +$(NAME): $(VERSIONED_NAME) + rm -f $@ + ln -s $(VERSIONED_BASE) $@ + +Grammer.cpp Grammer.h: Grammer.y + bison -dvt Grammer.y + rm -f Grammer.cpp ; mv Grammer.tab.c Grammer.cpp + rm -f Grammer.h ; mv Grammer.tab.h Grammer.h + +Scanner.cpp: Scanner.l Grammer.h + flex Scanner.l + rm -f Scanner.cpp ; mv lex.yy.c Scanner.cpp + +clean:: + -rm -f Grammer.cpp Grammer.h Grammer.output + -rm -f Scanner.cpp lex.yy.c + +Shared.cpp: ../../library/Shared.cpp + rm -f $@ + ln -s ../../library/Shared.cpp $@ + +clean:: + -rm -f Shared.cpp + +include .depend diff --git a/cpp/src/Slice/OutputUtil.cpp b/cpp/src/Slice/OutputUtil.cpp new file mode 100644 index 00000000000..b55fdac2e70 --- /dev/null +++ b/cpp/src/Slice/OutputUtil.cpp @@ -0,0 +1,182 @@ +// ********************************************************************** +// +// Copyright (c) 2001 +// MutableRealms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#include <Ice/Config.h> +#include <OutputUtil.h> + +using namespace std; +using namespace IceLang; + +namespace IceLang +{ + +NextLine nl; +StartBlock sb; +EndBlock eb; +Separator sp; + +} + +// ---------------------------------------------------------------------- +// Output +// ---------------------------------------------------------------------- + +IceLang::Output::Output() + : pos_(0), + indent_(0), + indentSave_(-1), + separator_(true) +{ +} + +void +IceLang::Output::open(const char* s) +{ + out_.open(s); +} + +void +IceLang::Output::print(const char* s) +{ + for(unsigned int i = 0; i < strlen(s); ++i) + { + if(s[i] == '\n') + pos_ = 0; + else + ++pos_; + } + + out_ << s; +} + +void +IceLang::Output::inc() +{ + indent_ += 4; + separator_ = true; +} + +void +IceLang::Output::dec() +{ + assert(indent_ >= 4); + indent_ -= 4; + separator_ = true; +} + +void +IceLang::Output::useCurrentPosAsIndent() +{ + assert(indentSave_ == -1); + indentSave_ = indent_; + indent_ = pos_; +} + +void +IceLang::Output::zeroIndent() +{ + assert(indentSave_ == -1); + indentSave_ = indent_; + indent_ = 0; +} + +void +IceLang::Output::restoreIndent() +{ + assert(indentSave_ != -1); + indent_ = indentSave_; + indentSave_ = -1; +} + +void +IceLang::Output::nl() +{ + out_ << '\n'; + pos_ = 0; + separator_ = true; + + int indent = indent_; + + while(indent >= 8) + { + indent -= 8; + out_ << "\t"; + pos_ += 8; + } + + while(indent > 0) + { + --indent; + out_ << ' '; + ++pos_; + } + + out_.flush(); +} + +void +IceLang::Output::sb() +{ + nl(); + out_ << '{'; + ++pos_; + inc(); + separator_ = false; +} + +void +IceLang::Output::eb() +{ + dec(); + nl(); + out_ << '}'; + --pos_; +} + +void +IceLang::Output::sp() +{ + if(separator_) + out_ << '\n'; +} + +bool +IceLang::Output::operator!() const +{ + return !out_; +} + +Output& +IceLang::operator<<(Output& o, const NextLine&) +{ + o.nl(); + return o; +} + +Output& +IceLang::operator<<(Output& o, const StartBlock&) +{ + o.sb(); + return o; +} + +Output& +IceLang::operator<<(Output& o, const EndBlock&) +{ + o.eb(); + return o; +} + +Output& +IceLang::operator<<(Output& o, const Separator&) +{ + o.sp(); + return o; +} diff --git a/cpp/src/Slice/OutputUtil.h b/cpp/src/Slice/OutputUtil.h new file mode 100644 index 00000000000..52250c2ecee --- /dev/null +++ b/cpp/src/Slice/OutputUtil.h @@ -0,0 +1,83 @@ +// ********************************************************************** +// +// Copyright (c) 2001 +// MutableRealms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#ifndef OUTPUT_UTIL_H +#define OUTPUT_UTIL_H + +#include <fstream> +#include <sstream> + +namespace IceLang +{ + +class NextLine { }; +class StartBlock { }; +class EndBlock { }; +class Separator { }; + +extern NextLine nl; +extern StartBlock sb; +extern EndBlock eb; +extern Separator sp; + +// ---------------------------------------------------------------------- +// Indent +// ---------------------------------------------------------------------- + +class Output : ::__Ice::noncopyable +{ +public: + + Output(); + + void open(const char*); // Open output stream + + void print(const char*); // Print a string + + void inc(); // Increment indentation level + void dec(); // Decrement indentation level + + void useCurrentPosAsIndent(); // Save the current position as indentation + void zeroIndent(); // Use zero identation + void restoreIndent(); // Restore indentation + + void nl(); // Print newline + void sb(); // Start a block + void eb(); // End a block + void sp(); // Print separator + + bool operator!() const; // Check whether the output state is ok + +private: + + std::ofstream out_; + int pos_; + int indent_; + int indentSave_; + bool separator_; +}; + +template<typename T> +Output& operator<<(Output& out, const T& val) +{ + std::ostringstream s; + s << val; + out.print(s.str().c_str()); + return out; +} + +Output& operator<<(Output&, const NextLine&); +Output& operator<<(Output&, const StartBlock&); +Output& operator<<(Output&, const EndBlock&); +Output& operator<<(Output&, const Separator&); + +} + +#endif diff --git a/cpp/src/Slice/Parser.cpp b/cpp/src/Slice/Parser.cpp new file mode 100644 index 00000000000..beafbc1725a --- /dev/null +++ b/cpp/src/Slice/Parser.cpp @@ -0,0 +1,973 @@ +// ********************************************************************** +// +// Copyright (c) 2001 +// MutableRealms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#include <Ice/Functional.h> +#include <Parser.h> + +using namespace std; +using namespace IceLang; + +namespace IceLang +{ + +Parser* parser; + +} + +void __Ice::incRef(Token* p) { p -> __incRef(); } +void __Ice::decRef(Token* p) { p -> __decRef(); } +void __Ice::incRef(String* p) { p -> __incRef(); } +void __Ice::decRef(String* p) { p -> __decRef(); } +void __Ice::incRef(Parameters* p) { p -> __incRef(); } +void __Ice::decRef(Parameters* p) { p -> __decRef(); } +void __Ice::incRef(Throws* p) { p -> __incRef(); } +void __Ice::decRef(Throws* p) { p -> __decRef(); } +void __Ice::incRef(DataMember* p) { p -> __incRef(); } +void __Ice::decRef(DataMember* p) { p -> __decRef(); } +void __Ice::incRef(SyntaxTreeBase* p) { p -> __incRef(); } +void __Ice::decRef(SyntaxTreeBase* p) { p -> __decRef(); } +void __Ice::incRef(Type* p) { p -> __incRef(); } +void __Ice::decRef(Type* p) { p -> __decRef(); } +void __Ice::incRef(Builtin* p) { p -> __incRef(); } +void __Ice::decRef(Builtin* p) { p -> __decRef(); } +void __Ice::incRef(Contained* p) { p -> __incRef(); } +void __Ice::decRef(Contained* p) { p -> __decRef(); } +void __Ice::incRef(Container* p) { p -> __incRef(); } +void __Ice::decRef(Container* p) { p -> __decRef(); } +void __Ice::incRef(Module* p) { p -> __incRef(); } +void __Ice::decRef(Module* p) { p -> __decRef(); } +void __Ice::incRef(Constructed* p) { p -> __incRef(); } +void __Ice::decRef(Constructed* p) { p -> __decRef(); } +void __Ice::incRef(ClassDecl* p) { p -> __incRef(); } +void __Ice::decRef(ClassDecl* p) { p -> __decRef(); } +void __Ice::incRef(ClassDef* p) { p -> __incRef(); } +void __Ice::decRef(ClassDef* p) { p -> __decRef(); } +void __Ice::incRef(Proxy* p) { p -> __incRef(); } +void __Ice::decRef(Proxy* p) { p -> __decRef(); } +void __Ice::incRef(Operation* p) { p -> __incRef(); } +void __Ice::decRef(Operation* p) { p -> __decRef(); } +void __Ice::incRef(Vector* p) { p -> __incRef(); } +void __Ice::decRef(Vector* p) { p -> __decRef(); } +void __Ice::incRef(Parser* p) { p -> __incRef(); } +void __Ice::decRef(Parser* p) { p -> __decRef(); } + +// ---------------------------------------------------------------------- +// SyntaxTreeBase +// ---------------------------------------------------------------------- + +void +IceLang::SyntaxTreeBase::destroy() +{ + parser_ = 0; +} + +Parser_ptr +IceLang::SyntaxTreeBase::parser() +{ + return parser_; +} + +void +IceLang::SyntaxTreeBase::visit(ParserVisitor*) +{ +} + +IceLang::SyntaxTreeBase::SyntaxTreeBase(const Parser_ptr& parser) + : parser_(parser) +{ +} + +// ---------------------------------------------------------------------- +// Type +// ---------------------------------------------------------------------- + +IceLang::Type::Type(const Parser_ptr& parser) + : SyntaxTreeBase(parser) +{ +} + +// ---------------------------------------------------------------------- +// Builtin +// ---------------------------------------------------------------------- + +IceLang::Builtin::Kind +IceLang::Builtin::kind() +{ + return kind_; +} + +IceLang::Builtin::Builtin(const Parser_ptr& parser, Kind kind) + : Type(parser), + SyntaxTreeBase(parser), + kind_(kind) +{ +} + +// ---------------------------------------------------------------------- +// Contained +// ---------------------------------------------------------------------- + +Container_ptr +IceLang::Contained::container() +{ + return container_; +} + +string +IceLang::Contained::name() +{ + return name_; +} + +string +IceLang::Contained::scoped() +{ + return scoped_; +} + +string +IceLang::Contained::scope() +{ + string::size_type idx = scoped_.rfind("::"); + assert(idx != string::npos); + return string(scoped_, 0, idx); +} + +IceLang::Contained::Contained(const Container_ptr& container, + const string& name) + : SyntaxTreeBase(container -> parser()), + container_(container), + name_(name) +{ + Contained_ptr cont = Contained_ptr::dynamicCast(container_); + if(cont) + scoped_ = cont -> scoped(); + scoped_ += "::" + name_; + if(parser_) + parser_ -> addContent(this); +} + +bool +IceLang::operator<(Contained& l, Contained& r) +{ + return l.name() < r.name(); +} + +bool +IceLang::operator==(Contained& l, Contained& r) +{ + return l.name() == r.name(); +} + +// ---------------------------------------------------------------------- +// Container +// ---------------------------------------------------------------------- + +void +IceLang::Container::destroy() +{ + for(vector<Contained_ptr>::iterator p = contents_.begin(); + p != contents_.end(); + ++p) + { + (*p) -> destroy(); + } + + contents_.clear(); + SyntaxTreeBase::destroy(); +} + +Module_ptr +IceLang::Container::createModule(const string& name) +{ + vector<Contained_ptr> matches = + parser_ -> findContents(thisScope() + name); + for(vector<Contained_ptr>::iterator p = matches.begin(); + p != matches.end(); + ++p) + { + Module_ptr module = Module_ptr::dynamicCast(*p); + if(module) + continue; // Reopening modules is permissible + + assert(false); // TODO: Already exits + } + + Module_ptr q = new Module(this, name); + contents_.push_back(q); + return q; +} + +ClassDef_ptr +IceLang::Container::createClassDef(const string& name, + const ClassDef_ptr& base, + bool local) +{ + vector<Contained_ptr> matches = + parser_ -> findContents(thisScope() + name); + for(vector<Contained_ptr>::iterator p = matches.begin(); + p != matches.end(); + ++p) + { + ClassDecl_ptr cl = ClassDecl_ptr::dynamicCast(*p); + assert(cl); // TODO: Already exits + + // TODO: Check whether locality matches + } + + ClassDef_ptr def = new ClassDef(this, name, base, local); + contents_.push_back(def); + + for(vector<Contained_ptr>::iterator q = matches.begin(); + q != matches.end(); + ++q) + { + ClassDecl_ptr cl = ClassDecl_ptr::dynamicCast(*q); + cl -> definition_ = def; + } + + // + // Implicitly create a class declaration for each class + // definition. This way the code generator can rely on always + // having a class declaration available for lookup. + // + createClassDecl(name, local); + + return def; +} + +ClassDecl_ptr +IceLang::Container::createClassDecl(const string& name, bool local) +{ + ClassDef_ptr def; + + vector<Contained_ptr> matches = + parser_ -> findContents(thisScope() + name); + for(vector<Contained_ptr>::iterator p = matches.begin(); + p != matches.end(); + ++p) + { + ClassDef_ptr clDef = ClassDef_ptr::dynamicCast(*p); + if(clDef) + { + assert(!def); + def = clDef; + continue; // TODO: Check whether locality matches + } + + ClassDecl_ptr clDecl = ClassDecl_ptr::dynamicCast(*p); + if(clDecl) + continue; // TODO: Check whether locality matches + + assert(false); // TODO: Not a class + } + + // + // Multiple declarations are permissible. But if we do already + // have a declaration for the class in this container, we don't + // create another one. + // + for(vector<Contained_ptr>::iterator q = contents_.begin(); + q != contents_.end(); + ++q) + { + if((*q) -> name() == name) + { + ClassDecl_ptr cl = ClassDecl_ptr::dynamicCast(*q); + if(cl) + return cl; + + assert(ClassDef_ptr::dynamicCast(*q)); + } + } + + ClassDecl_ptr cl = new ClassDecl(this, name, local); + contents_.push_back(cl); + + if(def) + cl -> definition_ = def; + + return cl; +} + +Vector_ptr +IceLang::Container::createVector(const string& name, const Type_ptr& type) +{ + vector<Contained_ptr> matches = + parser_ -> findContents(thisScope() + name); + assert(matches.empty()); // TODO: Already exits + + Vector_ptr p = new Vector(this, name, type); + contents_.push_back(p); + return p; +} + +vector<Type_ptr> +IceLang::Container::lookupType(const string& scoped) +{ + assert(!scoped.empty()); + + if(scoped[0] == ':') + return parser_ -> lookupType(scoped.substr(2)); + + vector<Contained_ptr> matches = + parser_ -> findContents(thisScope() + scoped); + if(matches.empty()) + { + Contained_ptr contained = Contained_ptr::dynamicCast(this); + assert(contained); // TODO: Not found error + return contained -> container() -> lookupType(scoped); + } + else + { + vector<Type_ptr> results; + results.reserve(matches.size()); + for(vector<Contained_ptr>::iterator p = matches.begin(); + p != matches.end(); + ++p) + { + ClassDef_ptr cl = ClassDef_ptr::dynamicCast(*p); + if(cl) + continue; // Ignore class definitions + + Type_ptr type = Type_ptr::dynamicCast(*p); + assert(type); // TODO: Not a type error + results.push_back(type); + } + return results; + } +} + +int +IceLang::Container::includeLevel() +{ + return includeLevel_; +} + +bool +IceLang::Container::hasProxies() +{ + for(vector<Contained_ptr>::const_iterator p = contents_.begin(); + p != contents_.end(); + ++p) + { + ClassDecl_ptr cl = ClassDecl_ptr::dynamicCast(*p); + if(cl && !cl -> local()) + return true; + + Container_ptr container = Container_ptr::dynamicCast(*p); + if(container && container -> hasProxies()) + return true; + } + + return false; +} + +bool +IceLang::Container::hasClassDecls() +{ + for(vector<Contained_ptr>::const_iterator p = contents_.begin(); + p != contents_.end(); + ++p) + { + if(ClassDecl_ptr::dynamicCast(*p)) + return true; + + Container_ptr container = Container_ptr::dynamicCast(*p); + if(container && container -> hasClassDecls()) + return true; + } + + return false; +} + +bool +IceLang::Container::hasClassDefs() +{ + for(vector<Contained_ptr>::const_iterator p = contents_.begin(); + p != contents_.end(); + ++p) + { + if(ClassDef_ptr::dynamicCast(*p)) + return true; + + Container_ptr container = Container_ptr::dynamicCast(*p); + if(container && container -> hasClassDefs()) + return true; + } + + return false; +} + +bool +IceLang::Container::hasOtherConstructedTypes() +{ + for(vector<Contained_ptr>::const_iterator p = contents_.begin(); + p != contents_.end(); + ++p) + { + if(Constructed_ptr::dynamicCast(*p) && + !ClassDecl_ptr::dynamicCast(*p) && + !ClassDef_ptr::dynamicCast(*p)) + return true; + + Container_ptr container = Container_ptr::dynamicCast(*p); + if(container && container -> hasOtherConstructedTypes()) + return true; + } + + return false; +} + +string +IceLang::Container::thisScope() +{ + string s; + Contained_ptr contained = Contained_ptr::dynamicCast(this); + if(contained) + s = contained -> scoped(); + s += "::"; + return s; +} + +void +IceLang::Container::visit(ParserVisitor* visitor) +{ + for(vector<Contained_ptr>::const_iterator p = contents_.begin(); + p != contents_.end(); + ++p) + { + (*p) -> visit(visitor); + } +} + +IceLang::Container::Container(const Parser_ptr& parser) + : SyntaxTreeBase(parser) +{ + if(parser_) + includeLevel_ = parser -> currentIncludeLevel(); + else + includeLevel_ = 0; +} + +// ---------------------------------------------------------------------- +// Module +// ---------------------------------------------------------------------- + +void +IceLang::Module::visit(ParserVisitor* visitor) +{ + if(includeLevel_ > 0) + return; + + visitor -> visitModuleStart(this); + Container::visit(visitor); + visitor -> visitModuleEnd(this); +} + +IceLang::Module::Module(const Container_ptr& container, + const string& name) + : Contained(container, name), + Container(container -> parser()), + SyntaxTreeBase(container -> parser()) +{ +} + +// ---------------------------------------------------------------------- +// Constructed +// ---------------------------------------------------------------------- + +IceLang::Constructed::Constructed(const Container_ptr& container, + const string& name) + : Type(container -> parser()), + Contained(container, name), + SyntaxTreeBase(container -> parser()) +{ +} + +// ---------------------------------------------------------------------- +// ClassDecl +// ---------------------------------------------------------------------- + +ClassDef_ptr +IceLang::ClassDecl::definition() +{ + return definition_; +} + +bool +IceLang::ClassDecl::local() +{ + return local_; +} + +void +IceLang::ClassDecl::visit(ParserVisitor* visitor) +{ + visitor -> visitClassDecl(this); +} + +IceLang::ClassDecl::ClassDecl(const Container_ptr& container, + const string& name, + bool local) + : Constructed(container, name), + Type(container -> parser()), + Contained(container, name), + SyntaxTreeBase(container -> parser()), + local_(local) +{ +} + +// ---------------------------------------------------------------------- +// ClassDef +// ---------------------------------------------------------------------- + +void +IceLang::ClassDef::destroy() +{ + base_ = 0; + Container::destroy(); +} + +Operation_ptr +IceLang::ClassDef::createOperation(const string& name, + const Type_ptr& returnType, + const TypeNameList& inParams, + const TypeNameList& outParams, + const TypeList& throws) +{ + vector<Contained_ptr> matches = + parser_ -> findContents(thisScope() + name); + assert(matches.empty()); // TODO: Already exits + + Operation_ptr p = new Operation(this, name, returnType, + inParams, outParams, throws); + contents_.push_back(p); + return p; +} + +DataMember_ptr +IceLang::ClassDef::createDataMember(const string& name, const Type_ptr& type) +{ + vector<Contained_ptr> matches = + parser_ -> findContents(thisScope() + name); + assert(matches.empty()); // TODO: Already exits + + DataMember_ptr p = new DataMember(this, name, type); + contents_.push_back(p); + return p; +} + +ClassDef_ptr +IceLang::ClassDef::base() +{ + return base_; +} + +void +IceLang::ClassDef::base(const ClassDef_ptr& cl) +{ + base_ = cl; +} + +vector<Operation_ptr> +IceLang::ClassDef::operations() +{ + vector<Operation_ptr> result; + for(vector<Contained_ptr>::const_iterator p = contents_.begin(); + p != contents_.end(); + ++p) + { + Operation_ptr derived = Operation_ptr::dynamicCast(*p); + if(derived) + result.push_back(derived); + } + return result; +} + +vector<DataMember_ptr> +IceLang::ClassDef::dataMembers() +{ + vector<DataMember_ptr> result; + for(vector<Contained_ptr>::const_iterator p = contents_.begin(); + p != contents_.end(); + ++p) + { + DataMember_ptr derived = DataMember_ptr::dynamicCast(*p); + if(derived) + result.push_back(derived); + } + return result; +} + +bool +IceLang::ClassDef::abstract() +{ + if(base_ && base_ -> abstract()) + return true; + + for(vector<Contained_ptr>::const_iterator p = contents_.begin(); + p != contents_.end(); + ++p) + { + if(Operation_ptr::dynamicCast(*p)) + return true; + } + + return false; +} + +bool +IceLang::ClassDef::local() +{ + return local_; +} + +void +IceLang::ClassDef::visit(ParserVisitor* visitor) +{ + if(includeLevel_ > 0) + return; + + visitor -> visitClassDefStart(this); + Container::visit(visitor); + visitor -> visitClassDefEnd(this); +} + +IceLang::ClassDef::ClassDef(const Container_ptr& container, + const string& name, + const ClassDef_ptr& base, + bool local) + : Contained(container, name), + Container(container -> parser()), + SyntaxTreeBase(container -> parser()), + base_(base), + local_(local) +{ +} + +// ---------------------------------------------------------------------- +// Proxy +// ---------------------------------------------------------------------- + +ClassDecl_ptr +IceLang::Proxy::_class() +{ + return class_; +} + +IceLang::Proxy::Proxy(const ClassDecl_ptr& cl) + : Type(cl -> parser()), + SyntaxTreeBase(cl -> parser()), + class_(cl) +{ +} + +// ---------------------------------------------------------------------- +// Operation +// ---------------------------------------------------------------------- + +Type_ptr +IceLang::Operation::returnType() +{ + return returnType_; +} + +TypeNameList +IceLang::Operation::inputParameters() +{ + return inParams_; +} + +TypeNameList +IceLang::Operation::outputParameters() +{ + return outParams_; +} + +TypeList +IceLang::Operation::throws() +{ + return throws_; +} + +void +IceLang::Operation::visit(ParserVisitor* visitor) +{ + visitor -> visitOperation(this); +} + +IceLang::Operation::Operation(const Container_ptr& container, + const string& name, + const Type_ptr& returnType, + const TypeNameList& inParams, + const TypeNameList& outParams, + const TypeList& throws) + : Contained(container, name), + SyntaxTreeBase(container -> parser()), + returnType_(returnType), + inParams_(inParams), + outParams_(outParams), + throws_(throws) +{ +} + +// ---------------------------------------------------------------------- +// DataMember +// ---------------------------------------------------------------------- + +Type_ptr +IceLang::DataMember::type() +{ + return type_; +} +void +IceLang::DataMember::visit(ParserVisitor* visitor) +{ + visitor -> visitDataMember(this); +} + +IceLang::DataMember::DataMember(const Container_ptr& container, + const string& name, + const Type_ptr& type) + : Contained(container, name), + SyntaxTreeBase(container -> parser()), + type_(type) +{ +} + +// ---------------------------------------------------------------------- +// Vector +// ---------------------------------------------------------------------- + +Type_ptr +IceLang::Vector::type() +{ + return type_; +} + +void +IceLang::Vector::visit(ParserVisitor* visitor) +{ + visitor -> visitVector(this); +} + +IceLang::Vector::Vector(const Container_ptr& container, + const string& name, + const Type_ptr& type) + : Constructed(container, name), + Type(container -> parser()), + Contained(container, name), + SyntaxTreeBase(container -> parser()), + type_(type) +{ +} + +// ---------------------------------------------------------------------- +// Parser +// ---------------------------------------------------------------------- + +Parser_ptr +IceLang::Parser::createParser() +{ + return new Parser; +} + +void +IceLang::Parser::nextLine() +{ + currentLine_++; +} + +void +IceLang::Parser::scanPosition(const char* s) +{ + string line(s); + string::size_type idx; + + idx = line.find("line"); + if(idx != string::npos) + line.erase(0, idx + 4); + + idx = line.find_first_not_of(" \t\r#"); + if(idx != string::npos) + line.erase(0, idx); + + currentLine_ = atoi(line.c_str()) - 1; + + idx = line.find_first_of(" \t\r"); + if(idx != string::npos) + line.erase(0, idx); + + idx = line.find_first_not_of(" \t\r\""); + if(idx != string::npos) + { + line.erase(0, idx); + + idx = line.find_first_of(" \t\r\""); + if(idx != string::npos) + { + currentFile_ = line.substr(0, idx); + line.erase(0, idx + 1); + } + else + currentFile_ = line; + + idx = line.find_first_not_of(" \t\r"); + if(idx != string::npos) + { + line.erase(0, idx); + int val = atoi(line.c_str()); + if(val == 1) + { + if(++currentIncludeLevel_ == 1) + { + if(find(includeFiles_.begin(), includeFiles_.end(), + currentFile_) == includeFiles_.end()) + { + includeFiles_.push_back(currentFile_); + } + } + } + else if(val == 2) + { + --currentIncludeLevel_; + } + } + else + { + if(currentIncludeLevel_ == 0) + topLevelFile_ = currentFile_; + } + } +} + +int +IceLang::Parser::currentIncludeLevel() +{ + return currentIncludeLevel_; +} + +void +IceLang::Parser::error(const char* s) +{ + cerr << currentFile_ << ':' << currentLine_ << " error: " << s << endl; + yynerrs++; +} + +void +IceLang::Parser::warning(const char* s) +{ + cerr << currentFile_ << ':' << currentLine_ << " warning: " << s << endl; +} + +Container_ptr +IceLang::Parser::currentContainer() +{ + assert(!containerStack_.empty()); + return containerStack_.top(); +} + +void +IceLang::Parser::pushContainer(const Container_ptr& cont) +{ + containerStack_.push(cont); +} + +void +IceLang::Parser::popContainer() +{ + assert(!containerStack_.empty()); + containerStack_.pop(); +} + +void +IceLang::Parser::addContent(const Contained_ptr& contained) +{ + contentMap_[contained -> scoped()].push_back(contained); +} + +vector<Contained_ptr> +IceLang::Parser::findContents(const string& scoped) +{ + assert(!scoped.empty()); + assert(scoped[0] == ':'); + + map<string, vector<Contained_ptr> >::iterator p = + contentMap_.find(scoped); + + if(p != contentMap_.end()) + return p -> second; + else + return vector<Contained_ptr>(); +} + +vector<string> +IceLang::Parser::includeFiles() +{ + return includeFiles_; +} + +int +IceLang::Parser::parse(FILE* file) +{ + assert(!IceLang::parser); + IceLang::parser = this; + + currentLine_ = 1; + currentIncludeLevel_ = 0; + currentFile_ = "<standard input>"; + topLevelFile_ = currentFile_; + includeFiles_.clear(); + pushContainer(this); + + extern FILE* yyin; + yyin = file; + int status = yyparse(); + + assert(containerStack_.size() == 1); + popContainer(); + + IceLang::parser = 0; + return status; +} + +void +IceLang::Parser::destroy() +{ + builtins_.clear(); + Container::destroy(); +} + +void +IceLang::Parser::visit(ParserVisitor* visitor) +{ + visitor -> visitUnitStart(this); + Container::visit(visitor); + visitor -> visitUnitEnd(this); +} + +Builtin_ptr +IceLang::Parser::builtin(Builtin::Kind kind) +{ + map<Builtin::Kind, Builtin_ptr>::iterator p = builtins_.find(kind); + if(p != builtins_.end()) + return p -> second; + Builtin_ptr builtin = new Builtin(this, kind); + builtins_.insert(make_pair(kind, builtin)); + return builtin; +} + +IceLang::Parser::Parser() + : SyntaxTreeBase(0), + Container(0) +{ + parser_ = this; +} diff --git a/cpp/src/Slice/Parser.h b/cpp/src/Slice/Parser.h new file mode 100644 index 00000000000..0c30a3b097b --- /dev/null +++ b/cpp/src/Slice/Parser.h @@ -0,0 +1,545 @@ +// ********************************************************************** +// +// Copyright (c) 2001 +// MutableRealms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#ifndef PARSER_H +#define PARSER_H + +#include <Ice/Shared.h> +#include <Ice/Handle.h> +#include <list> +#include <stack> +#include <map> + +extern int yynerrs; + +int yyparse(); +int yylex(); +void yyerror(const char* s); + +// ---------------------------------------------------------------------- +// Type_ptr declarations, reference counting, and handle types +// ---------------------------------------------------------------------- + +namespace IceLang +{ + +class Token; +class String; +class Parameters; +class Throws; +class SyntaxTreeBase; +class Type; +class Builtin; +class Contained; +class Container; +class Module; +class Constructed; +class ClassDecl; +class ClassDef; +class Proxy; +class Operation; +class DataMember; +class Vector; +class Parser; + +} + +namespace __Ice +{ + +void incRef(::IceLang::Token*); +void decRef(::IceLang::Token*); +void incRef(::IceLang::String*); +void decRef(::IceLang::String*); +void incRef(::IceLang::Parameters*); +void decRef(::IceLang::Parameters*); +void incRef(::IceLang::Throws*); +void decRef(::IceLang::Throws*); +void incRef(::IceLang::SyntaxTreeBase*); +void decRef(::IceLang::SyntaxTreeBase*); +void incRef(::IceLang::Type*); +void decRef(::IceLang::Type*); +void incRef(::IceLang::Builtin*); +void decRef(::IceLang::Builtin*); +void incRef(::IceLang::Contained*); +void decRef(::IceLang::Contained*); +void incRef(::IceLang::Container*); +void decRef(::IceLang::Container*); +void incRef(::IceLang::Module*); +void decRef(::IceLang::Module*); +void incRef(::IceLang::Constructed*); +void decRef(::IceLang::Constructed*); +void incRef(::IceLang::ClassDecl*); +void decRef(::IceLang::ClassDecl*); +void incRef(::IceLang::ClassDef*); +void decRef(::IceLang::ClassDef*); +void incRef(::IceLang::Proxy*); +void decRef(::IceLang::Proxy*); +void incRef(::IceLang::Operation*); +void decRef(::IceLang::Operation*); +void incRef(::IceLang::DataMember*); +void decRef(::IceLang::DataMember*); +void incRef(::IceLang::Vector*); +void decRef(::IceLang::Vector*); +void incRef(::IceLang::Parser*); +void decRef(::IceLang::Parser*); + +} + +namespace IceLang +{ + +typedef ::__Ice::Handle<Token> Token_ptr; +typedef ::__Ice::Handle<String> String_ptr; +typedef ::__Ice::Handle<Parameters> Parameters_ptr; +typedef ::__Ice::Handle<Throws> Throws_ptr; +typedef ::__Ice::Handle<SyntaxTreeBase> SyntaxTreeBase_ptr; +typedef ::__Ice::Handle<Type> Type_ptr; +typedef ::__Ice::Handle<Builtin> Builtin_ptr; +typedef ::__Ice::Handle<Contained> Contained_ptr; +typedef ::__Ice::Handle<Container> Container_ptr; +typedef ::__Ice::Handle<Module> Module_ptr; +typedef ::__Ice::Handle<Constructed> Constructed_ptr; +typedef ::__Ice::Handle<ClassDecl> ClassDecl_ptr; +typedef ::__Ice::Handle<ClassDef> ClassDef_ptr; +typedef ::__Ice::Handle<Proxy> Proxy_ptr; +typedef ::__Ice::Handle<Operation> Operation_ptr; +typedef ::__Ice::Handle<DataMember> DataMember_ptr; +typedef ::__Ice::Handle<Vector> Vector_ptr; +typedef ::__Ice::Handle<Parser> Parser_ptr; + +} + +namespace IceLang +{ + +typedef std::list<Type_ptr> TypeList; +typedef std::pair<Type_ptr, std::string> TypeName; +typedef std::list<TypeName> TypeNameList; + +// ---------------------------------------------------------------------- +// ParserVisitor +// ---------------------------------------------------------------------- + +class ParserVisitor +{ +public: + + virtual ~ParserVisitor() { } + virtual void visitUnitStart(const Parser_ptr&) { }; + virtual void visitUnitEnd(const Parser_ptr&) { }; + virtual void visitModuleStart(const Module_ptr&) { }; + virtual void visitModuleEnd(const Module_ptr&) { }; + virtual void visitClassDecl(const ClassDecl_ptr&) { }; + virtual void visitClassDefStart(const ClassDef_ptr&) { }; + virtual void visitClassDefEnd(const ClassDef_ptr&) { }; + virtual void visitOperation(const Operation_ptr&) { }; + virtual void visitDataMember(const DataMember_ptr&) { }; + virtual void visitVector(const Vector_ptr&) { }; +}; + +// ---------------------------------------------------------------------- +// Token +// ---------------------------------------------------------------------- + +class Token : virtual public ::__Ice::SimpleShared +{ +}; + +#define YYSTYPE IceLang::Token_ptr + +// ---------------------------------------------------------------------- +// String +// ---------------------------------------------------------------------- + +class String : virtual public Token +{ +public: + + String() { } + std::string v; +}; + +// ---------------------------------------------------------------------- +// Parameters +// ---------------------------------------------------------------------- + +class Parameters : virtual public Token +{ +public: + + Parameters() { } + TypeNameList v; +}; + +// ---------------------------------------------------------------------- +// Throws +// ---------------------------------------------------------------------- + +class Throws : virtual public Token +{ +public: + + Throws() { } + TypeList v; +}; + +// ---------------------------------------------------------------------- +// SyntaxTreeBase +// ---------------------------------------------------------------------- + +class SyntaxTreeBase : virtual public ::__Ice::SimpleShared +{ +public: + + virtual void destroy(); + Parser_ptr parser(); + virtual void visit(ParserVisitor*); + +protected: + + SyntaxTreeBase(const Parser_ptr&); + + Parser_ptr parser_; +}; + +// ---------------------------------------------------------------------- +// Type +// ---------------------------------------------------------------------- + +class Type : virtual public SyntaxTreeBase, virtual public Token +{ +public: + +protected: + + Type(const Parser_ptr&); +}; + +// ---------------------------------------------------------------------- +// Builtin +// ---------------------------------------------------------------------- + +class Builtin : virtual public Type +{ +public: + + enum Kind + { + KindByte, + KindBool, + KindShort, + KindInt, + KindLong, + KindFloat, + KindDouble, + KindString, + KindWString, + KindObject, + KindObjectProxy, + KindLocalObject + }; + Kind kind(); + +protected: + + Builtin(const Parser_ptr&, Kind); + friend class Parser; + + Kind kind_; +}; + +// ---------------------------------------------------------------------- +// Contained +// ---------------------------------------------------------------------- + +class Contained : virtual public SyntaxTreeBase +{ +public: + + Container_ptr container(); + std::string name(); + std::string scoped(); + std::string scope(); + +protected: + + Contained(const Container_ptr&, + const std::string&); + friend class Container; + + Container_ptr container_; + std::string name_; + std::string scoped_; +}; + +bool operator<(Contained&, Contained&); +bool operator==(Contained&, Contained&); + +// ---------------------------------------------------------------------- +// Container +// ---------------------------------------------------------------------- + +class Container : virtual public SyntaxTreeBase +{ +public: + + virtual void destroy(); + Module_ptr createModule(const std::string&); + ClassDef_ptr createClassDef(const std::string&, const ClassDef_ptr&, bool); + ClassDecl_ptr createClassDecl(const std::string&, bool); + Vector_ptr createVector(const std::string&, const Type_ptr&); + std::vector<Type_ptr> lookupType(const std::string&); + int includeLevel(); + bool hasProxies(); + bool hasClassDecls(); + bool hasClassDefs(); + bool hasOtherConstructedTypes(); // Other than classes + std::string thisScope(); + virtual void visit(ParserVisitor*); + +protected: + + Container(const Parser_ptr&); + + int includeLevel_; + std::vector<Contained_ptr> contents_; +}; + +// ---------------------------------------------------------------------- +// Module +// ---------------------------------------------------------------------- + +class Module : virtual public Container, virtual public Contained +{ +public: + + virtual void visit(ParserVisitor*); + +protected: + + Module(const Container_ptr&, + const std::string&); + friend class Container; +}; + +// ---------------------------------------------------------------------- +// Constructed +// ---------------------------------------------------------------------- + +class Constructed : virtual public Type, virtual public Contained +{ +public: + +protected: + + Constructed(const Container_ptr&, + const std::string&); +}; + +// ---------------------------------------------------------------------- +// ClassDecl +// ---------------------------------------------------------------------- + +class ClassDecl : virtual public Constructed +{ +public: + + ClassDef_ptr definition(); + bool local(); + virtual void visit(ParserVisitor*); + +protected: + + ClassDecl(const Container_ptr&, + const std::string&, + bool); + friend class Container; + friend class ClassDef; + + bool local_; + ClassDef_ptr definition_; +}; + +// ---------------------------------------------------------------------- +// ClassDef +// ---------------------------------------------------------------------- + +class ClassDef : virtual public Container, virtual public Contained, + virtual public Token +{ +public: + + virtual void destroy(); + Operation_ptr createOperation(const std::string&, const Type_ptr&, + const TypeNameList&, const TypeNameList&, + const TypeList&); + DataMember_ptr createDataMember(const std::string&, const Type_ptr&); + ClassDef_ptr base(); + void base(const ClassDef_ptr&); + std::vector<Operation_ptr> operations(); + std::vector<DataMember_ptr> dataMembers(); + bool abstract(); + bool local(); + virtual void visit(ParserVisitor*); + +protected: + + ClassDef(const Container_ptr&, + const std::string&, + const ClassDef_ptr&, + bool); + friend class Container; + + ClassDef_ptr base_; + bool local_; +}; + +// ---------------------------------------------------------------------- +// Proxy +// ---------------------------------------------------------------------- + +class Proxy : virtual public Type +{ +public: + + ClassDecl_ptr _class(); + + Proxy(const ClassDecl_ptr&); + +protected: + + ClassDecl_ptr class_; +}; + +// ---------------------------------------------------------------------- +// Operation +// ---------------------------------------------------------------------- + +class Operation : virtual public Contained +{ +public: + + Type_ptr returnType(); + TypeNameList inputParameters(); + TypeNameList outputParameters(); + TypeList throws(); + virtual void visit(ParserVisitor*); + +protected: + + Operation(const Container_ptr&, + const std::string&, + const Type_ptr&, + const TypeNameList&, + const TypeNameList&, + const TypeList&); + friend class ClassDef; + + Type_ptr returnType_; + TypeNameList inParams_; + TypeNameList outParams_; + TypeList throws_; +}; + +// ---------------------------------------------------------------------- +// DataMember +// ---------------------------------------------------------------------- + +class DataMember : virtual public Contained +{ +public: + + Type_ptr type(); + virtual void visit(ParserVisitor*); + +protected: + + DataMember(const Container_ptr&, + const std::string&, + const Type_ptr&); + friend class ClassDef; + + Type_ptr type_; +}; + +// ---------------------------------------------------------------------- +// Vector +// ---------------------------------------------------------------------- + +class Vector : virtual public Constructed +{ +public: + + Type_ptr type(); + virtual void visit(ParserVisitor*); + +protected: + + Vector(const Container_ptr&, + const std::string&, + const Type_ptr&); + friend class Container; + + Type_ptr type_; +}; + +// ---------------------------------------------------------------------- +// Parser +// ---------------------------------------------------------------------- + +class Parser : virtual public Container +{ +public: + + static Parser_ptr createParser(); + + void nextLine(); + void scanPosition(const char*); + int currentIncludeLevel(); + + void error(const char*); + void warning(const char*); + + Container_ptr currentContainer(); + void pushContainer(const Container_ptr&); + void popContainer(); + + void addContent(const Contained_ptr&); + std::vector<Contained_ptr> findContents(const std::string&); + + std::vector<std::string> includeFiles(); + + int parse(FILE*); + + virtual void destroy(); + virtual void visit(ParserVisitor*); + + Builtin_ptr builtin(Builtin::Kind); + +private: + + Parser(); + + int currentLine_; + int currentIncludeLevel_; + std::string currentFile_; + std::string topLevelFile_; + std::vector<std::string> includeFiles_; + std::stack<Container_ptr> containerStack_; + std::map<Builtin::Kind, Builtin_ptr> builtins_; + std::map<std::string, std::vector<Contained_ptr> > contentMap_; +}; + +extern Parser* parser; // The current parser for bison/flex + +} + +#endif diff --git a/cpp/src/Slice/Scanner.l b/cpp/src/Slice/Scanner.l new file mode 100644 index 00000000000..111290afb1d --- /dev/null +++ b/cpp/src/Slice/Scanner.l @@ -0,0 +1,197 @@ +%{ + +// ********************************************************************** +// +// Copyright (c) 2001 +// MutableRealms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#include <Parser.h> +#include <Grammer.h> + +using namespace std; +using namespace IceLang; + +%} + +%option noyywrap +%option never-interactive + +WS [ \t\v\n\r\f] +S [ \t] +D [0-9] +L [a-zA-Z_] + +%% + +^"#"{S}*{D}+{S}*$ { + parser -> scanPosition(yytext); +} + +^"#"{S}*{D}+{S}+"\""[^\"]*"\"".*$ { + parser -> scanPosition(yytext); +} + +^"#"{S}*"line"{S}+{D}+{S}*$ { + parser -> scanPosition(yytext); +} + +^"#"{S}*"line"{S}+{D}+{S}+"\""[^\"]*"\"".*$ { + parser -> scanPosition(yytext); +} + +"//" { + // C++-style comment + + int c; + + do + { + c = yyinput(); + if(c == '\n') + parser -> nextLine(); + } + while(c != '\n' && c != EOF); +} + +"/*" { + // C-style comment + + while(true) + { + int c = yyinput(); + + if(c == '\n') + { + parser -> nextLine(); + } + else if(c == '*') + { + int next = yyinput(); + + if(next == '/') + break; + else + unput(next); + } + else if(c == EOF) + { + parser -> warning("EOF in comment"); + break; + } + } +} + +"::" { + return ICE_SCOPE_DELIMITOR; +} + +"module" { + return ICE_MODULE; +} + +"class" { + return ICE_CLASS; +} + +"local" { + return ICE_LOCAL; +} + +"extends" { + return ICE_EXTENDS; +} + +"throws" { + return ICE_THROWS; +} + +"void" { + return ICE_VOID; +} + +"byte" { + return ICE_BYTE; +} + +"bool" { + return ICE_BOOL; +} + +"short" { + return ICE_SHORT; +} + +"int" { + return ICE_INT; +} + +"long" { + return ICE_LONG; +} + +"float" { + return ICE_FLOAT; +} + +"double" { + return ICE_DOUBLE; +} + +"string" { + return ICE_STRING; +} + +"wstring" { + return ICE_WSTRING; +} + +"Object" { + return ICE_OBJECT; +} + +"vector" { + return ICE_VECTOR; +} + +"\\"?{L}({L}|{D})* { + char* s = yytext; + + if(s[0] == '\\') // Strip leading backslash + ++s; + + String_ptr ident = new String; + ident -> v = s; + yylval = ident; + return ICE_IDENTIFIER; +} + +"\\"?{L}({L}|{D})*{WS}*"(" { + char* s = yytext; + + if(s[0] == '\\') // Strip leading backslash + ++s; + + String_ptr ident = new String; + ident -> v = s; + ident -> v.erase(ident -> v.find_first_of(" \t\v\n\r\f(")); + yylval = ident; + return ICE_OP_IDENTIFIER; +} + +{WS} { + // Igore white-space + + if(yytext[0] == '\n') + parser -> nextLine(); +} + +. { + return yytext[0]; +} + +%% diff --git a/cpp/src/Slice/dummyinclude/unistd.h b/cpp/src/Slice/dummyinclude/unistd.h new file mode 100644 index 00000000000..92d53d10b9b --- /dev/null +++ b/cpp/src/Slice/dummyinclude/unistd.h @@ -0,0 +1,4 @@ +// +// Files generated by flex need unistd.h, which is not available on +// Windows. Thus this dummy file. +// diff --git a/cpp/src/slice2cpp/GenCPlusPlus.cpp b/cpp/src/slice2cpp/GenCPlusPlus.cpp new file mode 100644 index 00000000000..21559bee07d --- /dev/null +++ b/cpp/src/slice2cpp/GenCPlusPlus.cpp @@ -0,0 +1,1519 @@ +// ********************************************************************** +// +// Copyright (c) 2001 +// MutableRealms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#include <Ice/Functional.h> +#include <GenCPlusPlus.h> +#include <GenCPlusPlusUtil.h> + +using namespace std; +using namespace IceLang; + +struct ToIfdef +{ + char operator()(char c) + { + if(!isalnum(c)) + return '_'; + else + return c; + } +}; + +// ---------------------------------------------------------------------- +// GenCPlusPlus +// ---------------------------------------------------------------------- + +IceLang::GenCPlusPlus::GenCPlusPlus(const string& name, + const string& base, + const string& include, + const vector<string>& includePaths, + const string& dllExport) + : base_(base), + include_(include), + includePaths_(includePaths), + dllExport_(dllExport) +{ + for(vector<string>::iterator p = includePaths_.begin(); + p != includePaths_.end(); + ++p) + { + if(p -> length() && (*p)[p -> length() - 1] != '/') + *p += '/'; + } + + if(dllExport_.length()) + dllExport_ = " " + dllExport_; + + string::size_type pos = base_.rfind('/'); + if(pos != string::npos) + base_.erase(0, pos + 1); + + string fileH = base_ + ".h"; + string fileC = base_ + ".cpp"; + + H.open(fileH.c_str()); + if(!H) + { + cerr << name << ": can't open `" << fileH << "' for writing: " + << strerror(errno) << endl; + return; + } + + C.open(fileC.c_str()); + if(!C) + { + cerr << name << ": can't open `" << fileC << "' for writing: " + << strerror(errno) << endl; + } + + printHeader(H); + printHeader(C); + + string s = fileH; + transform(s.begin(), s.end(), s.begin(), ToIfdef()); + H << "\n#ifndef __" << s << "__"; + H << "\n#define __" << s << "__"; + H << '\n'; +} + +IceLang::GenCPlusPlus::~GenCPlusPlus() +{ + H << "\n\n#endif\n"; + C << '\n'; +} + +bool +IceLang::GenCPlusPlus::operator!() const +{ + return !H || !C; +} + +void +IceLang::GenCPlusPlus::generate(const Parser_ptr& parser) +{ + C << "\n#include <"; + if(include_.length()) + C << include_ << '/'; + C << base_ << ".h>"; + + if(parser -> hasProxies()) + { +// H << "\n#include <Ice/ProxyF.h>"; +// H << "\n#include <Ice/ObjectF.h>"; + H << "\n#include <Ice/Proxy.h>"; + H << "\n#include <Ice/Object.h>"; + H << "\n#include <Ice/Outgoing.h>"; + H << "\n#include <Ice/Incoming.h>"; + H << "\n#include <Ice/LocalException.h>"; + } + else + { +// H << "\n#include <Ice/LocalObjectF.h>"; + H << "\n#include <Ice/LocalObject.h>"; + C << "\n#include <Ice/Stream.h>"; + } + + vector<string> includes = parser -> includeFiles(); + for(vector<string>::iterator q = includes.begin(); + q != includes.end(); + ++q) + { + H << "\n#include <" << changeInclude(*q) << ".h>"; + } + + ProxyDeclVisitor proxyDeclVisitor(H, C, dllExport_); + parser -> visit(&proxyDeclVisitor); + + ObjectDeclVisitor objectDeclVisitor(H, C, dllExport_); + parser -> visit(&objectDeclVisitor); + + IceVisitor iceVisitor(H, C, dllExport_); + parser -> visit(&iceVisitor); + + HandleVisitor handleVisitor(H, C, dllExport_); + parser -> visit(&handleVisitor); + + TypesVisitor typesVisitor(H, C, dllExport_); + parser -> visit(&typesVisitor); + + ProxyVisitor proxyVisitor(H, C, dllExport_); + parser -> visit(&proxyVisitor); + + DelegateVisitor delegateVisitor(H, C, dllExport_); + parser -> visit(&delegateVisitor); + + DelegateMVisitor delegateMVisitor(H, C, dllExport_); + parser -> visit(&delegateMVisitor); + + ObjectVisitor objectVisitor(H, C, dllExport_); + parser -> visit(&objectVisitor); +} + +string +IceLang::GenCPlusPlus::changeInclude(const string& orig) +{ + string file = orig; + for(vector<string>::iterator p = includePaths_.begin(); + p != includePaths_.end(); + ++p) + { + if(orig.compare(0, p -> length(), *p) == 0) + { + string s = orig.substr(p -> length()); + if(s.length() < file.length()) + file = s; + } + } + + string::size_type pos = file.rfind('.'); + if(pos != string::npos) + file.erase(pos); + + return file; +} + +void +IceLang::GenCPlusPlus::printHeader(Output& out) +{ + static const char* header = +"// **********************************************************************\n" +"//\n" +"// Copyright (c) 2001\n" +"// MutableRealms, Inc.\n" +"// Huntsville, AL, USA\n" +"//\n" +"// All Rights Reserved\n" +"//\n" +"// **********************************************************************\n" + ; + + out << header; + out << "\n// Generated from file `" << changeInclude(base_) << ".ice'"; + out << '\n'; +} + +// ---------------------------------------------------------------------- +// TypesVisitor +// ---------------------------------------------------------------------- + +IceLang::GenCPlusPlus::TypesVisitor::TypesVisitor( + Output& h, Output& c, const string& dllExport) + : H(h), C(c), dllExport_(dllExport) +{ +} + +void +IceLang::GenCPlusPlus::TypesVisitor::visitModuleStart( + const Module_ptr& p) +{ + if(!p -> hasOtherConstructedTypes()) + return; + + string name = p -> name(); + + H << sp; + H << nl << "namespace " << name << nl << '{'; +} + +void +IceLang::GenCPlusPlus::TypesVisitor::visitModuleEnd( + const Module_ptr& p) +{ + if(!p -> hasOtherConstructedTypes()) + return; + + H << sp; + H << nl << '}'; +} + +void +IceLang::GenCPlusPlus::TypesVisitor::visitVector( + const Vector_ptr& p) +{ + string name = p -> name(); + Type_ptr subtype = p -> type(); + string s = typeToString(subtype); + if(s[0] == ':') + s.insert(0, " "); + H << sp; + H << nl << "typedef ::std::vector<" << s << "> " << name << ';'; + + Builtin_ptr builtin = Builtin_ptr::dynamicCast(subtype); + if(!builtin) + { + string scoped = p -> scoped(); + string scope = p -> scope(); + if(scope.length()) + scope.erase(0, 2); + + H << sp; + H << nl << "void" << dllExport_ << " __write(::__Ice::Stream*, const " + << name << "&);"; + H << nl << "void" << dllExport_ << " __read(::__Ice::Stream*, " + << name << "&);"; + C << sp; + C << nl << "void" << nl << scope + << "::__write(::__Ice::Stream* __os, const " << scoped << "& v)"; + C << sb; + C << nl << "__os -> write(::Ice::Int(v.size()));"; + C << nl << scoped << "::const_iterator p;"; + C << nl << "for(p = v.begin(); p != v.end(); ++p)"; + C.inc(); + writeMarshalUnmarshalCode(C, subtype, "*p", true); + C.dec(); + C << eb; + C << sp; + C << nl << "void" << nl << scope + << "::__read(::__Ice::Stream* __is, " << scoped << "& v)"; + C << sb; + C << nl << "::Ice::Int sz;"; + C << nl << "__is -> read(sz);"; + // Don't use v.resize(sz) or v.reserve(sz) here, as it + // cannot be checked whether sz is a reasonable value + C << nl << "while(sz--)"; + C << sb; + C.zeroIndent(); + C << nl << "#ifdef WIN32"; // STLBUG + C.restoreIndent(); + C << nl << "v.push_back(" << typeToString(subtype) << "());"; + C.zeroIndent(); + C << nl << "#else"; + C.restoreIndent(); + C << nl << "v.push_back();"; + C.zeroIndent(); + C << nl << "#endif"; + C.restoreIndent(); + writeMarshalUnmarshalCode(C, subtype, "v.back()", false); + C << eb; + C << eb; + } +} + +// ---------------------------------------------------------------------- +// ProxyDeclVisitor +// ---------------------------------------------------------------------- + +IceLang::GenCPlusPlus::ProxyDeclVisitor::ProxyDeclVisitor( + Output& h, Output& c, const string& dllExport) + : H(h), C(c), dllExport_(dllExport) +{ +} + +void +IceLang::GenCPlusPlus::ProxyDeclVisitor::visitUnitStart( + const Parser_ptr& p) +{ + if(!p -> hasProxies()) + return; + + H << sp; + H << nl << "namespace __IceProxy" << nl << '{'; +} + +void +IceLang::GenCPlusPlus::ProxyDeclVisitor::visitUnitEnd( + const Parser_ptr& p) +{ + if(!p -> hasProxies()) + return; + + H << sp; + H << nl << '}'; +} + +void +IceLang::GenCPlusPlus::ProxyDeclVisitor::visitModuleStart( + const Module_ptr& p) +{ + if(!p -> hasProxies()) + return; + + string name = p -> name(); + + H << sp; + H << nl << "namespace " << name << nl << '{'; +} + +void +IceLang::GenCPlusPlus::ProxyDeclVisitor::visitModuleEnd( + const Module_ptr& p) +{ + if(!p -> hasProxies()) + return; + + H << sp; + H << nl << '}'; +} + +void +IceLang::GenCPlusPlus::ProxyDeclVisitor::visitClassDecl( + const ClassDecl_ptr& p) +{ + if(p -> local()) + return; + + string name = p -> name(); + + H << sp; + H << nl << "class " << name << ';'; +} + +// ---------------------------------------------------------------------- +// ProxyVisitor +// ---------------------------------------------------------------------- + +IceLang::GenCPlusPlus::ProxyVisitor::ProxyVisitor( + Output& h, Output& c, const string& dllExport) + : H(h), C(c), dllExport_(dllExport) +{ +} + +void +IceLang::GenCPlusPlus::ProxyVisitor::visitUnitStart( + const Parser_ptr& p) +{ + if(!p -> hasProxies()) + return; + + H << sp; + H << nl << "namespace __IceProxy" << nl << '{'; +} + +void +IceLang::GenCPlusPlus::ProxyVisitor::visitUnitEnd( + const Parser_ptr& p) +{ + if(!p -> hasProxies()) + return; + + H << sp; + H << nl << '}'; +} + +void +IceLang::GenCPlusPlus::ProxyVisitor::visitModuleStart( + const Module_ptr& p) +{ + if(!p -> hasProxies()) + return; + + string name = p -> name(); + + H << sp; + H << nl << "namespace " << name << nl << '{'; +} + +void +IceLang::GenCPlusPlus::ProxyVisitor::visitModuleEnd( + const Module_ptr& p) +{ + if(!p -> hasProxies()) + return; + + H << sp; + H << nl << '}'; +} + +void +IceLang::GenCPlusPlus::ProxyVisitor::visitClassDefStart( + const ClassDef_ptr& p) +{ + if(p -> local()) + return; + + string name = p -> name(); + + ClassDef_ptr base = p -> base(); + string baseS; + if(base) + baseS = base -> scoped(); + else + baseS = "::Ice::Object"; + + H << sp; + H << nl << "class" << dllExport_ << ' ' << name << " : " + << "virtual public ::__IceProxy" << baseS; + H << sb; + H.dec(); + H << nl << "public: "; + H.inc(); +} + +void +IceLang::GenCPlusPlus::ProxyVisitor::visitClassDefEnd( + const ClassDef_ptr& p) +{ + if(p -> local()) + return; + + string scoped = p -> scoped(); + + H.dec(); + H << sp; + H << nl << "private: "; + H.inc(); + H << sp; + H << nl << "virtual ::__Ice::Handle< ::__IceDelegateM::Ice::Object> " + << "__createDelegateM();"; + H << eb << ';'; + C << sp; + C << nl << "::__Ice::Handle< ::__IceDelegateM::Ice::Object>" + << nl << "__IceProxy" << scoped << "::__createDelegateM()" << sb; + C << nl << "return ::__Ice::Handle< ::__IceDelegateM::Ice::Object>" + << "(new ::__IceDelegateM" << scoped << ");"; + C << eb; +} + +void +IceLang::GenCPlusPlus::ProxyVisitor::visitOperation( + const Operation_ptr& p) +{ + Container_ptr container = p -> container(); + ClassDef_ptr cl = ClassDef_ptr::dynamicCast(container); + if(cl -> local()) + return; + + string name = p -> name(); + string scoped = p -> scoped(); + string scope = p -> scope(); + + Type_ptr ret = p -> returnType(); + string retS = returnTypeToString(ret); + + TypeNameList inParams = p -> inputParameters(); + TypeNameList outParams = p -> outputParameters(); + TypeNameList::iterator q; + + string params = "("; + string paramsDecl = "("; // With declarators + string args = "("; + + for(q = inParams.begin(); q != inParams.end(); ++q) + { + if(q != inParams.begin()) + { + params += ", "; + paramsDecl += ", "; + args += ", "; + } + + string typeString = inputTypeToString(q -> first); + params += typeString; + paramsDecl += typeString; + paramsDecl += ' '; + paramsDecl += q -> second; + args += q -> second; + } + + for(q = outParams.begin(); q != outParams.end(); ++q) + { + if(q != outParams.begin() || !inParams.empty()) + { + params += ", "; + paramsDecl += ", "; + args += ", "; + } + + string typeString = outputTypeToString(q -> first); + params += typeString; + paramsDecl += typeString; + paramsDecl += ' '; + paramsDecl += q -> second; + args += q -> second; + } + + params += ')'; + paramsDecl += ')'; + args += ')'; + + TypeList throws = p -> throws(); + + H << sp; + H << nl << retS << ' ' << name << params << ';'; + C << sp; + C << nl << retS << nl << "__IceProxy" << scoped << paramsDecl + << sb; + C << nl << "::__Ice::Handle< ::__IceDelegate::Ice::Object> __delBase" + << " = __getDelegate();"; + C << nl << "::__IceDelegate" << scope + << "* __del = dynamic_cast< ::__IceDelegate" << scope + << "*>(__delBase.get());"; + C << nl; + if(ret) + C << "return "; + C << "__del -> " << name << args << ";"; + C << eb; +} + +// ---------------------------------------------------------------------- +// DelegateVisitor +// ---------------------------------------------------------------------- + +IceLang::GenCPlusPlus::DelegateVisitor::DelegateVisitor( + Output& h, Output& c, const string& dllExport) + : H(h), C(c), dllExport_(dllExport) +{ +} + +void +IceLang::GenCPlusPlus::DelegateVisitor::visitUnitStart( + const Parser_ptr& p) +{ + if(!p -> hasProxies()) + return; + + H << sp; + H << nl << "namespace __IceDelegate" << nl << '{'; +} + +void +IceLang::GenCPlusPlus::DelegateVisitor::visitUnitEnd( + const Parser_ptr& p) +{ + if(!p -> hasProxies()) + return; + + H << sp; + H << nl << '}'; +} + +void +IceLang::GenCPlusPlus::DelegateVisitor::visitModuleStart( + const Module_ptr& p) +{ + if(!p -> hasProxies()) + return; + + string name = p -> name(); + + H << sp; + H << nl << "namespace " << name << nl << '{'; +} + +void +IceLang::GenCPlusPlus::DelegateVisitor::visitModuleEnd( + const Module_ptr& p) +{ + if(!p -> hasProxies()) + return; + + H << sp; + H << nl << '}'; +} + +void +IceLang::GenCPlusPlus::DelegateVisitor::visitClassDefStart( + const ClassDef_ptr& p) +{ + if(p -> local()) + return; + + string name = p -> name(); + ClassDef_ptr base = p -> base(); + string baseS; + if(base) + baseS = base -> scoped(); + else + baseS = "::Ice::Object"; + + H << sp; + H << nl << "class" << dllExport_ << ' ' << name << " : " + << "virtual public ::__IceDelegate" << baseS; + H << sb; + H.dec(); + H << nl << "public: "; + H.inc(); +} + +void +IceLang::GenCPlusPlus::DelegateVisitor::visitClassDefEnd( + const ClassDef_ptr& p) +{ + if(p -> local()) + return; + + H << eb << ';'; +} + +void +IceLang::GenCPlusPlus::DelegateVisitor::visitOperation( + const Operation_ptr& p) +{ + Container_ptr container = p -> container(); + ClassDef_ptr cl = ClassDef_ptr::dynamicCast(container); + if(cl -> local()) + return; + + string name = p -> name(); + + Type_ptr ret = p -> returnType(); + string retS = returnTypeToString(ret); + + TypeNameList inParams = p -> inputParameters(); + TypeNameList outParams = p -> outputParameters(); + TypeNameList::iterator q; + + string params = "("; + string args = "("; + + for(q = inParams.begin(); q != inParams.end(); ++q) + { + if(q != inParams.begin()) + { + params += ", "; + args += ", "; + } + + string typeString = inputTypeToString(q -> first); + params += typeString; + args += q -> second; + } + + for(q = outParams.begin(); q != outParams.end(); ++q) + { + if(q != outParams.begin() || !inParams.empty()) + { + params += ", "; + args += ", "; + } + + string typeString = outputTypeToString(q -> first); + params += typeString; + args += q -> second; + } + + params += ')'; + args += ')'; + + TypeList throws = p -> throws(); + + H << sp; + H << nl << "virtual " << retS << ' ' << name << params << " = 0;"; +} + +// ---------------------------------------------------------------------- +// DelegateMVisitor +// ---------------------------------------------------------------------- + +IceLang::GenCPlusPlus::DelegateMVisitor::DelegateMVisitor( + Output& h, Output& c, const string& dllExport) + : H(h), C(c), dllExport_(dllExport) +{ +} + +void +IceLang::GenCPlusPlus::DelegateMVisitor::visitUnitStart( + const Parser_ptr& p) +{ + if(!p -> hasProxies()) + return; + + H << sp; + H << nl << "namespace __IceDelegateM" << nl << '{'; +} + +void +IceLang::GenCPlusPlus::DelegateMVisitor::visitUnitEnd( + const Parser_ptr& p) +{ + if(!p -> hasProxies()) + return; + + H << sp; + H << nl << '}'; +} + +void +IceLang::GenCPlusPlus::DelegateMVisitor::visitModuleStart( + const Module_ptr& p) +{ + if(!p -> hasProxies()) + return; + + string name = p -> name(); + + H << sp; + H << nl << "namespace " << name << nl << '{'; +} + +void +IceLang::GenCPlusPlus::DelegateMVisitor::visitModuleEnd( + const Module_ptr& p) +{ + if(!p -> hasProxies()) + return; + + H << sp; + H << nl << '}'; +} + +void +IceLang::GenCPlusPlus::DelegateMVisitor::visitClassDefStart( + const ClassDef_ptr& p) +{ + if(p -> local()) + return; + + string name = p -> name(); + string scoped = p -> scoped(); + + ClassDef_ptr base = p -> base(); + string baseS; + if(base) + baseS = base -> scoped(); + else + baseS = "::Ice::Object"; + + H << sp; + H << nl << "class" << dllExport_ << ' ' << name << " : "; + H.useCurrentPosAsIndent(); + H << "virtual public ::__IceDelegate" << scoped << ','; + H << nl << "virtual public ::__IceDelegateM" << baseS; + H.restoreIndent(); + H << sb; + H.dec(); + H << nl << "public: "; + H.inc(); +} + +void +IceLang::GenCPlusPlus::DelegateMVisitor::visitClassDefEnd( + const ClassDef_ptr& p) +{ + if(p -> local()) + return; + + H << eb << ';'; +} + +void +IceLang::GenCPlusPlus::DelegateMVisitor::visitOperation( + const Operation_ptr& p) +{ + Container_ptr container = p -> container(); + ClassDef_ptr cl = ClassDef_ptr::dynamicCast(container); + if(cl -> local()) + return; + + string name = p -> name(); + string scoped = p -> scoped(); + string scope = p -> scope(); + + Type_ptr ret = p -> returnType(); + string retS = returnTypeToString(ret); + + TypeNameList inParams = p -> inputParameters(); + TypeNameList outParams = p -> outputParameters(); + TypeNameList::iterator q; + + string params = "("; + string paramsDecl = "("; // With declarators + string args = "("; + + for(q = inParams.begin(); q != inParams.end(); ++q) + { + if(q != inParams.begin()) + { + params += ", "; + paramsDecl += ", "; + args += ", "; + } + + string typeString = inputTypeToString(q -> first); + params += typeString; + paramsDecl += typeString; + paramsDecl += ' '; + paramsDecl += q -> second; + args += q -> second; + } + + for(q = outParams.begin(); q != outParams.end(); ++q) + { + if(q != outParams.begin() || !inParams.empty()) + { + params += ", "; + paramsDecl += ", "; + args += ", "; + } + + string typeString = outputTypeToString(q -> first); + params += typeString; + paramsDecl += typeString; + paramsDecl += ' '; + paramsDecl += q -> second; + args += q -> second; + } + + params += ')'; + paramsDecl += ')'; + args += ')'; + + TypeList throws = p -> throws(); + + H << sp; + H << nl << "virtual " << retS << ' ' << name << params << ';'; + C << sp; + C << nl << retS << nl << "__IceDelegateM" << scoped << paramsDecl + << sb; + C << nl << "::__Ice::Outgoing __out(__emitter(), __reference());"; + if(ret || !outParams.empty() || !throws.empty()) + C << nl << "::__Ice::Stream* __is = __out.is();"; + C << nl << "::__Ice::Stream* __os = __out.os();"; + C << nl << "__os -> write(\"" << name << "\");"; + writeMarshalCode(C, inParams, 0); + C << nl << "if(!__out.invoke())"; + if(!throws.empty()) + { + C << sb; + C << nl << "::Ice::Int __exnum;"; + C << nl << "__is -> read(__exnum);"; + C << nl << "switch(__exnum)"; + C << sb; + TypeList::iterator r; + Ice::Int cnt = 0; + for(r = throws.begin(); r != throws.end(); ++r) + { + C.dec(); + C << nl << "case " << cnt++ << ':'; + C.sb(); + TypeNameList li; + li.push_back(make_pair(*r, string("__ex"))); + writeAllocateCode(C, li, 0); + writeUnmarshalCode(C, li, 0); + C << nl << "throw __ex;"; + C.eb(); + C.inc(); + } + C << eb; + C << nl + << "throw ::Ice::UnknownUserException(__FILE__, __LINE__);"; + C << eb; + } + else + { + C.inc(); + C << nl + << "throw ::Ice::UnknownUserException(__FILE__, __LINE__);"; + C.dec(); + } + writeAllocateCode(C, TypeNameList(), ret); + writeUnmarshalCode(C, outParams, ret); + if(ret) + C << nl << "return __ret;"; + C << eb; +} + +// ---------------------------------------------------------------------- +// ObjectDeclVisitor +// ---------------------------------------------------------------------- + +IceLang::GenCPlusPlus::ObjectDeclVisitor::ObjectDeclVisitor( + Output& h, Output& c, const string& dllExport) + : H(h), C(c), dllExport_(dllExport) +{ +} + +void +IceLang::GenCPlusPlus::ObjectDeclVisitor::visitModuleStart( + const Module_ptr& p) +{ + if(!p -> hasClassDecls()) + return; + + string name = p -> name(); + + H << sp; + H << nl << "namespace " << name << nl << '{'; +} + +void +IceLang::GenCPlusPlus::ObjectDeclVisitor::visitModuleEnd( + const Module_ptr& p) +{ + if(!p -> hasClassDecls()) + return; + + H << sp; + H << nl << '}'; +} + +void +IceLang::GenCPlusPlus::ObjectDeclVisitor::visitClassDecl( + const ClassDecl_ptr& p) +{ + string name = p -> name(); + + H << sp; + H << nl << "class " << name << ';'; +} + +// ---------------------------------------------------------------------- +// ObjectVisitor +// ---------------------------------------------------------------------- + +IceLang::GenCPlusPlus::ObjectVisitor::ObjectVisitor( + Output& h, Output& c, const string& dllExport) + : H(h), C(c), dllExport_(dllExport) +{ +} + +void +IceLang::GenCPlusPlus::ObjectVisitor::visitModuleStart( + const Module_ptr& p) +{ + if(!p -> hasClassDefs()) + return; + + string name = p -> name(); + + H << sp; + H << nl << "namespace " << name << nl << '{'; +} + +void +IceLang::GenCPlusPlus::ObjectVisitor::visitModuleEnd( + const Module_ptr& p) +{ + if(!p -> hasClassDefs()) + return; + + H << sp; + H << nl << '}'; +} + +void +IceLang::GenCPlusPlus::ObjectVisitor::visitClassDefStart( + const ClassDef_ptr& p) +{ + bool local = p -> local(); + string name = p -> name(); + string scoped = p -> scoped(); + + vector<ClassDef_ptr> bases; + vector<ClassDef_ptr>::const_iterator q; + + ClassDef_ptr base = p; + while((base = base -> base())) + bases.push_back(base); + + string baseS; + if(!bases.empty()) + { + base = bases[0]; + baseS = base -> scoped(); + } + else + { + if(local) + baseS = "::Ice::LocalObject"; + else + baseS = "::Ice::Object"; + } + + H << sp; + H << nl << "class" << dllExport_ << ' ' << name << " : "; + if(local) + { + // No virtual inheritance for local objects + H << "public " << baseS; + } + else + { + H.useCurrentPosAsIndent(); + H << "virtual public ::__IceDelegate" << scoped << ','; + H << nl << "virtual public " << baseS; + H.restoreIndent(); + } + H << sb; + H.dec(); + H << nl << "public: "; + H.inc(); + if(!local) + { + H << sp; + H << nl << "static std::string __implements[" + << bases.size() + 2 << "];"; + H << sp; + H << nl << "virtual bool _implements(const std::string&);"; + H << sp; + H << nl << "virtual const std::string* __ids();"; + C << sp; + C << nl << "std::string " << scoped.substr(2) + << "::__implements[" << bases.size() + 2 << "] ="; + C << sb; + C << nl << '"' << scoped << "\","; + for(q = bases.begin(); q != bases.end(); ++q) + C << nl << '"' << (*q) -> scoped() << "\","; + C << nl << "\"::Ice::Object\""; + C << eb << ';'; + C << sp; + C << nl << "bool" << nl << scoped.substr(2) + << "::_implements(const std::string& s)"; + C << sb; + C << nl << "std::string* b = __implements;"; + C << nl << "std::string* e = __implements + " << bases.size() + 2 + << ';'; + C << nl << "std::string* r = std::find(b, e, s);"; + C << nl << "return(r != e);"; + C << eb; + C << sp; + C << nl << "const std::string*" << nl << scoped.substr(2) + << "::__ids()"; + C << sb; + C << nl << "return __implements;"; + C << eb; + } +} + +void +IceLang::GenCPlusPlus::ObjectVisitor::visitClassDefEnd( + const ClassDef_ptr& p) +{ + string name = p -> name(); + string scoped = p -> scoped(); + + vector<Operation_ptr> operations = p -> operations(); + ClassDef_ptr base = p -> base(); + + if(!p -> local() && !operations.empty()) + { + sort(operations.begin(), operations.end()); + vector<Operation_ptr>::iterator op; + + H << sp; + H << nl << "typedef ::__Ice::DispatchStatus (" << name + << "::*__Op)(::__Ice::Incoming&);"; + H << nl << "static __Op __ops[" << operations.size() << "];"; + H << nl << "static std::string __names[" << operations.size() + << "];"; + H << nl << "virtual ::__Ice::DispatchStatus " + << "__dispatch(::__Ice::Incoming&, const std::string&);"; + C << sp; + C << nl << scoped << "::__Op " << scoped.substr(2) + << "::__ops[" << operations.size() << "] ="; + C << sb; + for(op = operations.begin(); op != operations.end(); ++op) + { + C << nl << '&' << scoped.substr(2) << "::___" + << (*op) -> name(); + if(op + 1 != operations.end()) + C << ','; + } + C << eb << ';'; + C << sp; + C << nl << "std::string " << scoped.substr(2) + << "::__names[" << operations.size() << "] ="; + C << sb; + for(op = operations.begin(); op != operations.end(); ++op) + { + C << nl << '"' << (*op) -> name() << '"'; + if(op + 1 != operations.end()) + C << ','; + } + C << eb << ';'; + C << sp; + C << nl << "::__Ice::DispatchStatus" << nl << scoped.substr(2) + << "::__dispatch(::__Ice::Incoming& in, const std::string& s)"; + C << sb; + C << nl << "std::string* b = __names;"; + C << nl << "std::string* e = __names + " << operations.size() + << ';'; + C << nl << "std::pair<std::string*, std::string*> r = " + << "std::equal_range(b, e, s);"; + C << nl << "if(r.first != r.second)"; + C.inc(); + C << nl << "return (this ->* __ops[r.first - b])(in);"; + C.dec(); + C << nl << "else"; + C.inc(); + C.zeroIndent(); + C << nl << "#ifdef WIN32"; // COMPILERBUG + C.restoreIndent(); + if(base) + C << nl << "return " << base -> name(); + else + C << nl << "return Object"; + C << "::__dispatch(in, s);"; + C.zeroIndent(); + C << nl << "#else"; + C.restoreIndent(); + if(base) + C << nl << "return " << base -> scoped(); + else + C << nl << "return ::Ice::Object"; + C << "::__dispatch(in, s);"; + C.zeroIndent(); + C << nl << "#endif"; + C.restoreIndent(); + C.dec(); + C << eb; + } + H << sp; + H << nl << "virtual void __write(::__Ice::Stream*);"; + H << nl << "virtual void __read(::__Ice::Stream*);"; + H << eb << ';'; + TypeNameList memberList; + vector<DataMember_ptr> dataMembers = p -> dataMembers(); + vector<DataMember_ptr>::const_iterator q; + for(q = dataMembers.begin(); q != dataMembers.end(); ++q) + memberList.push_back(make_pair((*q) -> type(), (*q) -> name())); + C << sp; + C << nl << "void" << nl << scoped.substr(2) + << "::__write(::__Ice::Stream* __os)"; + C << sb; + C << nl << "__os -> startWriteEncaps();"; + writeMarshalCode(C, memberList, 0); + C << nl << "__os -> endWriteEncaps();"; + if(base) + { + C.zeroIndent(); + C << nl << "#ifdef WIN32"; // COMPILERBUG + C.restoreIndent(); + C << nl << base -> name() << "::__write(__os);"; + C.zeroIndent(); + C << nl << "#else"; + C.restoreIndent(); + C << nl << base -> scoped() << "::__write(__os);"; + C.zeroIndent(); + C << nl << "#endif"; + C.restoreIndent(); + } + C << eb; + C << sp; + C << nl << "void" << nl << scoped.substr(2) + << "::__read(::__Ice::Stream* __is)"; + C << sb; + C << nl << "__is -> startReadEncaps();"; + writeUnmarshalCode(C, memberList, 0); + C << nl << "__is -> endReadEncaps();"; + if(base) + { + C.zeroIndent(); + C << nl << "#ifdef WIN32"; // COMPILERBUG + C.restoreIndent(); + C << nl << base -> name() << "::__read(__is);"; + C.zeroIndent(); + C << nl << "#else"; + C.restoreIndent(); + C << nl << base -> scoped() << "::__read(__is);"; + C.zeroIndent(); + C << nl << "#endif"; + C.restoreIndent(); + } + C << eb; +} + +void +IceLang::GenCPlusPlus::ObjectVisitor::visitOperation( + const Operation_ptr& p) +{ + Container_ptr container = p -> container(); + ClassDef_ptr cl = ClassDef_ptr::dynamicCast(container); + string name = p -> name(); + string scoped = p -> scoped(); + string scope = p -> scope(); + + Type_ptr ret = p -> returnType(); + string retS = returnTypeToString(ret); + + TypeNameList inParams = p -> inputParameters(); + TypeNameList outParams = p -> outputParameters(); + TypeNameList::iterator q; + + string params = "("; + string paramsDecl = "("; // With declarators + string args = "("; + + for(q = inParams.begin(); q != inParams.end(); ++q) + { + if(q != inParams.begin()) + { + params += ", "; + paramsDecl += ", "; + args += ", "; + } + + string typeString = inputTypeToString(q -> first); + params += typeString; + paramsDecl += typeString; + paramsDecl += ' '; + paramsDecl += q -> second; + args += q -> second; + } + + for(q = outParams.begin(); q != outParams.end(); ++q) + { + if(q != outParams.begin() || !inParams.empty()) + { + params += ", "; + paramsDecl += ", "; + args += ", "; + } + + string typeString = outputTypeToString(q -> first); + params += typeString; + paramsDecl += typeString; + paramsDecl += ' '; + paramsDecl += q -> second; + args += q -> second; + } + + params += ')'; + paramsDecl += ')'; + args += ')'; + + TypeList throws = p -> throws(); + + H << sp; + H << nl << "virtual " << retS << ' ' << name << params << " = 0;"; + + if(!cl -> local()) + { + H << nl << "::__Ice::DispatchStatus ___" << name + << "(::__Ice::Incoming&);"; + C << sp; + C << nl << "::__Ice::DispatchStatus" << nl << scope.substr(2) + << "::___" << name << "(::__Ice::Incoming& __in)"; + C << sb; + if(!inParams.empty()) + C << nl << "::__Ice::Stream* __is = __in.is();"; + if(ret || !outParams.empty() || !throws.empty()) + C << nl << "::__Ice::Stream* __os = __in.os();"; + writeAllocateCode(C, inParams, 0); + writeUnmarshalCode(C, inParams, 0); + writeAllocateCode(C, outParams, 0); + if(!throws.empty()) + { + C << nl << "try"; + C << sb; + } + C << nl; + if(ret) + C << retS << " __ret = "; + C << name << args << ';'; + if(!throws.empty()) + { + C << eb; + TypeList::iterator r; + Ice::Int cnt = 0; + for(r = throws.begin(); r != throws.end(); ++r) + { + C << nl << "catch(" << inputTypeToString(*r) << " __ex)"; + C << sb; + C << nl << "__os -> write(" << cnt++ << ");"; + writeMarshalUnmarshalCode(C, *r, "__ex", true); + C << nl << "return ::__Ice::DispatchException;"; + C << eb; + } + } + writeMarshalCode(C, outParams, ret); + C << nl << "return ::__Ice::DispatchOK;"; + C << eb; + } +} + +void +IceLang::GenCPlusPlus::ObjectVisitor::visitDataMember( + const DataMember_ptr& p) +{ + string name = p -> name(); + string s = typeToString(p -> type()); + H << sp; + H << nl << s << ' ' << name << ';'; +} + +// ---------------------------------------------------------------------- +// IceVisitor +// ---------------------------------------------------------------------- + +IceLang::GenCPlusPlus::IceVisitor::IceVisitor( + Output& h, Output& c, const string& dllExport) + : H(h), C(c), dllExport_(dllExport) +{ +} + +void +IceLang::GenCPlusPlus::IceVisitor::visitUnitStart( + const Parser_ptr& p) +{ + if(!p -> hasClassDecls()) + return; + + H << sp; + H << nl << "namespace __Ice" << nl << '{'; +} + +void +IceLang::GenCPlusPlus::IceVisitor::visitUnitEnd( + const Parser_ptr& p) +{ + if(!p -> hasClassDecls()) + return; + + H << sp; + H << nl << '}'; +} + +void +IceLang::GenCPlusPlus::IceVisitor::visitClassDecl( + const ClassDecl_ptr& p) +{ + string scoped = p -> scoped(); + + H << sp; + H << nl << "void" << dllExport_ << " incRef(" << scoped << "*);"; + H << nl << "void" << dllExport_ << " decRef(" << scoped << "*);"; + if(!p -> local()) + { + H << sp; + H << nl << "void" << dllExport_ << " incRef(::__IceProxy" << scoped + << "*);"; + H << nl << "void" << dllExport_ << " decRef(::__IceProxy" << scoped + << "*);"; + H << sp; + H << nl << "void" << dllExport_ + << " checkedCast(::__IceProxy::Ice::Object*, ::__IceProxy" + << scoped << "*&);"; + H << nl << "void" << dllExport_ + << " uncheckedCast(::__IceProxy::Ice::Object*, ::__IceProxy" + << scoped << "*&);"; + } +} + +void +IceLang::GenCPlusPlus::IceVisitor::visitClassDefStart( + const ClassDef_ptr& p) +{ + string scoped = p -> scoped(); + + C << sp; + C << nl << "void __Ice::incRef(" << scoped << "* p) { p -> __incRef(); }"; + C << nl << "void __Ice::decRef(" << scoped << "* p) { p -> __decRef(); }"; + + if(!p -> local()) + { + C << sp; + C << nl << "void __Ice::incRef(::__IceProxy" << scoped + << "* p) { p -> __incRef(); }"; + C << nl << "void __Ice::decRef(::__IceProxy" << scoped + << "* p) { p -> __decRef(); }"; + C << sp; + C << nl << "void __Ice::checkedCast(::__IceProxy::Ice::Object* b, " + << "::__IceProxy" << scoped << "*& d)"; + C << sb; + C << nl << "d = dynamic_cast< ::__IceProxy" << scoped + << "*>(b);"; + C << nl << "if(!d && b -> _implements(\"" << scoped << "\"))"; + C << sb; + C << nl << "d = new ::__IceProxy" << scoped << ';'; + C << nl << "b -> __copyTo(d);"; + C << eb; + C << eb; + C << sp; + C << nl << "void __Ice::uncheckedCast(::__IceProxy::Ice::Object* b, " + << "::__IceProxy" << scoped << "*& d)"; + C << sb; + C << nl << "d = dynamic_cast< ::__IceProxy" << scoped + << "*>(b);"; + C << nl << "if(!d)"; + C << sb; + C << nl << "d = new ::__IceProxy" << scoped << ';'; + C << nl << "b -> __copyTo(d);"; + C << eb; + C << eb; + } +} + +// ---------------------------------------------------------------------- +// HandleVisitor +// ---------------------------------------------------------------------- + +IceLang::GenCPlusPlus::HandleVisitor::HandleVisitor( + Output& h, Output& c, const string& dllExport) + : H(h), C(c), dllExport_(dllExport) +{ +} + +void +IceLang::GenCPlusPlus::HandleVisitor::visitModuleStart( + const Module_ptr& p) +{ + if(!p -> hasClassDecls()) + return; + + string name = p -> name(); + + H << sp; + H << nl << "namespace " << name << nl << '{'; +} + +void +IceLang::GenCPlusPlus::HandleVisitor::visitModuleEnd( + const Module_ptr& p) +{ + if(!p -> hasClassDecls()) + return; + + H << sp; + H << nl << '}'; +} + +void +IceLang::GenCPlusPlus::HandleVisitor::visitClassDecl( + const ClassDecl_ptr& p) +{ + string name = p -> name(); + string scoped = p -> scoped(); + + H << sp; + H << nl << "typedef ::__Ice::Handle< " << scoped << "> " << name + << "_ptr;"; + if(!p -> local()) + { + H << nl << "typedef ::__Ice::ProxyHandle< ::__IceProxy" << scoped + << "> " << name << "_prx;"; + H << sp; + H << nl << "void" << dllExport_ << " __write(::__Ice::Stream*, const " + << name << "_prx&);"; + H << nl << "void" << dllExport_ << " __read(::__Ice::Stream*, " + << name << "_prx&);"; + } +} + +void +IceLang::GenCPlusPlus::HandleVisitor::visitClassDefStart( + const ClassDef_ptr& p) +{ + if(p -> local()) + return; + + string scoped = p -> scoped(); + string scope = p -> scope(); + if(scope.length()) + scope.erase(0, 2); + + C << sp; + C << nl << "void" << nl << scope + << "::__write(::__Ice::Stream* __os, const " << scoped << "_prx& v)"; + C << sb; + // TODO: Should be ::Ice::__write + C << nl << "::__Ice::write(__os, ::Ice::Object_prx(v));"; + C << eb; + C << sp; + C << nl << "void" << nl << scope + << "::__read(::__Ice::Stream* __is, " << scoped << "_prx& v)"; + C << sb; + C << nl << "::Ice::Object_prx proxy;"; + // TODO: Should be ::Ice::__read + C << nl << "::__Ice::read(__is, proxy);"; + C << nl << "v = new ::__IceProxy" << scoped << ';'; + C << nl << "proxy -> __copyTo(v.get());"; + C << eb; +} diff --git a/cpp/src/slice2cpp/GenCPlusPlus.h b/cpp/src/slice2cpp/GenCPlusPlus.h new file mode 100644 index 00000000000..c0b6b640cae --- /dev/null +++ b/cpp/src/slice2cpp/GenCPlusPlus.h @@ -0,0 +1,233 @@ +// ********************************************************************** +// +// Copyright (c) 2001 +// MutableRealms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#ifndef GEN_C_PLUS_PLUS_H +#define GEN_C_PLUS_PLUS_H + +#include <Parser.h> +#include <OutputUtil.h> + +namespace IceLang +{ + +class GenCPlusPlus : ::__Ice::noncopyable +{ +public: + + GenCPlusPlus(const std::string&, + const std::string&, + const std::string&, + const std::vector<std::string>&, + const std::string&); + ~GenCPlusPlus(); + + bool operator!() const; // Returns true if there was a constructor error + + void generate(const Parser_ptr&); + +private: + + std::string changeInclude(const std::string&); + void printHeader(Output&); + + Output FH; + Output H; + Output C; + + std::string base_; + std::string include_; + std::vector<std::string> includePaths_; + std::string dllExport_; + + class TypesVisitor : ::__Ice::noncopyable, public ParserVisitor + { + public: + + TypesVisitor(Output&, Output&, const std::string&); + + virtual void visitModuleStart(const Module_ptr&); + virtual void visitModuleEnd(const Module_ptr&); + virtual void visitVector(const Vector_ptr&); + + private: + + Output& H; + Output& C; + + std::string dllExport_; + }; + + class ProxyDeclVisitor : ::__Ice::noncopyable, public ParserVisitor + { + public: + + ProxyDeclVisitor(Output&, Output&, const std::string&); + + virtual void visitUnitStart(const Parser_ptr&); + virtual void visitUnitEnd(const Parser_ptr&); + virtual void visitModuleStart(const Module_ptr&); + virtual void visitModuleEnd(const Module_ptr&); + virtual void visitClassDecl(const ClassDecl_ptr&); + + private: + + Output& H; + Output& C; + + std::string dllExport_; + }; + + class ProxyVisitor : ::__Ice::noncopyable, public ParserVisitor + { + public: + + ProxyVisitor(Output&, Output&, const std::string&); + + virtual void visitUnitStart(const Parser_ptr&); + virtual void visitUnitEnd(const Parser_ptr&); + virtual void visitModuleStart(const Module_ptr&); + virtual void visitModuleEnd(const Module_ptr&); + virtual void visitClassDefStart(const ClassDef_ptr&); + virtual void visitClassDefEnd(const ClassDef_ptr&); + virtual void visitOperation(const Operation_ptr&); + + private: + + Output& H; + Output& C; + + std::string dllExport_; + }; + + class DelegateVisitor : ::__Ice::noncopyable, public ParserVisitor + { + public: + + DelegateVisitor(Output&, Output&, const std::string&); + + virtual void visitUnitStart(const Parser_ptr&); + virtual void visitUnitEnd(const Parser_ptr&); + virtual void visitModuleStart(const Module_ptr&); + virtual void visitModuleEnd(const Module_ptr&); + virtual void visitClassDefStart(const ClassDef_ptr&); + virtual void visitClassDefEnd(const ClassDef_ptr&); + virtual void visitOperation(const Operation_ptr&); + + private: + + Output& H; + Output& C; + + std::string dllExport_; + }; + + class DelegateMVisitor : ::__Ice::noncopyable, public ParserVisitor + { + public: + + DelegateMVisitor(Output&, Output&, const std::string&); + + virtual void visitUnitStart(const Parser_ptr&); + virtual void visitUnitEnd(const Parser_ptr&); + virtual void visitModuleStart(const Module_ptr&); + virtual void visitModuleEnd(const Module_ptr&); + virtual void visitClassDefStart(const ClassDef_ptr&); + virtual void visitClassDefEnd(const ClassDef_ptr&); + virtual void visitOperation(const Operation_ptr&); + + private: + + Output& H; + Output& C; + + std::string dllExport_; + }; + + class ObjectDeclVisitor : ::__Ice::noncopyable, public ParserVisitor + { + public: + + ObjectDeclVisitor(Output&, Output&, const std::string&); + + virtual void visitModuleStart(const Module_ptr&); + virtual void visitModuleEnd(const Module_ptr&); + virtual void visitClassDecl(const ClassDecl_ptr&); + + private: + + Output& H; + Output& C; + + std::string dllExport_; + }; + + class ObjectVisitor : ::__Ice::noncopyable, public ParserVisitor + { + public: + + ObjectVisitor(Output&, Output&, const std::string&); + + virtual void visitModuleStart(const Module_ptr&); + virtual void visitModuleEnd(const Module_ptr&); + virtual void visitClassDefStart(const ClassDef_ptr&); + virtual void visitClassDefEnd(const ClassDef_ptr&); + virtual void visitOperation(const Operation_ptr&); + virtual void visitDataMember(const DataMember_ptr&); + + private: + + Output& H; + Output& C; + + std::string dllExport_; + }; + + class IceVisitor : ::__Ice::noncopyable, public ParserVisitor + { + public: + + IceVisitor(Output&, Output&, const std::string&); + + virtual void visitUnitStart(const Parser_ptr&); + virtual void visitUnitEnd(const Parser_ptr&); + virtual void visitClassDecl(const ClassDecl_ptr&); + virtual void visitClassDefStart(const ClassDef_ptr&); + + private: + + Output& H; + Output& C; + + std::string dllExport_; + }; + + class HandleVisitor : ::__Ice::noncopyable, public ParserVisitor + { + public: + + HandleVisitor(Output&, Output&, const std::string&); + + virtual void visitModuleStart(const Module_ptr&); + virtual void visitModuleEnd(const Module_ptr&); + virtual void visitClassDecl(const ClassDecl_ptr&); + virtual void visitClassDefStart(const ClassDef_ptr&); + + private: + + Output& H; + Output& C; + + std::string dllExport_; + }; +}; + +} + +#endif diff --git a/cpp/src/slice2cpp/GenCPlusPlusUtil.cpp b/cpp/src/slice2cpp/GenCPlusPlusUtil.cpp new file mode 100644 index 00000000000..957cb0c0fd2 --- /dev/null +++ b/cpp/src/slice2cpp/GenCPlusPlusUtil.cpp @@ -0,0 +1,250 @@ +// ********************************************************************** +// +// Copyright (c) 2001 +// MutableRealms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#include <GenCPlusPlusUtil.h> + +using namespace std; +using namespace IceLang; + +string +IceLang::typeToString(const Type_ptr& type) +{ + static const char* builtinTable[] = + { + "::Ice::Byte", + "bool", + "::Ice::Short", + "::Ice::Int", + "::Ice::Long", + "::Ice::Float", + "::Ice::Double", + "::std::string", + "::std::wstring", + "::Ice::Object_ptr", + "::Ice::Object_prx", + "::Ice::LocalObject_ptr" + }; + + Builtin_ptr builtin = Builtin_ptr::dynamicCast(type); + if(builtin) + return builtinTable[builtin -> kind()]; + + ClassDecl_ptr cl = ClassDecl_ptr::dynamicCast(type); + if(cl) + return cl -> scoped() + "_ptr"; + + Proxy_ptr proxy = Proxy_ptr::dynamicCast(type); + if(proxy) + return proxy -> _class() -> scoped() + "_prx"; + + Contained_ptr contained = Contained_ptr::dynamicCast(type); + if(contained) + return contained -> scoped(); + + return "???"; +} + +string +IceLang::returnTypeToString(const Type_ptr& type) +{ + if(!type) + return "void"; + + return typeToString(type); +} + +string +IceLang::inputTypeToString(const Type_ptr& type) +{ + static const char* inputBuiltinTable[] = + { + "::Ice::Byte", + "bool", + "::Ice::Short", + "::Ice::Int", + "::Ice::Long", + "::Ice::Float", + "::Ice::Double", + "const ::std::string&", + "const ::std::wstring&", + "const ::Ice::Object_ptr&", + "const ::Ice::Object_prx&", + "const ::Ice::LocalObject_ptr&" + }; + + Builtin_ptr builtin = Builtin_ptr::dynamicCast(type); + if(builtin) + return inputBuiltinTable[builtin -> kind()]; + + ClassDecl_ptr cl = ClassDecl_ptr::dynamicCast(type); + if(cl) + return "const " + cl -> scoped() + "_ptr&"; + + Proxy_ptr proxy = Proxy_ptr::dynamicCast(type); + if(proxy) + return "const " + proxy -> _class() -> scoped() + "_prx&"; + + Contained_ptr contained = Contained_ptr::dynamicCast(type); + if(contained) + return "const " + contained -> scoped() + "&"; + + return "???"; +} + +string +IceLang::outputTypeToString(const Type_ptr& type) +{ + static const char* outputBuiltinTable[] = + { + "::Ice::Byte&", + "bool&", + "::Ice::Short&", + "::Ice::Int&", + "::Ice::Long&", + "::Ice::Float&", + "::Ice::Double&", + "::std::string&", + "::std::wstring&", + "::Ice::Object_ptr", + "::Ice::Object_prx", + "::Ice::LocalObject_ptr" + }; + + Builtin_ptr builtin = Builtin_ptr::dynamicCast(type); + if(builtin) + return outputBuiltinTable[builtin -> kind()]; + + ClassDecl_ptr cl = ClassDecl_ptr::dynamicCast(type); + if(cl) + return cl -> scoped() + "_ptr&"; + + Proxy_ptr proxy = Proxy_ptr::dynamicCast(type); + if(proxy) + return proxy -> _class() -> scoped() + "_prx&"; + + Contained_ptr contained = Contained_ptr::dynamicCast(type); + if(contained) + return contained -> scoped() + "&"; + + return "???"; +} + +void +IceLang::writeMarshalUnmarshalCode(Output& out, const Type_ptr& type, + const string& param, bool marshal) +{ + const char* func = marshal ? "write(" : "read("; + const char* stream = marshal ? "__os" : "__is"; + + if(Builtin_ptr::dynamicCast(type)) + { + out << nl << stream << " -> " << func << param << ");"; + return; + } + + Vector_ptr vector = Vector_ptr::dynamicCast(type); + if(vector && Builtin_ptr::dynamicCast(vector -> type())) + { + out << nl << stream << " -> " << func << param << ");"; + return; + } + + ClassDecl_ptr cl = ClassDecl_ptr::dynamicCast(type); + if(cl) + { + out << sb; + if(marshal) + { + out << nl << "::Ice::Object_ptr __obj = " << param << ';'; + out << nl << stream << " -> write(__obj);"; + } + else + { + out << nl << "::Ice::Object_ptr __obj;"; + out << nl << stream << " -> read(__obj, " << cl -> scoped() + << "::__implements[0]);"; + out << nl << "if(!__obj)"; + ClassDef_ptr def = cl -> definition(); + if(def && !def -> abstract()) + { + out << sb; + out << nl << "__obj = new " << cl -> scoped() << ";"; + out << nl << "__obj -> __read(__is);"; + out << eb; + } + else + { + out.inc(); + out << nl + << "throw ::Ice::NoFactoryException(__FILE__, __LINE__);"; + out.dec(); + } + out << nl << param << " = " << cl -> scoped() + << "_ptr::dynamicCast(__obj);"; + out << nl << "if(!" << param << ')'; + out.inc(); + out << nl + << "throw ::Ice::ValueUnmarshalException(__FILE__, __LINE__);"; + out.dec(); + } + out << eb; + + return; + } + + Constructed_ptr constructed = Constructed_ptr::dynamicCast(type); + if(!constructed) + { + Proxy_ptr proxy = Proxy_ptr::dynamicCast(type); + assert(proxy); + constructed = proxy -> _class(); + } + + out << nl << constructed -> scope() << "::__" << func << stream << ", " + << param << ");"; +} + +void +IceLang::writeMarshalCode(Output& out, + const list<pair<Type_ptr, string> >& params, + const Type_ptr& ret) +{ + list<pair<Type_ptr, string> >::const_iterator p; + for(p = params.begin(); p != params.end(); ++p) + writeMarshalUnmarshalCode(out, p -> first, p -> second, true); + if(ret) + writeMarshalUnmarshalCode(out, ret, "__ret", true); +} + +void +IceLang::writeUnmarshalCode(Output& out, + const list<pair<Type_ptr, string> >& params, + const Type_ptr& ret) +{ + list<pair<Type_ptr, string> >::const_iterator p; + for(p = params.begin(); p != params.end(); ++p) + writeMarshalUnmarshalCode(out, p -> first, p -> second, false); + if(ret) + writeMarshalUnmarshalCode(out, ret, "__ret", false); +} + +void +IceLang::writeAllocateCode(Output& out, + const list<pair<Type_ptr, string> >& params, + const Type_ptr& ret) +{ + list<pair<Type_ptr, string> > ps = params; + if(ret) + ps.push_back(make_pair(ret, string("__ret"))); + + list<pair<Type_ptr, string> >::const_iterator p; + for(p = ps.begin(); p != ps.end(); ++p) + out << nl << typeToString(p -> first) << ' ' << p -> second << ';'; +} diff --git a/cpp/src/slice2cpp/GenCPlusPlusUtil.h b/cpp/src/slice2cpp/GenCPlusPlusUtil.h new file mode 100644 index 00000000000..35eefdd4c3e --- /dev/null +++ b/cpp/src/slice2cpp/GenCPlusPlusUtil.h @@ -0,0 +1,41 @@ +// ********************************************************************** +// +// Copyright (c) 2001 +// MutableRealms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#ifndef GEN_C_PLUS_PLUS_UTIL_H +#define GEN_C_PLUS_PLUS_UTIL_H + +#include <Parser.h> +#include <OutputUtil.h> + +namespace IceLang +{ + +std::string typeToString(const Type_ptr&); +std::string returnTypeToString(const Type_ptr&); +std::string inputTypeToString(const Type_ptr&); +std::string outputTypeToString(const Type_ptr&); + +void writeMarshalUnmarshalCode(Output&, const Type_ptr&, const std::string&, bool); + +void writeMarshalCode(Output&, + const std::list<std::pair<Type_ptr, std::string> >&, + const Type_ptr&); + +void writeUnmarshalCode(Output&, + const std::list<std::pair<Type_ptr, std::string> >&, + const Type_ptr&); + +void writeAllocateCode(Output&, + const std::list<std::pair<Type_ptr, std::string> >&, + const Type_ptr&); + +} + +#endif diff --git a/cpp/src/slice2cpp/Main.cpp b/cpp/src/slice2cpp/Main.cpp new file mode 100644 index 00000000000..4915c2a0600 --- /dev/null +++ b/cpp/src/slice2cpp/Main.cpp @@ -0,0 +1,192 @@ +// ********************************************************************** +// +// Copyright (c) 2001 +// MutableRealms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#include <GenCPlusPlus.h> +#include <fstream> + +using namespace std; +using namespace IceLang; + +void +usage(const char* n) +{ + cerr << "Usage: " << n << " [options] ice-files ...\n"; + cerr << +"Options:\n" +"-h, --help Show this message.\n" +"-DNAME Define NAME as 1.\n" +"-DNAME=DEF Define NAME as DEF.\n" +"-UNAME Remove any definition for NAME.\n" +"-IDIR Put DIR in the include file search path.\n" +"--include-dir Specify the header include directory.\n" +"--dll-export Specify a symbol for DLL exports.\n" +"-d, --debug Print debug messages.\n" + ; +} + +int +main(int argc, char* argv[]) +{ + string cpp("cpp"); + vector<string> includePaths; + string include; + string dllExport; + + int idx = 1; + while(idx < argc) + { + if(strncmp(argv[idx], "-I", 2) == 0) + { + cpp += ' '; + cpp += argv[idx]; + + string path = argv[idx] + 2; + if(path.length()) + includePaths.push_back(path); + + for(int i = idx ; i + 1 < argc ; ++i) + argv[i] = argv[i + 1]; + --argc; + } + else if(strncmp(argv[idx], "-D", 2) == 0 || + strncmp(argv[idx], "-U", 2) == 0) + { + cpp += ' '; + cpp += argv[idx]; + + for(int i = idx ; i + 1 < argc ; ++i) + argv[i] = argv[i + 1]; + --argc; + } + else if(strcmp(argv[idx], "-h") == 0 || + strcmp(argv[idx], "--help") == 0) + { + usage(argv[0]); + return EXIT_SUCCESS; + } + else if(strcmp(argv[idx], "-d") == 0 || + strcmp(argv[idx], "--debug") == 0) + { + extern int yydebug; + yydebug = 1; + for(int i = idx ; i + 1 < argc ; ++i) + argv[i] = argv[i + 1]; + --argc; + } + else if(strcmp(argv[idx], "--include-dir") == 0) + { + if(idx + 1 >= argc) + { + cerr << argv[0] << ": error: argument expected for`" + << argv[idx] << "'" << endl; + usage(argv[0]); + return EXIT_FAILURE; + } + + include = argv[idx + 1]; + for(int i = idx ; i + 2 < argc ; ++i) + argv[i] = argv[i + 2]; + argc -= 2; + } + else if(strcmp(argv[idx], "--dll-export") == 0) + { + if(idx + 1 >= argc) + { + cerr << argv[0] << ": error: argument expected for`" + << argv[idx] << "'" << endl; + usage(argv[0]); + return EXIT_FAILURE; + } + + dllExport = argv[idx + 1]; + for(int i = idx ; i + 2 < argc ; ++i) + argv[i] = argv[i + 2]; + argc -= 2; + } + else if(argv[idx][0] == '-') + { + cerr << argv[0] << ": error: unknown option `" << argv[idx] << "'" + << endl; + usage(argv[0]); + return EXIT_FAILURE; + } + else + ++idx; + } + + if(argc < 2) + { + cerr << argv[0] << ": error: no input file" << endl; + usage(argv[0]); + return EXIT_FAILURE; + } + + for(idx = 1 ; idx < argc ; ++idx) + { + string base(argv[idx]); + string suffix; + string::size_type pos = base.rfind('.'); + if(pos != string::npos) + { + suffix = base.substr(pos); + transform(suffix.begin(), suffix.end(), suffix.begin(), tolower); + } + if(suffix != ".ice") + { + cerr << argv[0] << ": input files must end with `.ice'" + << endl; + return EXIT_FAILURE; + } + base.erase(pos); + + ifstream test(argv[idx]); + if(!test) + { + cerr << argv[0] << ": can't open `" << argv[idx] + << "' for reading: " << strerror(errno) << endl; + return EXIT_FAILURE; + } + test.close(); + + string cmd = cpp + " " + argv[idx]; +#ifdef WIN32 + FILE* cppHandle = _popen(cmd.c_str(), "r"); +#else + FILE* cppHandle = popen(cmd.c_str(), "r"); +#endif + if(cppHandle == NULL) + { + cerr << argv[0] << ": can't run C++ preprocessor: " + << strerror(errno) << endl; + return EXIT_FAILURE; + } + + Parser_ptr parser = Parser::createParser(); + int status = parser -> parse(cppHandle); + +#ifdef WIN32 + _pclose(cppHandle); +#else + pclose(cppHandle); +#endif + + if(status == EXIT_FAILURE) + return status; + + GenCPlusPlus gen(argv[0], base, include, includePaths, dllExport); + if(!gen) + return EXIT_FAILURE; + gen.generate(parser); + + parser -> destroy(); + } + + return EXIT_SUCCESS; +} diff --git a/cpp/src/slice2cpp/Makefile b/cpp/src/slice2cpp/Makefile new file mode 100644 index 00000000000..fee98be25d5 --- /dev/null +++ b/cpp/src/slice2cpp/Makefile @@ -0,0 +1,31 @@ +# ********************************************************************** +# +# Copyright (c) 2001 +# MutableRealms, Inc. +# Huntsville, AL, USA +# +# All Rights Reserved +# +# ********************************************************************** + +top_srcdir = ../../.. + +NAME = $(top_srcdir)/bin/slice2cpp + +TARGETS = $(NAME) + +OBJS = GenCPlusPlus.o \ + GenCPlusPlusUtil.o \ + Main.o + +SRCS = $(OBJS:.o=.cpp) + +include $(top_srcdir)/config/Make.rules + +CPPFLAGS := -I../parser $(CPPFLAGS) + +$(NAME): $(OBJS) + rm -f $@ + $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $(OBJS) -lSlice $(BASELIBS) + +include .depend |