Deleted Added
full compact
prefix.c (94290) prefix.c (102657)
1/*******************************************************************
2** p r e f i x . c
3** Forth Inspired Command Language
4** Parser extensions for Ficl
5** Authors: Larry Hastings & John Sadler (john_sadler@alum.mit.edu)
6** Created: April 2001
7** $Id: prefix.c,v 1.6 2001/12/05 07:21:34 jsadler Exp $
8*******************************************************************/
9/*
10** Copyright (c) 1997-2001 John Sadler (john_sadler@alum.mit.edu)
11** All rights reserved.
12**
13** Get the latest Ficl release at http://ficl.sourceforge.net
14**
15** I am interested in hearing from anyone who uses ficl. If you have
16** a problem, a success story, a defect, an enhancement request, or
17** if you would like to contribute to the ficl release, please
18** contact me by email at the address above.
19**
20** L I C E N S E and D I S C L A I M E R
21**
22** Redistribution and use in source and binary forms, with or without
23** modification, are permitted provided that the following conditions
24** are met:
25** 1. Redistributions of source code must retain the above copyright
26** notice, this list of conditions and the following disclaimer.
27** 2. Redistributions in binary form must reproduce the above copyright
28** notice, this list of conditions and the following disclaimer in the
29** documentation and/or other materials provided with the distribution.
30**
31** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
32** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
35** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
39** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
40** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
41** SUCH DAMAGE.
42*/
43
1/*******************************************************************
2** p r e f i x . c
3** Forth Inspired Command Language
4** Parser extensions for Ficl
5** Authors: Larry Hastings & John Sadler (john_sadler@alum.mit.edu)
6** Created: April 2001
7** $Id: prefix.c,v 1.6 2001/12/05 07:21:34 jsadler Exp $
8*******************************************************************/
9/*
10** Copyright (c) 1997-2001 John Sadler (john_sadler@alum.mit.edu)
11** All rights reserved.
12**
13** Get the latest Ficl release at http://ficl.sourceforge.net
14**
15** I am interested in hearing from anyone who uses ficl. If you have
16** a problem, a success story, a defect, an enhancement request, or
17** if you would like to contribute to the ficl release, please
18** contact me by email at the address above.
19**
20** L I C E N S E and D I S C L A I M E R
21**
22** Redistribution and use in source and binary forms, with or without
23** modification, are permitted provided that the following conditions
24** are met:
25** 1. Redistributions of source code must retain the above copyright
26** notice, this list of conditions and the following disclaimer.
27** 2. Redistributions in binary form must reproduce the above copyright
28** notice, this list of conditions and the following disclaimer in the
29** documentation and/or other materials provided with the distribution.
30**
31** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
32** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
35** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
39** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
40** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
41** SUCH DAMAGE.
42*/
43
44/* $FreeBSD: head/sys/boot/ficl/prefix.c 94290 2002-04-09 17:45:28Z dcs $ */
44/* $FreeBSD: head/sys/boot/ficl/prefix.c 102657 2002-08-31 01:04:53Z scottl $ */
45
46#include <string.h>
47#include <ctype.h>
48#include "ficl.h"
49#include "math64.h"
50
51/*
52** (jws) revisions:
53** A prefix is a word in a dedicated wordlist (name stored in list_name below)
54** that is searched in a special way by the prefix parse step. When a prefix
55** matches the beginning of an incoming token, push the non-prefix part of the
56** token back onto the input stream and execute the prefix code.
57**
58** The parse step is called ficlParsePrefix.
59** Storing prefix entries in the dictionary greatly simplifies
60** the process of matching and dispatching prefixes, avoids the
61** need to clean up a dynamically allocated prefix list when the system
62** goes away, but still allows prefixes to be allocated at runtime.
63*/
64
65static char list_name[] = "<prefixes>";
66
67/**************************************************************************
68 f i c l P a r s e P r e f i x
69** This is the parse step for prefixes - it checks an incoming word
70** to see if it starts with a prefix, and if so runs the corrseponding
71** code against the remainder of the word and returns true.
72**************************************************************************/
73int ficlParsePrefix(FICL_VM *pVM, STRINGINFO si)
74{
75 int i;
76 FICL_HASH *pHash;
77 FICL_WORD *pFW = ficlLookup(pVM->pSys, list_name);
78
79 /*
80 ** Make sure we found the prefix dictionary - otherwise silently fail
81 ** If forth-wordlist is not in the search order, we won't find the prefixes.
82 */
83 if (!pFW)
84 return FICL_FALSE;
85
86 pHash = (FICL_HASH *)(pFW->param[0].p);
87 /*
88 ** Walk the list looking for a match with the beginning of the incoming token
89 */
90 for (i = 0; i < (int)pHash->size; i++)
91 {
92 pFW = pHash->table[i];
93 while (pFW != NULL)
94 {
95 int n;
96 n = pFW->nName;
97 /*
98 ** If we find a match, adjust the TIB to give back the non-prefix characters
99 ** and execute the prefix word.
100 */
101 if (!strincmp(SI_PTR(si), pFW->name, (FICL_UNS)n))
102 {
103 /* (sadler) fixed off-by-one error when the token has no trailing space in the TIB */
104 vmSetTibIndex(pVM, si.cp + n - pVM->tib.cp );
105 vmExecute(pVM, pFW);
106
45
46#include <string.h>
47#include <ctype.h>
48#include "ficl.h"
49#include "math64.h"
50
51/*
52** (jws) revisions:
53** A prefix is a word in a dedicated wordlist (name stored in list_name below)
54** that is searched in a special way by the prefix parse step. When a prefix
55** matches the beginning of an incoming token, push the non-prefix part of the
56** token back onto the input stream and execute the prefix code.
57**
58** The parse step is called ficlParsePrefix.
59** Storing prefix entries in the dictionary greatly simplifies
60** the process of matching and dispatching prefixes, avoids the
61** need to clean up a dynamically allocated prefix list when the system
62** goes away, but still allows prefixes to be allocated at runtime.
63*/
64
65static char list_name[] = "<prefixes>";
66
67/**************************************************************************
68 f i c l P a r s e P r e f i x
69** This is the parse step for prefixes - it checks an incoming word
70** to see if it starts with a prefix, and if so runs the corrseponding
71** code against the remainder of the word and returns true.
72**************************************************************************/
73int ficlParsePrefix(FICL_VM *pVM, STRINGINFO si)
74{
75 int i;
76 FICL_HASH *pHash;
77 FICL_WORD *pFW = ficlLookup(pVM->pSys, list_name);
78
79 /*
80 ** Make sure we found the prefix dictionary - otherwise silently fail
81 ** If forth-wordlist is not in the search order, we won't find the prefixes.
82 */
83 if (!pFW)
84 return FICL_FALSE;
85
86 pHash = (FICL_HASH *)(pFW->param[0].p);
87 /*
88 ** Walk the list looking for a match with the beginning of the incoming token
89 */
90 for (i = 0; i < (int)pHash->size; i++)
91 {
92 pFW = pHash->table[i];
93 while (pFW != NULL)
94 {
95 int n;
96 n = pFW->nName;
97 /*
98 ** If we find a match, adjust the TIB to give back the non-prefix characters
99 ** and execute the prefix word.
100 */
101 if (!strincmp(SI_PTR(si), pFW->name, (FICL_UNS)n))
102 {
103 /* (sadler) fixed off-by-one error when the token has no trailing space in the TIB */
104 vmSetTibIndex(pVM, si.cp + n - pVM->tib.cp );
105 vmExecute(pVM, pFW);
106
107 return FICL_TRUE;
107 return (int)FICL_TRUE;
108 }
109 pFW = pFW->link;
110 }
111 }
112
113 return FICL_FALSE;
114}
115
116
117static void tempBase(FICL_VM *pVM, int base)
118{
119 int oldbase = pVM->base;
120 STRINGINFO si = vmGetWord0(pVM);
121
122 pVM->base = base;
123 if (!ficlParseNumber(pVM, si))
124 {
125 int i = SI_COUNT(si);
126 vmThrowErr(pVM, "%.*s not recognized", i, SI_PTR(si));
127 }
128
129 pVM->base = oldbase;
130 return;
131}
132
133static void fTempBase(FICL_VM *pVM)
134{
135 int base = stackPopINT(pVM->pStack);
136 tempBase(pVM, base);
137 return;
138}
139
140static void prefixHex(FICL_VM *pVM)
141{
142 tempBase(pVM, 16);
143}
144
145static void prefixTen(FICL_VM *pVM)
146{
147 tempBase(pVM, 10);
148}
149
150
151/**************************************************************************
152 f i c l C o m p i l e P r e f i x
153** Build prefix support into the dictionary and the parser
154** Note: since prefixes always execute, they are effectively IMMEDIATE.
155** If they need to generate code in compile state you must add
156** this code explicitly.
157**************************************************************************/
158void ficlCompilePrefix(FICL_SYSTEM *pSys)
159{
160 FICL_DICT *dp = pSys->dp;
161 FICL_HASH *pHash;
162 FICL_HASH *pPrevCompile = dp->pCompile;
163#if (FICL_EXTENDED_PREFIX)
164 FICL_WORD *pFW;
165#endif
166
167 /*
168 ** Create a named wordlist for prefixes to reside in...
169 ** Since we're doing a special kind of search, make it
170 ** a single bucket hashtable - hashing does not help here.
171 */
172 pHash = dictCreateWordlist(dp, 1);
173 pHash->name = list_name;
174 dictAppendWord(dp, list_name, constantParen, FW_DEFAULT);
175 dictAppendCell(dp, LVALUEtoCELL(pHash));
176
177 /*
178 ** Put __tempbase in the forth-wordlist
179 */
180 dictAppendWord(dp, "__tempbase", fTempBase, FW_DEFAULT);
181
182 /*
183 ** Temporarily make the prefix list the compile wordlist so that
184 ** we can create some precompiled prefixes.
185 */
186 dp->pCompile = pHash;
187 dictAppendWord(dp, "0x", prefixHex, FW_DEFAULT);
188 dictAppendWord(dp, "0d", prefixTen, FW_DEFAULT);
189#if (FICL_EXTENDED_PREFIX)
190 pFW = ficlLookup(pSys, "\\");
191 if (pFW)
192 {
193 dictAppendWord(dp, "//", pFW->code, FW_DEFAULT);
194 }
195#endif
196 dp->pCompile = pPrevCompile;
197
198 return;
199}
108 }
109 pFW = pFW->link;
110 }
111 }
112
113 return FICL_FALSE;
114}
115
116
117static void tempBase(FICL_VM *pVM, int base)
118{
119 int oldbase = pVM->base;
120 STRINGINFO si = vmGetWord0(pVM);
121
122 pVM->base = base;
123 if (!ficlParseNumber(pVM, si))
124 {
125 int i = SI_COUNT(si);
126 vmThrowErr(pVM, "%.*s not recognized", i, SI_PTR(si));
127 }
128
129 pVM->base = oldbase;
130 return;
131}
132
133static void fTempBase(FICL_VM *pVM)
134{
135 int base = stackPopINT(pVM->pStack);
136 tempBase(pVM, base);
137 return;
138}
139
140static void prefixHex(FICL_VM *pVM)
141{
142 tempBase(pVM, 16);
143}
144
145static void prefixTen(FICL_VM *pVM)
146{
147 tempBase(pVM, 10);
148}
149
150
151/**************************************************************************
152 f i c l C o m p i l e P r e f i x
153** Build prefix support into the dictionary and the parser
154** Note: since prefixes always execute, they are effectively IMMEDIATE.
155** If they need to generate code in compile state you must add
156** this code explicitly.
157**************************************************************************/
158void ficlCompilePrefix(FICL_SYSTEM *pSys)
159{
160 FICL_DICT *dp = pSys->dp;
161 FICL_HASH *pHash;
162 FICL_HASH *pPrevCompile = dp->pCompile;
163#if (FICL_EXTENDED_PREFIX)
164 FICL_WORD *pFW;
165#endif
166
167 /*
168 ** Create a named wordlist for prefixes to reside in...
169 ** Since we're doing a special kind of search, make it
170 ** a single bucket hashtable - hashing does not help here.
171 */
172 pHash = dictCreateWordlist(dp, 1);
173 pHash->name = list_name;
174 dictAppendWord(dp, list_name, constantParen, FW_DEFAULT);
175 dictAppendCell(dp, LVALUEtoCELL(pHash));
176
177 /*
178 ** Put __tempbase in the forth-wordlist
179 */
180 dictAppendWord(dp, "__tempbase", fTempBase, FW_DEFAULT);
181
182 /*
183 ** Temporarily make the prefix list the compile wordlist so that
184 ** we can create some precompiled prefixes.
185 */
186 dp->pCompile = pHash;
187 dictAppendWord(dp, "0x", prefixHex, FW_DEFAULT);
188 dictAppendWord(dp, "0d", prefixTen, FW_DEFAULT);
189#if (FICL_EXTENDED_PREFIX)
190 pFW = ficlLookup(pSys, "\\");
191 if (pFW)
192 {
193 dictAppendWord(dp, "//", pFW->code, FW_DEFAULT);
194 }
195#endif
196 dp->pCompile = pPrevCompile;
197
198 return;
199}