Neale Pickett
·
2024-12-04
forf.h
1#pragma once
2
3#include <inttypes.h>
4#include <stdio.h>
5
6#define MAX_TOKEN_LEN 20
7#define MAX_CMDSTACK 200
8
9struct forf_env;
10
11enum forf_value_type {
12 forf_type_number,
13 forf_type_proc,
14 forf_type_stack_begin,
15 forf_type_stack_end,
16};
17
18enum forf_error_type {
19 forf_error_none,
20 forf_error_runtime,
21 forf_error_parse,
22 forf_error_underflow,
23 forf_error_overflow,
24 forf_error_type,
25 forf_error_noproc,
26 forf_error_divzero,
27};
28
29extern char *forf_error_str[];
30
31typedef void(forf_proc)(struct forf_env *);
32
33struct forf_value {
34 enum forf_value_type type;
35 union {
36 forf_proc *p;
37 long i;
38 } v;
39};
40
41struct forf_stack {
42 size_t size;
43 size_t top;
44 struct forf_value *stack;
45};
46
47struct forf_memory {
48 size_t size;
49 long *mem;
50};
51
52struct forf_lexical_env {
53 char *name;
54 forf_proc *proc;
55};
56
57struct forf_env {
58 enum forf_error_type error;
59 struct forf_lexical_env *lenv;
60 struct forf_stack *data;
61 struct forf_stack *command;
62 struct forf_memory *memory;
63 void *udata;
64};
65
66/*
67 *
68 * Main entry points
69 *
70 */
71
72/** Initialize a memory structure, given an array of longs */
73void forf_memory_init(struct forf_memory *m, long *values, size_t size);
74
75/** Initialize a stack, given an array of values */
76void forf_stack_init(struct forf_stack *s, struct forf_value *values,
77 size_t size);
78
79void forf_stack_reset(struct forf_stack *s);
80void forf_stack_copy(struct forf_stack *dst, struct forf_stack *src);
81int forf_stack_push(struct forf_stack *s, struct forf_value *v);
82int forf_stack_pop(struct forf_stack *s, struct forf_value *v);
83
84/** Pop a number off the data stack */
85long forf_pop_num(struct forf_env *env);
86
87/** Push a number onto the data stack */
88void forf_push_num(struct forf_env *env, long i);
89
90/** Pop a whole stack */
91struct forf_stack forf_pop_stack(struct forf_env *env);
92
93/** The base lexical environment */
94extern struct forf_lexical_env forf_base_lexical_env[];
95
96/** Extend a lexical environment */
97int forf_extend_lexical_env(struct forf_lexical_env *dest,
98 struct forf_lexical_env *src, size_t size);
99
100/** Initialize a forf runtime environment.
101 *
102 * data, cmd, and mem should have already been initialized
103 */
104void forf_env_init(struct forf_env *env, struct forf_lexical_env *lenv,
105 struct forf_stack *data, struct forf_stack *cmd,
106 struct forf_memory *mem, void *udata);
107
108/** The type of a getch function (used for parsing) */
109typedef int(forf_getch_func)(void *);
110
111/** Parse something by calling getch(datum)
112 *
113 * Returns the character at which an error was encountered, or
114 * 0 for successful parse.
115 */
116int forf_parse_stream(struct forf_env *env, forf_getch_func *getch,
117 void *datum);
118
119/** Parse a buffer */
120int forf_parse_buffer(struct forf_env *env, char *buf, size_t len);
121
122/** Parse a string */
123int forf_parse_string(struct forf_env *env, char *str);
124
125/** Parse a FILE * */
126int forf_parse_file(struct forf_env *env, FILE *f);
127
128/** Evaluate the topmost value on the command stack */
129int forf_eval_once(struct forf_env *env);
130
131/** Evaluate the entire command stack */
132int forf_eval(struct forf_env *env);