1888 lines
81 KiB
Plaintext
1888 lines
81 KiB
Plaintext
%{
|
|
/*
|
|
* $Id$
|
|
*/
|
|
|
|
/*
|
|
* Harbour Project source code:
|
|
* Compiler YACC rules and actions
|
|
*
|
|
* Copyright 1999 Antonio Linares <alinares@fivetech.com>
|
|
* www - http://www.harbour-project.org
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version, with one exception:
|
|
*
|
|
* The exception is that if you link the Harbour Runtime Library (HRL)
|
|
* and/or the Harbour Virtual Machine (HVM) with other files to produce
|
|
* an executable, this does not by itself cause the resulting executable
|
|
* to be covered by the GNU General Public License. Your use of that
|
|
* executable is in no way restricted on account of linking the HRL
|
|
* and/or HVM code into it.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA (or visit
|
|
* their web site at http://www.gnu.org/).
|
|
*
|
|
*/
|
|
|
|
/* TODO list
|
|
* 1) jumps longer then 2^15 bytes
|
|
* 2) Change the pcode generated by ::cVar from Self:cVar to QSELF():cVar
|
|
* 3) Support this syntax: nPtr := @Hello()
|
|
*/
|
|
|
|
#include <malloc.h>
|
|
|
|
#include "hbcomp.h"
|
|
|
|
/* Compile using: bison -d -v harbour.y */
|
|
|
|
extern FILE *yyin; /* currently yacc parsed file */
|
|
extern int hb_comp_iLine; /* currently parsed file line number */
|
|
extern char *yytext;
|
|
|
|
#ifdef __cplusplus
|
|
typedef struct yy_buffer_state *YY_BUFFER_STATE;
|
|
extern YY_BUFFER_STATE yy_create_buffer( FILE *, int ); /* yacc functions to manage multiple files */
|
|
extern void yy_switch_to_buffer( YY_BUFFER_STATE ); /* yacc functions to manage multiple files */
|
|
extern void yy_delete_buffer( YY_BUFFER_STATE ); /* yacc functions to manage multiple files */
|
|
#else
|
|
extern void * yy_create_buffer( FILE *, int ); /* yacc functions to manage multiple files */
|
|
extern void yy_switch_to_buffer( void * ); /* yacc functions to manage multiple files */
|
|
extern void yy_delete_buffer( void * ); /* yacc functions to manage multiple files */
|
|
#endif
|
|
|
|
/* lex & yacc related prototypes */
|
|
extern int yyparse( void ); /* main yacc parsing function */
|
|
extern void yyerror( char * ); /* parsing error management function */
|
|
extern int yylex( void ); /* main lex token function, called by yyparse() */
|
|
#ifdef __cplusplus
|
|
extern "C" int yywrap( void );
|
|
#else
|
|
extern int yywrap( void ); /* manages the EOF of current processed file */
|
|
#endif
|
|
|
|
static void hb_compLoopStart( void );
|
|
static void hb_compLoopEnd( void );
|
|
static void hb_compLoopLoop( void );
|
|
static void hb_compLoopExit( void );
|
|
static void hb_compLoopHere( void );
|
|
|
|
static void * hb_compElseIfGen( void * pFirstElseIf, ULONG ulOffset ); /* generates a support structure for elseifs pcode fixups */
|
|
static void hb_compElseIfFix( void * pIfElseIfs ); /* implements the ElseIfs pcode fixups */
|
|
|
|
static void hb_compRTVariableAdd( HB_EXPR_PTR, BOOL );
|
|
static void hb_compRTVariableGen( char * );
|
|
|
|
static void hb_compVariableDim( char *, HB_EXPR_PTR );
|
|
|
|
#ifdef HARBOUR_YYDEBUG
|
|
#define YYDEBUG 1 /* Parser debug information support */
|
|
#endif
|
|
|
|
typedef struct __ELSEIF
|
|
{
|
|
ULONG ulOffset;
|
|
struct __ELSEIF * pNext;
|
|
} _ELSEIF, * PELSEIF; /* support structure for else if pcode fixups */
|
|
|
|
typedef struct _LOOPEXIT
|
|
{
|
|
ULONG ulOffset;
|
|
int iLine;
|
|
USHORT wSeqCounter;
|
|
struct _LOOPEXIT * pLoopList;
|
|
struct _LOOPEXIT * pExitList;
|
|
struct _LOOPEXIT * pNext;
|
|
} LOOPEXIT, * PTR_LOOPEXIT; /* support structure for EXIT and LOOP statements */
|
|
|
|
typedef struct HB_RTVAR_
|
|
{
|
|
HB_EXPR_PTR pVar;
|
|
BOOL bPopValue;
|
|
struct HB_RTVAR_ *pNext;
|
|
struct HB_RTVAR_ *pPrev;
|
|
} HB_RTVAR, *HB_RTVAR_PTR; /* support structure for PUBLIC and PRIVATE statements */
|
|
|
|
USHORT hb_comp_wSeqCounter = 0;
|
|
USHORT hb_comp_wForCounter = 0;
|
|
USHORT hb_comp_wIfCounter = 0;
|
|
USHORT hb_comp_wWhileCounter = 0;
|
|
USHORT hb_comp_wCaseCounter = 0;
|
|
|
|
char * hb_comp_buffer; /* yacc input buffer */
|
|
|
|
static PTR_LOOPEXIT hb_comp_pLoops = NULL;
|
|
static HB_RTVAR_PTR hb_comp_rtvars = NULL;
|
|
|
|
char * hb_comp_szAnnounce = NULL; /* ANNOUNCEd procedure */
|
|
|
|
%}
|
|
|
|
%union /* special structure used by lex and yacc to share info */
|
|
{
|
|
char * string; /* to hold a string returned by lex */
|
|
int iNumber; /* to hold a temporary integer number */
|
|
long lNumber; /* to hold a temporary long number */
|
|
struct
|
|
{
|
|
int iNumber; /* to hold a number returned by lex */
|
|
char * szValue;
|
|
} valInteger;
|
|
struct
|
|
{
|
|
long lNumber; /* to hold a long number returned by lex */
|
|
char * szValue;
|
|
} valLong;
|
|
struct
|
|
{
|
|
double dNumber; /* to hold a double number returned by lex */
|
|
/* NOTE: Intentionally using "unsigned char" instead of "BYTE" */
|
|
unsigned char bDec; /* to hold the number of decimal points in the value */
|
|
char * szValue;
|
|
} valDouble;
|
|
HB_EXPR_PTR asExpr;
|
|
void * pVoid; /* to hold any memory structure we may need */
|
|
};
|
|
|
|
%token FUNCTION PROCEDURE IDENTIFIER RETURN NIL NUM_DOUBLE INASSIGN NUM_INTEGER NUM_LONG
|
|
%token LOCAL STATIC IIF IF ELSE ELSEIF END ENDIF LITERAL TRUEVALUE FALSEVALUE
|
|
%token ANNOUNCE EXTERN INIT EXIT AND OR NOT PUBLIC EQ NE1 NE2
|
|
%token INC DEC ALIASOP DOCASE CASE OTHERWISE ENDCASE ENDDO MEMVAR
|
|
%token WHILE EXIT LOOP END FOR NEXT TO STEP LE GE FIELD IN PARAMETERS
|
|
%token PLUSEQ MINUSEQ MULTEQ DIVEQ POWER EXPEQ MODEQ EXITLOOP
|
|
%token PRIVATE BEGINSEQ BREAK RECOVER RECOVERUSING DO WITH SELF LINE
|
|
%token MACROVAR MACROTEXT
|
|
%token AS_NUMERIC AS_CHARACTER AS_LOGICAL AS_DATE AS_ARRAY AS_BLOCK AS_OBJECT DECLARE_FUN
|
|
|
|
/*the lowest precedence*/
|
|
/*postincrement and postdecrement*/
|
|
%left POST
|
|
/*assigment - from right to left*/
|
|
%right INASSIGN
|
|
%right PLUSEQ MINUSEQ
|
|
%right MULTEQ DIVEQ MODEQ
|
|
%right EXPEQ
|
|
/*logical operators*/
|
|
%right OR
|
|
%right AND
|
|
%right NOT
|
|
/*relational operators*/
|
|
%right '=' '<' '>' EQ NE1 NE2 LE GE '$'
|
|
/*mathematical operators*/
|
|
%right '+' '-'
|
|
%right '*' '/' '%'
|
|
%right POWER
|
|
%right UNARY
|
|
/*preincrement and predecrement*/
|
|
%right PRE
|
|
/*special operators*/
|
|
%right ALIASOP '&' '@'
|
|
%right '\n' ';' ','
|
|
/*the highest precedence*/
|
|
|
|
%type <string> IdentName IDENTIFIER LITERAL SendId MACROVAR MACROTEXT
|
|
%type <valDouble> NUM_DOUBLE
|
|
%type <valInteger> NUM_INTEGER
|
|
%type <valLong> NUM_LONG
|
|
%type <iNumber> FunScope AsType
|
|
%type <iNumber> Params ParamList
|
|
%type <iNumber> IfBegin VarList ExtVarList
|
|
%type <iNumber> FieldList
|
|
%type <lNumber> WhileBegin
|
|
%type <pVoid> IfElseIf Cases
|
|
%type <asExpr> Argument ArgList ElemList BlockExpList BlockVarList BlockNoVar
|
|
%type <asExpr> DoName DoProc DoArgument DoArgList
|
|
%type <asExpr> PareExpList1 PareExpList2 PareExpList3 PareExpListN
|
|
%type <asExpr> ExpList ExpList1 ExpList2 ExpList3
|
|
%type <asExpr> NumValue NumAlias
|
|
%type <asExpr> NilValue NilAlias
|
|
%type <asExpr> LiteralValue LiteralAlias
|
|
%type <asExpr> CodeBlock CodeBlockAlias
|
|
%type <asExpr> Logical LogicalAlias
|
|
%type <asExpr> SelfValue SelfAlias
|
|
%type <asExpr> Array ArrayAlias
|
|
%type <asExpr> ArrayAt ArrayAtAlias
|
|
%type <asExpr> Variable VarAlias
|
|
%type <asExpr> MacroVar MacroVarAlias
|
|
%type <asExpr> MacroExpr MacroExprAlias
|
|
%type <asExpr> AliasId AliasVar AliasExpr
|
|
%type <asExpr> VariableAt VariableAtAlias
|
|
%type <asExpr> FunCall FunCallAlias
|
|
%type <asExpr> ObjectData ObjectDataAlias
|
|
%type <asExpr> ObjectMethod ObjectMethodAlias
|
|
%type <asExpr> IfInline IfInlineAlias
|
|
%type <asExpr> PareExpList PareExpListAlias
|
|
%type <asExpr> Expression SimpleExpression LValue
|
|
%type <asExpr> EmptyExpression
|
|
%type <asExpr> ExprAssign ExprOperEq ExprPreOp ExprPostOp
|
|
%type <asExpr> ExprEqual ExprMath ExprBool ExprRelation ExprUnary
|
|
%type <asExpr> ExprPlusEq ExprMinusEq ExprMultEq ExprDivEq ExprModEq ExprExpEq
|
|
%type <asExpr> ArrayIndex IndexList
|
|
%type <asExpr> DimIndex DimList
|
|
%type <asExpr> FieldAlias FieldVarAlias
|
|
%type <asExpr> PostOp
|
|
|
|
%%
|
|
|
|
Main : { hb_compLinePush(); } Source { }
|
|
| /* empty file */
|
|
;
|
|
|
|
Source : Crlf
|
|
| VarDefs
|
|
| FieldsDef
|
|
| MemvarDef
|
|
| Function
|
|
| Statement
|
|
| Line
|
|
| Source Crlf
|
|
| Source Function
|
|
| Source Statement
|
|
| Source VarDefs
|
|
| Source FieldsDef
|
|
| Source MemvarDef
|
|
| Source Line
|
|
;
|
|
|
|
Line : LINE NUM_INTEGER LITERAL Crlf
|
|
| LINE NUM_INTEGER LITERAL '@' LITERAL Crlf /* XBase++ style */
|
|
;
|
|
|
|
Function : FunScope FUNCTION IdentName { hb_comp_cVarType = ' '; hb_compFunctionAdd( $3, ( HB_SYMBOLSCOPE ) $1, 0 ); } Params Crlf {}
|
|
| FunScope PROCEDURE IdentName { hb_comp_cVarType = ' '; hb_compFunctionAdd( $3, ( HB_SYMBOLSCOPE ) $1, FUN_PROCEDURE ); } Params Crlf {}
|
|
| FunScope DECLARE_FUN IdentName Params AsType Crlf { hb_compSymbolAdd( $3, NULL ); }
|
|
;
|
|
|
|
FunScope : { $$ = HB_FS_PUBLIC; }
|
|
| STATIC { $$ = HB_FS_STATIC; }
|
|
| INIT { $$ = HB_FS_INIT; }
|
|
| EXIT { $$ = HB_FS_EXIT; }
|
|
;
|
|
|
|
Params : { $$ = 0; }
|
|
| '(' ')' { $$ = 0; }
|
|
| '(' { hb_comp_iVarScope = VS_PARAMETER; } ParamList ')' { $$ = $3; }
|
|
;
|
|
|
|
AsType : /* not specified */ { hb_comp_cVarType = ' '; }
|
|
| AS_NUMERIC { hb_comp_cVarType = 'N'; }
|
|
| AS_CHARACTER { hb_comp_cVarType = 'C'; }
|
|
| AS_DATE { hb_comp_cVarType = 'D'; }
|
|
| AS_LOGICAL { hb_comp_cVarType = 'L'; }
|
|
| AS_ARRAY { hb_comp_cVarType = 'A'; }
|
|
| AS_BLOCK { hb_comp_cVarType = 'B'; }
|
|
| AS_OBJECT { hb_comp_cVarType = 'O'; }
|
|
;
|
|
|
|
ParamList : IdentName AsType { hb_compVariableAdd( $1, ' ' ); $$ = 1; }
|
|
| ParamList ',' IdentName AsType { hb_compVariableAdd( $3, $4 ); $$++; }
|
|
;
|
|
|
|
/* NOTE: This alllows the use of Expression as a statement.
|
|
* The Expression is validated later in reduction phase of
|
|
* hb_compExprGenStatement(). With this solution we don't have to
|
|
* stop compilation if invalid syntax will be used.
|
|
*/
|
|
Statement : ExecFlow CrlfStmnt { }
|
|
| IfInline CrlfStmnt { hb_compExprDelete( hb_compExprGenStatement( $1 ) ); }
|
|
| FunCall CrlfStmnt { hb_compExprDelete( hb_compExprGenStatement( $1 ) ); }
|
|
| AliasExpr CrlfStmnt { hb_compExprDelete( hb_compExprGenStatement( $1 ) ); }
|
|
| ObjectMethod CrlfStmnt { hb_compExprDelete( hb_compExprGenStatement( $1 ) ); }
|
|
| PareExpList CrlfStmnt { hb_compExprDelete( hb_compExprGenStatement( $1 ) ); }
|
|
| ExprPreOp CrlfStmnt { hb_compExprDelete( hb_compExprGenStatement( $1 ) ); }
|
|
| ExprPostOp CrlfStmnt { hb_compExprDelete( hb_compExprGenStatement( $1 ) ); }
|
|
| ExprOperEq CrlfStmnt { hb_compExprDelete( hb_compExprGenStatement( $1 ) ); }
|
|
| ExprEqual CrlfStmnt { hb_compExprDelete( hb_compExprGenStatement( $1 ) ); }
|
|
| ExprAssign CrlfStmnt { hb_compExprDelete( hb_compExprGenStatement( $1 ) ); }
|
|
| DoProc CrlfStmnt { hb_compExprDelete( hb_compExprGenStatement( $1 ) ); }
|
|
| BREAK CrlfStmnt { hb_compGenBreak(); hb_compGenPCode3( HB_P_DO, 0, 0 );
|
|
hb_comp_functions.pLast->bFlags |= FUN_BREAK_CODE; }
|
|
| BREAK { hb_compLinePushIfInside(); } Expression Crlf { hb_compGenBreak(); hb_compExprDelete( hb_compExprGenPush( $3 ) );
|
|
hb_compGenPCode3( HB_P_DO, 1, 0 );
|
|
hb_comp_functions.pLast->bFlags |= FUN_BREAK_CODE;
|
|
}
|
|
| RETURN CrlfStmnt {
|
|
if( hb_comp_wSeqCounter )
|
|
{
|
|
hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_EXIT_IN_SEQUENCE, "RETURN", NULL );
|
|
}
|
|
hb_compGenPCode1( HB_P_ENDPROC );
|
|
if( (hb_comp_functions.pLast->bFlags & FUN_PROCEDURE) == 0 )
|
|
{ /* return from a function without a return value */
|
|
hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_NO_RETURN_VALUE, NULL, NULL );
|
|
}
|
|
hb_comp_functions.pLast->bFlags |= FUN_WITH_RETURN;
|
|
hb_comp_bDontGenLineNum = TRUE;
|
|
hb_comp_functions.pLast->bFlags |= FUN_BREAK_CODE;
|
|
}
|
|
| RETURN { hb_compLinePushIfInside(); } Expression Crlf {
|
|
if( hb_comp_wSeqCounter )
|
|
{
|
|
hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_EXIT_IN_SEQUENCE, "RETURN", NULL );
|
|
}
|
|
hb_compExprGenPush( $3 ); /* TODO: check if return value agree with declared value */
|
|
hb_compGenPCode1( HB_P_RETVALUE );
|
|
hb_compGenPCode1( HB_P_ENDPROC );
|
|
if( hb_comp_functions.pLast->bFlags & FUN_PROCEDURE )
|
|
{ /* procedure returns a value */
|
|
hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_PROC_RETURN_VALUE, NULL, NULL );
|
|
}
|
|
hb_comp_functions.pLast->bFlags |= FUN_WITH_RETURN;
|
|
hb_comp_bDontGenLineNum = TRUE;
|
|
hb_comp_functions.pLast->bFlags |= FUN_BREAK_CODE;
|
|
}
|
|
| PUBLIC { hb_compLinePushIfInside(); hb_comp_iVarScope = VS_PUBLIC; }
|
|
ExtVarList
|
|
{ hb_compRTVariableGen( "__MVPUBLIC" ); } CrlfStmnt
|
|
| PRIVATE { hb_compLinePushIfInside(); hb_comp_iVarScope = VS_PRIVATE; }
|
|
ExtVarList
|
|
{ hb_compRTVariableGen( "__MVPRIVATE" ); } CrlfStmnt
|
|
|
|
| EXITLOOP CrlfStmnt { hb_compLoopExit(); hb_comp_functions.pLast->bFlags |= FUN_BREAK_CODE; }
|
|
| LOOP CrlfStmnt { hb_compLoopLoop(); hb_comp_functions.pLast->bFlags |= FUN_BREAK_CODE; }
|
|
| EXTERN ExtList Crlf
|
|
| ANNOUNCE IdentName {
|
|
if( hb_comp_szAnnounce == NULL )
|
|
{
|
|
/* check for reserved name
|
|
* NOTE: Clipper doesn't check for it
|
|
*/
|
|
char * szFunction = hb_compReservedName( $2 );
|
|
if( szFunction )
|
|
hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_FUNC_RESERVED, szFunction, $2 );
|
|
hb_comp_szAnnounce = $2;
|
|
}
|
|
else
|
|
hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_DUPL_ANNOUNCE, $2, NULL );
|
|
} Crlf
|
|
|
|
;
|
|
|
|
CrlfStmnt : { hb_compLinePushIfInside(); } Crlf
|
|
;
|
|
|
|
LineStat : Crlf { $<lNumber>$ = 0; hb_comp_bDontGenLineNum = TRUE; }
|
|
| Statement { $<lNumber>$ = 1; }
|
|
;
|
|
|
|
Statements : LineStat { $<lNumber>$ = $<lNumber>1; hb_compLinePush(); }
|
|
| Statements LineStat { $<lNumber>$ += $<lNumber>2; hb_compLinePush(); }
|
|
;
|
|
|
|
ExtList : IdentName { hb_compExternAdd( $1 ); }
|
|
| ExtList ',' IdentName { hb_compExternAdd( $3 ); }
|
|
;
|
|
|
|
IdentName : IDENTIFIER { $$ = $1; }
|
|
| STEP { $$ = hb_strdup( "STEP" ); }
|
|
| TO { $$ = hb_strdup( "TO" ); }
|
|
;
|
|
|
|
/* Numeric values
|
|
*/
|
|
NumValue : NUM_DOUBLE { $$ = hb_compExprNewDouble( $1.dNumber, $1.bDec ); }
|
|
| NUM_INTEGER { $$ = hb_compExprNewLong( $1.iNumber ); }
|
|
| NUM_LONG { $$ = hb_compExprNewLong( $1.lNumber ); }
|
|
;
|
|
|
|
NumAlias : NUM_INTEGER ALIASOP { $$ = hb_compExprNewLong( $1.iNumber ); }
|
|
| NUM_LONG ALIASOP { $$ = hb_compExprNewLong( $1.lNumber ); }
|
|
| NUM_DOUBLE ALIASOP { $$ = hb_compErrorAlias( hb_compExprNewDouble( $1.dNumber, $1.bDec ) ); }
|
|
;
|
|
|
|
/* NIL value
|
|
*/
|
|
NilValue : NIL { $$ = hb_compExprNewNil(); }
|
|
;
|
|
|
|
NilAlias : NilValue ALIASOP { $$ = $1; }
|
|
;
|
|
|
|
/* Literal string value
|
|
*/
|
|
LiteralValue : LITERAL { $$ = hb_compExprNewString( $1 ); }
|
|
;
|
|
|
|
LiteralAlias : LiteralValue ALIASOP { $$ = $1; }
|
|
;
|
|
|
|
/* Codeblock value
|
|
*/
|
|
CodeBlockAlias : CodeBlock ALIASOP { $$ = $1; }
|
|
;
|
|
|
|
/* Logical value
|
|
*/
|
|
Logical : TRUEVALUE { $$ = hb_compExprNewLogical( TRUE ); }
|
|
| FALSEVALUE { $$ = hb_compExprNewLogical( FALSE ); }
|
|
;
|
|
|
|
LogicalAlias : Logical ALIASOP { $$ = $1; }
|
|
;
|
|
|
|
/* SELF value and expressions
|
|
*/
|
|
SelfValue : SELF { $$ = hb_compExprNewSelf(); }
|
|
;
|
|
|
|
SelfAlias : SelfValue ALIASOP { $$ = $1; }
|
|
;
|
|
|
|
/* Literal array
|
|
*/
|
|
Array : '{' ElemList '}' { $$ = hb_compExprNewArray( $2 ); }
|
|
;
|
|
|
|
ArrayAlias : Array ALIASOP { $$ = $1; }
|
|
;
|
|
|
|
/* Literal array access
|
|
*/
|
|
ArrayAt : Array ArrayIndex { $$ = $2; }
|
|
;
|
|
|
|
ArrayAtAlias : ArrayAt ALIASOP { $$ = $1; }
|
|
;
|
|
|
|
/* Variables
|
|
*/
|
|
Variable : IdentName { $$ = hb_compExprNewVar( $1 ); }
|
|
;
|
|
|
|
VarAlias : IdentName ALIASOP { $$ = hb_compExprNewAlias( $1 ); }
|
|
;
|
|
|
|
/* Macro variables
|
|
*/
|
|
MacroVar : MACROVAR { $$ = hb_compExprNewMacro( NULL, '&', $1 ); }
|
|
| MACROTEXT { $$ = hb_compExprNewMacro( NULL, 0, $1 ); }
|
|
;
|
|
|
|
MacroVarAlias : MacroVar ALIASOP { $$ = $1; }
|
|
;
|
|
|
|
/* Macro expressions
|
|
*/
|
|
MacroExpr : '&' PareExpList { $$ = hb_compExprNewMacro( $2, 0, NULL ); }
|
|
;
|
|
|
|
MacroExprAlias : MacroExpr ALIASOP { $$ = $1; }
|
|
;
|
|
|
|
/* Aliased variables
|
|
*/
|
|
/* special case: _FIELD-> and FIELD-> can be nested
|
|
*/
|
|
FieldAlias : FIELD ALIASOP { $$ = hb_compExprNewAlias( "FIELD" ); }
|
|
| FIELD ALIASOP FieldAlias { $$ = $3; }
|
|
;
|
|
|
|
/* ignore _FIELD-> or FIELD-> if a real alias is specified
|
|
*/
|
|
FieldVarAlias : FieldAlias VarAlias { hb_compExprDelete( $1 ); $$ = $2; }
|
|
| FieldAlias NumAlias { hb_compExprDelete( $1 ); $$ = $2; }
|
|
| FieldAlias PareExpListAlias { hb_compExprDelete( $1 ); $$ = $2; }
|
|
| FieldAlias MacroVarAlias { hb_compExprDelete( $1 ); $$ = $2; }
|
|
| FieldAlias MacroExprAlias { hb_compExprDelete( $1 ); $$ = $2; }
|
|
| FieldAlias NilAlias { hb_compExprDelete( $1 ); $$ = hb_compErrorAlias( $2 ); }
|
|
| FieldAlias LiteralAlias { hb_compExprDelete( $1 ); $$ = hb_compErrorAlias( $2 ); }
|
|
| FieldAlias LogicalAlias { hb_compExprDelete( $1 ); $$ = hb_compErrorAlias( $2 ); }
|
|
| FieldAlias CodeBlockAlias { hb_compExprDelete( $1 ); $$ = hb_compErrorAlias( $2 ); }
|
|
| FieldAlias SelfAlias { hb_compExprDelete( $1 ); $$ = hb_compErrorAlias( $2 ); }
|
|
| FieldAlias ArrayAlias { hb_compExprDelete( $1 ); $$ = hb_compErrorAlias( $2 ); }
|
|
| FieldAlias ArrayAtAlias { hb_compExprDelete( $1 ); $$ = hb_compErrorAlias( $2 ); }
|
|
| FieldAlias IfInlineAlias { hb_compExprDelete( $1 ); $$ = hb_compErrorAlias( $2 ); }
|
|
;
|
|
|
|
AliasId : IdentName { $$ = hb_compExprNewVar( $1 ); }
|
|
| MacroVar { $$ = $1; }
|
|
| MacroExpr { $$ = $1; }
|
|
;
|
|
|
|
AliasVar : NumAlias AliasId { $$ = hb_compExprNewAliasVar( $1, $2 ); }
|
|
| MacroVarAlias AliasId { $$ = hb_compExprNewAliasVar( $1, $2 ); }
|
|
| MacroExprAlias AliasId { $$ = hb_compExprNewAliasVar( $1, $2 ); }
|
|
| PareExpListAlias AliasId { $$ = hb_compExprNewAliasVar( $1, $2 ); }
|
|
| NilAlias AliasId { $$ = hb_compErrorAlias( $1 ); }
|
|
| LiteralAlias AliasId { $$ = hb_compErrorAlias( $1 ); }
|
|
| LogicalAlias AliasId { $$ = hb_compErrorAlias( $1 ); }
|
|
| CodeBlockAlias AliasId { $$ = hb_compErrorAlias( $1 ); }
|
|
| SelfAlias AliasId { $$ = hb_compErrorAlias( $1 ); }
|
|
| ArrayAlias AliasId { $$ = hb_compErrorAlias( $1 ); }
|
|
| ArrayAtAlias AliasId { $$ = hb_compErrorAlias( $1 ); } /* QUESTION: Clipper reports error here - we can handle this */
|
|
| VariableAtAlias AliasId { $$ = hb_compErrorAlias( $1 ); } /* QUESTION: Clipper reports error here - we can handle this */
|
|
| IfInlineAlias AliasId { $$ = hb_compErrorAlias( $1 ); } /* QUESTION: Clipper reports error here - we can handle this */
|
|
| FunCallAlias AliasId { $$ = hb_compErrorAlias( $1 ); } /* QUESTION: Clipper reports error here - we can handle this */
|
|
| ObjectDataAlias AliasId { $$ = hb_compErrorAlias( $1 ); } /* QUESTION: Clipper reports error here - we can handle this */
|
|
| ObjectMethodAlias AliasId { $$ = hb_compErrorAlias( $1 ); } /* QUESTION: Clipper reports error here - we can handle this */
|
|
| VarAlias AliasId { $$ = hb_compExprNewAliasVar( $1, $2 ); }
|
|
| FieldAlias AliasId { $$ = hb_compExprNewAliasVar( $1, $2 ); }
|
|
| FieldVarAlias AliasId { $$ = hb_compExprNewAliasVar( $1, $2 ); }
|
|
;
|
|
|
|
/* Aliased expressions
|
|
*/
|
|
/* NOTE: In the case:
|
|
* alias->( Expression )
|
|
* alias always selects a workarea at runtime
|
|
*/
|
|
AliasExpr : NumAlias PareExpList { $$ = hb_compExprNewAliasExpr( $1, $2 ); }
|
|
| VarAlias PareExpList { $$ = hb_compExprNewAliasExpr( $1, $2 ); }
|
|
| MacroVarAlias PareExpList { $$ = hb_compExprNewAliasExpr( $1, $2 ); }
|
|
| MacroExprAlias PareExpList { $$ = hb_compExprNewAliasExpr( $1, $2 ); }
|
|
| PareExpListAlias PareExpList { $$ = hb_compExprNewAliasExpr( $1, $2 ); }
|
|
| FieldAlias PareExpList { $$ = hb_compErrorAlias( $2 ); } /* QUESTION: Clipper reports error here - we can handle it */
|
|
;
|
|
|
|
/* Array expressions access
|
|
*/
|
|
VariableAt : NilValue ArrayIndex { $$ = $2; }
|
|
| LiteralValue ArrayIndex { $$ = $2; }
|
|
| CodeBlock ArrayIndex { $$ = $2; }
|
|
| Logical ArrayIndex { $$ = $2; }
|
|
| SelfValue ArrayIndex { $$ = $2; }
|
|
| Variable ArrayIndex { $$ = $2; }
|
|
| AliasVar ArrayIndex { $$ = $2; }
|
|
| AliasExpr ArrayIndex { $$ = $2; }
|
|
| MacroVar ArrayIndex { $$ = $2; }
|
|
| MacroExpr ArrayIndex { $$ = $2; }
|
|
| ObjectData ArrayIndex { $$ = $2; }
|
|
| ObjectMethod ArrayIndex { $$ = $2; }
|
|
| FunCall ArrayIndex { $$ = $2; }
|
|
| IfInline ArrayIndex { $$ = $2; }
|
|
| PareExpList ArrayIndex { $$ = $2; }
|
|
;
|
|
|
|
VariableAtAlias : VariableAt ALIASOP { $$ = $1; }
|
|
;
|
|
|
|
/* Function call
|
|
*/
|
|
FunCall : IdentName '(' ArgList ')' { $$ = hb_compExprNewFunCall( hb_compExprNewFunName( $1 ), $3 ); }
|
|
| MacroVar '(' ArgList ')' { $$ = hb_compExprNewFunCall( $1, $3 ); }
|
|
;
|
|
|
|
ArgList : Argument { $$ = hb_compExprNewArgList( $1 ); }
|
|
| ArgList ',' Argument { $$ = hb_compExprAddListExpr( $1, $3 ); }
|
|
;
|
|
|
|
Argument : EmptyExpression { $$ = $1; }
|
|
| '@' IdentName { $$ = hb_compExprNewVarRef( $2 ); }
|
|
| '@' IdentName '(' ')' { $$ = hb_compExprNewFunRef( $2 ); }
|
|
;
|
|
|
|
FunCallAlias : FunCall ALIASOP { $$ = $1; }
|
|
;
|
|
|
|
/* Object's instance variable
|
|
*/
|
|
SendId : IdentName { $$ = $1; }
|
|
| MacroVar { $$ = "&"; hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_INVALID_SEND, "&", NULL); }
|
|
;
|
|
|
|
ObjectData : NumValue ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
|
| NilValue ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
|
| LiteralValue ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
|
| CodeBlock ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
|
| Logical ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
|
| SelfValue ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
|
| Array ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
|
| ArrayAt ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
|
| Variable ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
|
| AliasVar ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
|
| AliasExpr ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
|
| MacroVar ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
|
| MacroExpr ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
|
| FunCall ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
|
| IfInline ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
|
| PareExpList ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
|
| VariableAt ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
|
| ObjectMethod ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
|
| ObjectData ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
|
;
|
|
|
|
ObjectDataAlias : ObjectData ALIASOP { $$ = $1; }
|
|
;
|
|
|
|
/* Object's method
|
|
*/
|
|
ObjectMethod : ObjectData '(' ArgList ')' { $$ = hb_compExprNewMethodCall( $1, $3 ); }
|
|
;
|
|
|
|
ObjectMethodAlias : ObjectMethod ALIASOP { $$ = $1; }
|
|
;
|
|
|
|
/* NOTE: We have to distinguish IdentName here because it is repeated
|
|
* in DoArgument (a part of DO <proc> WITH .. statement)
|
|
* where it generates different action.
|
|
*/
|
|
SimpleExpression :
|
|
NumValue
|
|
| NilValue { $$ = $1; }
|
|
| LiteralValue { $$ = $1; }
|
|
| CodeBlock { $$ = $1; }
|
|
| Logical { $$ = $1; }
|
|
| SelfValue { $$ = $1; }
|
|
| Array { $$ = $1; }
|
|
| ArrayAt { $$ = $1; }
|
|
| AliasVar { $$ = $1; }
|
|
| MacroVar { $$ = $1; }
|
|
| MacroExpr { $$ = $1; }
|
|
| VariableAt { $$ = $1; }
|
|
| FunCall { $$ = $1; }
|
|
| IfInline { $$ = $1; }
|
|
| ObjectData { $$ = $1; }
|
|
| ObjectMethod { $$ = $1; }
|
|
| AliasExpr { $$ = $1; }
|
|
| ExprAssign { $$ = $1; }
|
|
| ExprOperEq { $$ = $1; }
|
|
| ExprPostOp { $$ = $1; }
|
|
| ExprPreOp { $$ = $1; }
|
|
| ExprUnary { $$ = $1; }
|
|
| ExprMath { $$ = $1; }
|
|
| ExprBool { $$ = $1; }
|
|
| ExprRelation { $$ = $1; }
|
|
;
|
|
|
|
Expression : Variable { $$ = $1; }
|
|
| SimpleExpression { $$ = $1; }
|
|
| PareExpList { $$ = $1; }
|
|
;
|
|
|
|
EmptyExpression: /* nothing => nil */ { $$ = hb_compExprNewEmpty(); }
|
|
| Expression
|
|
;
|
|
|
|
LValue : IdentName { $$ = hb_compExprNewVar( $1 ); }
|
|
| AliasVar
|
|
| MacroVar
|
|
| MacroExpr
|
|
| ObjectData
|
|
| VariableAt
|
|
;
|
|
|
|
/* NOTE: PostOp can be used in one context only - it uses $0 rule
|
|
* (the rule that stands before PostOp)
|
|
*/
|
|
PostOp : INC { $$ = hb_compExprNewPostInc( $<asExpr>0 ); }
|
|
| DEC { $$ = hb_compExprNewPostDec( $<asExpr>0 ); }
|
|
;
|
|
|
|
/* NOTE: The rule: Expression Operator Expression
|
|
* that can be used standalone as a statement have to be written
|
|
* using all possible left values to resolve shift/reduce conflicts
|
|
*/
|
|
ExprPostOp : NumValue PostOp %prec POST { $$ = $2; }
|
|
| NilValue PostOp %prec POST { $$ = $2; }
|
|
| LiteralValue PostOp %prec POST { $$ = $2; }
|
|
| CodeBlock PostOp %prec POST { $$ = $2; }
|
|
| Logical PostOp %prec POST { $$ = $2; }
|
|
| SelfValue PostOp %prec POST { $$ = $2; }
|
|
| Array PostOp %prec POST { $$ = $2; }
|
|
| ArrayAt PostOp %prec POST { $$ = $2; }
|
|
| Variable PostOp %prec POST { $$ = $2; }
|
|
| MacroVar PostOp %prec POST { $$ = $2; }
|
|
| MacroExpr PostOp %prec POST { $$ = $2; }
|
|
| AliasVar PostOp %prec POST { $$ = $2; }
|
|
| AliasExpr PostOp %prec POST { $$ = $2; }
|
|
| VariableAt PostOp %prec POST { $$ = $2; }
|
|
| PareExpList PostOp %prec POST { $$ = $2; }
|
|
| IfInline PostOp %prec POST { $$ = $2; }
|
|
| FunCall PostOp %prec POST { $$ = $2; }
|
|
| ObjectData PostOp %prec POST { $$ = $2; }
|
|
| ObjectMethod PostOp %prec POST { $$ = $2; }
|
|
;
|
|
|
|
ExprPreOp : INC Expression %prec PRE { $$ = hb_compExprNewPreInc( $2 ); }
|
|
| DEC Expression %prec PRE { $$ = hb_compExprNewPreDec( $2 ); }
|
|
;
|
|
|
|
ExprUnary : NOT Expression { $$ = hb_compExprNewNot( $2 ); }
|
|
| '-' Expression %prec UNARY { $$ = hb_compExprNewNegate( $2 ); }
|
|
| '+' Expression %prec UNARY { $$ = $2; }
|
|
;
|
|
/*
|
|
ExprAssign : Expression INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
|
|
;
|
|
*/
|
|
|
|
ExprAssign : NumValue INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
|
|
| NilValue INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
|
|
| LiteralValue INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
|
|
| CodeBlock INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
|
|
| Logical INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
|
|
| SelfValue INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
|
|
| Array INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
|
|
| ArrayAt INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
|
|
| Variable INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
|
|
| MacroVar INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
|
|
| MacroExpr INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
|
|
| AliasVar INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
|
|
| AliasExpr INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
|
|
| VariableAt INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
|
|
| PareExpList INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
|
|
| IfInline INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
|
|
| FunCall INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
|
|
| ObjectData INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
|
|
| ObjectMethod INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
|
|
;
|
|
|
|
ExprEqual : NumValue '=' Expression %prec INASSIGN { $$ = hb_compExprAssign( $1, $3 ); }
|
|
| NilValue '=' Expression %prec INASSIGN { $$ = hb_compExprAssign( $1, $3 ); }
|
|
| LiteralValue '=' Expression %prec INASSIGN { $$ = hb_compExprAssign( $1, $3 ); }
|
|
| CodeBlock '=' Expression %prec INASSIGN { $$ = hb_compExprAssign( $1, $3 ); }
|
|
| Logical '=' Expression %prec INASSIGN { $$ = hb_compExprAssign( $1, $3 ); }
|
|
| SelfValue '=' Expression %prec INASSIGN { $$ = hb_compExprAssign( $1, $3 ); }
|
|
| Array '=' Expression %prec INASSIGN { $$ = hb_compExprAssign( $1, $3 ); }
|
|
| ArrayAt '=' Expression %prec INASSIGN { $$ = hb_compExprAssign( $1, $3 ); }
|
|
| Variable '=' Expression %prec INASSIGN { $$ = hb_compExprAssign( $1, $3 ); }
|
|
| MacroVar '=' Expression %prec INASSIGN { $$ = hb_compExprAssign( $1, $3 ); }
|
|
| MacroExpr '=' Expression %prec INASSIGN { $$ = hb_compExprAssign( $1, $3 ); }
|
|
| AliasVar '=' Expression %prec INASSIGN { $$ = hb_compExprAssign( $1, $3 ); }
|
|
| AliasExpr '=' Expression %prec INASSIGN { $$ = hb_compExprAssign( $1, $3 ); }
|
|
| VariableAt '=' Expression %prec INASSIGN { $$ = hb_compExprAssign( $1, $3 ); }
|
|
| PareExpList '=' Expression %prec INASSIGN { $$ = hb_compExprAssign( $1, $3 ); }
|
|
| IfInline '=' Expression %prec INASSIGN { $$ = hb_compExprAssign( $1, $3 ); }
|
|
| FunCall '=' Expression %prec INASSIGN { $$ = hb_compExprAssign( $1, $3 ); }
|
|
| ObjectData '=' Expression %prec INASSIGN { $$ = hb_compExprAssign( $1, $3 ); }
|
|
| ObjectMethod '=' Expression %prec INASSIGN { $$ = hb_compExprAssign( $1, $3 ); }
|
|
;
|
|
|
|
ExprPlusEq : NumValue PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3 ); }
|
|
| NilValue PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3 ); }
|
|
| LiteralValue PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3 ); }
|
|
| CodeBlock PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3 ); }
|
|
| Logical PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3 ); }
|
|
| SelfValue PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3 ); }
|
|
| Array PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3 ); }
|
|
| ArrayAt PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3 ); }
|
|
| Variable PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3 ); }
|
|
| MacroVar PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3 ); }
|
|
| MacroExpr PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3 ); }
|
|
| AliasVar PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3 ); }
|
|
| AliasExpr PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3 ); }
|
|
| VariableAt PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3 ); }
|
|
| PareExpList PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3 ); }
|
|
| IfInline PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3 ); }
|
|
| FunCall PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3 ); }
|
|
| ObjectData PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3 ); }
|
|
| ObjectMethod PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3 ); }
|
|
;
|
|
|
|
ExprMinusEq : NumValue MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3 ); }
|
|
| NilValue MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3 ); }
|
|
| LiteralValue MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3 ); }
|
|
| CodeBlock MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3 ); }
|
|
| Logical MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3 ); }
|
|
| SelfValue MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3 ); }
|
|
| Array MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3 ); }
|
|
| ArrayAt MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3 ); }
|
|
| Variable MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3 ); }
|
|
| MacroVar MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3 ); }
|
|
| MacroExpr MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3 ); }
|
|
| AliasVar MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3 ); }
|
|
| AliasExpr MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3 ); }
|
|
| VariableAt MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3 ); }
|
|
| PareExpList MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3 ); }
|
|
| IfInline MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3 ); }
|
|
| FunCall MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3 ); }
|
|
| ObjectData MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3 ); }
|
|
| ObjectMethod MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3 ); }
|
|
;
|
|
|
|
ExprMultEq : NumValue MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3 ); }
|
|
| NilValue MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3 ); }
|
|
| LiteralValue MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3 ); }
|
|
| CodeBlock MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3 ); }
|
|
| Logical MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3 ); }
|
|
| SelfValue MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3 ); }
|
|
| Array MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3 ); }
|
|
| ArrayAt MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3 ); }
|
|
| Variable MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3 ); }
|
|
| MacroVar MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3 ); }
|
|
| MacroExpr MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3 ); }
|
|
| AliasVar MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3 ); }
|
|
| AliasExpr MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3 ); }
|
|
| VariableAt MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3 ); }
|
|
| PareExpList MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3 ); }
|
|
| IfInline MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3 ); }
|
|
| FunCall MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3 ); }
|
|
| ObjectData MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3 ); }
|
|
| ObjectMethod MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3 ); }
|
|
;
|
|
|
|
ExprDivEq : NumValue DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3 ); }
|
|
| NilValue DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3 ); }
|
|
| LiteralValue DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3 ); }
|
|
| CodeBlock DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3 ); }
|
|
| Logical DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3 ); }
|
|
| SelfValue DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3 ); }
|
|
| Array DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3 ); }
|
|
| ArrayAt DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3 ); }
|
|
| Variable DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3 ); }
|
|
| MacroVar DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3 ); }
|
|
| MacroExpr DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3 ); }
|
|
| AliasVar DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3 ); }
|
|
| AliasExpr DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3 ); }
|
|
| VariableAt DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3 ); }
|
|
| PareExpList DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3 ); }
|
|
| IfInline DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3 ); }
|
|
| FunCall DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3 ); }
|
|
| ObjectData DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3 ); }
|
|
| ObjectMethod DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3 ); }
|
|
;
|
|
|
|
ExprModEq : NumValue MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3 ); }
|
|
| NilValue MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3 ); }
|
|
| LiteralValue MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3 ); }
|
|
| CodeBlock MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3 ); }
|
|
| Logical MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3 ); }
|
|
| SelfValue MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3 ); }
|
|
| Array MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3 ); }
|
|
| ArrayAt MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3 ); }
|
|
| Variable MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3 ); }
|
|
| MacroVar MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3 ); }
|
|
| MacroExpr MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3 ); }
|
|
| AliasVar MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3 ); }
|
|
| AliasExpr MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3 ); }
|
|
| VariableAt MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3 ); }
|
|
| PareExpList MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3 ); }
|
|
| IfInline MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3 ); }
|
|
| FunCall MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3 ); }
|
|
| ObjectData MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3 ); }
|
|
| ObjectMethod MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3 ); }
|
|
;
|
|
|
|
ExprExpEq : NumValue EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3 ); }
|
|
| NilValue EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3 ); }
|
|
| LiteralValue EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3 ); }
|
|
| CodeBlock EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3 ); }
|
|
| Logical EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3 ); }
|
|
| SelfValue EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3 ); }
|
|
| Array EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3 ); }
|
|
| ArrayAt EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3 ); }
|
|
| Variable EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3 ); }
|
|
| MacroVar EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3 ); }
|
|
| MacroExpr EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3 ); }
|
|
| AliasVar EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3 ); }
|
|
| AliasExpr EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3 ); }
|
|
| VariableAt EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3 ); }
|
|
| PareExpList EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3 ); }
|
|
| IfInline EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3 ); }
|
|
| FunCall EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3 ); }
|
|
| ObjectData EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3 ); }
|
|
| ObjectMethod EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3 ); }
|
|
;
|
|
|
|
ExprOperEq : ExprPlusEq { $$ = $1; }
|
|
| ExprMinusEq { $$ = $1; }
|
|
| ExprMultEq { $$ = $1; }
|
|
| ExprDivEq { $$ = $1; }
|
|
| ExprModEq { $$ = $1; }
|
|
| ExprExpEq { $$ = $1; }
|
|
;
|
|
|
|
ExprMath : Expression '+' Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlus( $1 ), $3 ); }
|
|
| Expression '-' Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinus( $1 ), $3 ); }
|
|
| Expression '*' Expression { $$ = hb_compExprSetOperand( hb_compExprNewMult( $1 ), $3 ); }
|
|
| Expression '/' Expression { $$ = hb_compExprSetOperand( hb_compExprNewDiv( $1 ), $3 ); }
|
|
| Expression '%' Expression { $$ = hb_compExprSetOperand( hb_compExprNewMod( $1 ), $3 ); }
|
|
| Expression POWER Expression { $$ = hb_compExprSetOperand( hb_compExprNewPower( $1 ), $3 ); }
|
|
;
|
|
|
|
ExprBool : Expression AND Expression { $$ = hb_compExprSetOperand( hb_compExprNewAnd( $1 ), $3 ); }
|
|
| Expression OR Expression { $$ = hb_compExprSetOperand( hb_compExprNewOr( $1 ), $3 ); }
|
|
;
|
|
|
|
ExprRelation: Expression EQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewEQ( $1 ), $3 ); }
|
|
| Expression '<' Expression { $$ = hb_compExprSetOperand( hb_compExprNewLT( $1 ), $3 ); }
|
|
| Expression '>' Expression { $$ = hb_compExprSetOperand( hb_compExprNewGT( $1 ), $3 ); }
|
|
| Expression LE Expression { $$ = hb_compExprSetOperand( hb_compExprNewLE( $1 ), $3 ); }
|
|
| Expression GE Expression { $$ = hb_compExprSetOperand( hb_compExprNewGE( $1 ), $3 ); }
|
|
| Expression NE1 Expression { $$ = hb_compExprSetOperand( hb_compExprNewNE( $1 ), $3 ); }
|
|
| Expression NE2 Expression { $$ = hb_compExprSetOperand( hb_compExprNewNE( $1 ), $3 ); }
|
|
| Expression '$' Expression { $$ = hb_compExprSetOperand( hb_compExprNewIN( $1 ), $3 ); }
|
|
| Expression '=' Expression { $$ = hb_compExprSetOperand( hb_compExprNewEqual( $1 ), $3 ); }
|
|
;
|
|
|
|
ArrayIndex : IndexList ']' { $$ = $1; }
|
|
;
|
|
|
|
/* NOTE: $0 represents the expression before ArrayIndex
|
|
* Don't use ArrayIndex in other context than as an array index!
|
|
*/
|
|
IndexList : '[' Expression { $$ = hb_compExprNewArrayAt( $<asExpr>0, $2 ); }
|
|
| IndexList ',' Expression { $$ = hb_compExprNewArrayAt( $1, $3 ); }
|
|
| IndexList ']' '[' Expression { $$ = hb_compExprNewArrayAt( $1, $4 ); }
|
|
;
|
|
|
|
ElemList : EmptyExpression { $$ = hb_compExprNewList( $1 ); }
|
|
| ElemList ',' EmptyExpression { $$ = hb_compExprAddListExpr( $1, $3 ); }
|
|
;
|
|
|
|
CodeBlock : '{' '|' { $<asExpr>$ = hb_compExprNewCodeBlock(); } BlockNoVar
|
|
'|' BlockExpList '}' { $$ = $<asExpr>3; }
|
|
| '{' '|' { $<asExpr>$ = hb_compExprNewCodeBlock(); } BlockVarList
|
|
'|' BlockExpList '}' { $$ = $<asExpr>3; }
|
|
;
|
|
|
|
/* NOTE: This uses $-2 then don't use BlockExpList in other context
|
|
*/
|
|
BlockExpList : Expression { $$ = hb_compExprAddListExpr( $<asExpr>-2, $1 ); }
|
|
| BlockExpList ',' Expression { $$ = hb_compExprAddListExpr( $<asExpr>-2, $3 ); }
|
|
;
|
|
|
|
/* NOTE: This is really not needed however it allows the use of $-2 item
|
|
* in BlockExpList to refer the same rule defined in Codeblock
|
|
*/
|
|
BlockNoVar : /* empty list */ { $$ = NULL; }
|
|
;
|
|
|
|
BlockVarList : IdentName AsType { hb_comp_iVarScope = VS_LOCAL; $$ = hb_compExprCBVarAdd( $<asExpr>0, $1, $2 ); }
|
|
| BlockVarList ',' IdentName AsType { hb_comp_iVarScope = VS_LOCAL; $$ = hb_compExprCBVarAdd( $<asExpr>0, $3, $4 ); }
|
|
;
|
|
|
|
/* There is a conflict between the use of IF( Expr1, Expr2, Expr3 )
|
|
* and parenthesized expression ( Expr1, Expr2, Expr3 )
|
|
* To solve this conflict we have to split the definitions into more
|
|
* atomic ones.
|
|
* Also the generation of pcodes have to be delayed and moved to the
|
|
* end of whole parenthesized expression.
|
|
*/
|
|
PareExpList1: ExpList1 ')' { $$ = $1; }
|
|
;
|
|
|
|
PareExpList2: ExpList2 ')' { $$ = $1; }
|
|
;
|
|
|
|
PareExpList3: ExpList3 ')' { $$ = $1; }
|
|
;
|
|
|
|
PareExpListN: ExpList ')' { $$ = $1; }
|
|
;
|
|
|
|
PareExpList : PareExpList1 { $$ = $1; }
|
|
| PareExpList2 { $$ = $1; }
|
|
| PareExpList3 { $$ = $1; }
|
|
| PareExpListN { $$ = $1; }
|
|
;
|
|
|
|
PareExpListAlias : PareExpList ALIASOP { $$ = $1; }
|
|
;
|
|
|
|
ExpList1 : '(' EmptyExpression { $$ = hb_compExprNewList( $2 ); }
|
|
;
|
|
|
|
ExpList2 : ExpList1 ',' EmptyExpression { $$ = hb_compExprAddListExpr( $1, $3 ); }
|
|
;
|
|
|
|
ExpList3 : ExpList2 ',' EmptyExpression { $$ = hb_compExprAddListExpr( $1, $3 ); }
|
|
;
|
|
|
|
ExpList : ExpList3 ',' EmptyExpression { $$ = hb_compExprAddListExpr( $1, $3 ); }
|
|
| ExpList ',' EmptyExpression { $$ = hb_compExprAddListExpr( $1, $3 ); }
|
|
;
|
|
|
|
IfInline : IIF PareExpList3 { $$ = hb_compExprNewIIF( $2 ); }
|
|
| IF ExpList1 ',' EmptyExpression ','
|
|
{ $<asExpr>$ = hb_compExprAddListExpr( $2, $4 ); }
|
|
EmptyExpression ')'
|
|
{ $$ = hb_compExprNewIIF( hb_compExprAddListExpr( $<asExpr>6, $7 ) ); }
|
|
;
|
|
|
|
IfInlineAlias : IfInline ALIASOP { $$ = $1; }
|
|
;
|
|
|
|
VarDefs : LOCAL { hb_comp_iVarScope = VS_LOCAL; hb_compLinePush(); } VarList Crlf { hb_comp_cVarType = ' '; }
|
|
| STATIC { hb_comp_iVarScope = VS_STATIC; hb_compLinePush(); } VarList Crlf { hb_comp_cVarType = ' '; }
|
|
| PARAMETERS { if( hb_comp_functions.pLast->bFlags & FUN_USES_LOCAL_PARAMS )
|
|
hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_PARAMETERS_NOT_ALLOWED, NULL, NULL );
|
|
else
|
|
hb_comp_functions.pLast->wParamNum=0; hb_comp_iVarScope = ( VS_PRIVATE | VS_PARAMETER ); }
|
|
MemvarList Crlf
|
|
;
|
|
|
|
VarList : VarDef { $$ = 1; }
|
|
| VarList ',' VarDef { $$++; }
|
|
;
|
|
|
|
ExtVarList : ExtVarDef { $$ = 1; }
|
|
| ExtVarList ',' ExtVarDef { $$++; }
|
|
;
|
|
|
|
/* NOTE: if STATIC or LOCAL variables are declared and initialized then we can
|
|
* assign a value immediately - however for PRIVATE and PUBLIC variables
|
|
* initialization have to be delayed because we have to create these variables
|
|
* first.
|
|
*/
|
|
ExtVarDef : VarDef
|
|
| MacroVar AsType
|
|
{ hb_compRTVariableAdd( hb_compExprNewRTVar( NULL, $1 ), FALSE ); }
|
|
| MacroVar AsType INASSIGN Expression
|
|
{ hb_compExprDelete( hb_compExprGenPush( $4 ) );
|
|
hb_compRTVariableAdd( hb_compExprNewRTVar( NULL, $1 ), TRUE );
|
|
}
|
|
| MacroVar DimList
|
|
{
|
|
USHORT uCount = hb_compExprListLen( $2 );
|
|
hb_compExprDelete( hb_compExprGenPush( $2 ) );
|
|
hb_compGenPCode3( HB_P_ARRAYDIM, HB_LOBYTE( uCount ), HB_HIBYTE( uCount ) );
|
|
hb_compRTVariableAdd( hb_compExprNewRTVar( NULL, $1 ), TRUE );
|
|
}
|
|
| MacroVar DimList AS_ARRAY
|
|
{
|
|
USHORT uCount = hb_compExprListLen( $2 );
|
|
hb_compExprDelete( hb_compExprGenPush( $2 ) );
|
|
hb_compGenPCode3( HB_P_ARRAYDIM, HB_LOBYTE( uCount ), HB_HIBYTE( uCount ) );
|
|
hb_compRTVariableAdd( hb_compExprNewRTVar( NULL, $1 ), TRUE );
|
|
}
|
|
;
|
|
|
|
VarDef : IdentName AsType { hb_compVariableAdd( $1, $2 ); }
|
|
{
|
|
if( hb_comp_iVarScope == VS_STATIC )
|
|
{
|
|
hb_compStaticDefStart(); /* switch to statics pcode buffer */
|
|
hb_compStaticDefEnd();
|
|
}
|
|
else if( hb_comp_iVarScope == VS_PUBLIC || hb_comp_iVarScope == VS_PRIVATE )
|
|
{
|
|
hb_compRTVariableAdd( hb_compExprNewRTVar( $1, NULL ), FALSE );
|
|
}
|
|
}
|
|
|
|
| IdentName AsType { hb_compVariableAdd( $1, $2 );
|
|
$<iNumber>$ = hb_comp_iVarScope;
|
|
}
|
|
INASSIGN Expression
|
|
{
|
|
hb_comp_iVarScope = $<iNumber>3;
|
|
if( hb_comp_iVarScope == VS_STATIC )
|
|
{
|
|
hb_compStaticDefStart(); /* switch to statics pcode buffer */
|
|
hb_compExprDelete( hb_compExprGenStatement( hb_compExprAssignStatic( hb_compExprNewVar( $1 ), $5 ) ) );
|
|
hb_compStaticDefEnd();
|
|
}
|
|
else if( hb_comp_iVarScope == VS_PUBLIC || hb_comp_iVarScope == VS_PRIVATE )
|
|
{
|
|
hb_compExprDelete( hb_compExprGenPush( $5 ) );
|
|
hb_compRTVariableAdd( hb_compExprNewRTVar( $1, NULL ), TRUE );
|
|
}
|
|
else
|
|
{
|
|
hb_compExprDelete( hb_compExprGenStatement( hb_compExprAssign( hb_compExprNewVar( $1 ), $5 ) ) );
|
|
}
|
|
}
|
|
|
|
| IdentName DimList { hb_compVariableDim( $1, $2 ); }
|
|
| IdentName DimList AS_ARRAY { hb_compVariableDim( $1, $2 ); }
|
|
;
|
|
|
|
/* NOTE: DimList and DimIndex is the same as ArrayIndex and IndexList
|
|
* however we are using quite different actions here
|
|
*/
|
|
DimList : DimIndex ']' { $$ = $1; }
|
|
;
|
|
|
|
DimIndex : '[' Expression { $$ = hb_compExprNewArgList( $2 ); }
|
|
| DimIndex ',' Expression { $$ = hb_compExprAddListExpr( $1, $3 ); }
|
|
| DimIndex ']' '[' Expression { $$ = hb_compExprAddListExpr( $1, $4 ); }
|
|
;
|
|
|
|
|
|
FieldsDef : FIELD { hb_comp_iVarScope = VS_FIELD; } FieldList Crlf
|
|
;
|
|
|
|
FieldList : IdentName AsType { $$=hb_compFieldsCount(); hb_compVariableAdd( $1, $2 ); }
|
|
| FieldList ',' IdentName AsType { hb_compVariableAdd( $3, $4 ); }
|
|
| FieldList IN IdentName { hb_compFieldSetAlias( $3, $<iNumber>1 ); }
|
|
;
|
|
|
|
MemvarDef : MEMVAR { hb_comp_iVarScope = VS_MEMVAR; } MemvarList Crlf
|
|
;
|
|
|
|
MemvarList : IdentName { hb_compVariableAdd( $1, ' ' ); }
|
|
| MemvarList ',' IdentName { hb_compVariableAdd( $3, ' ' ); }
|
|
;
|
|
|
|
ExecFlow : IfEndif
|
|
| DoCase
|
|
| DoWhile
|
|
| ForNext
|
|
| BeginSeq
|
|
;
|
|
|
|
IfEndif : IfBegin EndIf { hb_compGenJumpHere( $1 ); }
|
|
| IfBegin IfElse EndIf { hb_compGenJumpHere( $1 ); }
|
|
| IfBegin IfElseIf EndIf { hb_compGenJumpHere( $1 ); hb_compElseIfFix( $2 ); }
|
|
| IfBegin IfElseIf IfElse EndIf { hb_compGenJumpHere( $1 ); hb_compElseIfFix( $2 ); }
|
|
;
|
|
|
|
EmptyStats : /* empty */ { hb_comp_bDontGenLineNum = TRUE; }
|
|
| Statements
|
|
;
|
|
|
|
IfBegin : IF SimpleExpression { ++hb_comp_wIfCounter; hb_compLinePush(); } Crlf { hb_compExprDelete( hb_compExprGenPush( $2 ) ); $$ = hb_compGenJumpFalse( 0 ); hb_compLinePush(); }
|
|
EmptyStats
|
|
{ $$ = hb_compGenJump( 0 ); hb_compGenJumpHere( $<iNumber>5 ); }
|
|
|
|
| IF Variable { ++hb_comp_wIfCounter; hb_compLinePush(); } Crlf { hb_compExprDelete( hb_compExprGenPush( $2 ) ); $$ = hb_compGenJumpFalse( 0 ); hb_compLinePush(); }
|
|
EmptyStats
|
|
{ $$ = hb_compGenJump( 0 ); hb_compGenJumpHere( $<iNumber>5 ); }
|
|
|
|
| IF PareExpList1 { ++hb_comp_wIfCounter; hb_compLinePush(); } Crlf { hb_compExprDelete( hb_compExprGenPush( $2 ) ); $$ = hb_compGenJumpFalse( 0 ); hb_compLinePush(); }
|
|
EmptyStats
|
|
{ $$ = hb_compGenJump( 0 ); hb_compGenJumpHere( $<iNumber>5 ); }
|
|
|
|
| IF PareExpList2 { ++hb_comp_wIfCounter; hb_compLinePush(); } Crlf { hb_compExprDelete( hb_compExprGenPush( $2 ) ); $$ = hb_compGenJumpFalse( 0 ); hb_compLinePush(); }
|
|
EmptyStats
|
|
{ $$ = hb_compGenJump( 0 ); hb_compGenJumpHere( $<iNumber>5 ); }
|
|
|
|
| IF PareExpListN { ++hb_comp_wIfCounter; hb_compLinePush(); } Crlf { hb_compExprDelete( hb_compExprGenPush( $2 ) ); $$ = hb_compGenJumpFalse( 0 ); hb_compLinePush(); }
|
|
EmptyStats
|
|
{ $$ = hb_compGenJump( 0 ); hb_compGenJumpHere( $<iNumber>5 ); }
|
|
;
|
|
|
|
IfElse : ELSE Crlf { hb_comp_functions.pLast->bFlags &= ~ FUN_BREAK_CODE; hb_compLinePush(); }
|
|
EmptyStats
|
|
;
|
|
|
|
IfElseIf : ELSEIF Expression Crlf { hb_comp_functions.pLast->bFlags &= ~ FUN_BREAK_CODE; hb_compExprDelete( hb_compExprGenPush( $2 ) ); $<iNumber>$ = hb_compGenJumpFalse( 0 ); hb_compLinePush(); }
|
|
EmptyStats { $$ = hb_compElseIfGen( NULL, hb_compGenJump( 0 ) ); hb_compGenJumpHere( $<iNumber>4 ); }
|
|
|
|
| IfElseIf ELSEIF Expression Crlf { hb_comp_functions.pLast->bFlags &= ~ FUN_BREAK_CODE; hb_compExprDelete( hb_compExprGenPush( $3 ) ); $<iNumber>$ = hb_compGenJumpFalse( 0 ); hb_compLinePush(); }
|
|
EmptyStats { $$ = hb_compElseIfGen( $1, hb_compGenJump( 0 ) ); hb_compGenJumpHere( $<iNumber>5 ); }
|
|
;
|
|
|
|
EndIf : ENDIF { --hb_comp_wIfCounter; hb_comp_functions.pLast->bFlags &= ~ ( FUN_WITH_RETURN | FUN_BREAK_CODE ); }
|
|
| END { --hb_comp_wIfCounter; hb_comp_functions.pLast->bFlags &= ~ ( FUN_WITH_RETURN | FUN_BREAK_CODE ); }
|
|
;
|
|
|
|
DoCase : DoCaseBegin
|
|
Cases
|
|
EndCase { hb_compElseIfFix( $2 ); }
|
|
|
|
| DoCaseBegin
|
|
Otherwise
|
|
EndCase
|
|
|
|
| DoCaseBegin
|
|
EndCase
|
|
|
|
| DoCaseBegin
|
|
Cases
|
|
Otherwise
|
|
EndCase { hb_compElseIfFix( $2 ); }
|
|
;
|
|
|
|
EndCase : ENDCASE
|
|
{ --hb_comp_wCaseCounter;
|
|
hb_comp_functions.pLast->bFlags &= ~ ( FUN_WITH_RETURN | FUN_BREAK_CODE );
|
|
}
|
|
| END
|
|
{ --hb_comp_wCaseCounter;
|
|
hb_comp_functions.pLast->bFlags &= ~ ( FUN_WITH_RETURN | FUN_BREAK_CODE );
|
|
}
|
|
;
|
|
|
|
DoCaseStart : DOCASE { ++hb_comp_wCaseCounter; } Crlf { hb_compLinePush(); }
|
|
;
|
|
|
|
DoCaseBegin : DoCaseStart { }
|
|
| DoCaseStart Statements {
|
|
if( $<lNumber>2 > 0 )
|
|
{
|
|
--hb_comp_iLine;
|
|
hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_MAYHEM_IN_CASE, NULL, NULL );
|
|
}
|
|
}
|
|
;
|
|
|
|
Cases : CASE Expression Crlf
|
|
{
|
|
hb_compExprDelete( hb_compExprGenPush( $2 ) );
|
|
$<iNumber>$ = hb_compGenJumpFalse( 0 );
|
|
hb_compLinePush();
|
|
}
|
|
EmptyStats
|
|
{
|
|
hb_comp_functions.pLast->bFlags &= ~ FUN_BREAK_CODE;
|
|
$$ = hb_compElseIfGen( 0, hb_compGenJump( 0 ) );
|
|
hb_compGenJumpHere( $<iNumber>4 );
|
|
hb_compLinePush();
|
|
}
|
|
|
|
| Cases CASE Expression Crlf
|
|
{
|
|
hb_compExprDelete( hb_compExprGenPush( $3 ) );
|
|
$<iNumber>$ = hb_compGenJumpFalse( 0 );
|
|
hb_compLinePush();
|
|
}
|
|
EmptyStats
|
|
{
|
|
hb_comp_functions.pLast->bFlags &= ~ FUN_BREAK_CODE;
|
|
$$ = hb_compElseIfGen( $1, hb_compGenJump( 0 ) );
|
|
hb_compGenJumpHere( $<iNumber>5 );
|
|
hb_compLinePush();
|
|
}
|
|
;
|
|
|
|
Otherwise : OTHERWISE Crlf { hb_comp_functions.pLast->bFlags &= ~ FUN_BREAK_CODE; hb_compLinePush(); }
|
|
EmptyStats
|
|
| Otherwise OTHERWISE { hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_MAYHEM_IN_CASE, NULL, NULL ); } Crlf
|
|
EmptyStats
|
|
;
|
|
|
|
DoWhile : WhileBegin Expression Crlf
|
|
{
|
|
hb_compExprDelete( hb_compExprGenPush( $2 ) );
|
|
$<lNumber>$ = hb_compGenJumpFalse( 0 );
|
|
hb_compLinePush();
|
|
}
|
|
EmptyStats
|
|
{
|
|
hb_compLoopHere();
|
|
hb_compGenJump( $1 - hb_comp_functions.pLast->lPCodePos );
|
|
}
|
|
EndWhile
|
|
{
|
|
hb_compGenJumpHere( $<lNumber>4 ); --hb_comp_wWhileCounter;
|
|
hb_compLoopEnd();
|
|
hb_comp_functions.pLast->bFlags &= ~ FUN_WITH_RETURN;
|
|
}
|
|
;
|
|
|
|
WhileBegin : WHILE { $$ = hb_comp_functions.pLast->lPCodePos; hb_compLinePushIfInside(); ++hb_comp_wWhileCounter; hb_compLoopStart(); }
|
|
;
|
|
|
|
EndWhile : END
|
|
| ENDDO
|
|
;
|
|
|
|
ForNext : FOR LValue ForAssign Expression /* 1 2 3 4 */
|
|
{
|
|
hb_compLinePush();
|
|
++hb_comp_wForCounter; /* 5 */
|
|
$<asExpr>$ = hb_compExprGenStatement( hb_compExprAssign( $2, $4 ) );
|
|
}
|
|
TO Expression StepExpr /* 6 7 8 */
|
|
{
|
|
hb_compLoopStart();
|
|
$<lNumber>$ = hb_comp_functions.pLast->lPCodePos; /* 9 */
|
|
hb_compExprGenPush( $2 ); /* counter */
|
|
hb_compExprGenPush( $7 ); /* end */
|
|
if( $<asExpr>8 )
|
|
hb_compExprGenPush( $<asExpr>8 ); /* step */
|
|
}
|
|
Crlf /* 10 */
|
|
{
|
|
if( $<asExpr>8 )
|
|
hb_compGenPCode1( HB_P_FORTEST );
|
|
else
|
|
hb_compGenPCode1( HB_P_LESSEQUAL );
|
|
$<lNumber>$ = hb_compGenJumpFalse( 0 ); /* 11 */
|
|
hb_compLinePush();
|
|
}
|
|
ForStatements /* 12 */
|
|
{
|
|
hb_compLoopHere();
|
|
if( $<asExpr>8 )
|
|
hb_compExprClear( hb_compExprGenStatement( hb_compExprSetOperand( hb_compExprNewPlusEq( $2 ), $<asExpr>8 ) ) );
|
|
else
|
|
hb_compExprClear( hb_compExprGenStatement( hb_compExprNewPreInc( $2 ) ) );
|
|
hb_compGenJump( $<lNumber>9 - hb_comp_functions.pLast->lPCodePos );
|
|
hb_compGenJumpHere( $<lNumber>11 );
|
|
hb_compLoopEnd();
|
|
hb_compExprDelete( $7 );
|
|
hb_compExprDelete( $<asExpr>5 ); /* deletes $5, $2, $4 */
|
|
if( $<asExpr>8 )
|
|
hb_compExprDelete( $<asExpr>8 );
|
|
hb_comp_functions.pLast->bFlags &= ~ FUN_WITH_RETURN;
|
|
}
|
|
;
|
|
|
|
ForAssign : '='
|
|
| INASSIGN
|
|
;
|
|
|
|
StepExpr : /* default step expression */ { $<asExpr>$ = NULL; }
|
|
| STEP Expression { $<asExpr>$ = $2; }
|
|
;
|
|
|
|
ForStatements : EmptyStats NEXT { --hb_comp_wForCounter; }
|
|
| EmptyStats NEXT IdentName { --hb_comp_wForCounter; }
|
|
;
|
|
|
|
BeginSeq : BEGINSEQ { ++hb_comp_wSeqCounter; $<lNumber>$ = hb_compSequenceBegin(); } Crlf { hb_compLinePush(); }
|
|
EmptyStats
|
|
{
|
|
/* Set jump address for HB_P_SEQBEGIN opcode - this address
|
|
* will be used in BREAK code if there is no RECOVER clause
|
|
*/
|
|
hb_compGenJumpHere( $<lNumber>2 );
|
|
$<lNumber>$ = hb_compSequenceEnd();
|
|
hb_compLinePush();
|
|
}
|
|
RecoverSeq
|
|
{
|
|
/* Replace END address with RECOVER address in
|
|
* HB_P_SEQBEGIN opcode if there is RECOVER clause
|
|
*/
|
|
if( $<lNumber>7 )
|
|
hb_compGenJumpThere( $<lNumber>2, $<lNumber>7-( hb_comp_bLineNumbers ? 3 : 0 ) );
|
|
}
|
|
END
|
|
{
|
|
/* Fix END address
|
|
* There is no line number after HB_P_SEQEND in case no
|
|
* RECOVER clause is used
|
|
*/
|
|
hb_compGenJumpThere( $<lNumber>6, hb_comp_functions.pLast->lPCodePos-((hb_comp_bLineNumbers && !$<lNumber>7)?3:0) );
|
|
if( $<lNumber>7 ) /* only if there is RECOVER clause */
|
|
hb_compLinePushIfDebugger();
|
|
else
|
|
--hb_comp_wSeqCounter; /* RECOVER is also considered as end of sequence */
|
|
hb_compSequenceFinish( $<lNumber>2, $<iNumber>5 );
|
|
hb_comp_functions.pLast->bFlags &= ~ FUN_WITH_RETURN;
|
|
}
|
|
;
|
|
|
|
RecoverSeq : /* no recover */ { $<lNumber>$ = 0; }
|
|
| RecoverEmpty Crlf { $<lNumber>$ = $<lNumber>1; hb_compLinePush(); } EmptyStats
|
|
| RecoverUsing Crlf { $<lNumber>$ = $<lNumber>1; hb_compLinePush(); } EmptyStats
|
|
;
|
|
|
|
RecoverEmpty : RECOVER
|
|
{
|
|
hb_comp_functions.pLast->bFlags &= ~ FUN_BREAK_CODE;
|
|
$<lNumber>$ = hb_comp_functions.pLast->lPCodePos;
|
|
--hb_comp_wSeqCounter;
|
|
hb_compGenPCode1( HB_P_SEQRECOVER );
|
|
hb_compGenPCode1( HB_P_POP );
|
|
}
|
|
;
|
|
|
|
RecoverUsing : RECOVERUSING IdentName
|
|
{
|
|
hb_comp_functions.pLast->bFlags &= ~ FUN_BREAK_CODE;
|
|
$<lNumber>$ = hb_comp_functions.pLast->lPCodePos;
|
|
--hb_comp_wSeqCounter;
|
|
hb_compGenPCode1( HB_P_SEQRECOVER );
|
|
hb_compGenPopVar( $2 );
|
|
}
|
|
;
|
|
|
|
/* NOTE: In Clipper all variables used in DO .. WITH are passed by reference
|
|
* however if they are part of an expression then they are passed by value
|
|
* for example:
|
|
* DO .. WITH ++variable
|
|
* will pass the value of variable not a reference
|
|
*/
|
|
DoName : IdentName { $$ = hb_compExprNewFunName( $1 ); }
|
|
| MacroVar { $$ = $1; }
|
|
| MacroExpr { $$ = $1; }
|
|
;
|
|
|
|
DoProc : DO DoName
|
|
{ $$ = hb_compExprNewFunCall( $2, NULL ); }
|
|
| DO DoName WITH DoArgList
|
|
{ $$ = hb_compExprNewFunCall( $2, $4 ); }
|
|
| WHILE WITH DoArgList
|
|
{ $$ = hb_compExprNewFunCall( hb_compExprNewFunName( hb_strdup("WHILE") ), $3 ); }
|
|
;
|
|
|
|
DoArgList : ',' { $$ = hb_compExprAddListExpr( hb_compExprNewArgList( hb_compExprNewNil() ), hb_compExprNewNil() ); }
|
|
| ',' DoArgument { $$ = hb_compExprAddListExpr( hb_compExprNewArgList( hb_compExprNewNil() ), $2 ); }
|
|
| DoArgument { $$ = hb_compExprNewArgList( $1 ); }
|
|
| DoArgList ',' { $$ = hb_compExprAddListExpr( $1, hb_compExprNewNil() ); }
|
|
| DoArgList ',' DoArgument { $$ = hb_compExprAddListExpr( $1, $3 ); }
|
|
;
|
|
|
|
DoArgument : IdentName { $$ = hb_compExprNewVarRef( $1 ); }
|
|
| '@' IdentName '(' ')' { $$ = hb_compExprNewFunRef( $2 ); }
|
|
| SimpleExpression { $$ = $1; }
|
|
| PareExpList { $$ = $1; }
|
|
;
|
|
|
|
Crlf : '\n' { ++hb_comp_iLine; }
|
|
| ';' { hb_comp_bDontGenLineNum = TRUE; }
|
|
;
|
|
|
|
%%
|
|
|
|
/*
|
|
** ------------------------------------------------------------------------ **
|
|
*/
|
|
|
|
int hb_compYACCMain( char * szName )
|
|
{
|
|
/* Generate the starting procedure frame
|
|
*/
|
|
if( hb_comp_bStartProc )
|
|
hb_compFunctionAdd( hb_strupr( hb_strdup( szName ) ), HB_FS_PUBLIC, FUN_PROCEDURE );
|
|
else
|
|
/* Don't pass the name of module if the code for starting procedure
|
|
* will be not generated. The name cannot be placed as first symbol
|
|
* because this symbol can be used as function call or memvar's name.
|
|
*/
|
|
hb_compFunctionAdd( hb_strupr( hb_strdup( "" ) ), HB_FS_PUBLIC, FUN_PROCEDURE );
|
|
|
|
yyparse();
|
|
|
|
/* fix all previous function returns offsets */
|
|
hb_compFixReturns();
|
|
|
|
hb_compExternGen(); /* generates EXTERN symbols names */
|
|
|
|
if( hb_comp_pInitFunc )
|
|
{
|
|
PCOMSYMBOL pSym;
|
|
|
|
/* Fix the number of static variables */
|
|
hb_comp_pInitFunc->pCode[ 3 ] = HB_LOBYTE( hb_comp_iStaticCnt );
|
|
hb_comp_pInitFunc->pCode[ 4 ] = HB_HIBYTE( hb_comp_iStaticCnt );
|
|
hb_comp_pInitFunc->iStaticsBase = hb_comp_iStaticCnt;
|
|
|
|
pSym = hb_compSymbolAdd( hb_comp_pInitFunc->szName, NULL );
|
|
pSym->cScope |= hb_comp_pInitFunc->cScope;
|
|
hb_comp_functions.pLast->pNext = hb_comp_pInitFunc;
|
|
hb_comp_functions.pLast = hb_comp_pInitFunc;
|
|
++hb_comp_functions.iCount;
|
|
}
|
|
|
|
if( hb_comp_szAnnounce )
|
|
hb_compAnnounce( hb_comp_szAnnounce );
|
|
|
|
/* Close processed file (it is opened in hb_compInclude() function )
|
|
*/
|
|
fclose( yyin );
|
|
|
|
hb_comp_files.pLast = NULL;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
|
|
void yyerror( char * s )
|
|
{
|
|
if( yytext[ 0 ] == '\n' )
|
|
hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_YACC, s, "<eol>" );
|
|
else
|
|
hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_YACC, s, yytext );
|
|
}
|
|
|
|
|
|
BOOL hb_compInclude( char * szFileName, PATHNAMES * pSearch )
|
|
{
|
|
PFILE pFile;
|
|
|
|
yyin = fopen( szFileName, "r" );
|
|
if( ! yyin )
|
|
{
|
|
if( pSearch )
|
|
{
|
|
PHB_FNAME pFileName = hb_fsFNameSplit( szFileName );
|
|
|
|
while( pSearch && !yyin )
|
|
{
|
|
char szFName[ _POSIX_PATH_MAX ]; /* filename to parse */
|
|
|
|
pFileName->szPath = pSearch->szPath;
|
|
hb_fsFNameMerge( szFName, pFileName );
|
|
yyin = fopen( szFName, "r" );
|
|
if( ! yyin )
|
|
{
|
|
pSearch = pSearch->pNext;
|
|
if( ! pSearch )
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
hb_xfree( ( void * ) pFileName );
|
|
}
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
pFile = ( PFILE ) hb_xgrab( sizeof( _FILE ) );
|
|
pFile->handle = yyin;
|
|
pFile->pBuffer = hb_xgrab( HB_PP_BUFF_SIZE );
|
|
pFile->iBuffer = pFile->lenBuffer = 10;
|
|
pFile->szFileName = szFileName;
|
|
pFile->pPrev = NULL;
|
|
|
|
/*
|
|
if( ! hb_comp_files.iFiles )
|
|
hb_comp_files.pLast = pFile;
|
|
else
|
|
{
|
|
hb_comp_files.pLast->iLine = hb_comp_iLine;
|
|
hb_comp_iLine = 1;
|
|
pFile->pPrev = hb_comp_files.pLast;
|
|
hb_comp_files.pLast = pFile;
|
|
}
|
|
#ifdef __cplusplus
|
|
yy_switch_to_buffer( ( YY_BUFFER_STATE ) ( pFile->pBuffer = yy_create_buffer( yyin, 8192 * 2 ) ) );
|
|
#else
|
|
yy_switch_to_buffer( pFile->pBuffer = yy_create_buffer( yyin, 8192 * 2 ) );
|
|
#endif
|
|
*/
|
|
|
|
hb_comp_files.pLast = pFile;
|
|
#ifdef __cplusplus
|
|
yy_switch_to_buffer( ( YY_BUFFER_STATE ) ( hb_comp_buffer = ( char * ) yy_create_buffer( yyin, 8192 * 2 ) ) );
|
|
#else
|
|
yy_switch_to_buffer( hb_comp_buffer = yy_create_buffer( yyin, 8192 * 2 ) );
|
|
#endif
|
|
hb_comp_files.iFiles++;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
int yywrap( void ) /* handles the EOF of the currently processed file */
|
|
{
|
|
if( hb_comp_files.iFiles == 1 )
|
|
{
|
|
hb_xfree( hb_comp_files.pLast->pBuffer );
|
|
return 1; /* we have reached the main EOF */
|
|
}
|
|
|
|
/*
|
|
else
|
|
{
|
|
void * pLast;
|
|
|
|
pLast = hb_comp_files.pLast;
|
|
fclose( hb_comp_files.pLast->handle );
|
|
hb_comp_files.pLast = ( PFILE ) ( ( PFILE ) hb_comp_files.pLast )->pPrev;
|
|
hb_comp_iLine = hb_comp_files.pLast->iLine;
|
|
#ifdef __cplusplus
|
|
yy_delete_buffer( ( YY_BUFFER_STATE ) ( ( PFILE ) pLast )->pBuffer );
|
|
#else
|
|
yy_delete_buffer( ( ( PFILE ) pLast )->pBuffer );
|
|
#endif
|
|
free( pLast );
|
|
hb_comp_files.iFiles--;
|
|
yyin = hb_comp_files.pLast->handle;
|
|
#ifdef __cplusplus
|
|
yy_switch_to_buffer( ( YY_BUFFER_STATE ) hb_comp_files.pLast->pBuffer );
|
|
#else
|
|
yy_switch_to_buffer( hb_comp_files.pLast->pBuffer );
|
|
#endif
|
|
return 0;
|
|
}
|
|
*/ /* we close the currently include file and continue */
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* ************************************************************************* */
|
|
|
|
/*
|
|
* This function stores the position in pcode buffer where the FOR/WHILE
|
|
* loop starts. It will be used to fix any LOOP/EXIT statements
|
|
*/
|
|
static void hb_compLoopStart( void )
|
|
{
|
|
PTR_LOOPEXIT pLoop = ( PTR_LOOPEXIT ) hb_xgrab( sizeof( LOOPEXIT ) );
|
|
|
|
if( hb_comp_pLoops )
|
|
{
|
|
PTR_LOOPEXIT pLast = hb_comp_pLoops;
|
|
|
|
while( pLast->pNext )
|
|
pLast = pLast->pNext;
|
|
pLast->pNext = pLoop;
|
|
}
|
|
else
|
|
hb_comp_pLoops = pLoop;
|
|
|
|
pLoop->pNext = NULL;
|
|
pLoop->pExitList = NULL;
|
|
pLoop->pLoopList = NULL;
|
|
pLoop->ulOffset = hb_comp_functions.pLast->lPCodePos; /* store the start position */
|
|
pLoop->iLine = hb_comp_iLine;
|
|
pLoop->wSeqCounter = hb_comp_wSeqCounter; /* store current SEQUENCE counter */
|
|
}
|
|
|
|
/*
|
|
* Stores the position of LOOP statement to fix it later at the end of loop
|
|
*/
|
|
static void hb_compLoopLoop( void )
|
|
{
|
|
if( ! hb_comp_pLoops )
|
|
{
|
|
hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_EXIT_IN_SEQUENCE, "LOOP", NULL );
|
|
}
|
|
else
|
|
{
|
|
PTR_LOOPEXIT pLast, pLoop;
|
|
|
|
pLoop = ( PTR_LOOPEXIT ) hb_xgrab( sizeof( LOOPEXIT ) );
|
|
|
|
pLoop->pLoopList = NULL;
|
|
pLoop->ulOffset = hb_comp_functions.pLast->lPCodePos; /* store the position to fix */
|
|
|
|
pLast = hb_comp_pLoops;
|
|
while( pLast->pNext )
|
|
pLast = pLast->pNext;
|
|
|
|
if( pLast->wSeqCounter != hb_comp_wSeqCounter )
|
|
{
|
|
/* Attempt to LOOP from BEGIN/END sequence
|
|
* Current SEQUENCE counter is different then at the beginning of loop
|
|
* Notice that LOOP is allowed in RECOVER code.
|
|
*/
|
|
hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_EXIT_IN_SEQUENCE, "LOOP", NULL );
|
|
}
|
|
else
|
|
{
|
|
while( pLast->pLoopList )
|
|
pLast = pLast->pLoopList;
|
|
|
|
pLast->pLoopList = pLoop;
|
|
|
|
hb_compGenJump( 0 );
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Stores the position of EXIT statement to fix it later at the end of loop
|
|
*/
|
|
static void hb_compLoopExit( void )
|
|
{
|
|
if( ! hb_comp_pLoops )
|
|
{
|
|
hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_EXIT_IN_SEQUENCE, "EXIT", NULL );
|
|
}
|
|
else
|
|
{
|
|
PTR_LOOPEXIT pLast, pLoop;
|
|
|
|
pLoop = ( PTR_LOOPEXIT ) hb_xgrab( sizeof( LOOPEXIT ) );
|
|
|
|
pLoop->pExitList = NULL;
|
|
pLoop->ulOffset = hb_comp_functions.pLast->lPCodePos; /* store the position to fix */
|
|
|
|
pLast = hb_comp_pLoops;
|
|
while( pLast->pNext )
|
|
pLast = pLast->pNext;
|
|
|
|
if( pLast->wSeqCounter != hb_comp_wSeqCounter )
|
|
{
|
|
/* Attempt to LOOP from BEGIN/END sequence
|
|
* Current SEQUENCE counter is different then at the beginning of loop
|
|
* Notice that LOOP is allowed in RECOVER code.
|
|
*/
|
|
hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_EXIT_IN_SEQUENCE, "EXIT", NULL );
|
|
}
|
|
else
|
|
{
|
|
while( pLast->pExitList )
|
|
pLast = pLast->pExitList;
|
|
|
|
pLast->pExitList = pLoop;
|
|
|
|
hb_compGenJump( 0 );
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Fixes the LOOP statement
|
|
*/
|
|
static void hb_compLoopHere( void )
|
|
{
|
|
PTR_LOOPEXIT pLoop = hb_comp_pLoops, pFree;
|
|
|
|
if( pLoop )
|
|
{
|
|
while( pLoop->pNext )
|
|
pLoop = pLoop->pNext;
|
|
|
|
pLoop = pLoop->pLoopList;
|
|
while( pLoop )
|
|
{
|
|
hb_compGenJumpHere( pLoop->ulOffset + 1 );
|
|
pFree = pLoop;
|
|
pLoop = pLoop->pLoopList;
|
|
hb_xfree( ( void * ) pFree );
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Fixes the EXIT statements and releases memory allocated for current loop
|
|
*/
|
|
static void hb_compLoopEnd( void )
|
|
{
|
|
PTR_LOOPEXIT pExit, pLoop = hb_comp_pLoops, pLast = hb_comp_pLoops, pFree;
|
|
|
|
if( pLoop )
|
|
{
|
|
while( pLoop->pNext )
|
|
{
|
|
pLast = pLoop;
|
|
pLoop = pLoop->pNext;
|
|
}
|
|
|
|
pExit = pLoop->pExitList;
|
|
while( pExit )
|
|
{
|
|
hb_compGenJumpHere( pExit->ulOffset + 1 );
|
|
pFree = pExit;
|
|
pExit = pExit->pExitList;
|
|
hb_xfree( ( void * ) pFree );
|
|
}
|
|
|
|
pLast->pNext = NULL;
|
|
if( pLoop == hb_comp_pLoops )
|
|
hb_comp_pLoops = NULL;
|
|
hb_xfree( ( void * ) pLoop );
|
|
}
|
|
}
|
|
|
|
static void * hb_compElseIfGen( void * pFirst, ULONG ulOffset )
|
|
{
|
|
PELSEIF pElseIf = ( PELSEIF ) hb_xgrab( sizeof( _ELSEIF ) ), pLast;
|
|
|
|
pElseIf->ulOffset = ulOffset;
|
|
pElseIf->pNext = 0;
|
|
|
|
if( ! pFirst )
|
|
pFirst = pElseIf;
|
|
else
|
|
{
|
|
pLast = ( PELSEIF ) pFirst;
|
|
while( pLast->pNext )
|
|
pLast = pLast->pNext;
|
|
pLast->pNext = pElseIf;
|
|
}
|
|
return pFirst;
|
|
}
|
|
|
|
|
|
static void hb_compElseIfFix( void * pFixElseIfs )
|
|
{
|
|
PELSEIF pFix = ( PELSEIF ) pFixElseIfs;
|
|
|
|
while( pFix )
|
|
{
|
|
hb_compGenJumpHere( pFix->ulOffset );
|
|
pFix = pFix->pNext;
|
|
}
|
|
}
|
|
|
|
static void hb_compRTVariableAdd( HB_EXPR_PTR pVar, BOOL bPopInitValue )
|
|
{
|
|
HB_RTVAR_PTR pRTvar = ( HB_RTVAR_PTR ) hb_xgrab( sizeof( HB_RTVAR ) );
|
|
|
|
pRTvar->pVar = pVar;
|
|
pRTvar->bPopValue = bPopInitValue;
|
|
pRTvar->pNext = NULL;
|
|
pRTvar->pPrev = NULL;
|
|
|
|
if( hb_comp_rtvars )
|
|
{
|
|
HB_RTVAR_PTR pLast = hb_comp_rtvars;
|
|
while( pLast->pNext )
|
|
pLast = pLast->pNext;
|
|
pLast->pNext = pRTvar;
|
|
pRTvar->pPrev = pLast;
|
|
}
|
|
else
|
|
hb_comp_rtvars = pRTvar;
|
|
}
|
|
|
|
static void hb_compRTVariableGen( char * szCreateFun )
|
|
{
|
|
USHORT usCount = 0;
|
|
HB_RTVAR_PTR pVar = hb_comp_rtvars;
|
|
HB_RTVAR_PTR pDel;
|
|
|
|
/* generate the function call frame */
|
|
hb_compGenPushSymbol( hb_strdup( szCreateFun ), 1);
|
|
hb_compGenPushNil();
|
|
|
|
/* push variable names to create */
|
|
while( pVar->pNext )
|
|
{
|
|
hb_compExprGenPush( pVar->pVar );
|
|
pVar = pVar->pNext;
|
|
++usCount;
|
|
}
|
|
hb_compExprGenPush( pVar->pVar );
|
|
++usCount;
|
|
|
|
/* call function that will create either PUBLIC or PRIVATE variables */
|
|
hb_compGenPCode3( HB_P_DO, HB_LOBYTE( usCount ), HB_HIBYTE( usCount ) );
|
|
|
|
/* pop initial values */
|
|
while( pVar )
|
|
{
|
|
if( pVar->bPopValue )
|
|
hb_compExprDelete( hb_compExprGenPop( pVar->pVar ) );
|
|
else
|
|
hb_compExprDelete( pVar->pVar );
|
|
pDel = pVar;
|
|
pVar = pVar->pPrev;
|
|
hb_xfree( pDel );
|
|
}
|
|
hb_comp_rtvars = NULL;
|
|
}
|
|
|
|
static void hb_compVariableDim( char * szName, HB_EXPR_PTR pInitValue )
|
|
{
|
|
if( hb_comp_iVarScope == VS_PUBLIC || hb_comp_iVarScope == VS_PRIVATE )
|
|
{
|
|
USHORT uCount = hb_compExprListLen( pInitValue );
|
|
hb_compVariableAdd( szName, 'A' );
|
|
hb_compExprDelete( hb_compExprGenPush( pInitValue ) );
|
|
hb_compGenPCode3( HB_P_ARRAYDIM, HB_LOBYTE( uCount ), HB_HIBYTE( uCount ) );
|
|
hb_compRTVariableAdd( hb_compExprNewRTVar( szName, NULL ), TRUE );
|
|
}
|
|
else if( hb_comp_iVarScope == VS_STATIC )
|
|
{
|
|
USHORT uCount = hb_compExprListLen( pInitValue );
|
|
HB_EXPR_PTR pVar = hb_compExprNewVar( szName );
|
|
HB_EXPR_PTR pAssign;
|
|
|
|
hb_compStaticDefStart(); /* switch to statics pcode buffer */
|
|
/* create a static variable */
|
|
hb_compVariableAdd( szName, 'A' );
|
|
/* create an array */
|
|
hb_compExprGenPush( pInitValue );
|
|
hb_compGenPCode3( HB_P_ARRAYDIM, HB_LOBYTE( uCount ), HB_HIBYTE( uCount ) );
|
|
/* check if valid initializers were used but don't generate any code */
|
|
pAssign = hb_compExprAssignStatic( pVar, pInitValue );
|
|
/* now pop an array */
|
|
hb_compExprGenPop( pVar );
|
|
/* delete all used expressions */
|
|
hb_compExprDelete( pAssign );
|
|
hb_compStaticDefEnd();
|
|
}
|
|
else
|
|
{
|
|
USHORT uCount = hb_compExprListLen( pInitValue );
|
|
|
|
hb_compVariableAdd( szName, 'A' );
|
|
hb_compExprDelete( hb_compExprGenPush( pInitValue ) );
|
|
hb_compGenPCode3( HB_P_ARRAYDIM, HB_LOBYTE( uCount ), HB_HIBYTE( uCount ) );
|
|
hb_compExprDelete( hb_compExprGenPop( hb_compExprNewVar( szName ) ) );
|
|
}
|
|
}
|
|
|