1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
|
/* @(#) pf_cglue.c 98/02/11 1.4 */
/***************************************************************
** 'C' Glue support for Forth based on 'C'
**
** Author: Phil Burk
** Copyright 1994 3DO, Phil Burk, Larry Polansky, Devid Rosenboom
**
** The pForth software code is dedicated to the public domain,
** and any third party may reproduce, distribute and modify
** the pForth software code or any derivative works thereof
** without any compensation or license. The pForth software
** code is provided on an "as is" basis without any warranty
** of any kind, including, without limitation, the implied
** warranties of merchantability and fitness for a particular
** purpose and their equivalents under the laws of any jurisdiction.
**
***************************************************************/
#include "pf_all.h"
typedef cell (*CFunc0)( void );
typedef cell (*CFunc1)( cell P1 );
typedef cell (*CFunc2)( cell P1, cell P2 );
typedef cell (*CFunc3)( cell P1, cell P2, cell P3 );
typedef cell (*CFunc4)( cell P1, cell P2, cell P3, cell P4 );
typedef cell (*CFunc5)( cell P1, cell P2, cell P3, cell P4, cell P5 );
extern void *CustomFunctionTable[];
/***************************************************************/
int32 CallUserFunction( int32 Index, int32 ReturnMode, int32 NumParams )
{
cell P1, P2, P3, P4, P5;
cell Result = 0;
void *CF;
DBUG(("CallUserFunction: Index = %d, ReturnMode = %d, NumParams = %d\n",
Index, ReturnMode, NumParams ));
CF = CustomFunctionTable[Index];
switch( NumParams )
{
case 0:
Result = ((CFunc0) CF) ( );
break;
case 1:
P1 = POP_DATA_STACK;
Result = ((CFunc1) CF) ( P1 );
break;
case 2:
P2 = POP_DATA_STACK;
P1 = POP_DATA_STACK;
Result = ((CFunc2) CF) ( P1, P2 );
break;
case 3:
P3 = POP_DATA_STACK;
P2 = POP_DATA_STACK;
P1 = POP_DATA_STACK;
Result = ((CFunc3) CF) ( P1, P2, P3 );
break;
case 4:
P4 = POP_DATA_STACK;
P3 = POP_DATA_STACK;
P2 = POP_DATA_STACK;
P1 = POP_DATA_STACK;
Result = ((CFunc4) CF) ( P1, P2, P3, P4 );
break;
case 5:
P5 = POP_DATA_STACK;
P4 = POP_DATA_STACK;
P3 = POP_DATA_STACK;
P2 = POP_DATA_STACK;
P1 = POP_DATA_STACK;
Result = ((CFunc5) CF) ( P1, P2, P3, P4, P5 );
break;
default:
pfReportError("CallUserFunction", PF_ERR_NUM_PARAMS);
EXIT(1);
}
/* Push result on Forth stack if requested. */
if(ReturnMode == C_RETURNS_VALUE) PUSH_DATA_STACK( Result );
return Result;
}
#if (!defined(PF_NO_INIT)) && (!defined(PF_NO_SHELL))
/***************************************************************/
Err CreateGlueToC( const char *CName, uint32 Index, int32 ReturnMode, int32 NumParams )
{
uint32 Packed;
char FName[40];
CStringToForth( FName, CName );
Packed = (Index & 0xFFFF) | 0 | (NumParams << 24) |
(ReturnMode << 31);
DBUG(("Packed = 0x%8x\n", Packed));
ffCreateSecondaryHeader( FName );
CODE_COMMA( ID_CALL_C );
CODE_COMMA(Packed);
ffFinishSecondary();
return 0;
}
#endif
|