2013-04-18 14:58 UTC+0200 Przemysław Czerpak (druzus/at/poczta.onet.pl)
* .gitignore
! removed executable file permission
* package/mpkg_src.sh
! added executable file permission
* contrib/hbct/screen2.c
% use STR API for parameters instead of using local conversions
* contrib/hbct/token1.c
% small simplification
* contrib/hbnetio/netiosrv.c
+ respect timeout parameter also in send operation
* contrib/make.hb
! moved project name normalization and directory verification to
AddProject() function. It fixes HB_BUILD_ADDONS envvar functionality.
* doc/xhb-diff.txt
+ added new paragraph: DECLARATION AND INITIALIZATION OF VARIABLES
* src/rtl/hbcom.c
* added 3-rd parameter to TIOCEXCL and TIOCNXCL ioctl() codes
to pacify valgrind warnings
* include/hbexpra.c
! fixed compilation with HB_USE_ENUM_FUNCTIONS macro
* include/hbapicls.h
* include/hbcompdf.h
* include/hbexpra.c
* src/compiler/harbour.y
* src/vm/classes.c
+ added support for :__enumIsFirst() iterator message. It's opposite
to recently added :__enumIsLast()
+ added support for overloading :__enumIsFirst() and :__enumIsLast()
functionality in custom FOR EACH implementations
* include/hbcompdf.h
* include/hbexpra.c
* src/compiler/harbour.y
+ added support for reverting :__enumIsFirst() and :__enumIsLast()
messages in descendant FOR EACH loops. It's disabled now by 2 #if 0
but I think it should be discussed. Should we keep it enable it?
The answer is not trivial when FOR EACH is used to iterate some
objects. In general such names are confusing.
* src/compiler/harbour.yyc
* src/compiler/harbour.yyh
* regenerated using bison 2.5
* tests/foreach.prg
+ added :__enumIsFirst() to test code
* tests/foreach2.prg
! typo in comment
This commit is contained in:
@@ -521,6 +521,105 @@ references by detached locals and add workarounds for it if necessary.
|
||||
|
||||
|
||||
|
||||
### DECLARATION AND INITIALIZATION OF VARIABLES ###
|
||||
=========================================================
|
||||
Clipper parses variable declaration in a little bit different way then
|
||||
Harbour and xHarbour. It makes it in two passes. In first pass it collects
|
||||
names and scope of all declared variables and then in second pass this
|
||||
information is available during variable initialization. This can be
|
||||
illustrated by the following example:
|
||||
|
||||
/*** tst.prg ***/
|
||||
proc main()
|
||||
local cb := {|| qout( n + 5 ), qout( f ) } // (*)
|
||||
field f in table
|
||||
local n := 10
|
||||
eval( cb )
|
||||
return
|
||||
|
||||
In the line which initialize cb code (*) we are using local variable n
|
||||
and field f. Both are declared below the line in which codeblock is
|
||||
initialized anyhow Clipper does not recognize it as undeclared variables
|
||||
and use their later declarations. If you compile above code using Clipper
|
||||
with -n -w -es2 switches, i.e.
|
||||
cl tst -n -w -es2
|
||||
then it's compiled without any compile time warnings or errors. Then
|
||||
during execution it shows 15 for the first QOUT() function call and
|
||||
generate runtime error
|
||||
Error BASE/1002 Alias does not exist: TABLE
|
||||
for the second QOUT() call. It means that it correctly recognized scope
|
||||
of both variables and also bound alias TABLE with field F though it was
|
||||
declared two lines below codeblock initialization.
|
||||
|
||||
In fact Clipper probably does not make two passes but parsing declarations
|
||||
which have to be at the beginning of function or module it stores names of
|
||||
variables which should be initialized with the initialization expressions.
|
||||
Then when all declarations are processed for each line with declared and
|
||||
initialized variables it generates code which pushes on VM stack results
|
||||
of initialization expressions and then code which pops it initializing
|
||||
variables. As result in Clipper this code cannot work:
|
||||
local x := 10, y := x + 2
|
||||
because Clipper generate PCODE like:
|
||||
push 10
|
||||
push x
|
||||
push 2
|
||||
add
|
||||
pop y
|
||||
pop x
|
||||
but this code:
|
||||
local x := 10
|
||||
local y := x + 2
|
||||
works correctly because declarations were in separated lines and in such
|
||||
case Clipper generates PCODE like:
|
||||
push 10
|
||||
pop x
|
||||
push x
|
||||
push 2
|
||||
add
|
||||
pop y
|
||||
|
||||
In Harbour and xHarbour all variables are declared in the moment when they
|
||||
are processed. It means that during compilation of above example using
|
||||
harbour tst -n -w -es2
|
||||
both compilers generate compile time warnings:
|
||||
tst.prg(2) Warning W0001 Ambiguous reference 'N'
|
||||
tst.prg(2) Warning W0001 Ambiguous reference 'F'
|
||||
but it also means that in Harbour and xHarbour it's possible to write code
|
||||
like:
|
||||
proc main()
|
||||
local x := 10, y := x + 2
|
||||
? x, y
|
||||
return
|
||||
and unlike Clipper both compilers generates correct PCODE which shows
|
||||
10 12
|
||||
Maybe in the future we add support for Clipper compatible local variable
|
||||
initialization covered by -kc Harbor compiler switch.
|
||||
|
||||
xBase++ uses mixed behavior. Just like Clipper it stores variables with
|
||||
initialization expressions but then it generates slightly different code
|
||||
initializing variables one by one without line groping like in Clipper.
|
||||
|
||||
Please also note that in Clipper PRIVATE and PUBLIC declarations are
|
||||
executable statements so they are not used used as declarations by
|
||||
Clipper compiler even if -a compiler switch is used. So when we talk
|
||||
about initialization then it means that we are talking about LOCAL
|
||||
variables. STATIC variables are initialized in different way at
|
||||
application startup so cannot use local variables though due to but
|
||||
in Clipper in some cases compiler can accept local variables and then
|
||||
it may cause VM crash or runtime error, i.e. this code:
|
||||
|
||||
proc main()
|
||||
local n
|
||||
static s := {|| n }
|
||||
eval( s )
|
||||
return
|
||||
|
||||
is cleanly compiled by Clipper and xBase++ but it causes RTE in
|
||||
Clipper and FATAL ERROR LOG in xBase++.
|
||||
Harbour and xHarbour correctly report compile time error for it.
|
||||
|
||||
|
||||
|
||||
### FUNCTIONS WITH VARIABLE NUMBER OF PARAMETERS ###
|
||||
==========================================================
|
||||
Both compilers supports them though xHarbour is limited to all parameters
|
||||
|
||||
Reference in New Issue
Block a user