; INF2PRE.LSP [22 Apr 1990] - Rod Anderson ; Functions to convert Algebraic notation formulas to prefix ; (LISP) functions ;---------------------------------------------------------------- ; ; R.A. Anderson ; P.O. Box 922 ; Hayden, ID 83835-0922 ; ; Voice: (208)772-6889 18:00-21:00 Pacific Time ; ; NOTICE ; ~~~~~~ ; This is from the book 'LISP (second edition )', by Winston and Horn ; ; Comments ; ~~~~~~~~ ; This is a suggestion for the method to implement a equation ; for a *REAL* AutoLISP calculator. Has been tested with AutoLISP! ; ; Functions ; ~~~~~~~~~ ; WEIGHT (operator ) - Give the operator a weight in the ; mathmatical hierarchy ; ; OPCODE (operator ) - Translate the normal mathematical ; operators to AutoLISP functions. ; ; INF-TO-PRE (ae ) ; INF-AUX ; INF-ITER (ae operators operands ) - These three functions do ; the actual translation with INF-TO-PRE being the function to ; call. ; Example ; ~~~~~~~ ; (INF-TO-PRE '(TOTAL = PRINCIPAL * (1.0 + INTEREST ) ^ YEARS )) ; (SETQ TOTAL (* PRINCIPAL (EXPT (+ 1.0 INTEREST) YEARS)))) ; by setting PRINCIPAL, INTEREST, and YEARS to some value and ; then EVALing the returned symbol the actual numbers are ; returned. ;---------------------------------------------------------------- ; (defun WEIGHT (operator ) (cond ((equal operator '= ) 0 ) ((equal operator '+ ) 1 ) ((equal operator '- ) 1 ) ((equal operator '* ) 2 ) ((equal operator '/ ) 2 ) ((equal operator '~ ) 2 ) ((equal operator '^ ) 3 ) ;---------------------------------------------------------------- ; ? Here is one problem. AutoLISP doesn't have a backquote or ; comma operator. A different method to report an invalid ; operator is needed. This is from the original code ; (T (print `(,operator not an Operator )) 4 ) ;---------------------------------------------------------------- ; ! I haven't tried entering a formula with an invalid operator ; Perhaps this will work. (T (print (strcat operator "is not an Operator" ))) ); end cond ); end defun WEIGHT (defun OPCODE (operator ) (cond ((equal operator '= ) 'setq ) ((equal operator '+ ) '+ ) ((equal operator '- ) '- ) ((equal operator '* ) '* ) ((equal operator '/ ) '/ ) ((equal operator '~ ) 'rem ) ((equal operator '^ ) 'expt ) ;---------------------------------------------------------------- ; ? Here is one problem. AutoLISP doesn't have a backquote or ; comma operator. A different method to report an invalid ; operator is needed ; (T (print `(,operator not an Operator )) 4 ) ;---------------------------------------------------------------- ; See above (T (print (strcat operator "is not an Operator" ))) ); end cond ); end defun OPCODE (defun INF-TO-PRE (ae ) (cond ((atom ae ) ae ) (T (INF-AUX ae nil nil )) ); end cond ); end defun INF-TO-PRE (defun INF-AUX (ae operators operands ) (INF-ITER (cdr ae ) operators (cons (INF-TO-PRE (car ae )) operands )) ) (defun INF-ITER (ae operators operands ) (cond ((and (null ae ) (null operators )) (car operands ) ) ((and (not (null ae )) (or (null operators ) (> (WEIGHT (car ae )) (WEIGHT (car operators )) ) ) ) (INF-AUX (cdr ae ) (cons (car ae ) operators ) operands ) ) (T (INF-ITER ae (cdr operators ) (cons (list (OPCODE (car operators )) (cadr operands ) (car operands )) (cddr operands )))) ); end cond ); end defun INF-ITER ;------