File: pf_cglue.c

package info (click to toggle)
pforth 21-6
  • links: PTS
  • area: main
  • in suites: potato
  • size: 816 kB
  • ctags: 873
  • sloc: ansic: 5,050; makefile: 104
file content (108 lines) | stat: -rw-r--r-- 2,936 bytes parent folder | download | duplicates (5)
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