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}
|