The RPCL API #
The RPCL Datatype #
A RPCL datatype holds argc
and argv
as specified by RPCL* RPCLCreate(int argc, char** argv)
,
its dictionary skip list and its stack:
typedef struct rpcl_struct {
int argc;
char** argv;
SL* dictionary;
struct rpcl_stack s;
uint32_t exec_depth;
uint32_t eval_counter;
time_t startup_time;
void (*exithook)(void);
} RPCL;
Additionally, exec_depth
monitors the execution stack, eval_counter
is for (endless) loop detection and
the time_t
startup_time is set at start. void (*exithook)(void)
allows to do something at the very end (if
not NULL
).
The Stacks #
The Data Stack #
struct rpcl_stack {
char stack[RPCLSTACKDEPTH][RPCLWORDLEN];
int sp;
};
The Execution Stack #
The execution stack is represented by the underlying CPU stack, the interpreter keeps track of nested calls and signals an error when a threshold overflows.
API Functions #
Managing the Interpreter #
RPCL* RPCLCreate(int argc, char** argv);
void RPCLDestroy(RPCL * rpcl);
void RPCLMainLoop(RPCL * rpcl);
RPCL_OK and RPCL_ERROR #
#define RPCL_OK 0
#define RPCL_ERROR -1
Registering a Function #
void RPCLRegister(RPCL * rpcl, char* key_string,
char* value_string, int (*function)(RPCL * rpcl));
void RPCLRegisterCompound(RPCL * rpcl, char* key_string, char* value_string,
int (*function)(RPCL * rpcl));
Evaluating #
int RPCLEvalLine(RPCL * rpcl, char* line);
int RPCLEvalToken(RPCL * rpcl, char* token);
The macro RPCLEvalLineF
allows printf()
-style formatting of a line to
be evaluated:
int RPCLEvalLineF(RPCL * rpcl, const char *restrict format, ...);
Converting a 0-Terminated char*
to a RPCLWORD
#
void RPCLPrepareWord(char* string, RPCLWORD result);
Processing the “arbitrary data” Interpretation of an RPCLWORD #
void RPCLPrepareData(uint8_t* data, int len, RPCLWORD result);
int RPCLIsData(RPCLWORD word);
int RPCLDataLength(RPCLWORD word);
uint8_t* RPCLData(RPCLWORD word);
Stack Frame Delimiter (SFD) Functions #
void RPCLPrepareSFD(RPCLWORD result);
int RPCLIsSFD(RPCLWORD word);
int RPCLPopSFD(RPCL * rpcl);
int RPCLPushSFD(RPCL * rpcl);
Push and Pop #
Both functions return either RPCL_OK
or RPCL_ERROR
. A function registered
with RPCLRegister()
should also immediately return RPCL_ERROR
in case
that RPCLPush()
or RPCLPop()
are failing.
int RPCLPush(RPCL * rpcl, RPCLWORD word);
int RPCLPop(RPCL * rpcl, RPCLWORD result);
An Example: RPCLInternalPlus()
#
|
|
This is how RPCLInternalPlus()
is registered as the built-in RPCL word +
:
RPCLRegister(rpcl, "+", "sum of two values ( n1 n2 - sum )", RPCLInternalPlus);
The RPCL Shell rpclsh
#
These few lines implement the RPCL shell (rpclsh
):
|
|