File: comfunc.h

package info (click to toggle)
ivtools 1.2.11a2-4
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 13,364 kB
  • sloc: cpp: 174,988; ansic: 12,717; xml: 5,359; perl: 2,164; makefile: 831; sh: 326
file content (281 lines) | stat: -rw-r--r-- 12,090 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
/*
 * Copyright (c) 2000 IET Inc.
 * Copyright (c) 1994-1999 Vectaport Inc.
 *
 * Permission to use, copy, modify, distribute, and sell this software and
 * its documentation for any purpose is hereby granted without fee, provided
 * that the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the names of the copyright holders not be used in
 * advertising or publicity pertaining to distribution of the software
 * without specific, written prior permission.  The copyright holders make
 * no representations about the suitability of this software for any purpose.
 * It is provided "as is" without express or implied warranty.
 *
 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
 * IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL,
 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 * 
 */

/*
 * ComFunc is a simple action callback pointed to by a ComCom
 * (or possibly any other external function binding mechanism)
 */

#if !defined(_comfunc_h)
#define _comfunc_h

#include <stdlib.h>
#include <OS/types.h>
#include <ComTerp/comterpserv.h>
#include <ComTerp/comvalue.h>
#include <Attribute/classid.h>
#include <Unidraw/Components/component.h>

class AttributeList;
class ComFuncState;
class Component;


//: command base class for extending ComTerp.
// class whose derived classes get constructed and added to a 
// ComTerp command interpreter, one per command to be supported.
class ComFunc {
public:
    ComFunc(ComTerp*);
    virtual ~ComFunc() { delete _docstring2;}

    virtual void execute() = 0;
    // method that needs to be filled in, that will take ComValue arguments
    // off the stack, then compute and push a ComValue result on the stack.

    virtual void exec(int nargs, int nkeys, int pedepth=0, int command_symid=0);
    // invokes push_funcstate, then plain execute, then pop_funcstate.
    // for use from the body of regular execute methods.

    int& nargs();
    // number of white space separated arguments inside parentheses
    // that are not keywords (keywords indicated by a ':' prefix 
    // on a symbol).
    int& nkeys();
    // number of arguments inside parentheses that are keywords (keywords 
    // indicated by a ':' prefix  on a symbol).  Arguments that follow
    // keywords are counted by nargs().  That's why there is a need for
    // nargsfixed() and nargstotal() methods, to distinguish between
    // arguments associated with fixed arguments (the ones that
    // precede the keyword arguments), and the ones enmeshed with the
    // keywords.  

    int nargsfixed() {return nargs() - nargskey();}
    // number of arguments prior to any keyword.  The ones that require a 
    // fixed order to determine their meaning (unlike the arguments that 
    // follow keywords, which can be in any order).
    int nargstotal() {return nargs() + nkeys();}
    // nargs()+nkeys()
    int nargskey();
    // number of arguments follow keywords, assumed to be less than
    // or equal to nkeys()  (this requirement could be relaxed).
    int nargspost();
    // number of arguments to a post-evaluating command 
    // that represent commands and arguments ready to be evaluated
    // by the post-eval methods: stack_arg_post_eval() and 
    // stack_key_post_eval().

    ComFuncState* funcstate();
    // current ComFuncState for use of current ComFunc.
    void push_funcstate(int nargs, int nkeys, int pedepth=0, 
                        int command_symid=0, unsigned linenum=0);
    // push new ComFuncState on a stack of them.
    void pop_funcstate();
    // pop the top one off the ComFuncState stack.

    ComTerp* comterp() { return _comterp; }
    // return ComTerp this ComFunc is associated with.
    ComTerpServ* comterpserv();
    // return ComTerpServ this ComFunc is associated with.
    void comterp( ComTerp* comterp) { _comterp = comterp; }
    void comterpserv( ComTerpServ* serv) { _comterp = (ComTerp*)serv; }


    ComValue pop_stack(); 
    // pop top off the stack.
    ComValue pop_symbol();
    // pop top off the stack preserving symbol ids if ComValue is a symbol type.
    void push_stack(ComValue&);
    // push ComValue onto the stack.
    void push_stack(AttributeValue&);
    // push AttributeValue onto the stack, converting to a ComValue
    // in the process.
    void reset_stack();
    // reset the stack to its state before this ComFunc execute() method
    // was called.  Needs to be called once and only once in each
    // derived execute() method.  Save it to last if you're using references
    // to ComValue objects directly on the stack.  Otherwise, call it as
    // soon as all the arguments have been loaded into local copies.
    

    ComValue& stack_arg(int n, boolean symbol=false, 
			ComValue& dflt=ComValue::nullval());
    // return the nth argument on the stack for this ComFunc execute() call.

    ComValue& stack_key(int id, boolean symbol=false, 
			ComValue& dflt=ComValue::trueval(), 
			boolean use_dflt_for_no_key=false
			/* the antonym would be use_dflt_for_no_arg */);
    // return the value of an argument that follows a keyword,
    // optionally return the value of 'dflt' if no argument follows
    // the keyword.  If 'use_dflt_for_no_key' is true, 'dflt' gets returned
    // as the value when a keyword is not found.

    ComValue& stack_dotname(int n);
    // unused method to get at a dotted list of names, i.e. a.b.c

    ComValue stack_arg_post_eval(int n, boolean symbol=false, 
				 ComValue& dflt=ComValue::nullval());
    // evaluate the nth argument for this post-evaluating ComFunc.
    void print_stack_arg_post_eval(int n);
    // print the expression for the nth argument for this post-evaluating ComFunc.
    postfix_token* copy_stack_arg_post_eval(int n, int& ntoks);
    // copy the expression for the nth argument for this post-evaluating ComFunc.

    ComValue stack_key_post_eval(int id, boolean symbol=false, 
				  ComValue& dflt=ComValue::trueval(), 
				  boolean use_dflt_for_no_key=false);
    // evaluate the argument following a keyword for this post-evaluating ComFunc.
    // Optionally return the value of 'dflt' if no argument follows
    // the keyword.  If 'use_dflt_for_no_key' is true, 'dflt' gets returned
    // as the value when a keyword is not found.

    AttributeList* stack_keys(boolean symbol = false, 
			      AttributeValue& dflt=ComValue::trueval());
    // return newly-constructed AttributeList (which needs referencing)
    // that contains a copy of each keyword/value pair in the arguments
    // to the invocation of this ComFunc.  'dflt' is used whenever a 
    // keyword has no matching argument.

    ComValue** stack_arg_post_eval_nargsfixed(boolean symbol=false, 
                                              ComValue& dflt=ComValue::nullval());
    // evaluate all nargsfixed arguments for this post-evaluating ComFunc,
    // and return in newly allocated array of newly allocated pointers.

    void funcid(int id) { _funcid = id; }
    // set symbol id of name for func
    int funcid() const { return _funcid; }
    // get symbol id of name for func

    ComValue& lookup_symval(ComValue&);
    // lookup variable value given a symbol ComValue
    ComValue& lookup_symval(int symid);
    // lookup variable value given a symbol id.
    void assign_symval(int id, ComValue*);

    virtual boolean post_eval() { return false; }
    virtual const char* docstring() { return "%s: no docstring method defined"; }
    const char* docstring2() { return _docstring2 ? _docstring2 : docstring(); }
    void docstring2(const char* str) { delete _docstring2; _docstring2 = strnew(str); }
    static int bintest(const char* name);
    static boolean bincheck(const char* name);
    
    friend ostream& operator << (ostream& s, const ComFunc&);
    // print contents to ostream, brief or not depending on
    // associated ComTerp brief flag.

    Component* context() { return _context; }
    void context(Component* comp) { _context = comp; }

protected:

    int& npops();
    // number of calls to pop_stack() since execute method called.
    int& pedepth();
    // depth of being embedded in blocks of post-evaluated ccommands 
    // (commands whose arguments are not pre-evaluated for them).


    ComValue& stack_arg_post(int n, boolean symbol=false, 
			     ComValue& dflt=ComValue::nullval());
    // find the ComValue object in the unevaluated input arguments 
    // of a post-eval ComFunc that represents the start of the
    // code for the nth argument (prior to any keywords).

    ComValue& stack_key_post(int id, boolean symbol=false, 
			     ComValue& dflt=ComValue::trueval(), 
			     boolean use_dflt_for_no_key=false);
    // find the ComValue object in the unevaluated input arguments 
    // of a post-eval ComFunc that represents the start of the
    // code for the argument that follows a keyword.  If no argument
    // follows keyword, 'dflt' is returned, unless 'use_dflt_for_no_key'
    // is true, when 'dflt' gets returned when no matching keyword is found.

    boolean skip_key_on_stack(int& stackptr, int& arglen);
    // skip a keyword going down the stack.
    boolean skip_arg_on_stack(int& stackptr, int& arglen);
    // skip an argument going down the stack.
    boolean skip_key_in_expr(int& topptr, int& arglen);
    // skip a keyword in a buffer of unevaluated ComValue objects,
    // decrementing an index into a buffer set up to hold the 
    // currently interpreting expression.
    boolean skip_arg_in_expr(int& topptr, int& arglen);
    // skip an argument in unevaluated ComValue objects, 
    // decrementing an index into a buffer set up to hold the
    // currently interpreting expression.

    ComTerp* _comterp;
    int _funcid;
    Component* _context;
    const char* _docstring2;

    CLASS_SYMID("ComFunc");
};

//: state object for holding invocation specific data about a ComFunc.
// object that holds the state of a ComFunc used in a particular context,
// which allows for nested and recursive use of a singular ComFunc.
class ComFuncState {
public:
  ComFuncState(int nargs, int nkeys, int pedepth=0, int command_symid=0, unsigned linenum=0);
  // initialize with number of arguments (including arguments following
  // keywords), number of keywords, an option post-eval depth (nesting
  // within blocks of post-evaluation commands), and an optional 
  // symbol id associated with the ComFunc.
  ComFuncState(const ComFuncState&);
  // copy constructor.

  int& nargs() {return _nargs;}
  // number of arguments (including arguments following keywords).
  int& nkeys() {return _nkeys;}
  // number of keywords, ':' prefixed symbols in a list of arguments.
  int& npops() { return _npops;}
  // number of pops since the execute method called.
  int& nargskey() { return _nargskey; }
  // number of arguments following keywords.  Assumption of nargskey()<=nkey().
  int& nargspost() { return _nargspost; }
  // number of unevaluated ComValue objects input to a post-evaluation ComFunc.
  int& pedepth() { return _pedepth; }
  // post-evaluation depth: the nesting within blocks of post-evaluation commands  // within blocks of conditionally executing control commands.
  int& command_symid() { return _command_symid; }
  // symbol id associated with the ComFunc.
  unsigned int& linenum() { return _linenum; }
  // original line number of command
  
  friend ostream& operator << (ostream& s, const ComFuncState&);
  // print contents to ostream, brief or not depending on
  // associated ComTerp brief flag.

protected:

  int _nargs;
  int _nkeys;
  int _npops;
  int _nargskey;
  int _nargspost;
  int _pedepth;
  int _command_symid;
  unsigned _linenum;
};
#endif /* !defined(_comfunc_h) */