/* * Pure Data Packet header file. Packet processor system * Copyright (c) by Tom Schouten * * 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. * */ /** * @file forth.h * @brief Packet Forth * * This file contains the c interface to the forth virtual machine. * See pf_vm for data slots. */ #ifndef __PF_PROCESSOR__ #define __PF_PROCESSOR__ #include // these are for inlined functions #include #include #include #include #define PF_FORTH_ATOM_FLAG_WRITABLE (1<<0) ///< the atom is writable #define PF_FORTH_VM_FLAG_NOTAILCALL (1<<1) ///< disable tail call opti for this instruction #define PF_FORTH_VM_FLAG_VERBOSE (1<<2) ///< be verbose /** * \brief Forth virtual machine * * Contains all context data for a running Forth VM. See forth.h for method info. */ struct pf_vm { pf_stack_t *data_stack; ///< data stack pf_stack_t *return_stack; ///< return stack pf_atom_t *current; ///< current word pf_atom_t *ip; ///< next instruction in thread pf_stack_t *allot_stack; ///< allot stack / dictionary pf_atom_t *abort; ///< contains abort xt int state; ///< compile/interpret state /* xt cache */ pf_atom_t *xt_comma; pf_atom_t *xt_execute; pf_atom_t *xt_leave; pf_atom_t *xt_lit; pf_atom_t *xt_do_pass; }; pf_vm_t *pf_forth_vm(void); ///< get global forth vm /** * Initialize a forth vm */ void pf_vm_init(pf_vm_t *vm); ///< the vm structure pf_vm_t * pf_vm_new(void); void pf_vm_free(pf_vm_t *vm); /** * De-initialize a forth vm */ void pf_vm_cleanup(pf_vm_t *vm); /** * Global exit with cleanup */ void pf_exit_program(int exitcode); /** * Hard reset a forth vm. Resulting state is the same * as after a pf_vm_init(). */ void pf_vm_reset(pf_vm_t *vm); /** * Soft reset a forth vm. This leaves everything except * the return stack and instruction pointer intact. The machine * will be in a halted state after calling this. */ void pf_vm_softreset(pf_vm_t *vm); /* the pf_vm_call_* routines CALL the interpreter. in short: if the vm is not idle (vm->ip == vm->reset) the context is saved and restored afterwards. this is in order to enable C stack recursion. to RESUME you can call pf_vm_resume() */ /** * Initialize PF */ pf_error_t pf_init(int argc, char **argv); /** * Resume forth vm (yield to forth). This singlesteps * the vm until an unrecoverable (uncaucht) error occurs, * or until the halt (e_idle). */ pf_error_t pf_vm_resume(pf_vm_t *vm); /** * Throw a highlevel error from primitive. */ pf_error_t pf_vm_throw_trampoline(pf_vm_t *vm, pf_error_t e, pf_packet_t infostring); /** * Map a symbol to a link using vm's link list. */ pf_list_t * pf_vm_lookup_link (pf_vm_t *vm, pf_symbol_t *symbol); /** * Map a symbol to an xt */ pf_atom_t * pf_vm_find (pf_vm_t *vm, pf_symbol_t *symbol); /** * Add a primitive to dictionary. */ pf_list_t * pf_vm_add_primitive(pf_vm_t *vm, pf_symbol_t *symbol, pf_forth_primitive_t word); /** * Move an atom to dictionary compilation point. */ void pf_vm_comma_atom(pf_vm_t *vm, pf_atom_t *a); /** * Add a word to dictionary compilation point. */ void pf_vm_comma(pf_vm_t *vm, pf_word_type_t t, pf_word_t w); /** * Convenience macro for defining a forth primitive * s: data stack, vm: virtual machine instance */ #define PF_PRIMITIVE(word) pf_error_t word (pf_stack_t *s, pf_vm_t *vm) /** * Convenience macro for executing a forth word inside the def * of another forth word, passing along the arguments. Note, this * is actually a hack to be able to nest primitives in C code. It * is definitely not the same as executing threaded code. */ #define PF_EXEC_PRIMITIVE(word) word (vm->data_stack, vm) #endif