1 /* yForth? - Written by Luca Padovani (C) 1996/97
2 * ------------------------------------------------------------------------
3 * This software is FreeWare as long as it comes with this header in each
4 * source file, anyway you can use it or any part of it whatever
5 * you want. It comes without any warranty, so use it at your own risk.
6 * ------------------------------------------------------------------------
7 * Module name: locals.c
8 * Abstract: locals word set
11 /* Implementation notes
12 * Local variables make use of the register "bp" of the Virtual Machine,
13 * which stores the location, wihtin the return stack, of the first
14 * local variable. All references to local variables are made relative
15 * to this register. This implies that "bp" must be saved between calls of
16 * words that make use of local variables, and every "exiting word" that
17 * make a word terminate must reset it.
18 * This is achieved by an auxiliary variable, called "local_defined", set
19 * to 1 inside a colon definition when local variables are used.
20 * Local names are stored dinamically by allocating a structure "word_def"
21 * for any name. The function which searches the vocabulary for a particular
22 * word has been modified accordingly so that the first try is always made
23 * in this dynamic vocabulary, pointed by "first_local".
32 /**************************************************************************/
33 /* VARIABLES **************************************************************/
34 /**************************************************************************/
36 static struct word_def *first_local;
37 static unsigned int local_defined;
39 /**************************************************************************/
40 /* WORDS ******************************************************************/
41 /**************************************************************************/
43 void _paren_local_paren() {
44 register UCell u = (UCell) *sp++;
45 register Char *s = (Char *) *sp++;
49 /* restore "bp" register from return stack */
50 void _paren_bp_restore_paren() {
55 /* save "bp" register on return stack */
56 void _paren_bp_save_paren() {
61 /* push on the data stack the value of i-th local variable, where i is the
62 * Cell value pointed to by "ip" when "_paren_read_local_paren" is called.
64 void _paren_read_local_paren() {
65 register UCell offset = (UCell) *ip++;
66 *--sp = *(bp - offset);
69 /* update the i-th local variable with the Cell value on the data stack.
70 * See "_paren_read_local_paren" for a comment about the value "i"
72 void _paren_write_local_paren() {
73 register UCell offset = (UCell) *ip++;
74 *(bp - offset) = *sp++;
77 /**************************************************************************/
78 /* AUXILIARY FUNCTIONS ****************************************************/
79 /**************************************************************************/
81 /* clear_locals: called inside the compilation of a colon definition to
82 * compile the code that restore "bp" and free the dynamic vocabulary of
87 compile_cell((Cell) _paren_bp_restore_paren);
88 compile_cell((Cell) local_defined); /* # di variabili locali */
94 /* free_locals: release the dynamic vocabulary. Called by "clear_locals". */
96 register struct word_def *p = first_local, *p1;
109 /* declare_local: declare a new local variable. If it's the first local
110 * variable for the current colon definition, compile the code to save
113 void declare_local(Char *s, UCell u) {
114 struct word_def *p = (struct word_def *) malloc(sizeof(struct word_def));
116 p->name = (Char *) malloc(u + 1);
118 p->name[0] = (Char) u;
119 memcpy(p->name + 1, s, u);
120 p->link = first_local;
122 p->func[0] = (pfp) (local_defined++);
123 if (!first_local) compile_cell((Cell) _paren_bp_save_paren);
129 /* get_first_local: interface function that returns a pointer to the first
130 * local name defined (actually is the last name, since names are stored
131 * in reverse order for efficiency, but this doesn't matter)
133 struct word_def *get_first_local() {
134 return (first_local);
137 /* locals_defined: interface function that returns true if current word
138 * has some local name defined
140 int locals_defined() {
141 return (local_defined);