2024-11-05 16:34:07 -07:00
|
|
|
#pragma once
|
2010-07-27 15:41:25 -06:00
|
|
|
|
|
|
|
#include <inttypes.h>
|
2024-12-04 18:40:53 -07:00
|
|
|
#include <stdio.h>
|
2010-07-27 15:41:25 -06:00
|
|
|
|
|
|
|
#define MAX_TOKEN_LEN 20
|
|
|
|
#define MAX_CMDSTACK 200
|
|
|
|
|
|
|
|
struct forf_env;
|
|
|
|
|
|
|
|
enum forf_value_type {
|
|
|
|
forf_type_number,
|
|
|
|
forf_type_proc,
|
|
|
|
forf_type_stack_begin,
|
|
|
|
forf_type_stack_end,
|
|
|
|
};
|
|
|
|
|
|
|
|
enum forf_error_type {
|
|
|
|
forf_error_none,
|
|
|
|
forf_error_runtime,
|
|
|
|
forf_error_parse,
|
|
|
|
forf_error_underflow,
|
|
|
|
forf_error_overflow,
|
|
|
|
forf_error_type,
|
|
|
|
forf_error_noproc,
|
|
|
|
forf_error_divzero,
|
|
|
|
};
|
|
|
|
|
|
|
|
extern char *forf_error_str[];
|
|
|
|
|
2024-12-04 18:40:53 -07:00
|
|
|
typedef void(forf_proc)(struct forf_env *);
|
2010-07-27 15:41:25 -06:00
|
|
|
|
|
|
|
struct forf_value {
|
2024-12-04 18:40:53 -07:00
|
|
|
enum forf_value_type type;
|
2010-07-27 15:41:25 -06:00
|
|
|
union {
|
2024-12-04 18:40:53 -07:00
|
|
|
forf_proc *p;
|
|
|
|
long i;
|
2010-07-27 15:41:25 -06:00
|
|
|
} v;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct forf_stack {
|
2024-12-04 18:40:53 -07:00
|
|
|
size_t size;
|
|
|
|
size_t top;
|
2010-07-27 15:41:25 -06:00
|
|
|
struct forf_value *stack;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct forf_memory {
|
2024-12-04 18:40:53 -07:00
|
|
|
size_t size;
|
|
|
|
long *mem;
|
2010-07-27 15:41:25 -06:00
|
|
|
};
|
|
|
|
|
|
|
|
struct forf_lexical_env {
|
2024-12-04 18:40:53 -07:00
|
|
|
char *name;
|
2010-07-27 15:41:25 -06:00
|
|
|
forf_proc *proc;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct forf_env {
|
2024-12-04 18:40:53 -07:00
|
|
|
enum forf_error_type error;
|
2010-07-27 15:41:25 -06:00
|
|
|
struct forf_lexical_env *lenv;
|
2024-12-04 18:40:53 -07:00
|
|
|
struct forf_stack *data;
|
|
|
|
struct forf_stack *command;
|
|
|
|
struct forf_memory *memory;
|
|
|
|
void *udata;
|
2010-07-27 15:41:25 -06:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Main entry points
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
/** Initialize a memory structure, given an array of longs */
|
2024-12-04 18:40:53 -07:00
|
|
|
void forf_memory_init(struct forf_memory *m, long *values, size_t size);
|
2010-07-27 15:41:25 -06:00
|
|
|
|
|
|
|
/** Initialize a stack, given an array of values */
|
2024-12-04 18:40:53 -07:00
|
|
|
void forf_stack_init(struct forf_stack *s, struct forf_value *values,
|
|
|
|
size_t size);
|
2010-07-27 15:41:25 -06:00
|
|
|
|
|
|
|
void forf_stack_reset(struct forf_stack *s);
|
|
|
|
void forf_stack_copy(struct forf_stack *dst, struct forf_stack *src);
|
|
|
|
int forf_stack_push(struct forf_stack *s, struct forf_value *v);
|
|
|
|
int forf_stack_pop(struct forf_stack *s, struct forf_value *v);
|
|
|
|
|
|
|
|
/** Pop a number off the data stack */
|
|
|
|
long forf_pop_num(struct forf_env *env);
|
|
|
|
|
|
|
|
/** Push a number onto the data stack */
|
|
|
|
void forf_push_num(struct forf_env *env, long i);
|
|
|
|
|
|
|
|
/** Pop a whole stack */
|
|
|
|
struct forf_stack forf_pop_stack(struct forf_env *env);
|
|
|
|
|
|
|
|
/** The base lexical environment */
|
|
|
|
extern struct forf_lexical_env forf_base_lexical_env[];
|
|
|
|
|
|
|
|
/** Extend a lexical environment */
|
2024-12-04 18:40:53 -07:00
|
|
|
int forf_extend_lexical_env(struct forf_lexical_env *dest,
|
|
|
|
struct forf_lexical_env *src, size_t size);
|
2010-07-27 15:41:25 -06:00
|
|
|
|
|
|
|
/** Initialize a forf runtime environment.
|
|
|
|
*
|
|
|
|
* data, cmd, and mem should have already been initialized
|
|
|
|
*/
|
2024-12-04 18:40:53 -07:00
|
|
|
void forf_env_init(struct forf_env *env, struct forf_lexical_env *lenv,
|
|
|
|
struct forf_stack *data, struct forf_stack *cmd,
|
|
|
|
struct forf_memory *mem, void *udata);
|
2010-07-27 15:41:25 -06:00
|
|
|
|
|
|
|
/** The type of a getch function (used for parsing) */
|
2024-12-04 18:40:53 -07:00
|
|
|
typedef int(forf_getch_func)(void *);
|
2010-07-27 15:41:25 -06:00
|
|
|
|
|
|
|
/** Parse something by calling getch(datum)
|
|
|
|
*
|
|
|
|
* Returns the character at which an error was encountered, or
|
|
|
|
* 0 for successful parse.
|
|
|
|
*/
|
2024-12-04 18:40:53 -07:00
|
|
|
int forf_parse_stream(struct forf_env *env, forf_getch_func *getch,
|
|
|
|
void *datum);
|
2010-07-27 15:41:25 -06:00
|
|
|
|
|
|
|
/** Parse a buffer */
|
2024-12-04 18:40:53 -07:00
|
|
|
int forf_parse_buffer(struct forf_env *env, char *buf, size_t len);
|
2010-07-27 15:41:25 -06:00
|
|
|
|
|
|
|
/** Parse a string */
|
2024-12-04 18:40:53 -07:00
|
|
|
int forf_parse_string(struct forf_env *env, char *str);
|
2010-07-27 15:41:25 -06:00
|
|
|
|
|
|
|
/** Parse a FILE * */
|
2024-12-04 18:40:53 -07:00
|
|
|
int forf_parse_file(struct forf_env *env, FILE *f);
|
2010-07-27 15:41:25 -06:00
|
|
|
|
|
|
|
/** Evaluate the topmost value on the command stack */
|
|
|
|
int forf_eval_once(struct forf_env *env);
|
|
|
|
|
|
|
|
/** Evaluate the entire command stack */
|
|
|
|
int forf_eval(struct forf_env *env);
|