The RPCL API

 

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;
} RPCL;

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));

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);

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() #

 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
int RPCLInternalPlus(RPCL * rpcl) {

  int rc;

  RPCLWORD s1;
  RPCLWORD s2;
  RPCLWORD result;

  uint8_t buffer[RPCLWORDLEN];

  rc = RPCLPop(rpcl, s2);
  if (rc != RPCL_OK) {
    return (rc);
  }

  rc = RPCLPop(rpcl, s1);
  if (rc != RPCL_OK) {
    return (rc);
  }

  sprintf(buffer, "%lld", atoll(s1) + atoll(s2));

  RPCLPrepareWord(buffer, result);
  return (RPCLPush(rpcl, result));
}

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):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <rpcl.h>

int main(int argc, char** argv) {

  RPCL* rpcl;

  rpcl = RPCLCreate(argc, argv);
  RPCLMainLoop(rpcl);
  RPCLDestroy(rpcl);

  exit(EXIT_SUCCESS);
}