/[pspp]/pspp/TODO
ViewVC logotype

Diff of /pspp/TODO

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.25 by blp, Wed Dec 1 07:03:42 2004 UTC revision 1.26 by blp, Fri Mar 4 07:12:41 2005 UTC
# Line 1  Line 1 
1  Time-stamp: <2004-11-30 22:59:24 blp>  Time-stamp: <2005-03-02 16:08:59 blp>
2    
3  What Ben's working on now.  What Ben's working on now.
4  --------------------------  --------------------------
5    
6  Workspace exhaustion heuristics.  Workspace exhaustion heuristics.
7    
 Does SET work correctly?  
   
8  Update q2c input format description.  Update q2c input format description.
9    
10  Rewrite output subsystem, break into multiple processes.  Rewrite output subsystem, break into multiple processes.
# Line 22  TODO Line 20  TODO
20    
21  Make valgrind --leak-check=yes --show-reachable=yes work.  Make valgrind --leak-check=yes --show-reachable=yes work.
22    
 Add Boolean type.  
   
23  Add NOT_REACHED() macro.  Add NOT_REACHED() macro.
24    
25  Add compression to casefiles.  Add compression to casefiles.
26    
 Expressions need to be able to abbreviate function names.  XDATE.QUARTER  
 abbreviates to XDA.QUA, etc.  
   
 The expression tests need tests for XDATE and a few others, see  
 tests/xforms/expressions.sh comments for details.  
   
 Expressions need random distribution functions.  
   
27  There needs to be another layer onto the lexer, which should probably be  There needs to be another layer onto the lexer, which should probably be
28  entirely rewritten anyway.  The lexer needs to read entire *commands* at a  entirely rewritten anyway.  The lexer needs to read entire *commands* at a
29  time, not just a *line* at a time.  It also needs to support arbitrary putback,  time, not just a *line* at a time.  It also needs to support arbitrary putback,
# Line 168  server independently.  The statistical p Line 156  server independently.  The statistical p
156  and results would be reported through HTML tables viewed with the user's choice  and results would be reported through HTML tables viewed with the user's choice
157  of web browsers.  Help could be implemented through the browser as well.  of web browsers.  Help could be implemented through the browser as well.
158    
 Design a plotting API, with scatterplots, line plots, pie charts, barcharts,  
 Pareto plots, etc., as subclasses of the plot superclass.  
   
159  HOWTOs  HOWTOs
160  ------  ------
161    
 1. How to add an operator for use in PSPP expressions:  
   
 a. Add the operator to the enumerated type at the top of expr.h.  If the  
 operator has arguments (i.e., it's not a terminal) then add it *before*  
 OP_TERMINAL; otherwise, add it *after* OP_TERMINAL.  All these begin with OP_.  
   
 b. If the operator's a terminal then you'll want to design a structure to hold  
 its content.  Add the structure to the union any_node.  (You can also reuse one  
 of the prefab structures, of course.)  
   
 c. Now switch to expr-prs.c--the module for expression parsing.  Insert the  
 operator somewhere in the precedence hierarchy.  
   
 (1) If you're adding a operator that is a function (like ACOS, ABS, etc.) then  
 add the function to functab in `void init_functab(void)'.  Order is not  
 important here.  The first element is the function name, like "ACOS".  The  
 second is the operator enumerator you added in expr.h, like OP_ARCOS.  The  
 third element is the C function to parse the PSPP function.  The predefined  
 functions will probably suit your needs, but if not, you can write your own.  
 The fourth element is an argument to the parsing function; it's only used  
 currently by generic_str_func(), which handles a rather general syntax for  
 functions that return strings; see the comment at the beginning of its code for  
 details.  
   
 (2) If you're adding an actual operator you'll have to put a function in  
 between two of the operators there already in functions `exprtype  
 parse_*(any_node **n)'.  Each of these stores the tree for its result into *n,  
 and returns the result type, or EX_ERROR on error.  Be sure to delete all the  
 allocated memory on error before returning.  
   
 d. Add the operator to the table `op_desc ops[OP_SENTINEL+1]' in expr-prs.c,  
 which has an entry for every operator.  These entries *must* be in the same  
 order as they are in expr.h.  The entries have the form `op(A,B,C,D)'.  A is  
 the name of the operator as it should be printed in a postfix output format.  
 For example, the addition operator is printed as `plus'.  B is a bitmapped set  
 of flags:  
   
 * Set the 001 bit (OP_VAR_ARGS) if the operator takes a variable number of  
 arguments.  If a function can take, say, two args or three args, but no other  
 numbers of args, this is a poor way to do it--instead implement the operator as  
 two separate operators, one with two args, the other with three.  (The main  
 effect of this bit is to cause the number of arguments to be output to the  
 postfix form so that the expression evaluator can know how many args the  
 operator takes.  It also causes the expression optimizer to calculate the  
 needed stack height differently, without referencing C.)  
   
 * Set the 002 bit (OP_MIN_ARGS) if the operator can take an optional `dotted  
 argument' that specified the minimum number of non-SYSMIS arguments in order to  
 have a non-SYSMIS result.  For instance, MIN.3(e1,e2,e3,e4,e5) returns a  
 non-SYSMIS result only if at least 3 out of 5 of the expressions e1 to e5 are  
 not missing.  
   
 Minargs are passed in the nonterm_node structure in `arg[]''s elements past  
 `n'--search expr-prs.c for the words `terrible crock' for an example of this.  
   
 Minargs are output to the postfix form.  A default value is output if none was  
 specified by the user.  
   
 You can use minargs for anything you want--they're not limited to actually  
 describing a minimum number of valid arguments; that's just what they're most  
 *commonly* used for.  
   
 * Set the 004 bit (OP_FMT_SPEC) if the operator has an argument that is a  
 format specifier.  (This causes the format specifier to be output to the  
 postfix representation.)  
   
 Format specs are passed in the nonterm_node structure in the same way as  
 minargs, except that there are three args, in this order: type, width, # of  
 decimals--search expr-prs.c for the words `is a crock' for an example of this.  
   
 * Set the 010 bit (OP_ABSORB_MISS) if the operator can *ever* have a result of  
 other than SYSMIS when given one or more arguments of SYSMIS.  Operators  
 lacking this bit and known to have a SYSMIS argument are short-circuited to  
 SYSMIS by the expression optimizer.  
   
 * If your operator doesn't fit easily into the existing categories,  
 congratulations, you get to write lots of code to adjust everything to cope  
 with this new operator.  Are you really sure you want to do that?  
   
 C is the effect the operator has on stack height.  Set this to `varies' if the  
 operator has a variable number of arguments.  Otherwise this 1, minus the  
 number of arguments the operator has.  (Since terminals have no arguments, they  
 have a value of +1 for this; other operators have a value of 0 or less.)  
   
 D is the number of items output to the postfix form after the operator proper.  
 This is 0, plus 1 if the operator has varargs, plus 1 if the operator has  
 minargs, plus 3 if the operator has a format spec.  Note that minargs/varargs  
 can't coexist with a format spec on the same operator as currently coded.  Some  
 terminals also have a nonzero value for this but don't fit into the above  
 categories.  
   
 e. Switch to expr-opt.c.  Add code to evaluate_tree() to evaluate the  
 expression when all arguments are known to be constants.  Pseudo-random  
 functions can't be evaluated even if their arguments are constants.  If the  
 function can be optimized even if its arguments aren't all known constants, add  
 code to optimize_tree() to do it.  
   
 f. Switch to expr-evl.c.  Add code to evaluate_expression() to evaluate the  
 expression.  You must be absolutely certain that the code in evaluate_tree(),  
 optimize_tree(), and evaluate_expression() will always return the same results,  
 otherwise users will get inconsistent results, a Bad Thing.  You must be  
 certain that even on boundary conditions users will get identical results, for  
 instance for the values 0, 1, -1, SYSMIS, or, for string functions, the null  
 string, 1-char strings, and 255-char strings.  
   
 g. Test the code.  Write some test syntax files.  Examine the output carefully.  
   
162  MORE NOTES/IDEAS/BUGS  MORE NOTES/IDEAS/BUGS
163  ---------------------  ---------------------
164    

Legend:
Removed from v.1.25  
changed lines
  Added in v.1.26

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26