-- Copyright 1993-1998, by the Cecil Project -- Department of Computer Science and Engineering, University of Washington -- See the LICENSE file for license information. ---------- -- comparing behavior ---------- --DOC All objects can be compared for identity, using a low-level --DOC implementation-dependent test. Two things that print out the --DOC same may not be `==', e.g. `"abc" == "abc"' may return `false'. --DOC By default, operations on collections that compare elements, --DOC such as finding an element in a list or adding an element to a --DOC set, use `=' (implemented by `comparable' objects) rather than --DOC `==', unless the collection's name includes `identity_'. -- == and !== test object identity --DOCSHORT object identity test; very low-level, but fast method ==(l:any, r:any):bool { prim -- just do a pointer compare rtl: "if l =_int_log r goto l1; return false; label l1; return true;" } --DOCSHORT not `==' method !==(l:any, r:any):bool { not(l == r) } precedence ==, !== with =; ---------- -- printing behavior ---------- --DOC Any object can be converted to a string, although the default --DOC version can be low-level and ugly. Most commonly-used objects --DOC override `print_string' to return something prettier. --DOC (A two-element version of `print' permits strings to be printed to --DOC `unix_file's.) --DOCSHORT return a string print version method print_string(x:any):string { basic_print_string(x) } --DOCSHORT print the `print_string' method print(x:any):void (** no_inline **) { x.print_string.print; } --DOCSHORT print the `print_string' and a newline method print_line(x:any):void (** no_inline **) { x.print; "\n".print; } --DOCSHORT just print a newline method print_line():void (** no_inline **) { "\n".print; } --DOCSKIP don't have to be in the manual method collection_to_string(msg:ordered_collection[any]):string { msg.flatten_eval(&(t:any){ t.no_quotes_string }) } method collection_to_string(msg@:string):string { msg } method no_quotes_string(t:any):string { t.print_string } method no_quotes_string(c@:char):string { c.as_string } method no_quotes_string(s@:string):string { s } --DOCENDSKIP --DOCSKIP seems to me like these should be omitted method basic_print_string(x:any):string (** return_type(i_vstring),sends(), formals_escape(f) **){ prim c_++: " if (x->isInt()) { char s[16]; sprintf(s, \"%ld\", x->asInt()); #ifdef DISPATCHERS RETURN(NEW_STRING(s)); #else BP(NEW_STRING(s)); #endif } else { #ifdef DISPATCHERS RETURN(x->asMem()->basicPrintString()); #else BP(x->asMem()->basicPrintString()); #endif } " } method basic_print(x:any):void (** return_type(void), sends(), does_io, formals_escape(f) **) { prim c_++: " if (x->isInt()) { printf(\"%d\\n\", x->asInt()); } else { pp(x); } #ifdef DISPATCHERS RETURN(BASE(void)); #else BP(BASE(void)); #endif " } --DOCENDSKIP --------------------- --DOC The `error' method is the standard way to prematurely quit --DOC execution of a Cecil program. -- note: error might have a non-local return, from the -- print_line, flush, and stdout messages. so it can't be a guaranteed -- end of the caller's control flow. but at least it is known not to -- return normally! --DOCSHORT quits with an error message; does not return method error(msg:ordered_collection[`T] ):none (** no_inline, does_not_return **) { "\n".print; -- ensure message appears at beginning of line msg.collection_to_string.print_line; -- flush(stdout()); exit(-1) } --------------------- --DOC The `not_defined' object can be used as a dummy object if there --DOC isn't a real one to use, e.g., if you have to have an --DOC uninitialized variable or field or want to reflect whether or not --DOC some value is present. `not_defined' is therefore used in places --DOC where a NULL pointer might be used in other languages. --DOC In general, it is poor style to use `not_defined'. It is better to --DOC define an application-specific "absent" object, integrated into a little --DOC class hierarchy of present or absent data, with appropriate application- --DOC specific behavior attached to the "absent" object. concrete object not_defined; --------------------- --DOCSKIP hardly want to brag about this.... -- This method can be used to type-cast explicitly. No runtime check performed! method cast[T](x:`S):T&S (** no_typecheck **) { x } --DOCENDSKIP