aboutsummaryrefslogtreecommitdiff
path: root/include/pdp_forth.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/pdp_forth.h')
-rw-r--r--include/pdp_forth.h192
1 files changed, 192 insertions, 0 deletions
diff --git a/include/pdp_forth.h b/include/pdp_forth.h
new file mode 100644
index 0000000..a53291f
--- /dev/null
+++ b/include/pdp_forth.h
@@ -0,0 +1,192 @@
+/*
+ * Pure Data Packet header file. Packet processor system
+ * Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __PDP_PROCESSOR__
+#define __PDP_PROCESSOR__
+
+#include "pdp_list.h"
+
+/*
+
+*/
+
+
+/*
+ PDP Processor Model
+
+ The model consists of two parts.
+
+ One being the forth system to provide a lowish level description of packet operations,
+ with a form of polymorphy that enables the system to call the right routines or
+ provide automatic conversion of packet types.
+
+ Two being the object description language. It describes processors in terms of packet
+ operations. In fact it is a forth process that sets up the input and output of the
+ processors, and organizes the local storage into registers.
+
+*/
+
+
+/* PDP FORTH (low level stack processors) */
+
+/* the error codes for a processor word */
+typedef enum {
+ e_ok = 0,
+ e_type, // a recoverable type error (stack untouched)
+ e_garbled, // a non recoverable error (stack messed up)
+ e_underflow, // a stack underflow error
+ e_undef, // an undefined word error
+ e_internal // an internal error (abort)
+} t_pdp_word_error;
+
+typedef struct _pdp_list t_pdp_stack;
+
+/* a pdp word operates on a stack containing atoms (floats, ints, symbols, packets)
+ it should return zero on success and an error value on failure.
+ whenever a (type) error occurs, the stack should be left untouched (this ensures the system
+ can try another implementation of the same word.
+
+ the type of the first packet on the stack determines the 'type' of the processor method.
+ this poses a problem for generating words (i.e pdp_noise or pdp_plasma). in that case
+ the first word should be a symbol, indicating the type. if the first item is neither
+ a symbol or a packet, the first word in the word list for the respective word symbol
+ is called.
+
+ words cannot be removed from the symbol table. (because compiled scripts will have
+ their addresses stored) however, they can be redefined, since new definitions are
+ appended to the start of a word list, and upon execution, the first (type) matching word
+ is called.
+
+ words can be accessed in two ways:
+ * the central dispatching system, which chooses a word based on it's symbol and
+ the first item on the stack (a packet's class (or unique type description) or
+ a symbol describing a type)
+ * by calling it's code directly. this can be used to optimize (compile) scripts.
+
+ a word may place invalid packets (-1) on the stack and must be robust at receiving
+ them. this is a way to silently recover from non fatal errors.
+
+ a stack error is always fatal and should abort execution. (e_garbled)
+
+*/
+
+typedef int (*t_pdp_forthword)(t_pdp_stack *);
+
+
+/* a dictionary item is the definition of a word.
+ if a word is type oblivious, it is a high level word, which means it can operate on any type */
+
+
+/* a struct describing a forth word implementation */
+typedef struct _pdp_forthword_imp
+{
+ struct _pdp_symbol *name; // the name of this word
+ struct _pdp_list *def; // the word definition with symbols (word or immediate symbol),
+ // pointer (primitive word) or int, float and packet immediates.
+ struct _pdp_symbol *type; // the type template this low level word operates on (0 == high level word)
+} t_pdp_forthword_imp;
+
+/* a struct describing a forth word specification
+ one specification can have multiple implementations (for type multiplexing) */
+typedef struct _pdp_forthword_spec
+{
+ /* name of this forth word */
+ struct _pdp_symbol *name;
+
+ /* stack effect */
+ int input_size;
+ int output_size;
+
+ /* index of the stack element to be used for implementation
+ multiplexing based on the implementation type template */
+ int type_index;
+
+ /* a list of implementations for this word */
+ t_pdp_list *implementations;
+
+} t_pdp_forthword_spec;
+
+
+
+/* compile a string definition to a list definition */
+t_pdp_list *pdp_forth_compile_def(char *chardef);
+
+
+/* add words to the forth dictionary
+ if the word is type oblivious, the type index should be -1 and the type symbol NULL */
+void pdp_forthdict_add_word(t_pdp_symbol *name, t_pdp_list *def, int input_size, int output_size,
+ int type_index, t_pdp_symbol *type);
+void pdp_forthdict_add_primitive(t_pdp_symbol *name, t_pdp_forthword w,int input_size, int output_size,
+ int type_index, t_pdp_symbol *type);
+void pdp_forthdict_compile_word(t_pdp_symbol *name, char *chardef, int input_size, int output_size,
+ int type_index, t_pdp_symbol *type);
+
+
+
+/* execute a word definition (a program) or a single symbolic word */
+t_pdp_word_error pdp_forth_execute_def(t_pdp_stack *stack, t_pdp_list *def);
+t_pdp_word_error pdp_forth_execute_word(t_pdp_stack *stack, t_pdp_symbol *word);
+
+
+/* PDP PDL (high level processor description language) */
+
+/* this uses the forth words to describe a processor: defining inputs and outputs,
+ preparing the stack, storing intermediates, .. */
+
+/* TODO */
+
+
+void pdp_forth_word_print_debug(t_pdp_symbol *s);
+
+
+
+
+
+/* STACK OPERATIONS */
+
+
+/* connecting the stack to the world */
+t_pdp_word_error pdp_stack_push_float(t_pdp_stack *, float f); // push thing to tos
+t_pdp_word_error pdp_stack_push_int(t_pdp_stack *s, int i);
+t_pdp_word_error pdp_stack_push_symbol(t_pdp_stack *s, t_pdp_symbol *x);
+t_pdp_word_error pdp_stack_push_packet(t_pdp_stack *s, int p);
+
+t_pdp_word_error pdp_stack_pop_float(t_pdp_stack *, float *f); // pop thing from tos
+t_pdp_word_error pdp_stack_pop_int(t_pdp_stack *, int *i);
+t_pdp_word_error pdp_stack_pop_symbol(t_pdp_stack *, t_pdp_symbol **s);
+t_pdp_word_error pdp_stack_pop_packet(t_pdp_stack *, int *p);
+
+
+/* stack operations */
+
+// DUP SWAP DROP OVER ...
+t_pdp_word_error pdp_stack_dup(t_pdp_stack *s);
+t_pdp_word_error pdp_stack_swap(t_pdp_stack *s);
+t_pdp_word_error pdp_stack_drop(t_pdp_stack *s);
+t_pdp_word_error pdp_stack_over(t_pdp_stack *s);
+
+
+/* some util stuff */
+t_pdp_stack *pdp_stack_new(void);
+void pdp_stack_free(t_pdp_stack *s);
+
+
+
+#endif