1afc2ba1dSToomas Soome /*
2afc2ba1dSToomas Soome * p r e f i x . c
3afc2ba1dSToomas Soome * Forth Inspired Command Language
4afc2ba1dSToomas Soome * Parser extensions for Ficl
5afc2ba1dSToomas Soome * Authors: Larry Hastings & John Sadler (john_sadler@alum.mit.edu)
6afc2ba1dSToomas Soome * Created: April 2001
7afc2ba1dSToomas Soome * $Id: prefix.c,v 1.8 2010/09/13 18:43:04 asau Exp $
8afc2ba1dSToomas Soome */
9afc2ba1dSToomas Soome /*
10afc2ba1dSToomas Soome * Copyright (c) 1997-2001 John Sadler (john_sadler@alum.mit.edu)
11afc2ba1dSToomas Soome * All rights reserved.
12afc2ba1dSToomas Soome *
13afc2ba1dSToomas Soome * Get the latest Ficl release at http://ficl.sourceforge.net
14afc2ba1dSToomas Soome *
15afc2ba1dSToomas Soome * I am interested in hearing from anyone who uses Ficl. If you have
16afc2ba1dSToomas Soome * a problem, a success story, a defect, an enhancement request, or
17afc2ba1dSToomas Soome * if you would like to contribute to the Ficl release, please
18afc2ba1dSToomas Soome * contact me by email at the address above.
19afc2ba1dSToomas Soome *
20afc2ba1dSToomas Soome * L I C E N S E and D I S C L A I M E R
21afc2ba1dSToomas Soome *
22afc2ba1dSToomas Soome * Redistribution and use in source and binary forms, with or without
23afc2ba1dSToomas Soome * modification, are permitted provided that the following conditions
24afc2ba1dSToomas Soome * are met:
25afc2ba1dSToomas Soome * 1. Redistributions of source code must retain the above copyright
26afc2ba1dSToomas Soome * notice, this list of conditions and the following disclaimer.
27afc2ba1dSToomas Soome * 2. Redistributions in binary form must reproduce the above copyright
28afc2ba1dSToomas Soome * notice, this list of conditions and the following disclaimer in the
29afc2ba1dSToomas Soome * documentation and/or other materials provided with the distribution.
30afc2ba1dSToomas Soome *
31afc2ba1dSToomas Soome * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
32afc2ba1dSToomas Soome * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33afc2ba1dSToomas Soome * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34afc2ba1dSToomas Soome * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
35afc2ba1dSToomas Soome * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36afc2ba1dSToomas Soome * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37afc2ba1dSToomas Soome * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38afc2ba1dSToomas Soome * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
39afc2ba1dSToomas Soome * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
40afc2ba1dSToomas Soome * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
41afc2ba1dSToomas Soome * SUCH DAMAGE.
42afc2ba1dSToomas Soome */
43afc2ba1dSToomas Soome
44afc2ba1dSToomas Soome #include "ficl.h"
45afc2ba1dSToomas Soome
46afc2ba1dSToomas Soome /*
47afc2ba1dSToomas Soome * (jws) revisions:
48afc2ba1dSToomas Soome * A prefix is a word in a dedicated wordlist (name stored in list_name below)
49afc2ba1dSToomas Soome * that is searched in a special way by the prefix parse step. When a prefix
50afc2ba1dSToomas Soome * matches the beginning of an incoming token, push the non-prefix part of the
51afc2ba1dSToomas Soome * token back onto the input stream and execute the prefix code.
52afc2ba1dSToomas Soome *
53afc2ba1dSToomas Soome * The parse step is called ficlParsePrefix.
54afc2ba1dSToomas Soome * Storing prefix entries in the dictionary greatly simplifies
55afc2ba1dSToomas Soome * the process of matching and dispatching prefixes, avoids the
56afc2ba1dSToomas Soome * need to clean up a dynamically allocated prefix list when the system
57afc2ba1dSToomas Soome * goes away, but still allows prefixes to be allocated at runtime.
58afc2ba1dSToomas Soome */
59afc2ba1dSToomas Soome
60afc2ba1dSToomas Soome static char list_name[] = "<prefixes>";
61afc2ba1dSToomas Soome
62afc2ba1dSToomas Soome /*
63afc2ba1dSToomas Soome * f i c l P a r s e P r e f i x
64afc2ba1dSToomas Soome * This is the parse step for prefixes - it checks an incoming word
65afc2ba1dSToomas Soome * to see if it starts with a prefix, and if so runs the corresponding
66afc2ba1dSToomas Soome * code against the remainder of the word and returns true.
67afc2ba1dSToomas Soome */
68afc2ba1dSToomas Soome int
ficlVmParsePrefix(ficlVm * vm,ficlString s)69afc2ba1dSToomas Soome ficlVmParsePrefix(ficlVm *vm, ficlString s)
70afc2ba1dSToomas Soome {
71afc2ba1dSToomas Soome int i;
72afc2ba1dSToomas Soome ficlHash *hash;
73afc2ba1dSToomas Soome ficlWord *word = ficlSystemLookup(vm->callback.system, list_name);
74afc2ba1dSToomas Soome
75afc2ba1dSToomas Soome /*
76afc2ba1dSToomas Soome * Make sure we found the prefix dictionary - otherwise silently fail
77afc2ba1dSToomas Soome * If forth-wordlist is not in the search order, we won't find the
78afc2ba1dSToomas Soome * prefixes.
79afc2ba1dSToomas Soome */
80afc2ba1dSToomas Soome if (!word)
81afc2ba1dSToomas Soome return (0); /* false */
82afc2ba1dSToomas Soome
83afc2ba1dSToomas Soome hash = (ficlHash *)(word->param[0].p);
84afc2ba1dSToomas Soome /*
85afc2ba1dSToomas Soome * Walk the list looking for a match with the beginning of the
86afc2ba1dSToomas Soome * incoming token
87afc2ba1dSToomas Soome */
88afc2ba1dSToomas Soome for (i = 0; i < (int)hash->size; i++) {
89afc2ba1dSToomas Soome word = hash->table[i];
90afc2ba1dSToomas Soome while (word != NULL) {
91afc2ba1dSToomas Soome int n;
92afc2ba1dSToomas Soome n = word->length;
93afc2ba1dSToomas Soome /*
94afc2ba1dSToomas Soome * If we find a match, adjust the TIB to give back
95afc2ba1dSToomas Soome * the non-prefix characters and execute the prefix
96afc2ba1dSToomas Soome * word.
97afc2ba1dSToomas Soome */
98afc2ba1dSToomas Soome if (!ficlStrincmp(FICL_STRING_GET_POINTER(s),
99afc2ba1dSToomas Soome word->name, (ficlUnsigned)n)) {
100afc2ba1dSToomas Soome /*
101afc2ba1dSToomas Soome * (sadler) fixed off-by-one error when the
102afc2ba1dSToomas Soome * token has no trailing space in the TIB
103afc2ba1dSToomas Soome */
104afc2ba1dSToomas Soome ficlVmSetTibIndex(vm,
105afc2ba1dSToomas Soome s.text + n - vm->tib.text);
106afc2ba1dSToomas Soome ficlVmExecuteWord(vm, word);
107afc2ba1dSToomas Soome
108afc2ba1dSToomas Soome return (1); /* true */
109afc2ba1dSToomas Soome }
110afc2ba1dSToomas Soome word = word->link;
111afc2ba1dSToomas Soome }
112afc2ba1dSToomas Soome }
113afc2ba1dSToomas Soome
114afc2ba1dSToomas Soome return (0); /* false */
115afc2ba1dSToomas Soome }
116afc2ba1dSToomas Soome
117afc2ba1dSToomas Soome static void
ficlPrimitiveTempBase(ficlVm * vm)118afc2ba1dSToomas Soome ficlPrimitiveTempBase(ficlVm *vm)
119afc2ba1dSToomas Soome {
120afc2ba1dSToomas Soome int oldbase = vm->base;
121afc2ba1dSToomas Soome ficlString number = ficlVmGetWord0(vm);
122afc2ba1dSToomas Soome int base = ficlStackPopInteger(vm->dataStack);
123afc2ba1dSToomas Soome
124afc2ba1dSToomas Soome vm->base = base;
125afc2ba1dSToomas Soome if (!ficlVmParseNumber(vm, number))
126afc2ba1dSToomas Soome ficlVmThrowError(vm, "%.*s not recognized",
127afc2ba1dSToomas Soome FICL_STRING_GET_LENGTH(number),
128afc2ba1dSToomas Soome FICL_STRING_GET_POINTER(number));
129afc2ba1dSToomas Soome
130afc2ba1dSToomas Soome vm->base = oldbase;
131afc2ba1dSToomas Soome }
132afc2ba1dSToomas Soome
133afc2ba1dSToomas Soome /*
134afc2ba1dSToomas Soome * f i c l C o m p i l e P r e f i x
135afc2ba1dSToomas Soome * Build prefix support into the dictionary and the parser
136afc2ba1dSToomas Soome * Note: since prefixes always execute, they are effectively IMMEDIATE.
137afc2ba1dSToomas Soome * If they need to generate code in compile state you must add
138afc2ba1dSToomas Soome * this code explicitly.
139afc2ba1dSToomas Soome */
140afc2ba1dSToomas Soome void
ficlSystemCompilePrefix(ficlSystem * system)141afc2ba1dSToomas Soome ficlSystemCompilePrefix(ficlSystem *system)
142afc2ba1dSToomas Soome {
143afc2ba1dSToomas Soome ficlDictionary *dictionary = system->dictionary;
144afc2ba1dSToomas Soome ficlHash *hash;
145afc2ba1dSToomas Soome
146afc2ba1dSToomas Soome /*
147afc2ba1dSToomas Soome * Create a named wordlist for prefixes to reside in...
148afc2ba1dSToomas Soome * Since we're doing a special kind of search, make it
149afc2ba1dSToomas Soome * a single bucket hashtable - hashing does not help here.
150afc2ba1dSToomas Soome */
151afc2ba1dSToomas Soome hash = ficlDictionaryCreateWordlist(dictionary, 1);
152afc2ba1dSToomas Soome hash->name = list_name;
153afc2ba1dSToomas Soome ficlDictionaryAppendConstantPointer(dictionary, list_name, hash);
154afc2ba1dSToomas Soome
155afc2ba1dSToomas Soome /*
156afc2ba1dSToomas Soome * Put __tempbase in the forth-wordlist
157afc2ba1dSToomas Soome */
158*c0bb4f73SToomas Soome (void) ficlDictionarySetPrimitive(dictionary, "__tempbase",
159afc2ba1dSToomas Soome ficlPrimitiveTempBase, FICL_WORD_DEFAULT);
160afc2ba1dSToomas Soome
161afc2ba1dSToomas Soome /*
162afc2ba1dSToomas Soome * If you want to add some prefixes at compilation-time, copy this
163afc2ba1dSToomas Soome * line to the top of this function:
164afc2ba1dSToomas Soome *
165afc2ba1dSToomas Soome * ficlHash *oldCompilationWordlist;
166afc2ba1dSToomas Soome *
167afc2ba1dSToomas Soome * then copy this code to the bottom, just above the return:
168afc2ba1dSToomas Soome *
169afc2ba1dSToomas Soome *
170afc2ba1dSToomas Soome * oldCompilationWordlist = dictionary->compilationWordlist;
171afc2ba1dSToomas Soome * dictionary->compilationWordlist = hash;
172afc2ba1dSToomas Soome * ficlDictionarySetPrimitive(dictionary, YOUR WORD HERE,
173afc2ba1dSToomas Soome * FICL_WORD_DEFAULT);
174afc2ba1dSToomas Soome * dictionary->compilationWordlist = oldCompilationWordlist;
175afc2ba1dSToomas Soome *
176afc2ba1dSToomas Soome * and substitute in your own actual calls to
177afc2ba1dSToomas Soome * ficlDictionarySetPrimitive() as needed.
178afc2ba1dSToomas Soome *
179afc2ba1dSToomas Soome * Or--better yet--do it in your own code, so you don't have
180afc2ba1dSToomas Soome * to re-modify the Ficl source code every time we cut a new release!
181afc2ba1dSToomas Soome */
182afc2ba1dSToomas Soome }
183