This document consists of two parts.  The first part describes some
changes to the interpreter that may affect existing slang macros.  The
second part describes changes that may affect applications that use
the library.

Part 1: Interpreter Changes.
============================

Changes to the slang syntax.
---------------------------
 The syntax has not changed too much since version 0.99-XX.  However
 there are a few changes that you need to be aware of so that you can
 modify your slang functions accordingly.  See slang/doc/* for more
 information about slang version 1.0.
 
 To help track areas where you code needs changed, add the following
 line to the top of each file that you load into the interpreter:
 
     _debug_info = 1;

 This will cause extra debugging information to get generated.

 The important differences that you must be aware of are listed below:

 * The parser is more sensitive to missing semi-colons.  For that
   reason, you may experience some parse errors.  Make sure each
   statement is terminated by a semi-colon.

 * The switch statement has changed--- it is cleaner.  In particular,
   the `pop' in the default case should be removed.  For example, in
   0.99-XX, the object was pushed onto the stack before each switch
   case block was executed.  In 1.0, the switch statement nolonger
   works this way.  So, if you currently have code that looks like:
       
          switch (x)
	  { case 1:                  do_something () }
	  { case 2 or case (x, 3):   do_something_else () }
	  { () > 7:                  do_big_thing ();
	  { pop ();                  do_default () }
	  
   
   You must change it to:

          switch (x)
	  { case 1:                  do_something (); }
	  { case 2 or case 3:        do_something_else (); }
	  { x > 7:                   do_big_thing (); }
	  {                          do_default (); }

   Note that this example also illustrates that you may need to insert
   some semi-colons to terminate statements.  In any event, it is a
   good idea to study your switch statements very carefully.

 * The `create_array' function has been eliminated in favor of a new,
   cleaner mechanism.  For example, instead of using
   
         a = create_array ('s', 10, 20, 2);
	 
   to create a 10x20 array of strings, you must now use
   
         a = String_Type [10, 20];
 
   Similarly, use `Integer_Type [10, 20]' to create a 10x20 array of
   integers.  [Note for JED users: See jed/lib/compat.sl for an
   implementation of create_array]
   
 * The semantics of the ``alias'' operator `&' has changed in a much
   more useful way.  Briefly, if you have code that looks like:
   
         define exec_function (f)
	 {
	    variable x = 1.0;
	    return f(x);
	 }
	 
	 variable y = exec_function (&sin);

   Then you must change it to:
   
         define exec_function (f)
	 {
	    variable x = 1.0;
	    return @f(x);
	 }
	 
	 variable y = exec_function (&sin);

   where `@' is a ``dereference'' operator.
   
 * Several intrinsic functions have changed and a few have been
   removed, or renamed.  See the documentation in slang/doc/ for more
   detailed information about each function.

   Functions ones that have been removed or renamed include:

     create_array
        Use simpler syntax, e.g.,  x = Integer_Type [10];

     _obj_info
        Use the new `typeof' function.  See documentation for more
	information.
	
     print_stack has been renamed to _print_stack
     
     `slapropos' has been renamed to `_apropos'.  It also takes an
     additional argument.
	
     `float' has been renamed to `double'.  See also `atof'.
     
     `slang_trace_function' renamed to `_trace_function'
     
     `pop_n' has been renamed to `_pop_n'
     
   The semantics of the following functions have changed:
   
      `fopen': 
         It now returns NULL upon failure.  Change code such as
      
            fp = fopen (file, "r");
	    if (fp == -1) error (...);

         to:

            fp = fopen (file, "r");
	    if (fp == NULL) error (...);
      
      `getenv', `extract_element':
         These return NULL upon failure instead of "".  This means code 
	 that looks like:
	   
	    n = 0;
	    while (elem = extract_element (list, n, ','), strlen(elem))
	      {
	         n++;
		 .
		 .
	      }

	 should be changed to:
	 
	    n = 0;
	    while (elem = extract_element (list, n, ','), elem != NULL)
	      {
	         n++;
		 .
		 .
	      }

      `fclose': It now returns -1 upon failure and sets errno, or 0 if
          successful. Previously, it returned 0 upon failure and 1
	  upon success. 
      
      `fgets': It now returns just 1 value but takes a reference as an
          argument.  That is, replace code such as:
	  
	    while (fgets (fp) > 0)
	      {
	         buf = ();
		 .
		 .
	      }
	     
	  with:
	  
	    while (-1 != fgets (&buf, fp))
	      {
	         .
		 .
	      }
	    

Part 2:  C interface changes
============================

[Please review slang/doc/text/cslang.txt for information regarding
 embedding the interpreter]

There have been many, many changes since 0.99-XX.  Most of the changes
concern the interpreter and the interpreter interface.  Other aspects
of the library, e.g., SLsmg, etc have not changed too much.  I made
every attempt to maintain as much backward compatibility as possible,
weighing the pros and cons of every change.  I think that I arrived at
a reasonable compromise, and, hopefully, you will agree.

When recompiling your application, make sure that you compile it with
warnings turned on so that prototype changes may be detected.

-----------------------------------------------------------------------
The way objects are accessed internally by the interpreter has changed
dramatically.  This has important ramifications for an any application
embedding the interpreter.  In particular, the way intrinsic objects
are made available to the interpreter has changed.

In 0.99-XX, the standard procedure was to use the MAKE_INTRINSIC macro
inside an array of SLang_Name_Type, e.g.,

    void c_fname (void) { ... }
    char *String_Variable;
    int Int_Variable;
    char String_Buf[256];

    static SLang_Name_Type My_Intrinsics [] = 
    {
       MAKE_INTRINSIC(".fname", c_fname, VOID_TYPE, 0),
       MAKE_VARIABLE(".string_vname", String_Variable, STRING_TYPE, 1),
       MAKE_VARIABLE(".string_buf_vname", String_Buf, STRING_TYPE, 1),
       MAKE_VARIABLE(".int_vname", &Int_Variable, INT_TYPE, 0),
       SLANG_END_TABLE
    };

In the new version, variables and intrinsics cannot be grouped in the
same table.  Instead two tables must be used:

    static SLang_Intrin_Fun_Type My_Intrinsic_Funs [] =
    {
       MAKE_INTRINSIC("fname", c_fname, VOID_TYPE, 0),
       SLANG_END_TABLE
    };
    
    char *String_Buf_Ptr = String_Buf;
    static SLang_Intrin_Var_Type My_Intrinsic_Funs [] =
    {
       MAKE_VARIABLE("string_vname", &String_Variable, STRING_TYPE, 1),
       MAKE_VARIABLE("int_vname", &Int_Variable, INT_TYPE, 0),
       MAKE_VARIABLE(".string_buf_vname", &String_Buf_Ptr, STRING_TYPE, 1),
       SLANG_END_TABLE
    };
    
Note that the `.' is no longer required to be the first character in
the name.  Also, the `&' address operator must be used for all
variables in the MAKE_VARIABLE macro.  Finally, intrinsic STRING_TYPE
variables must be pointers and not arrays.  This is the reason
String_Buf_Ptr was introduced.

You are encouraged to read the documentation about embedding the
interpreter because it is now possible to ensure that variables passed
to an intrinsic are type checked.  See slang/slstd.c for examples.

------------------------------------------------------------------------
0.99-XX had a very inconsistent interface.  For example, while some
functions returned 0 upon success, others returned 0 to indicate
failure.  One of the major changes to the library was to provide a
consistent return value to indicate error.  In this version, -1
indicates an error and 0 indicates success.  In particular, the
following functions were affected:

   SLdefine_for_ifdef
   SLang_execute_function
   SLexecute_function
   SLang_run_hooks
   SLang_load_object
   SLang_pop_*
   SLang_push_*
   SLsmg_resume_smg
   SLsmg_suspend_smg
   SLtt_init_video
   SLtt_reset_video

Another change involved the name space.  All external symbols now
start with `SL'.  To this end, the following functions have been
renamed:

    init_SLmath -->     SLang_init_slmath
    init_SLunix -->     SLang_init_slunix
    init_SLang -->      SLang_init_slang
    init_SLfiles -->    SLang_init_slfile
    slang_add_array --> SLang_add_intrinsic_array

Some other functions were renamed when the interface changed:

    SLang_extract_list_element --> SLextract_list_element
    SLang_Error_Routine --> SLang_Error_Hook

Some functions were not renamed but do have different prototypes:

    int SLang_run_hooks(char *, unsigned int, ...);

Some functions are nolonger available or have been replaced by newer,
more flexible versions:

    SLadd_name --> SLadd_intrinsic_variable, SLadd_intrinsic_function
    SLang_pop/push_float --> SLang_pop/push_double


Typedef Modifications
---------------------
SLang_Load_Type: The interface has been completely rewritten.  See
  the documentation.
  
Preprocessor defines:
--------------------
  __SLMATH__ if math functions available (SLang_init_slmath)
  __SLUNIX__ if unix functions available (SLang_init_slunix)
  __SLFILE__ if file I/O functions available (SLang_init_slfile)