From bbfb61f736406a019555a38d97e4b2646c844a45 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Fri, 19 Jul 2024 17:44:24 -0700 Subject: [PATCH] Add printer echo support --- doc/DRAWL.md | 130 ++++++++++++++++++++++++++++++++++++++++++ images/apple/DRAWL.po | Bin 143360 -> 143360 bytes src/lisp/drawl.pla | 55 ++++++++++++------ 3 files changed, 169 insertions(+), 16 deletions(-) diff --git a/doc/DRAWL.md b/doc/DRAWL.md index 01831e3..c8dee36 100644 --- a/doc/DRAWL.md +++ b/doc/DRAWL.md @@ -21,6 +21,132 @@ However, the code is partitioned to allow for easy extension so some of these mi - Bit-wise logic operations on 32 bit integers - Hexadecimal input/output +Thes DRAWL implementation comes with the follwoing built-in: + +### Constants +- T = True +- F = False +- NIL = NULL +- SPACE = SPACE character on output +- CR = Carriage Return character on output +- CSET() +- CSETQ() +- DEFINE() + +### Function types + +- LAMBDA +- FUNARG +- FUNCTION + + +### Predicates + +- ATOM() +- EQ() +- NOT() +- AND(...) +- OR(...) +- NULL() + +### Misc + +- SET +- QUOTE() +- ARRAY +- TRACE() = Turn tracing on/off +- GC() = Run garbage collector and return free memory amount +- QUIT() = Exit REPL + +### List manipulation + +- CAR() +- CDR() +- CONS() +- LIST(...) + +### Conditionals + +- COND(...) +- IF() + +### Output + +- PRHEX() = Turn hexadecimal output on/off +- PRI(...) = Print without newline +- PRINT(...) = Print with newline +- FMTFPI() = Floating point format integer digits +- FMTFPF() = Floating point format fractional digits +- PRINTER() = Turn printer echo on/off on slot# + +### Looping + +- FOR() +- WHILE() +- UNTIL() + +### Associations + +- LABEL() +- SET() +- SETQ() + +### Program feature + +- PROG +- GO() +- RETURN() + +### Numbers + +- +() +- -() +- '\*'() +- /() +- REM() +- NEG() +- ABS() +- >() +- <() +- MIN() +- MAX() + +### Integers + +- BITNOT() = Bit-wise NOT +- BITAND() = Bit-wise AND +- BITOR() = Bit-wise OR +- BITXOR= Bit-wise XOR +- SHIFT() = Bit-wise SHIFT (positive = left, negative = right) +- ROTATE() = Bit-wise ROTATE (positive = left, negative = right) + +### Floating Point (from the SANE library) + +- PI() +- MATH_E() +- LOGB() +- SCALEB_I() +- TRUNCATE() +- ROUND() +- SQRT() +- COS() +- SIN() +- TAN() +- ATAN() +- LOG2() +- LOG2_1() +- LN() +- LN_1() +- POW2() +- POW2_1() +- POWE() +- POWE_1() +- POWE2_1() +- POW_I() +- POWY() +- COMP() +- ANNUITY() + LISP is one of the earliest computer languages. As such, it holds a special place in the anals of computer science. I've always wanted to learn why LISP is held in such high regard by so many, so I went about learning LISP by actually implementing a LISP interpreter in PLASMA. PLASMA is well suited to implement other languages due to its rich syntax, performance and libraries. ## Links @@ -29,6 +155,10 @@ Here are some links to get you started. LISP 1.5 Manual: https://archive.org/details/bitsavers_mitrlelisprammersManual2ed1985_9279667 +LISP 1.5 Primer: https://www.softwarepreservation.org/projects/LISP/book/Weismann_LISP1.5_Primer_1967.pdf + +Apple Numerics Manual (SANE): https://vintageapple.org/inside_o/pdf/Apple_Numerics_Manual_Second_Edition_1988.pdf + Video showing DRAWL in action: https://youtu.be/wBMivg6xfSg Preconfigured PLASMA ProDOS boot floppy for DRAWL: https://github.com/dschmenk/PLASMA/blob/master/images/apple/DRAWL.po diff --git a/images/apple/DRAWL.po b/images/apple/DRAWL.po index 9fd625259a29efb021965dd436ca7540bcf1ea7a..175c3885329675f8696fabf892be4df4d69e8b4f 100644 GIT binary patch delta 2087 zcmZWqZERCj7=F*Wr|sx)yKSeym|OX1p&fK{e2tF*wJW1?yOymTu%L{u#Z+b4wSBjX`feAU^^4+Z7NRR;zgIiWk_d~6x(QEd&&lZvHa=HZPmlkMOUO)KHM5#- z%ZS9uTw7)vP7A|YThQ~Qal8?2A6Rm2nONdZVcXZO+gcw_N^@zHIFZP;Wkh0?p(1#q(5nuFf0xtXFEv9c*KSGXnAlndd_EWVGx6`kM`PKy{Y}PtljHxeRRII<W;^()Ye7m-B+vU>1ap!d=quj(QcY3><`;AQI*>5c~n@toMvbJ+n$XR7e52e~pbYXd72bA#Xq7JPIqhcl0*1J;G zD${e^@$y(jdQ`}UQSLtEdR8ZQKVbXK_bjm*wO%>kEJ@ycz}CdqsUDHO`G};e5sQa6 zg|fzH@fchDk!VYEwlHGxD0pwP?uNx9;5KKi%ZgTC*3?@)rf>`Xv;8gE$|0*qY>o!9 z&5hZ!n|4OjfPWVb#*XNLB+& zffYalBV9v11ib_3hW~^KeUQ2Ib4<}MqVF1Toh{UV1>XTbU^V(Un=1t;Y38Jt@fy9H z&y!W~4*11-7uNPFako4G^BT-SoYE*rw}8t8$r(U7 zUFKlD|OzA(W(jh|Rcg>mi%N@RQib2F4i2FXT?c ohY6K;jLhbYU0|G#7jx4zeA|o-lyU<%PtVAwA)hME$l2WXKXv}+!vFvP delta 1954 zcmZWoZERCj7=F*Wr|sCrcH0uZ(rq1M-4}GTV|>jS>RM*!?N+*W;sk*h7uFw>7=nbz zx+4ow6A5=UG#Vu_F%TJXb0gp%B19A8XEYKsNK7#Pz!(yO66C{fKD{fY>ze!Id7k$^ z?|siX_jdSt!SMBh3BM?+EG7Dqoc}acmL@{N;hFQ4_MBYpLEjUejr8beZl*%=s>a=P zn;{Y>vu(y>IMs%<-k|$&R<-6EqN%;pHdvTtr&W$BPXXfoKO0KN|%^&E_4xBka7Ft@EH|=D8 z+Y)cMqvzRd7tKgw^!40HJU)_}`EAvKu1K>dr)>lqOPTVfZ62Gqx5S=2|7M;aAA7VZ zXZnRjsot;ogFWu{ZlB+nW&V_`M9%COBQ}*9tNf`r=S4@S82^=>A7bSm99_~m!RDP^ zGBm*)@tpiLRr|u;=d_&dJR}pHv1I2MVw!4u{1LYn=m}+#f|x>Ecz$dJBDp!i8KaNb zyjZ++njArIC^sq;)oc->1H7r9_lfPCVjI-h zCbd2uvr+FLX%2#$q+`2RuC`D=9XmjCg?%Br5ml+T$u(d*)S^-!?g zUaQ+2_D7=Ou1w*a)ve%r%eX66w}9K0u{Acdwr9+Gn_Fy)1~Sn|tvytlUTv&J?FHf5 z+p21}W+QQYwmW#6O5AHD9tO?Ph#BeX{;(_55seTz~deW-P!7J`mKZ-?Hgl*rxS_(4VJhk;>5(Z|5! z%33*z8y6LqyafIZ{3Duv2Ce|tfZtI6Ls_NYP^#rk=)aXJ{Vw!FXp3;kLP5F}yhM;( z2JM7)f!BhY!B2sGU`@Ez$uPtVDC`061rLH>10Mz-5sEwtep{^3-w}24IP?jjB%R}I z*@ayxR>?l*oXsYg!eZjN4C#$~pfZ D-J8f7 diff --git a/src/lisp/drawl.pla b/src/lisp/drawl.pla index cf49541..775e58d 100644 --- a/src/lisp/drawl.pla +++ b/src/lisp/drawl.pla @@ -59,10 +59,14 @@ import smath predef eval_int(expr)#1 end + var prog, prog_expr, prog_return // Current PROG expressions var sym_cond, sym_if, sym_fpint, sym_fpfrac var pred_true +const csw = $0036 // Output switch vector +var scrncsw = 0 // Output screen value + const FILEBUF_SIZE = 128 var readfn // Read input routine var fileref, filebuf // File read vars @@ -174,6 +178,24 @@ def natv_gc(symptr, expr) return new_int(heapavail, 0) end +def natv_printer(symptr, expr) + byte slot + + slot = eval_int(expr)=>intval & 7 + if slot + if !scrncsw + scrncsw = *csw + fin + *csw = $C000 | (slot << 8) + else + if scrncsw + *csw = scrncsw + fin + scrncsw = 0 + fin + return new_int(slot, 0) +end + def natv_bye(symptr, expr) quit = TRUE return new_sym("GOODBYE!") @@ -267,22 +289,23 @@ end // puts("DRAWL (LISP 1.5) symbolic processor\n") -pred_true = bool_pred(TRUE) // Capture value of TRUE -sym_fpint = new_sym("FMTFPI") -sym_fpfrac = new_sym("FMTFPF") -sym_fpint=>natv = @natv_fpint -sym_fpfrac=>natv = @natv_fpfrac -sym_fpint=>apval = new_int(fmt_fpint, 0) ^ NULL_HACK -sym_fpfrac=>apval = new_int(fmt_fpfrac, 0) ^ NULL_HACK -sym_cond = new_sym("COND") // This should actually match COND -sym_if = new_sym("IF") // This should actually match IF -new_sym("PROG")=>natv = @natv_prog -new_sym("GO")=>natv = @natv_go -new_sym("RETURN")=>natv = @natv_return -new_sym("SET")=>natv = @natv_set -new_sym("SETQ")=>natv = @natv_setq -new_sym("GC")=>natv = @natv_gc -new_sym("QUIT")=>natv = @natv_bye +pred_true = bool_pred(TRUE) // Capture value of TRUE +sym_fpint = new_sym("FMTFPI") +sym_fpfrac = new_sym("FMTFPF") +sym_fpint=>natv = @natv_fpint +sym_fpfrac=>natv = @natv_fpfrac +sym_fpint=>apval = new_int(fmt_fpint, 0) ^ NULL_HACK +sym_fpfrac=>apval = new_int(fmt_fpfrac, 0) ^ NULL_HACK +sym_cond = new_sym("COND") // This should actually match COND +sym_if = new_sym("IF") // This should actually match IF +new_sym("PROG")=>natv = @natv_prog +new_sym("GO")=>natv = @natv_go +new_sym("RETURN")=>natv = @natv_return +new_sym("SET")=>natv = @natv_set +new_sym("SETQ")=>natv = @natv_setq +new_sym("GC")=>natv = @natv_gc +new_sym("PRINTER")=>natv = @natv_printer +new_sym("QUIT")=>natv = @natv_bye parse_cmdline while not quit