Files
harbour-core/harbour/doc/en/clipper.txt
Ryszard Glab 912b301c85 2006-07-14 16:00 UTC+0100 Ryszard Glab <rglab//imid.med.pl>
* include/hbcomp.h
   * include/hberrors.h
   * include/hbexpra.c
   * include/hbexprb.c
   * include/hbexprc.c
   * include/hbmacro.h
   * include/hbpcode.h
   * include/hbpp.h
   * include/hbxvm.h
   * source/common/expropt1.c
   * source/compiler/cmdcheck.c
   * source/compiler/expropta.c
   * source/compiler/exproptb.c
   * source/compiler/exproptc.c
   * source/compiler/genc.c
   * source/compiler/gencc.c
   * source/compiler/gencli.c
   * source/compiler/genhrb.c
   * source/compiler/genjava.c
   * source/compiler/genobj32.c
   * source/compiler/harbour.c
   * source/compiler/harbour.l
   * source/compiler/harbour.y
   * source/compiler/hbdead.c
   * source/compiler/hbfix.c
   * source/compiler/hbfunchk.c
   * source/compiler/hbgenerr.c
   * source/compiler/hblbl.c
   * source/compiler/hbpcode.c
   * source/compiler/hbstripl.c
   * source/macro/macroa.c
   * source/macro/macrob.c
   * source/macro/macroc.c
   * source/vm/hvm.c
   * source/vm/macro.c
      * fixed compilation of code that uses '@' pass by
       reference. The following syntax is no longer supported:
       var := IIF( .T., @var, var )
       however you can still use the following:
       funcall( IIF( bPassbyRef, @someVar, someVar ) )
      +added support for the following statement:
         WITH OBJECT <objexpression>
            ...
         END
       inside this statement you can use simplified form of sending
       messages to the object specified by <objexpression>
         :message( )    instead objexpression:message()
         :property      instead objexpression:property
       The runtime error will be generated at the time of message
       sending (or property access/assign) if <objexpression>
       is not a value of type object.
       You can use the reserved property:
         :__withobject
       to access/assign the controlling object.
      *fixed support for command line response file (@file.clp)
       to be compatible with Clipper (Clipper genertes a single
       obj file)
      *fixed memory leaks when there is a fatal error in autoopened
       module (using DO ... statement)
      *implicit startup functions are removed from the list of
       functions before generation of output code

   * source/pp/ppcomp.c
   * source/pp/pplib.c
   * source/pp/ppcore.c
      * redefinition of #define no longer causes a memory leak
      * fixed repeatable optional clauses
         #xcommand SET <var1> [, <varN>] WITH <val> =>
          <var1>:=<val>[; <varN>:=<val>]
      * fixed compilation of optional clauses (when used in different
        order then declared) -this fixes the following long
        waiting bug:
         #command MYCOMMAND [<mylist,...>] [MYCLAUSE <myval>] => ;
            MyFunction( {<mylist>} [, <myval>] )
         MYCOMMAND MYCLAUSE 321 "HELLO"
      * fixed restricted macro match marker <x:&>

   * tests/Makefile
   - tests/pretest.prg
   + utils/hbpptest
   + utils/hbpptest/Makefile
   + utils/hbpptest/pretest.prg
      * moved file 'pretest.prg' from tests to separate directory
        to make easier validation of the preprocessor

   * TODO
      * added note to fix hb_objGetMethod() so it will not generate
        error if there is no method

   * doc/en/clipper.txt
      * added documentation for WITH OBJECT usage
2006-07-14 13:47:17 +00:00

165 lines
4.7 KiB
Plaintext

$Id$
This document attempts to describe the features separating Harbour from
Clipper.
/* TODO: @FunPointer(), and all other Harbour extensions. */
Harbour Macro Compiler
----------------------
The Harbour Macro Compiler offers 2 additional layers of functionality
controlled by means of HB_SETMACRO()* function, not available in Clipper.
HB_SETMACRO( HB_SM_HARBOUR, TRUE ) will enable macro compilation and
evaluation of complex expressions not supported by Clipper like:
- exp++, exp--, var += exp, (exp), etc..
- Nested codeblocks.
- Expressions longer then 254 characters.
HB_SETMACRO( HB_SM_XBASE, TRUE ) will enable macro compilation and
evaluation of comma separated lists in all contexts where lists are
acceptable by Clipper*, including:
- { &cMacro } // Literal array elements list.
- SomeArray[ &cMacro ] // Array index list.
- SomeFun( &cMacro ) // Arguments list.
- ( &cMacro ) // parenthesized list expression.
*Clipper only supports list macros within codeblocks context.
Both these extra layers are activated by default.
* See also -k Compiler switch.
LIST Command
------------
LIST &cMacro
LIST in clipper [superficially] supports macros of lists expressions.
No error will be produced, and all expressions in the list will be
evaluated, but *only* the *last* expression will be displayed. This is
not documented in either the LIST Command or the Macro Operator
descriptions, but is the de-facto behavior in all Clipper 5.x versions.
Harbour instead will not only evaluate all of the expressions in
such list macro, but will also display all such values. This default
behavior may be disabled with HB_SETMACRO( HB_SM_XBASE, .F. )*
* See also -k Compiler switch.
INIT/EXIT and startup procedures
--------------------------------
In Clipper the startup procedure is always the first procedure/function
of the main module, even if such symbol is an INIT or EXIT symbol. In
such case the program will never execute the "main" symbol. In Harbour
the first *non* INIT/EXIT symbol, will be executed as the main symbol
after all INIT procedures have been executed.
FOR EACH statement
------------------
Harbour has support enumeration loop with the following syntax:
FOR EACH var1 [,var255] IN expr1 [,expr255] [DESCEND]
[EXIT]
[LOOP]
...
NEXT
Note:
-expr can be a string or an array
-enumerator variable 'var<n>' stores a reference to the element of
an array or a string specified by 'expr<n>' thus assigments to the
enumerator changes the value of given array element
-after the loop the controlling variable(s) store the value which
they had before entering the loop
-the enumeraqtor variable supports the following properties
:__enumindex - the loop counter for variable
:__enumbase - the value that is being traversed
:__enumvalue - the value of variable
for example:
a = 'A'
b = 'B'
FOR EACH a,b IN { 1, 2, 3, 4 }, "abcd"
? a, b //prints: 1 a
// 2 b
// 3 c
// 4 d
NEXT
? a, b //prints: A B
// you can use EXIT statement inside the loop
FOR EACH a IN { 1, 2, 3, 4 }
IF( a:__enumindex == 3 )
? a
EXIT
ENDIF
NEXT
arr := { 1, 2, 3 }
str := "abc"
FOR EACH a, b IN arr, str
a *= 2
str := UPPER( str )
NEXT
//now 'arr' stores { 2, 4, 6 }
//howerer 'str' still stores "abc"
Notice the difference:
FOR EACH a IN someValue
? a:__enumindex //prints current value of the index
? (a):__enumindex //sends '__enumindex' message to the current value
NEXT
WITH OBJECT
-----------
Harbour supports the following statement:
WITH OBJECT expression
...
END
Inside this WITH OBJECT/END enclosure you can use the simplified
form of sending messages to the object. You can use the syntax
:message( [params] )
:property
to send messages to the object specified by 'expression'
for example:
WITH OBJECT myobj:a[1]:myitem
:message( 1 )
:value := 9
END
The above code is equivalent to:
myobj:a[1]:myitem:message( 1 )
myobj:a[1]:myitem:value := 9
Inside WITH OBJECT/END you can access (or even assign a new object)
using a special reserved property :__withobject
The runtime error will be generated at the time of message
sending (or property access/assign) if <objexpression>
is not a value of type object.
for example:
CLASS foo
DATA name INIT 'FOO'
ENDCLASS
CLASS bar
DATA name INIT 'BAR'
ENDCLASS
WITH OBJECT foo():new()
? :name //prints 'FOO'
? :__withobject:name //also prints 'FOO'
? :__withobject := bar():new()
? :name //prints 'BAR'
END