443
443
(defvar *string-register* (make-array 100 :fill-pointer 0 :adjustable t :element-type '#.(array-element-type "a")))
444
444
(defun readlist (lis)
445
445
(setf (fill-pointer *string-register*) 0)
446
(sloop for u in lis do (vector-push-extend u *string-register*))
446
(loop for u in lis do (vector-push-extend u *string-register*))
447
447
(read-from-string *string-register*))
450
(DEFUN MAKE-NUMBER (DATA)
451
(SETQ DATA (NREVERSE DATA))
450
(defun make-number (data)
451
(setq data (nreverse data))
452
452
;; Maxima really wants to read in any number as a double-float
453
453
;; (except when we have a bigfloat, of course!). So convert an E or
454
454
;; S exponent marker to D.
455
455
(when (member (car (nth 3. data)) '(#\E #\S))
456
456
(setf (nth 3. data) (list #\D)))
457
(IF (NOT (EQUAL (NTH 3. DATA) '(#\B)))
458
(READLIST (APPLY #'APPEND DATA))
459
;; For bigfloats, turn them into rational numbers then convert to bigfloat
460
($BFLOAT `((MTIMES) ((MPLUS) ,(READLIST (or (FIRST DATA) '(#\0)))
461
((MTIMES) ,(READLIST (or (THIRD DATA) '(#\0)))
462
((MEXPT) 10. ,(f- (LENGTH (THIRD DATA))))))
463
((MEXPT) 10. ,(FUNCALL (IF (char= (FIRST (FIFTH DATA)) #\-) #'- #'+)
464
(READLIST (SIXTH DATA))))))))
466
(DEFUN SCAN-DIGITS (DATA CONTINUATION? CONTINUATION &optional exponent-p)
467
(DO ((C (PARSE-TYIPEEK) (PARSE-TYIPEEK))
469
((NOT (ASCII-NUMBERP C))
470
(COND ((IMEMBER C CONTINUATION?)
471
(FUNCALL CONTINUATION (LIST* (NCONS (FIXNUM-CHAR-UPCASE
457
(if (not (equal (nth 3. data) '(#\B)))
458
(readlist (apply #'append data))
459
;; For bigfloats, turn them into rational numbers then convert to bigfloat.
460
;; Fix for the 0.25b0 # 2.5b-1 bug. Richard J. Fateman posted this fix to the
461
;; Maxima list on 10 October 2005. Without this fix, some tests in rtestrationalize
462
;; will fail. Used with permission.
463
($bfloat (simplifya `((mtimes) ((mplus) ,(readlist (or (first data) '(#\0)))
464
((mtimes) ,(readlist (or (third data) '(#\0)))
465
((mexpt) 10. ,(f- (length (third data))))))
466
((mexpt) 10. ,(funcall (if (char= (first (fifth data)) #\-) #'- #'+)
467
(readlist (sixth data))))) nil))))
469
;; Richard J. Fateman wrote the big float to rational code and the function
472
(defun cl-rat-to-maxima (x) (if (integerp x) x (list '(rat simp) (numerator x) (denominator x))))
474
(defun scan-digits (data continuation? continuation &optional exponent-p)
475
(do ((c (parse-tyipeek) (parse-tyipeek))
477
((not (ascii-numberp c))
478
(cond ((imember c continuation?)
479
(funcall continuation (list* (ncons (fixnum-char-upcase
476
484
((and (null l) exponent-p)
477
485
;; We're trying to parse the exponent part of a number,
478
486
;; and we didn't get a value after the exponent marker.
479
487
;; That's an error.
480
488
(merror "Incomplete number. Missing exponent?"))
482
(MAKE-NUMBER (CONS (NREVERSE L) DATA)))))
486
(DEFUN SCAN-NUMBER-BEFORE-DOT (DATA)
487
(SCAN-DIGITS DATA '(#. period-char) #'SCAN-NUMBER-AFTER-DOT))
489
(DEFUN SCAN-NUMBER-AFTER-DOT (DATA)
490
(SCAN-DIGITS DATA '(#\E #\e #\B #\b #\D #\d #\S #\s) #'SCAN-NUMBER-EXPONENT))
492
(DEFUN SCAN-NUMBER-EXPONENT (DATA)
493
(PUSH (NCONS (IF (OR (char= (PARSE-TYIPEEK) #\+)
494
(char= (PARSE-TYIPEEK) #\-))
490
(make-number (cons (nreverse l) data)))))
494
;(DEFUN SCAN-NUMBER-BEFORE-DOT (DATA)
495
; (SCAN-DIGITS DATA '(#. period-char) #'SCAN-NUMBER-AFTER-DOT))
497
(defun scan-number-after-dot (data)
498
(scan-digits data '(#\E #\e #\B #\b #\D #\d #\S #\s) #'scan-number-exponent))
500
(defun scan-number-exponent (data)
501
(push (ncons (if (or (char= (parse-tyipeek) #\+)
502
(char= (parse-tyipeek) #\-))
498
(SCAN-DIGITS DATA () () t))
506
(scan-digits data () () t))
501
508
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
503
510
;;;;; The Expression Parser ;;;;;
807
808
;;; get bound to the parsed structure which was to the left of Arg1.
811
(DEFMACRO DEF-LED((OP . LBP-RBP) BVL . BODY)
811
(defmacro def-led((op . lbp-rbp) bvl . body)
812
812
(let (( lbp (nth 0 lbp-rbp))
813
813
( rbp (nth 1 lbp-rbp)))
815
,(MAKE-PARSER-FUN-DEF OP 'LED BVL BODY)
816
(SET-LBP-AND-RBP ',OP ',LBP ',RBP))))
819
(DEFMACRO DEF-LED ((OP #+(or cl NIL) &OPTIONAL LBP RBP) BVL . BODY)
821
,(MAKE-PARSER-FUN-DEF OP 'LED BVL BODY)
822
(SET-LBP-AND-RBP ',OP ',LBP ',RBP)))
824
(DEFMACRO DEF-COLLISIONS (OP &REST ALIST)
825
(LET ((KEYS (DO ((I 1. (#+cl ash #-cl LSH I 1.))
826
(LIS ALIST (CDR LIS))
827
(NL () (CONS (CONS (CAAR LIS) I) NL)))
830
(DEFPROP ,OP ,(let #+lispm ((default-cons-area working-storage-area))
815
,(make-parser-fun-def op 'led bvl body)
816
(set-lbp-and-rbp ',op ',lbp ',rbp))))
819
;(DEFMACRO DEF-LED ((OP #+(or cl NIL) &OPTIONAL LBP RBP) BVL . BODY)
821
; ,(MAKE-PARSER-FUN-DEF OP 'LED BVL BODY)
822
; (SET-LBP-AND-RBP ',OP ',LBP ',RBP)))
824
(defmacro def-collisions (op &rest alist)
825
(let ((keys (do ((i 1. (#+cl ash #-cl lsh i 1.))
826
(lis alist (cdr lis))
827
(nl () (cons (cons (caar lis) i) nl)))
830
(defprop ,op ,(let #+lispm ((default-cons-area working-storage-area))
832
(copy-tree KEYS )) KEYS)
833
,@(MAPCAR #'(LAMBDA (DATA)
834
`(DEFPROP ,(CAR DATA)
835
,(DO ((I 0 (LOGIOR I (CDR (ASSQ (CAR LIS) KEYS))))
836
(LIS (CDR DATA) (CDR LIS)))
843
(DEFUN COLLISION-LOOKUP (OP ACTIVE-BITMASK KEY-BITMASK)
844
(LET ((RESULT (LOGAND ACTIVE-BITMASK KEY-BITMASK)))
845
(IF (NOT (ZEROP RESULT))
846
(DO ((L (GET OP 'KEYS) (CDR L)))
847
((NULL L) (PARSE-BUG-ERR 'COLLISION-CHECK))
848
(IF (NOT (ZEROP (LOGAND RESULT (CDAR L))))
849
(RETURN (CAAR L)))))))
851
(DEFUN COLLISION-CHECK (OP ACTIVE-BITMASK KEY)
852
(LET ((KEY-BITMASK (GET KEY OP)))
853
(IF (NOT KEY-BITMASK)
854
(MREAD-SYNERR "~A is an unknown keyword in a ~A statement."
855
(MOPSTRIP KEY) (MOPSTRIP OP)))
856
(LET ((COLLISION (COLLISION-LOOKUP OP ACTIVE-BITMASK KEY-BITMASK)))
858
(IF (EQ COLLISION KEY)
859
(MREAD-SYNERR "This ~A's ~A slot is already filled."
862
(MREAD-SYNERR "A ~A cannot have a ~A with a ~A field."
865
(MOPSTRIP COLLISION))))
866
(LOGIOR (CDR (ASSQ KEY (GET OP 'KEYS))) ACTIVE-BITMASK))))
832
(copy-tree keys )) keys)
833
,@(mapcar #'(lambda (data)
834
`(defprop ,(car data)
835
,(do ((i 0 (logior i (cdr (assq (car lis) keys))))
836
(lis (cdr data) (cdr lis)))
842
(defun collision-lookup (op active-bitmask key-bitmask)
843
(let ((result (logand active-bitmask key-bitmask)))
844
(if (not (zerop result))
845
(do ((l (get op 'keys) (cdr l)))
846
((null l) (parse-bug-err 'collision-check))
847
(if (not (zerop (logand result (cdar l))))
848
(return (caar l)))))))
850
(defun collision-check (op active-bitmask key)
851
(let ((key-bitmask (get key op)))
852
(if (not key-bitmask)
853
(mread-synerr "~A is an unknown keyword in a ~A statement."
854
(mopstrip key) (mopstrip op)))
855
(let ((collision (collision-lookup op active-bitmask key-bitmask)))
857
(if (eq collision key)
858
(mread-synerr "This ~A's ~A slot is already filled."
861
(mread-synerr "A ~A cannot have a ~A with a ~A field."
864
(mopstrip collision))))
865
(logior (cdr (assq key (get op 'keys))) active-bitmask))))
870
868
;;;; Data abstraction
872
870
;;; LBP = Left Binding Power
1214
1210
;;; If <expressionmode> and <mode> are compatible, returns <expression>.
1216
(DEFUN CONVERT (ITEM MODE)
1217
(IF (OR (EQ MODE (CAR ITEM)) ; If modes match exactly
1218
(EQ '$ANY MODE) ; or target is $ANY
1219
(EQ '$ANY (CAR ITEM))) ; or input is $ANY
1220
(CDR ITEM) ; then return expression
1221
(MREAD-SYNERR "Found ~A expression where ~A expression expected"
1222
(GET (CAR ITEM) 'ENGLISH)
1223
(GET MODE 'ENGLISH))))
1225
(DEFPROP $ANY "untyped" ENGLISH)
1226
(DEFPROP $CLAUSE "logical" ENGLISH)
1227
(DEFPROP $EXPR "algebraic" ENGLISH)
1212
(defun convert (item mode)
1213
(if (or (eq mode (car item)) ; If modes match exactly
1214
(eq '$any mode) ; or target is $ANY
1215
(eq '$any (car item))) ; or input is $ANY
1216
(cdr item) ; then return expression
1217
(mread-synerr "Found ~A expression where ~A expression expected"
1218
(get (car item) 'english)
1219
(get mode 'english))))
1221
(defprop $any "untyped" english)
1222
(defprop $clause "logical" english)
1223
(defprop $expr "algebraic" english)
1230
1225
;;;; Parser Error Diagnostics
1232
1227
;; Call this for random user-generated parse errors
1234
(DEFUN PARSE-ERR () (MREAD-SYNERR "Syntax error"))
1229
(defun parse-err () (mread-synerr "Syntax error"))
1236
1231
;; Call this for random internal parser lossage (eg, code that shouldn't
1237
1232
;; be reachable.)
1239
(DEFUN PARSE-BUG-ERR (OP)
1241
"Parser bug in ~A. Please report this to the Macsyma maintainers,~
1234
(defun parse-bug-err (op)
1236
"Parser bug in ~A. Please report this to the Maxima maintainers,~
1242
1237
~%including the characters you just typed which caused the error. Thanks."
1245
1240
;;; Random shared error messages
1247
(DEFUN DELIM-ERR (OP)
1248
(MREAD-SYNERR "Illegal use of delimiter ~A" (MOPSTRIP OP)))
1250
(DEFUN ERB-ERR (OP L) L ;Ignored
1251
(MREAD-SYNERR "Too many ~A's" (MOPSTRIP OP)))
1253
(DEFUN PREMTERM-ERR (OP)
1254
(MREAD-SYNERR "Premature termination of input at ~A."
1242
(defun delim-err (op)
1243
(mread-synerr "Illegal use of delimiter ~A" (mopstrip op)))
1245
(defun erb-err (op l) l ;Ignored
1246
(mread-synerr "Too many ~A's" (mopstrip op)))
1248
(defun premterm-err (op)
1249
(mread-synerr "Premature termination of input at ~A."
1258
1252
;;;; Operator Specific Data
1260
(DEF-NUD-EQUIV |$]| DELIM-ERR)
1261
(DEF-LED-EQUIV |$]| ERB-ERR)
1254
(def-nud-equiv |$]| delim-err)
1255
(def-led-equiv |$]| erb-err)
1264
(DEF-NUD-EQUIV |$[| PARSE-MATCHFIX)
1265
(DEF-MATCH |$[| |$]|)
1258
(def-nud-equiv |$[| parse-matchfix)
1259
(def-match |$[| |$]|)
1268
(DEF-MHEADER |$[| (MLIST))
1270
(DEF-LPOS |$[| $ANY)
1262
(def-mheader |$[| (mlist))
1264
(def-lpos |$[| $any)
1273
(DEF-LED (|$[| 200.) (OP LEFT)
1274
(SETQ LEFT (CONVERT LEFT '$ANY))
1275
(IF (NUMBERP LEFT) (PARSE-ERR)) ; number[...] invalid
1276
(LET ((header (if (atom left)
1277
(add-lineinfo (LIST (AMPERCHK LEFT) 'array))
1278
(add-lineinfo '(MQAPPLY ARRAY))))
1267
(def-led (|$[| 200.) (op left)
1268
(setq left (convert left '$any))
1269
(if (numberp left) (parse-err)) ; number[...] invalid
1270
(let ((header (if (atom left)
1271
(add-lineinfo (list (amperchk left) 'array))
1272
(add-lineinfo '(mqapply array))))
1280
(RIGHT (PRSMATCH '|$]| '$ANY))) ; get sublist in RIGHT
1281
(COND ((NULL RIGHT) ; 1 subscript minimum
1282
(MREAD-SYNERR "No subscripts given"))
1283
((ATOM LEFT) ; atom[...]
1284
(SETQ RIGHT (CONS header
1286
(CONS '$ANY (ALIASLOOKUP RIGHT)))
1288
(CONS '$ANY (CONS header
1289
(CONS LEFT RIGHT)))))))
1292
(DEF-NUD-EQUIV |$)| DELIM-ERR)
1293
(DEF-LED-EQUIV |$)| ERB-ERR)
1296
(DEF-MHEADER |$(| (MPROGN))
1274
(right (prsmatch '|$]| '$any))) ; get sublist in RIGHT
1275
(cond ((null right) ; 1 subscript minimum
1276
(mread-synerr "No subscripts given"))
1277
((atom left) ; atom[...]
1278
(setq right (cons header
1280
(cons '$any (aliaslookup right)))
1282
(cons '$any (cons header
1283
(cons left right)))))))
1286
(def-nud-equiv |$)| delim-err)
1287
(def-led-equiv |$)| erb-err)
1290
(def-mheader |$(| (mprogn))
1298
1292
;; KMP: This function optimizes out (exp) into just exp.
1299
1293
;; This is useful for mathy expressions, but obnoxious for non-mathy
1307
1301
;; comes inside quoted expressions. There are many other problems with
1308
1302
;; the "QUOTE" concept however.
1310
(DEF-NUD (|$(| 200.) (OP)
1311
(LET ((RIGHT)(hdr (MHEADER '|$(|))) ; make mheader first for lineinfo
1312
(COND ((EQ '|$)| (FIRST-C)) (PARSE-ERR)) ; () is illegal
1313
((OR (NULL (SETQ RIGHT (PRSMATCH '|$)| '$ANY))) ; No args to MPROGN??
1314
(CDR RIGHT)) ; More than one arg.
1315
(CONS '$ANY (CONS hdr RIGHT))) ; Return an MPROGN
1316
(T (CONS '$ANY (CAR RIGHT)))))) ; Optimize out MPROGN
1304
(def-nud (|$(| 200.) (op)
1305
(let ((right)(hdr (mheader '|$(|))) ; make mheader first for lineinfo
1306
(cond ((eq '|$)| (first-c)) (parse-err)) ; () is illegal
1307
((or (null (setq right (prsmatch '|$)| '$any))) ; No args to MPROGN??
1308
(cdr right)) ; More than one arg.
1309
(cons '$any (cons hdr right))) ; Return an MPROGN
1310
(t (cons '$any (car right)))))) ; Optimize out MPROGN
1318
(DEF-LED (|$(| 200.) (OP LEFT)
1319
(SETQ LEFT (CONVERT LEFT '$ANY)) ;De-reference LEFT
1320
(IF (NUMBERP LEFT) (PARSE-ERR)) ;number(...) illegal
1321
(LET ((HDR (AND (ATOM LEFT)(MHEADER (AMPERCHK LEFT))))
1322
(R (PRSMATCH '|$)| '$ANY)) ;Get arglist in R
1312
(def-led (|$(| 200.) (op left)
1313
(setq left (convert left '$any)) ;De-reference LEFT
1314
(if (numberp left) (parse-err)) ;number(...) illegal
1315
(let ((hdr (and (atom left)(mheader (amperchk left))))
1316
(r (prsmatch '|$)| '$any)) ;Get arglist in R
1324
(CONS '$ANY ;Result is type $ANY
1325
(COND ((ATOM LEFT) ;If atom(...) =>
1326
(CONS hdr R)) ;(($atom) exp . args)
1327
(T ;Else exp(...) =>
1328
(CONS '(MQAPPLY) (CONS LEFT R))))))) ;((MQAPPLY) op . args)
1330
(DEF-MHEADER |$'| (MQUOTE))
1332
(DEF-NUD (|$'|) (OP)
1334
(COND ((EQ '|$(| (FIRST-C))
1335
(LIST '$ANY (MHEADER '|$'|) (PARSE '$ANY 190.)))
1336
((OR (ATOM (SETQ RIGHT (PARSE '$ANY 190.)))
1337
(MEMQ (CAAR RIGHT) '(MQUOTE MLIST MPROG MPROGN LAMBDA)))
1338
(LIST '$ANY (MHEADER '|$'|) RIGHT))
1339
((EQ 'MQAPPLY (CAAR RIGHT))
1340
(COND ((EQ (CAAADR RIGHT) 'LAMBDA)
1341
(LIST '$ANY (MHEADER '|$'|) RIGHT))
1342
(T (RPLACA (CDR RIGHT)
1343
(CONS (CONS ($NOUNIFY (CAAADR RIGHT))
1346
(CONS '$ANY RIGHT))))
1347
(T (CONS '$ANY (CONS (CONS ($NOUNIFY (CAAR RIGHT)) (CDAR RIGHT))
1350
(DEF-NUD (|$''|) (OP)
1353
(COND ((EQ '|$(| (FIRST-C)) (MEVAL (PARSE '$ANY 190.)))
1354
((ATOM (SETQ RIGHT (PARSE '$ANY 190.))) (MEVAL1 RIGHT))
1355
((EQ 'MQAPPLY (CAAR RIGHT))
1357
(CONS (CONS ($VERBIFY (CAAADR RIGHT)) (CDAADR RIGHT))
1360
(T (CONS (CONS ($VERBIFY (CAAR RIGHT)) (CDAR RIGHT))
1363
(DEF-LED-EQUIV |$:| PARSE-INFIX)
1367
(DEF-RPOS |$:| $ANY)
1368
(DEF-LPOS |$:| $ANY)
1369
(DEF-MHEADER |$:| (MSETQ))
1371
(DEF-LED-EQUIV |$::| PARSE-INFIX)
1372
(DEF-LBP |$::| 180.)
1374
(DEF-POS |$::| $ANY)
1375
(DEF-RPOS |$::| $ANY)
1376
(DEF-LPOS |$::| $ANY)
1377
(DEF-MHEADER |$::| (MSET))
1379
(DEF-LED-EQUIV |$:=| PARSE-INFIX)
1380
(DEF-LBP |$:=| 180.)
1382
(DEF-POS |$:=| $ANY)
1383
(DEF-RPOS |$:=| $ANY)
1384
(DEF-LPOS |$:=| $ANY)
1385
(DEF-MHEADER |$:=| (MDEFINE))
1387
(DEF-LED-EQUIV |$::=| PARSE-INFIX)
1388
(DEF-LBP |$::=| 180.)
1389
(DEF-RBP |$::=| 20.)
1390
(DEF-POS |$::=| $ANY)
1391
(DEF-RPOS |$::=| $ANY)
1392
(DEF-LPOS |$::=| $ANY)
1393
(DEF-MHEADER |$::=| (MDEFMACRO))
1395
(DEF-LED-EQUIV |$!| PARSE-POSTFIX)
1318
(cons '$any ;Result is type $ANY
1319
(cond ((atom left) ;If atom(...) =>
1320
(cons hdr r)) ;(($atom) exp . args)
1321
(t ;Else exp(...) =>
1322
(cons '(mqapply) (cons left r))))))) ;((MQAPPLY) op . args)
1324
(def-mheader |$'| (mquote))
1326
(def-nud (|$'|) (op)
1328
(cond ((eq '|$(| (first-c))
1329
(list '$any (mheader '|$'|) (parse '$any 190.)))
1330
((or (atom (setq right (parse '$any 190.)))
1331
(memq (caar right) '(mquote mlist mprog mprogn lambda)))
1332
(list '$any (mheader '|$'|) right))
1333
((eq 'mqapply (caar right))
1334
(cond ((eq (caaadr right) 'lambda)
1335
(list '$any (mheader '|$'|) right))
1336
(t (rplaca (cdr right)
1337
(cons (cons ($nounify (caaadr right))
1340
(cons '$any right))))
1341
(t (cons '$any (cons (cons ($nounify (caar right)) (cdar right))
1344
(def-nud (|$''|) (op)
1347
(cond ((eq '|$(| (first-c)) (meval (parse '$any 190.)))
1348
((atom (setq right (parse '$any 190.))) (meval1 right))
1349
((eq 'mqapply (caar right))
1351
(cons (cons ($verbify (caaadr right)) (cdaadr right))
1354
(t (cons (cons ($verbify (caar right)) (cdar right))
1357
(def-led-equiv |$:| parse-infix)
1361
(def-rpos |$:| $any)
1362
(def-lpos |$:| $any)
1363
(def-mheader |$:| (msetq))
1365
(def-led-equiv |$::| parse-infix)
1366
(def-lbp |$::| 180.)
1368
(def-pos |$::| $any)
1369
(def-rpos |$::| $any)
1370
(def-lpos |$::| $any)
1371
(def-mheader |$::| (mset))
1373
(def-led-equiv |$:=| parse-infix)
1374
(def-lbp |$:=| 180.)
1376
(def-pos |$:=| $any)
1377
(def-rpos |$:=| $any)
1378
(def-lpos |$:=| $any)
1379
(def-mheader |$:=| (mdefine))
1381
(def-led-equiv |$::=| parse-infix)
1382
(def-lbp |$::=| 180.)
1383
(def-rbp |$::=| 20.)
1384
(def-pos |$::=| $any)
1385
(def-rpos |$::=| $any)
1386
(def-lpos |$::=| $any)
1387
(def-mheader |$::=| (mdefmacro))
1389
(def-led-equiv |$!| parse-postfix)
1398
(DEF-POS |$!| $EXPR)
1399
(DEF-LPOS |$!| $EXPR)
1392
(def-pos |$!| $expr)
1393
(def-lpos |$!| $expr)
1401
(DEF-MHEADER |$!| (MFACTORIAL))
1403
(DEF-MHEADER |$!!| ($GENFACT))
1405
(DEF-LED (|$!!| 160.) (OP LEFT)
1408
(CONVERT LEFT '$EXPR)
1409
(LIST (MHEADER '#-cl $// #+cl $/ ) (CONVERT LEFT '$EXPR) 2)
1395
(def-mheader |$!| (mfactorial))
1397
(def-mheader |$!!| ($genfact))
1399
(def-led (|$!!| 160.) (op left)
1402
(convert left '$expr)
1403
(list (mheader '#-cl $// #+cl $/ ) (convert left '$expr) 2)
1414
(DEF-POS |$^| $EXPR)
1415
(DEF-LPOS |$^| $EXPR)
1416
(DEF-RPOS |$^| $EXPR)
1417
(DEF-MHEADER |$^| (MEXPT))
1419
(DEF-LED ((|$^| |$^^|)) (OP LEFT)
1421
(ALIASLOOKUP (LIST (MHEADER OP)
1422
(CONVERT LEFT (LPOS OP))
1423
(PARSE (RPOS OP) (RBP OP))))))
1425
(MAPC #'(LAMBDA (PROP) ; Make $** like $^
1426
(LET ((PROPVAL (GET '$^ PROP)))
1427
(IF PROPVAL (PUTPROP '$** PROPVAL PROP))))
1428
'(LBP RBP POS RPOS LPOS MHEADER))
1429
(INHERIT-PROPL '$** '$^ (LED-PROPL))
1431
(DEF-LBP |$^^| 140.)
1432
(DEF-RBP |$^^| 139.)
1433
(DEF-POS |$^^| $EXPR)
1434
(DEF-LPOS |$^^| $EXPR)
1435
(DEF-RPOS |$^^| $EXPR)
1436
(DEF-MHEADER |$^^| (MNCEXPT))
1408
(def-pos |$^| $expr)
1409
(def-lpos |$^| $expr)
1410
(def-rpos |$^| $expr)
1411
(def-mheader |$^| (mexpt))
1413
(def-led ((|$^| |$^^|)) (op left)
1415
(aliaslookup (list (mheader op)
1416
(convert left (lpos op))
1417
(parse (rpos op) (rbp op))))))
1419
(mapc #'(lambda (prop) ; Make $** like $^
1420
(let ((propval (get '$^ prop)))
1421
(if propval (putprop '$** propval prop))))
1422
'(lbp rbp pos rpos lpos mheader))
1423
(inherit-propl '$** '$^ (led-propl))
1425
(def-lbp |$^^| 140.)
1426
(def-rbp |$^^| 139.)
1427
(def-pos |$^^| $expr)
1428
(def-lpos |$^^| $expr)
1429
(def-rpos |$^^| $expr)
1430
(def-mheader |$^^| (mncexpt))
1438
1432
;; note y^^4.z gives an error because it scans the number 4 together with
1439
1433
;; the trailing '.' as a decimal place. I think the error is correct.
1440
(DEF-LED-EQUIV |$.| PARSE-INFIX)
1443
(DEF-POS |$.| $EXPR)
1444
(DEF-LPOS |$.| $EXPR)
1445
(DEF-RPOS |$.| $EXPR)
1446
(DEF-MHEADER |$.| (MNCTIMES))
1434
(def-led-equiv |$.| parse-infix)
1437
(def-pos |$.| $expr)
1438
(def-lpos |$.| $expr)
1439
(def-rpos |$.| $expr)
1440
(def-mheader |$.| (mnctimes))
1448
(DEF-LED-EQUIV |$*| PARSE-NARY)
1442
(def-led-equiv |$*| parse-nary)
1450
1444
;RBP not needed
1451
(DEF-POS |$*| $EXPR)
1445
(def-pos |$*| $expr)
1452
1446
;RPOS not needed
1453
(DEF-LPOS |$*| $EXPR)
1454
(DEF-MHEADER |$*| (MTIMES))
1456
(DEF-LED-EQUIV #-cl |$//| #+cl $/ PARSE-INFIX)
1457
(DEF-LBP #-cl |$//| #+cl $/ 120.)
1458
(DEF-RBP #-cl |$//| #+cl $/ 120.)
1459
(DEF-POS #-cl |$//| #+cl $/ $EXPR)
1460
(DEF-RPOS #-cl |$//| #+cl $/ $EXPR)
1461
(DEF-LPOS #-cl |$//| #+cl $/ $EXPR)
1462
(DEF-MHEADER #-cl |$//| #+cl $/ (MQUOTIENT))
1464
(DEF-NUD-EQUIV |$+| PARSE-PREFIX)
1467
(DEF-POS |$+| $EXPR)
1468
(DEF-RPOS |$+| $EXPR)
1470
(DEF-MHEADER |$+| (MPLUS))
1472
(DEF-LED ((|$+| |$-|) 100.) (OP LEFT)
1473
(SETQ LEFT (CONVERT LEFT '$EXPR))
1474
(DO ((NL (LIST (IF (EQ OP '$-)
1475
(LIST (MHEADER '$-) (PARSE '$EXPR 100.))
1476
(PARSE '$EXPR 100.))
1478
(CONS (PARSE '$EXPR 100.) NL)))
1479
((NOT (MEMQ (FIRST-C) '($+ $-)))
1480
(LIST* '$EXPR (MHEADER '$+) (NREVERSE NL)))
1481
(IF (EQ (FIRST-C) '$+) (POP-C))))
1483
(DEF-NUD-EQUIV |$-| PARSE-PREFIX)
1486
(DEF-POS |$-| $EXPR)
1487
(DEF-RPOS |$-| $EXPR)
1489
(DEF-MHEADER |$-| (MMINUS))
1491
(DEF-LED-EQUIV |$=| PARSE-INFIX)
1494
(DEF-POS |$=| $CLAUSE)
1495
(DEF-RPOS |$=| $EXPR)
1496
(DEF-LPOS |$=| $EXPR)
1497
(DEF-MHEADER |$=| (MEQUAL))
1499
(DEF-LED-EQUIV |$#| PARSE-INFIX)
1502
(DEF-POS |$#| $CLAUSE)
1503
(DEF-RPOS |$#| $EXPR)
1504
(DEF-LPOS |$#| $EXPR)
1505
(DEF-MHEADER |$#| (MNOTEQUAL))
1507
(DEF-LED-EQUIV |$>| PARSE-INFIX)
1510
(DEF-POS |$>| $CLAUSE)
1511
(DEF-RPOS |$>| $EXPR)
1512
(DEF-LPOS |$>| $EXPR)
1513
(DEF-MHEADER |$>| (MGREATERP))
1515
(DEF-LED-EQUIV |$>=| PARSE-INFIX)
1518
(DEF-POS |$>=| $CLAUSE)
1519
(DEF-RPOS |$>=| $EXPR)
1520
(DEF-LPOS |$>=| $EXPR)
1521
(DEF-MHEADER |$>=| (MGEQP))
1524
(DEF-NUD (|$>| 80.) (OP) ; > is a single-char object
1527
(DEF-LED-EQUIV |$<| PARSE-INFIX)
1530
(DEF-POS |$<| $CLAUSE)
1531
(DEF-RPOS |$<| $EXPR)
1532
(DEF-LPOS |$<| $EXPR)
1533
(DEF-MHEADER |$<| (MLESSP))
1535
(DEF-LED-EQUIV |$<=| PARSE-INFIX)
1538
(DEF-POS |$<=| $CLAUSE)
1539
(DEF-RPOS |$<=| $EXPR)
1540
(DEF-LPOS |$<=| $EXPR)
1541
(DEF-MHEADER |$<=| (MLEQP))
1543
(DEF-NUD-EQUIV |$NOT| PARSE-PREFIX)
1447
(def-lpos |$*| $expr)
1448
(def-mheader |$*| (mtimes))
1450
(def-led-equiv #-cl |$//| #+cl $/ parse-infix)
1451
(def-lbp #-cl |$//| #+cl $/ 120.)
1452
(def-rbp #-cl |$//| #+cl $/ 120.)
1453
(def-pos #-cl |$//| #+cl $/ $expr)
1454
(def-rpos #-cl |$//| #+cl $/ $expr)
1455
(def-lpos #-cl |$//| #+cl $/ $expr)
1456
(def-mheader #-cl |$//| #+cl $/ (mquotient))
1458
(def-nud-equiv |$+| parse-prefix)
1461
(def-pos |$+| $expr)
1462
(def-rpos |$+| $expr)
1464
(def-mheader |$+| (mplus))
1466
(def-led ((|$+| |$-|) 100.) (op left)
1467
(setq left (convert left '$expr))
1468
(do ((nl (list (if (eq op '$-)
1469
(list (mheader '$-) (parse '$expr 100.))
1470
(parse '$expr 100.))
1472
(cons (parse '$expr 100.) nl)))
1473
((not (memq (first-c) '($+ $-)))
1474
(list* '$expr (mheader '$+) (nreverse nl)))
1475
(if (eq (first-c) '$+) (pop-c))))
1477
(def-nud-equiv |$-| parse-prefix)
1480
(def-pos |$-| $expr)
1481
(def-rpos |$-| $expr)
1483
(def-mheader |$-| (mminus))
1485
(def-led-equiv |$=| parse-infix)
1488
(def-pos |$=| $clause)
1489
(def-rpos |$=| $expr)
1490
(def-lpos |$=| $expr)
1491
(def-mheader |$=| (mequal))
1493
(def-led-equiv |$#| parse-infix)
1496
(def-pos |$#| $clause)
1497
(def-rpos |$#| $expr)
1498
(def-lpos |$#| $expr)
1499
(def-mheader |$#| (mnotequal))
1501
(def-led-equiv |$>| parse-infix)
1504
(def-pos |$>| $clause)
1505
(def-rpos |$>| $expr)
1506
(def-lpos |$>| $expr)
1507
(def-mheader |$>| (mgreaterp))
1509
(def-led-equiv |$>=| parse-infix)
1512
(def-pos |$>=| $clause)
1513
(def-rpos |$>=| $expr)
1514
(def-lpos |$>=| $expr)
1515
(def-mheader |$>=| (mgeqp))
1517
(def-led-equiv |$<| parse-infix)
1520
(def-pos |$<| $clause)
1521
(def-rpos |$<| $expr)
1522
(def-lpos |$<| $expr)
1523
(def-mheader |$<| (mlessp))
1525
(def-led-equiv |$<=| parse-infix)
1528
(def-pos |$<=| $clause)
1529
(def-rpos |$<=| $expr)
1530
(def-lpos |$<=| $expr)
1531
(def-mheader |$<=| (mleqp))
1533
(def-nud-equiv $not parse-prefix)
1544
1534
;LBP not needed
1545
(DEF-RBP |$NOT| 70.)
1546
(DEF-POS |$NOT| $CLAUSE)
1547
(DEF-RPOS |$NOT| $CLAUSE)
1548
(DEF-LPOS |$NOT| $CLAUSE)
1549
(DEF-MHEADER |$NOT| (MNOT))
1551
(DEF-LED-EQUIV |$AND| PARSE-NARY)
1552
(DEF-LBP |$AND| 65.)
1554
(DEF-POS |$AND| $CLAUSE)
1556
(DEF-LPOS |$AND| $CLAUSE)
1557
(DEF-MHEADER |$AND| (MAND))
1559
(DEF-LED-EQUIV |$OR| PARSE-NARY)
1562
(DEF-POS |$OR| $CLAUSE)
1564
(DEF-LPOS |$OR| $CLAUSE)
1565
(DEF-MHEADER |$OR| (MOR))
1567
(DEF-LED-EQUIV |$,| PARSE-NARY)
1572
(DEF-LPOS |$,| $ANY)
1573
(DEF-MHEADER |$,| ($EV))
1575
(DEF-NUD-EQUIV |$THEN| DELIM-ERR)
1576
(DEF-LBP |$THEN| 5.)
1577
(DEF-RBP |$THEN| 25.)
1579
(DEF-NUD-EQUIV |$ELSE| DELIM-ERR)
1580
(DEF-LBP |$ELSE| 5.)
1581
(DEF-RBP |$ELSE| 25.)
1583
(DEF-NUD-EQUIV |$ELSEIF| DELIM-ERR)
1584
(DEF-LBP |$ELSEIF| 5.)
1585
(DEF-RBP |$ELSEIF| 45.)
1586
(DEF-POS |$ELSEIF| $ANY)
1587
(DEF-RPOS |$ELSEIF| $CLAUSE)
1536
(def-pos $not $clause)
1537
(def-rpos $not $clause)
1538
(def-lpos $not $clause)
1539
(def-mheader $not (mnot))
1541
(def-led-equiv $and parse-nary)
1544
(def-pos $and $clause)
1546
(def-lpos $and $clause)
1547
(def-mheader $and (mand))
1549
(def-led-equiv $or parse-nary)
1552
(def-pos $or $clause)
1554
(def-lpos $or $clause)
1555
(def-mheader $or (mor))
1557
(def-led-equiv |$,| parse-nary)
1562
(def-lpos |$,| $any)
1563
(def-mheader |$,| ($ev))
1565
(def-nud-equiv $then delim-err)
1569
(def-nud-equiv $else delim-err)
1573
(def-nud-equiv $elseif delim-err)
1574
(def-lbp $elseif 5.)
1575
(def-rbp $elseif 45.)
1576
(def-pos $elseif $any)
1577
(def-rpos $elseif $clause)
1589
1579
;No LBP - Default as high as possible
1592
(DEF-RPOS $IF $CLAUSE)
1582
(def-rpos $if $clause)
1594
(DEF-MHEADER $IF (MCOND))
1596
(DEF-NUD (|$IF|) (OP)
1599
(PARSE-CONDITION OP)))
1601
(DEFUN PARSE-CONDITION (OP)
1602
(LIST* (PARSE (RPOS OP) (RBP OP))
1603
(IF (EQ (FIRST-C) '$THEN)
1604
(PARSE '$ANY (RBP (POP-C)))
1605
(MREAD-SYNERR "Missing THEN"))
1607
(($ELSE) (LIST T (PARSE '$ANY (RBP (POP-C)))))
1608
(($ELSEIF) (PARSE-CONDITION (POP-C)))
1609
(T ; Note: $FALSE instead of () makes DISPLA suppress display!
1610
(LIST T '$FALSE)))))
1612
(DEF-MHEADER $DO (MDO))
1614
(DEFUN PARSE-$DO (LEX &aux (left (make-mdo)))
1615
(setf (car LEFT) (mheader 'mdo))
1616
(DO ((OP LEX (POP-C)) (ACTIVE-BITMASK 0))
1618
(IF (EQ OP '|$:|) (SETQ OP '$FROM))
1619
(SETQ ACTIVE-BITMASK (COLLISION-CHECK '$DO ACTIVE-BITMASK OP))
1620
(LET ((DATA (PARSE (RPOS OP) (RBP OP))))
1622
($DO (SETF (MDO-BODY LEFT) DATA) (RETURN (CONS '$ANY LEFT)))
1623
($FOR (SETF (MDO-FOR LEFT) DATA))
1624
($FROM (SETF (MDO-FROM LEFT) DATA))
1625
($IN (SETF (MDO-OP LEFT) 'MDOIN)
1626
(SETF (MDO-FROM LEFT) DATA))
1627
($STEP (SETF (MDO-STEP LEFT) DATA))
1628
($NEXT (SETF (MDO-NEXT LEFT) DATA))
1629
($THRU (SETF (MDO-THRU LEFT) DATA))
1632
(SETQ DATA (LIST (MHEADER '$NOT) DATA)))
1633
(SETF (MDO-UNLESS LEFT)
1634
(IF (NULL (MDO-UNLESS LEFT))
1636
(LIST (MHEADER '$OR) DATA (MDO-UNLESS LEFT)))))
1637
(T (PARSE-BUG-ERR '$DO))))))
1644
(DEF-LBP $UNLESS 25.)
1645
(DEF-LBP $WHILE 25.)
1648
(DEF-NUD-EQUIV $FOR PARSE-$DO)
1649
(DEF-NUD-EQUIV $FROM PARSE-$DO)
1650
(DEF-NUD-EQUIV $STEP PARSE-$DO)
1651
(DEF-NUD-EQUIV $NEXT PARSE-$DO)
1652
(DEF-NUD-EQUIV $THRU PARSE-$DO)
1653
(DEF-NUD-EQUIV $UNLESS PARSE-$DO)
1654
(DEF-NUD-EQUIV $WHILE PARSE-$DO)
1655
(DEF-NUD-EQUIV $DO PARSE-$DO)
1664
(DEF-RBP $UNLESS 45.)
1665
(DEF-RBP $WHILE 45.)
1668
(DEF-RPOS $FOR $ANY)
1669
(DEF-RPOS $FROM $ANY)
1670
(DEF-RPOS $STEP $EXPR)
1671
(DEF-RPOS $NEXT $ANY)
1672
(DEF-RPOS $THRU $EXPR)
1673
(DEF-RPOS $UNLESS $CLAUSE)
1674
(DEF-RPOS $WHILE $CLAUSE)
1680
($FROM . ($IN $FROM))
1681
($IN . ($IN $FROM $STEP $NEXT))
1682
($STEP . ($IN $STEP $NEXT))
1683
($NEXT . ($IN $STEP $NEXT))
1684
($THRU . ($IN $THRU)) ;$IN didn't used to get checked for
1688
#+ti ;;because of a bug the preceding doesn't give this..
1689
(defprop $do (($WHILE . 256) ($UNLESS . 128)
1699
(DEF-MHEADER |$$| (NODISPLAYINPUT))
1700
(DEF-NUD-EQUIV |$$| PREMTERM-ERR)
1702
;No RBP, POS, RPOS, RBP, or MHEADER
1704
(DEF-MHEADER |$;| (DISPLAYINPUT))
1705
(DEF-NUD-EQUIV |$;| PREMTERM-ERR)
1707
;No RBP, POS, RPOS, RBP, or MHEADER
1709
(DEF-NUD-EQUIV |$&&| DELIM-ERR)
1584
(def-mheader $if (mcond))
1589
(parse-condition op)))
1591
(defun parse-condition (op)
1592
(list* (parse (rpos op) (rbp op))
1593
(if (eq (first-c) '$then)
1594
(parse '$any (rbp (pop-c)))
1595
(mread-synerr "Missing `then'"))
1597
(($else) (list t (parse '$any (rbp (pop-c)))))
1598
(($elseif) (parse-condition (pop-c)))
1599
(t ; Note: $false instead of () makes DISPLA suppress display!
1600
(list t '$false)))))
1602
(def-mheader $do (mdo))
1604
(defun parse-$do (lex &aux (left (make-mdo)))
1605
(setf (car left) (mheader 'mdo))
1606
(do ((op lex (pop-c)) (active-bitmask 0))
1608
(if (eq op '|$:|) (setq op '$from))
1609
(setq active-bitmask (collision-check '$do active-bitmask op))
1610
(let ((data (parse (rpos op) (rbp op))))
1612
($do (setf (mdo-body left) data) (return (cons '$any left)))
1613
($for (setf (mdo-for left) data))
1614
($from (setf (mdo-from left) data))
1615
($in (setf (mdo-op left) 'mdoin)
1616
(setf (mdo-from left) data))
1617
($step (setf (mdo-step left) data))
1618
($next (setf (mdo-next left) data))
1619
($thru (setf (mdo-thru left) data))
1622
(setq data (list (mheader '$not) data)))
1623
(setf (mdo-unless left)
1624
(if (null (mdo-unless left))
1626
(list (mheader '$or) data (mdo-unless left)))))
1627
(t (parse-bug-err '$do))))))
1634
(def-lbp $unless 25.)
1635
(def-lbp $while 25.)
1638
(def-nud-equiv $for parse-$do)
1639
(def-nud-equiv $from parse-$do)
1640
(def-nud-equiv $step parse-$do)
1641
(def-nud-equiv $next parse-$do)
1642
(def-nud-equiv $thru parse-$do)
1643
(def-nud-equiv $unless parse-$do)
1644
(def-nud-equiv $while parse-$do)
1645
(def-nud-equiv $do parse-$do)
1654
(def-rbp $unless 45.)
1655
(def-rbp $while 45.)
1658
(def-rpos $for $any)
1659
(def-rpos $from $any)
1660
(def-rpos $step $expr)
1661
(def-rpos $next $any)
1662
(def-rpos $thru $expr)
1663
(def-rpos $unless $clause)
1664
(def-rpos $while $clause)
1670
($from . ($in $from))
1671
($in . ($in $from $step $next))
1672
($step . ($in $step $next))
1673
($next . ($in $step $next))
1674
($thru . ($in $thru)) ;$IN didn't used to get checked for
1678
;#+ti ;;because of a bug the preceding doesn't give this..
1679
;(defprop $do (($WHILE . 256) ($UNLESS . 128)
1689
(def-mheader |$$| (nodisplayinput))
1690
(def-nud-equiv |$$| premterm-err)
1692
;No RBP, POS, RPOS, RBP, or MHEADER
1694
(def-mheader |$;| (displayinput))
1695
(def-nud-equiv |$;| premterm-err)
1697
;No RBP, POS, RPOS, RBP, or MHEADER
1699
(def-nud-equiv |$&&| delim-err)
1713
1703
;; kludge interface function to allow the use of lisp PRINC in places.
1714
(COND ((NULL X) 'FALSE)
1715
((OR (EQ X T) (EQ X 'T)) 'TRUE)
1718
(OR (GET X 'REVERSEALIAS)
1719
(IF (IMEMBER (FIRSTCHARN X) '(#\$ #\% #\&))
1720
(IMPLODE (CDR (EXPLODEN X)))
1722
(T (MAKNAM (MSTRING X)))))
1704
(cond ((null x) 'false)
1705
((or (eq x t) (eq x 't)) 'true)
1708
(or (get x 'reversealias)
1709
(if (imember (firstcharn x) '(#\$ #\% #\&))
1710
(implode (cdr (exploden x)))
1712
(t (maknam (mstring x)))))
1725
(DEFINE-INITIAL-SYMBOLS
1714
(define-initial-symbols
1726
1715
;; * Note: /. is looked for explicitly rather than
1727
1716
;; existing in this chart. The reason is that
1728
1717
;; it serves a dual role (as a decimal point) and
1808
1793
;;; For more complete descriptions of these naming conventions, see
1809
1794
;;; the comments in GRAM package, which describe them in reasonable detail.
1811
(DEFUN DEF-OPERATOR (OP POS LBP LPOS RBP RPOS SP1 SP2
1812
PARSE-DATA GRIND-FN DIM-FN MATCH)
1814
(IF (OR (AND RBP (NOT (INTEGERP (SETQ X RBP))))
1815
(AND LBP (NOT (INTEGERP (SETQ X LBP)))))
1816
(MERROR "Binding powers must be integers.~%~M is not an integer." X))
1817
(IF (MSTRINGP OP) (SETQ OP (DEFINE-SYMBOL OP)))
1819
(LET ((NOUN ($NOUNIFY OP))
1820
(DISSYM (CDR (EXPLODEN OP))))
1796
(defun def-operator (op pos lbp lpos rbp rpos sp1 sp2
1797
parse-data grind-fn dim-fn match)
1799
(if (or (and rbp (not (integerp (setq x rbp))))
1800
(and lbp (not (integerp (setq x lbp)))))
1801
(merror "Binding powers must be integers.~%~M is not an integer." x))
1802
(if (mstringp op) (setq op (define-symbol op)))
1804
(let ((noun ($nounify op))
1805
(dissym (cdr (exploden op))))
1823
(SETQ DISSYM (APPEND (IF SP1 '(#\Space)) DISSYM (IF SP2 '(#\Space)))))
1824
(t (IF (MSTRINGP MATCH) (SETQ MATCH (DEFINE-SYMBOL MATCH)))
1826
(PUTPROP OP MATCH 'MATCH)
1827
(PUTPROP MATCH 5. 'LBP)
1828
(SETQ DISSYM (CONS DISSYM (CDR (EXPLODEN MATCH))))))
1829
(PUTPROP OP POS 'POS)
1830
(PUTPROP OP (CDR PARSE-DATA) (CAR PARSE-DATA))
1831
(PUTPROP OP GRIND-FN 'GRIND)
1832
(PUTPROP OP DIM-FN 'DIMENSION)
1833
(PUTPROP NOUN DIM-FN 'DIMENSION)
1834
(PUTPROP OP DISSYM 'DISSYM)
1835
(PUTPROP NOUN DISSYM 'DISSYM)
1837
(PUTPROP OP RBP 'RBP)
1838
(PUTPROP NOUN RBP 'RBP))
1840
(PUTPROP OP LBP 'LBP)
1841
(PUTPROP NOUN LBP 'LBP))
1842
(WHEN LPOS (PUTPROP OP LPOS 'LPOS))
1843
(WHEN RPOS (PUTPROP OP RPOS 'RPOS))
1808
(setq dissym (append (if sp1 '(#\space)) dissym (if sp2 '(#\space)))))
1809
(t (if (mstringp match) (setq match (define-symbol match)))
1811
(putprop op match 'match)
1812
(putprop match 5. 'lbp)
1813
(setq dissym (cons dissym (cdr (exploden match))))))
1814
(putprop op pos 'pos)
1815
(putprop op (cdr parse-data) (car parse-data))
1816
(putprop op grind-fn 'grind)
1817
(putprop op dim-fn 'dimension)
1818
(putprop noun dim-fn 'dimension)
1819
(putprop op dissym 'dissym)
1820
(putprop noun dissym 'dissym)
1822
(putprop op rbp 'rbp)
1823
(putprop noun rbp 'rbp))
1825
(putprop op lbp 'lbp)
1826
(putprop noun lbp 'lbp))
1827
(when lpos (putprop op lpos 'lpos))
1828
(when rpos (putprop op rpos 'rpos))
1846
(DEFUN OP-SETUP (OP)
1831
(defun op-setup (op)
1847
1832
(declare (special mopl))
1848
(LET ((DUMMY (OR (GET OP 'OP)
1849
(IMPLODE (CONS '& (STRING* OP))))))
1850
(PUTPROP OP DUMMY 'OP )
1851
(PUTPROP DUMMY OP 'OPR)
1852
(IF (AND (OPERATORP1 OP) (NOT (MEMQ DUMMY (CDR $PROPS))))
1854
(ADD2LNC DUMMY $PROPS)))
1833
(let ((dummy (or (get op 'op)
1834
(implode (cons '& (string* op))))))
1835
(putprop op dummy 'op )
1836
(putprop dummy op 'opr)
1837
(if (and (operatorp1 op) (not (memq dummy (cdr $props))))
1839
(add2lnc dummy $props)))
1856
(DEFUN KILL-OPERATOR (OP)
1857
(UNDEFINE-SYMBOL (STRIPDOLLAR OP))
1858
(LET ((OPR (GET OP 'OP)) (NOUN-FORM ($NOUNIFY OP)))
1861
(MAPC #'(LAMBDA (X) (REMPROP OP X))
1862
'(NUD-EXPR NUD-SUBR ; NUD info
1863
LED LED-EXPR LED-SUBR ; LED info
1864
LBP RBP ; Binding power info
1865
LPOS RPOS POS ; Part-Of-Speech info
1866
GRIND DIMENSION DISSYM ; Display info
1841
(defun kill-operator (op)
1842
(undefine-symbol (stripdollar op))
1843
(let ((opr (get op 'op)) (noun-form ($nounify op)))
1846
(mapc #'(lambda (x) (remprop op x))
1847
'(nud nud-expr nud-subr ; NUD info
1848
led led-expr led-subr ; LED info
1849
lbp rbp ; Binding power info
1850
lpos rpos pos ; Part-Of-Speech info
1851
grind dimension dissym ; Display info
1868
1853
)) ; Operator info
1869
(MAPC #'(LAMBDA (X) (REMPROP NOUN-FORM X))
1870
'(DIMENSION DISSYM LBP RBP))))
1854
(mapc #'(lambda (x) (remprop noun-form x))
1855
'(dimension dissym lbp rbp))))