Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
/* * This file: * http://anggtwu.net/lisptree/lisptree.mac.html * http://anggtwu.net/lisptree/lisptree.mac * (find-lisptree "lisptree.mac") * See: http://anggtwu.net/lisptree.html * https://github.com/edrx/lisptree * Author: Eduardo Ochs <eduardoochs@gmail.com> * License: Public Domain. * Version: 20241104. * * Long story short: * LispTree Draw Maxima objects as trees (using Lisp). * This Maxima command * * lisptree(f(2,g(3,4)); * * prints this: * * f__. * | | * 2 g__. * | | * 3 4 * * Here is a longer explanation. * A "Maxima object" is something like f(2,g(3,4)). * A "Maxima tree" is something like [f,2,[g,3,4]]. * A "Lispy tree " is something like ($F 2 ($G 3 4)). * A "2D tree" is something like this, * * f__. * | | * 2 g__. * | | * 3 4 * * as a string with newlines. * The main functions in this file do these conversions: * * lisptree: Maxima object --> Maxima tree --> Lispy Tree --> 2D tree * lisptreeq: Maxima object --> Maxima tree --> Lispy Tree --> 2D tree * lispytree: Maxima object --> Maxima tree --> Lispy tree --> string * lispytreeq: Maxima object --> Maxima tree --> Lispy tree --> string * lisptree0: Maxima object --> Maxima tree * * The versions that end in "q" are macros that quote their arguments. * `lisptree0' is very configurable. See `lisptree0_config' below. * * (defun e () (interactive) (find-angg "luatree/lisptree.mac")) * (find-angg "MAXIMA/luatree3.mac") * * «.load-lisp» (to "load-lisp") * «.format» (to "format") * «.atoms» (to "atoms") * «.atoms-test» (to "atoms-test") * «.lisptree0» (to "lisptree0") * «.lisptree0-tests» (to "lisptree0-tests") * «.config» (to "config") * «.config-tests» (to "config-tests") * «.lisptree» (to "lisptree") * «.lisptree-tests» (to "lisptree-tests") */ /* «load-lisp» (to ".load-lisp") * Outer part: this file. * Middle part: (find-lisptree "lisptree-middle.lisp") * Inner part: (find-lisptree "lisptree.lisp") */ lisptreedir : pathname_directory(load_pathname); load(concat(lisptreedir, "lisptree.lisp")); load(concat(lisptreedir, "lisptree-middle.lisp")); /* «format» (to ".format") */ format([args]) := apply(?format, append([false], args)); format0 (o) := format("~s",o); /* the Lisp representation of o, as a string */ stringp (o) := ?stringp(o); /* instead of an autoload to stringproc */ /* «atoms» (to ".atoms") * See: (find-maximanode "Lisp and Maxima" "Lisp symbol" "?foo") * (find-maximanode "Nouns and Verbs" "verb form" "$") * (find-maximanode "Nouns and Verbs" "noun form" "%") * (find-es "maxima" "low-level-nouns") * * Note: THIS IS BUGGY! * See the test below! */ lisptree0_string0(o) := o; /* send strings to Lisp unchanged */ lisptree0_string1(o) := format("~s", o); /* add double quotes to all strings */ lisptree0_number0(o) := o; /* send numbers to Lisp unchanged */ lisptree0_number1(o) := string(o); verbp (o) := symbolp(o) and (o = verbify(o)); nounp (o) := symbolp(o) and (o = nounify(o)); specialnounp (o) := nounp(o) and (string(o)#concat("",o)); lisptree0_symbol0(o) := o; /* send symbols to Lisp unchanged */ lisptree0_symbol1(o) := format0(o); /* Low-level names: %FOO, $FOO and FOO */ lisptree0_symbol3(o) := if nounp(o) then concat("'",string(o)) /* %DERIVATIVE -> 'diff */ else string(o); /* $FOO -> foo, FOO -> ?foo */ lisptree0_symbol4(o) := if specialnounp(o) then concat("",o) /* %DERIVATIVE -> derivative */ elseif nounp(o) then concat("'",o) /* %F -> 'f */ else string(o); /* $FOO -> foo, FOO -> ?foo */ /* «atoms-test» (to ".atoms-test") * (eepitch-maxima) * (eepitch-kill) * (eepitch-maxima) load("lisptree.mac"); _qfoo : op('foo(42)); _qdiff : op('diff(y,x)); mysymbols : [?foo, foo, _qfoo, diff, _qdiff]; lsymbol(n) := parse_string(concat("lisptree0_symbol", n)); lsyline(n) := map(lsymbol(n),mysymbols); lsylines : matrix(lsyline(0), lsyline(1), lsyline(3), lsyline(4)); propline(o) := [format0(o), verbp(o), nounp(o), specialnounp(o)]; topline : rhs(fundef(propline)); otherlines : map('propline, mysymbols); proplines : apply('matrix, append([topline],otherlines)); */ /* «config» (to ".config") */ lisptree0_config ([opts]) := makelist(lisptree0_config1(opt), opt, opts); lisptree0_config1(opt) := if opt = 'nq then lisptree0_string (o) := lisptree0_string0(o) /* no quotes */ elseif opt = 'q then lisptree0_string (o) := lisptree0_string1(o) /* use quotes */ elseif opt = 'n0 then lisptree0_number (o) := lisptree0_number0(o) elseif opt = 'n1 then lisptree0_number (o) := lisptree0_number1(o) elseif opt = 's0 then lisptree0_symbol (o) := lisptree0_symbol0(o) elseif opt = 's1 then lisptree0_symbol (o) := lisptree0_symbol1(o) elseif opt = 's3 then lisptree0_symbol (o) := lisptree0_symbol3(o) elseif opt = 's4 then lisptree0_symbol (o) := lisptree0_symbol4(o) elseif opt = 'raw then lisptree0_config('nq,'n0,'s0) elseif opt = 'lisp then lisptree0_config( 'q,'n1,'s1) elseif opt = 'maxima then lisptree0_config('nq,'n1,'s4) elseif opt = 'Maxima then lisptree0_config( 'q,'n1,'s4) else error(); /* «config-tests» (to ".config-tests") * (eepitch-maxima) * (eepitch-kill) * (eepitch-maxima) load("lisptree.mac"); lisptree0_config(nq,s0)$ lisptree0(f("foo", ?f)); lisptree0_config(q, s4)$ lisptree0(f("foo", ?f)); fundef(format); lisptree0_config('raw)$ lisptree(fundef(format)); lisptree0_config('lisp)$ lisptree(fundef(format)); lisptree0_config('maxima)$ lisptree(fundef(format)); lisptree0_config('Maxima)$ lisptree(fundef(format)); */ /* «lisptree0» (to ".lisptree0") */ lisptree0_string (o) := lisptree0_string0(o); /* Default: don't add double quotes */ lisptree0_number (o) := lisptree0_string1(o); /* Default: convert to string */ lisptree0_symbol (o) := lisptree0_symbol3(o); /* Default: "'diff" */ lisptree0_apatom (o) := append([ lisptree0(op(o))], map(lisptree0, args(o))); lisptree0_apother(o) := append(["ap", lisptree0(op(o))], map(lisptree0, args(o))); lisptree0_subvarp(o) := append(["[_]", lisptree0(op(o))], map(lisptree0, args(o))); lisptree0(o) := if stringp(o) then lisptree0_string (o) elseif symbolp(o) then lisptree0_symbol (o) elseif numberp(o) then lisptree0_number (o) elseif subvarp(o) then lisptree0_subvarp(o) elseif atom(op(o)) then lisptree0_apatom (o) else lisptree0_apother(o); /* «lisptree0-tests» (to ".lisptree0-tests") * (eepitch-maxima) * (eepitch-kill) * (eepitch-maxima) load("lisptree.mac"); lisptree0(f(a,g(b,c))); */ /* «lisptree» (to ".lisptree") * See: (find-lisptree "lisptree-middle.lisp") * These are the high-level words. */ lispytree (o) := tolispytreestr(lisptree0(o)); lispytreeq(o) ::= block([simp:false], tolispytreestr(lisptree0(o))); lisptree_ (o) := tolisptree2d_(lisptree0(o)); lisptree (o) := tolisptree2d (lisptree0(o)); lisptreeq (o) ::= block([simp:false], tolisptree2d(lisptree0(o))); /* «lisptree-tests» (to ".lisptree-tests") * (eepitch-maxima) * (eepitch-kill) * (eepitch-maxima) load("lisptree.mac"); lisptree0_config(nq,s0,n0)$ lisptreeq(a+2+3); lisptree0_config(q, s3,n0)$ lisptreeq(a+2+3); lisptree0_config(nq,s0,n0)$ lispytreeq(a+2+3); lisptree0_config(q, s3,n0)$ lisptree (a+2+3); lisptreeq(a+2+3); lisptreeq(a[b][c][d]); lisptreeq(a(b)(c)(d)); lisptree0_config(q, s0)$ lisptreeq('diff(x^2,x)); "%DERIVATIVE"$ lisptree0_config(nq,s4)$ lisptreeq('diff(x^2,x)); "derivative"$ lisptree0_config(nq,s3)$ lisptreeq('diff(x^2,x)); "'diff"$ lisptree0_config(q, s3)$ lisptreeq('diff(x^2,x)); "'diff"$ */