Graphing Calculator

I know what you're thinking. A 'graphing calculator' on a text-based MUSH? This was designed to accept human style input (i.e: "graph x + sin(x) - 2x^2") and plot it on the graph. It can also be used to do simple and quick calculations. A 'math chip' is included that contains only the math calculation functions.

Commands: @create, @lock, @parent, @pemit, @set.
Features: regexp commands.
Compatibility: PennMUSH.

Instructions

Copy and paste the below code into a compatible MUSH or MUX.

MUSHCode for Graphing Calculator

@create Math Chip
@lock Math Chip==me
&AUTHOR Math Chip=Walker@M*U*S*H. Email comments, changes, suggestions to walker@pennmush.org
@set Math Chip/AUTHOR=no_command
&CALC Math Chip=revwords(u(calc_rpn,u(convert,%0)))
@set Math Chip/CALC=no_command
&CALC2SOFTCODE Math Chip=u(rpn_to_softcode,u(convert,%0))
&CALC_RPN Math Chip=localize(squish(if(regmatch(%0,^\\d+(?:\\.\\d+)?\$),%0,[null(regmatch(,repeat(\(\),35),- 0 1 2 3 4 5 6 7 8 9 b c d e f g h i j k l m n o p q r s t u v w x y z))]fold(process_rpn,%0,)))
@set Math Chip/CALC_RPN=no_command
&CONVERT Math Chip=revwords(localize(squish(if(regmatch(%0,^-?\\d+(\\.\\d+)?\$),%0,[null(setq(0,,s,,o,,p,,a,))][u(process,%0)]))))
@set Math Chip/CONVERT=no_command
&DESCRIBE Math Chip=This is a math chip that contains processing routines for handling mathematical expressions. It is not really intended for direct use, but to be @parented to objects that need it.%r%r%b%bA function is a string, lowercase, followed by a (. Functions on math chip can take up to 10 arguments.%r%b%bA variable is a string of upper case characters and numbers - The first must be an upper case character. (e.g: VAL1 is a variable, 1VAL is 1 * the variable VAL)%r%rPre-set variables and functions:%r%b%bE, PI, sin(), cos(), tan(), sqrt(), abs(), acos(), asin(), atan(), ceil(), floor(), ln()%r%rCommon child-set attributes:%r%r[align(<30 45,%b%b&var`<NAME> child=<expr> -,Set NAME to a constant or a math expression.)]%r%r[align(<30 45,%b%b&dvar`<NAME> child=<ufun> -,If NAME is in an expression\, Math chip calls u(dvar`NAME) to fetch a value or expression.)]%r%r[align(<30 45,%b%b&fun`<name> child=<ufun> -,If name(...) is in an expression\, math chip calls u(fun`name,<arg0>,\[<arg1>,...\]) and expects a single number back.)]%r%rProvided functions:%r%r%b%bu(convert,<expression>) - Convert <expression> to RPN.%r%b%bu(calc_rpn,<rpn>) - Execute an RPN calculation string.%r%b%bu(rpn_to_softcode,<rpn>) - Turn <RPN> into a softcode s()-able string that uses u(get,varname) for unknown variables.%r%b%bu(calc,<expression>) - Just go straight from a math expression to its result.
@set Math Chip/DESCRIBE=no_command visual prefixmatch public nearby
&DESCRIBE`GRAPHING Math Chip=[setq(e,v(rpn))][edit([space(5)].[repeat(-,70)].%r[align(>4 1. 68 1.,[left(v(maxy),4)][repeat(%r,17)][left(v(miny),4)],|,u(graph),|)]%r[space(5)]'[repeat(-,70)]'%r[space(8)][ljust(left(v(minx),4),65)][left(v(maxx),4)],#,%b)]
@set Math Chip/DESCRIBE`GRAPHING=no_command
&DESCRIBE`NORMAL Math Chip=.[repeat(-,20)].%r|[space(20)]|%r[align(1. 18 1.,|,v(function)%r%r> [v(result)]%r,|)]%r|[space(20)]|%r'[repeat(-,20)]'
@set Math Chip/DESCRIBE`NORMAL=no_command
&DVAR Math Chip=
&FIX_NEGATIVES Math Chip=regeditall(edit(regeditall(edit(%0,~,-),v(fix_negatives`rx),\$1[chr(180)]\$2),\-,-%b,chr(180),-),\\b(-?\\d+(?:\\.\\d+)?)(\[A-Z\]+\[A-Z0-9\]*),\$1*\$2,(\\d+)(\[a-ce-z\]+|d[a-z]+),\$1*\$2)
@set Math Chip/FIX_NEGATIVES=no_command
&FIX_NEGATIVES`RX Math Chip=(^|[^0-9A-Za-z\)])\-([0-9\.\(\)])
&FUN Math Chip=Function definitions here.
@set Math Chip/FUN=no_command
&FUN`ABS Math Chip=abs(%0)
@set Math Chip/FUN`ABS=no_command
&FUN`ACOS Math Chip=acos(%0,v(trig))
@set Math Chip/FUN`ACOS=no_command
&FUN`ADD Math Chip=lmath(add,%0 %1 %2 %3 %4 %5 %6 %7 %8 %9)
&FUN`AND Math Chip=lmath(and,%0 %1 %2 %3 %4 %5 %6 %7 %8 %9)
@set Math Chip/FUN`AND=no_command
&FUN`ASIN Math Chip=asin(%0,v(trig))
@set Math Chip/FUN`ASIN=no_command
&FUN`ATAN Math Chip=atan(%0,v(trig))
@set Math Chip/FUN`ATAN=no_command
&FUN`ATAN2 Math Chip=atan2(%0,%1,v(trig))
&FUN`BAND Math Chip=lmath(band,%0 %1 %2 %3 %4 %5 %6 %7 %8 %9)
@set Math Chip/FUN`BAND=no_command
&FUN`BOR Math Chip=lmath(bor,%0 %1 %2 %3 %4 %5 %6 %7 %8 %9)
@set Math Chip/FUN`BOR=no_command
&FUN`BOUND Math Chip=bound(%0,%1,%2)
&FUN`BXOR Math Chip=lmath(bxor,%0 %1 %2 %3 %4 %5 %6 %7 %8 %9)
@set Math Chip/FUN`BXOR=no_command
&FUN`CEIL Math Chip=ceil(%0)
@set Math Chip/FUN`CEIL=no_command
&FUN`COS Math Chip=cos(%0,v(trig))
@set Math Chip/FUN`COS=no_command
&FUN`DIE Math Chip=die(%0,%1)
&FUN`DIST2D Math Chip=lmath(dist2d,%0 %1 %2 %3 %4 %5 %6 %7 %8 %9)
@set Math Chip/FUN`DIST2D=no_command
&FUN`DIST3D Math Chip=lmath(dist3d,%0 %1 %2 %3 %4 %5 %6 %7 %8 %9)
@set Math Chip/FUN`DIST3D=no_command
&FUN`DIV Math Chip=lmath(div,%0 %1 %2 %3 %4 %5 %6 %7 %8 %9)
@set Math Chip/FUN`DIV=no_command
&FUN`E Math Chip=e()
@set Math Chip/FUN`E=no_command
&FUN`EQ Math Chip=lmath(eq,%0 %1 %2 %3 %4 %5 %6 %7 %8 %9)
@set Math Chip/FUN`EQ=no_command
&FUN`FDIV Math Chip=lmath(fdiv,%0 %1 %2 %3 %4 %5 %6 %7 %8 %9)
@set Math Chip/FUN`FDIV=no_command
&FUN`FLOOR Math Chip=floor(%0)
@set Math Chip/FUN`FLOOR=no_command
&FUN`GAUSS Math Chip=mul(%1,power(e(),sub(0,fdiv(power(sub(%0,%2),2),mul(2,power(%3,2))))))
&FUN`GT Math Chip=lmath(gt,%0 %1 %2 %3 %4 %5 %6 %7 %8 %9)
@set Math Chip/FUN`GT=no_command
&FUN`GTE Math Chip=lmath(gte,%0 %1 %2 %3 %4 %5 %6 %7 %8 %9)
@set Math Chip/FUN`GTE=no_command
&FUN`LN Math Chip=ln(%0)
@set Math Chip/FUN`LN=no_command
&FUN`LOG Math Chip=log(%0,firstof(%1,10))
&FUN`LOG2 Math Chip=log(%0,2)
&FUN`LT Math Chip=lmath(lt,%0 %1 %2 %3 %4 %5 %6 %7 %8 %9)
@set Math Chip/FUN`LT=no_command
&FUN`LTE Math Chip=lmath(lte,%0 %1 %2 %3 %4 %5 %6 %7 %8 %9)
@set Math Chip/FUN`LTE=no_command
&FUN`MAX Math Chip=lmath(max,%0 %1 %2 %3 %4 %5 %6 %7 %8 %9)
@set Math Chip/FUN`MAX=no_command
&FUN`MEAN Math Chip=lmath(mean,%0 %1 %2 %3 %4 %5 %6 %7 %8 %9)
@set Math Chip/FUN`MEAN=no_command
&FUN`MEDIAN Math Chip=lmath(median,%0 %1 %2 %3 %4 %5 %6 %7 %8 %9)
@set Math Chip/FUN`MEDIAN=no_command
&FUN`MIN Math Chip=lmath(min,%0 %1 %2 %3 %4 %5 %6 %7 %8 %9)
@set Math Chip/FUN`MIN=no_command
&FUN`MOD Math Chip=mod(%0,%1)
&FUN`MODULO Math Chip=lmath(modulo,%0 %1 %2 %3 %4 %5 %6 %7 %8 %9)
@set Math Chip/FUN`MODULO=no_command
&FUN`MUL Math Chip=lmath(mul,%0 %1 %2 %3 %4 %5 %6 %7 %8 %9)
@set Math Chip/FUN`MUL=no_command
&FUN`NAND Math Chip=lmath(nand,%0 %1 %2 %3 %4 %5 %6 %7 %8 %9)
@set Math Chip/FUN`NAND=no_command
&FUN`NEQ Math Chip=lmath(neq,%0 %1 %2 %3 %4 %5 %6 %7 %8 %9)
@set Math Chip/FUN`NEQ=no_command
&FUN`NOR Math Chip=lmath(nor,%0 %1 %2 %3 %4 %5 %6 %7 %8 %9)
@set Math Chip/FUN`NOR=no_command
&FUN`OR Math Chip=lmath(or,%0 %1 %2 %3 %4 %5 %6 %7 %8 %9)
@set Math Chip/FUN`OR=no_command
&FUN`PI Math Chip=pi()
@set Math Chip/FUN`PI=no_command
&FUN`RAND Math Chip=switch(%+,1,rand(%0),2,rand(%0,%1),#-1 FUNCTION (RAND) EXPECTS 1 OR 2 ARGUMENTS BUT GOT %+)
&FUN`REMAINDER Math Chip=lmath(remainder,%0 %1 %2 %3 %4 %5 %6 %7 %8 %9)
@set Math Chip/FUN`REMAINDER=no_command
&FUN`ROUND Math Chip=round(%0,firstof(%1,2))
&FUN`SIN Math Chip=sin(%0,v(trig))
@set Math Chip/FUN`SIN=no_command
&FUN`SQRT Math Chip=sqrt(%0)
@set Math Chip/FUN`SQRT=no_command
&FUN`STDDEV Math Chip=lmath(stddev,%0 %1 %2 %3 %4 %5 %6 %7 %8 %9)
@set Math Chip/FUN`STDDEV=no_command
&FUN`SUB Math Chip=lmath(sub,%0 %1 %2 %3 %4 %5 %6 %7 %8 %9)
@set Math Chip/FUN`SUB=no_command
&FUN`TAN Math Chip=tan(%0,v(trig))
@set Math Chip/FUN`TAN=no_command
&FUN`VAL Math Chip=%0
@set Math Chip/FUN`VAL=no_command
&FUN`XOR Math Chip=lmath(xor,%0 %1 %2 %3 %4 %5 %6 %7 %8 %9)
@set Math Chip/FUN`XOR=no_command
&FUNCTION Math Chip=ceil(1 / 3)
@set Math Chip/FUNCTION=no_command
&GET Math Chip=switch(1,hasattrp(me,var`%0),u(calc_rpn,v(var`%0)),hasattrp(me,dvar`%0),u(calc,u(dvar`%0)),0)
&MODE Math Chip=graphing
@set Math Chip/MODE=no_command
&MUSHFUNS Math Chip=abs acos add and asin atan band bor bound bxor ceil cos die dist2d dist3d div e eq fdiv floor gt gte ln log log2 lt lte max mean median min mod modulo mul nand neq nor or pi remainder round sin sqrt stddev sub tan val xor
&PEMIT Math Chip=pemit(%0,Calc: %1)
@set Math Chip/PEMIT=no_command
&PROCESS Math Chip=[setq(p,v(process`priority))][if(strlen(regeditall(u(fix_negatives,%0),v(rx),null(u(process`token,\$1)),\\s+,)),FORMULA IMPROPER #-1,u(process`finish))]
@set Math Chip/PROCESS=no_command
&PROCESS`FINISH Math Chip=[null(setq(0,1,1,0),map(process`operator_call,%qs))]%qo
@set Math Chip/PROCESS`FINISH=no_command
&PROCESS`FUNCTION Math Chip=setq(o,\) %qo,s,switch(%0,\(,val,*\(,edit(%0,\(,),,wtf:%0) %qs)
@set Math Chip/PROCESS`FUNCTION=no_command
&PROCESS`FUNCTION_CLOSE Math Chip=null(setq(0,1,1,0),map(process`operator_call,%qs),setq(o,first(%qs) %qo,s,rest(%qs)))
@set Math Chip/PROCESS`FUNCTION_CLOSE=no_command
&PROCESS`NUMBER Math Chip=setq(o,%0 %qo)
@set Math Chip/PROCESS`NUMBER=no_command
&PROCESS`OPERATOR Math Chip=null(setq(0,1,1,wordpos(%qp,pos(%0,%qp))),map(process`operator_call,%qs),setq(s,%0 %qs))
@set Math Chip/PROCESS`OPERATOR=no_command
&PROCESS`OPERATOR_CALL Math Chip=switch(0,%q0,,t(gt(wordpos(x %qp,pos(%0,x %qp)),%q1)),setq(0,0),setq(o,%0 %qo)[setq(s,rest(%qs))])
@set Math Chip/PROCESS`OPERATOR_CALL=no_command
&PROCESS`PRIORITY Math Chip=&, ><= -+ %*/ ^ d
@set Math Chip/PROCESS`PRIORITY=no_command
&PROCESS`PUSH Math Chip=null(setq(0,1,1,0),map(process`operator_call,%qs))
&PROCESS`TOKEN Math Chip=reswitch(%0,^\,\$,u(process`push,%0),^\[-\%d^+*\\/<>=&\]\$,u(process`operator,%0),^\[A-Z!_`\]\[_!`A-Z0-9\]*\$,u(process`variable,%0),^-?\\d+(\\.\\d+)?,u(process`number,%0),^(\[a-z\]\[a-z0-8\]+)?\\\(,u(process`function,%0),\\\),u(process`function_close),#-1 INVALID TOKEN)[setq(l,%0)]
@set Math Chip/PROCESS`TOKEN=no_command
&PROCESS`VARIABLE Math Chip=setq(o,%0 %qo)
@set Math Chip/PROCESS`VARIABLE=no_command
&PROCESS_RPN Math Chip=reswitch(%1,^-?\\d+(\\.\\d+)?\$,%1 %0,^\[-\%d^+*\\/<>=&\]\$,u(process_rpn`operator,%1,%0),^\\\)\$,%1 %0,^\[A-Z!`_\]\[_!`A-Z0-9\]*\$,u(get,%1) %0,^\[a-z\]\[a-z0-9\]+\$,u(process_rpn`function,%1,%0),#-1 INVALID RPN)
@set Math Chip/PROCESS_RPN=no_command
&PROCESS_RPN`FUNCTION Math Chip=squish(step(fun`%0,revwords(before(%1,\))),words(before(%1,\)))) [after(%1,\))])
@set Math Chip/PROCESS_RPN`OPERATOR=no_command
&RESULT Math Chip=1
@set Math Chip/RESULT=no_command
&RPN Math Chip=1 3 / ceil
@set Math Chip/RPN=no_command
&RPN_TO_SOFTCODE Math Chip=localize(squish(if(regmatch(setr(e,edit(%0,\),CloseParen)),^\\d+(?:\\.\\d+)?\$),%qe,[null(regmatch(,repeat(\(\),35),- 0 1 2 3 4 5 6 7 8 9 b c d f g h i j k l m n o p q r s t u v w x y z))][if(pos(%b,setr(m,fold(rpn_to_softcode`each,%qe,))),cat\([edit(%qm,%b,\,)]\),%qm)])))
&RPN_TO_SOFTCODE`EACH Math Chip=reswitch(%1,^-?\\d+(\\.\\d+)?\$,%1 %0,^\[-\%d^+*\\/<>=&\]\$,u(rpn_to_softcode`operator,%1,%0),^\[A-Z!_`\]\[!`_A-Z0-9\]*\$,switch(1,strmatch(%1,X),u\(get\,%1\),isnum(v(var`%1)),v(var`%1),u\(get\,%1\)) %0,^\[a-z\]\[a-z0-9\]+\$,u(rpn_to_softcode`function,%1,%0),^CloseParen\$,%1 %0,#-1 INVALID RPN)
&RPN_TO_SOFTCODE`FUNCTION Math Chip=squish([switch(1,strmatch(%0,val),,t(member(v(mushfuns),%0)),%0\(,u\(fun`%0\,)][edit(revwords(before(%1,CloseParen)),%b,\,)][if(strmatch(%0,val),,\))] [after(%1,CloseParen)])
&RX Math Chip=(-?\d+(?:\.\d+)?|[-%^+*/><=&,]|d(?![a-z])|[()]|\w+\(|[A-Z!`_][_!`A-Z0-9]*)
@set Math Chip/RX=no_command
&TRIG Math Chip=r
@set Math Chip/TRIG=no_command
&USE Math Chip=u(describe)
@set Math Chip/USE=no_command prefixmatch
&VAR Math Chip=Variables go here.
@set Math Chip/VAR=no_command
&VAR`E Math Chip=2.718282
@set Math Chip/VAR`E=no_command
&VAR`PI Math Chip=3.141593
@set Math Chip/VAR`PI=no_command

@create Graphing Calculator
@lock Graphing Calculator==me
@parent Graphing Calculator=Math Chip
@set Graphing Calculator = OPAQUE
@set Graphing Calculator = !NO_COMMAND
&AUTHOR Graphing Calculator=Walker@M*U*S*H. Email comments, changes, suggestions to walker@pennmush.org
@set Graphing Calculator/AUTHOR=no_command
&CMD Graphing Calculator=Command tree.
&CMD`CALC Graphing Calculator=\$calc *:th u(pemit,%#,[setr(r,revwords(u(calc_rpn,setr(f,u(convert,%0)))))]) ; &result me=%qr ; &function me=%0 ; &rpn me=%qf
@set Graphing Calculator/CMD`DRG=regexp
&CMD`GRAPH Graphing Calculator=\$graph *:think setq(e,u(convert,%0)) ; &funsoft me=setr(s,u(rpn_to_softcode,e)) ; &function me=%0 ; &rpn me=%qe ; @pemit %#=tagwrap(pre,u(describe`graphing))[pemit(%#,?: %?)]
&CMD`MODE Graphing Calculator=\$^mode (normal|graphing)\$:th u(pemit,%#,Mode set to %1) ; &mode me=%1
@set Graphing Calculator/CMD`MODE=regexp
&CMD`MUSHCALC Graphing Calculator=\$mushcalc *:think u(pemit,%#,u(rpn_to_softcode,u(convert,%0)))
&CMD`RANGE Graphing Calculator=\$^range (-?\d+(?\:\.\d+)?)\s*-\s*(-?\d+(?\:\.\d+)?)\s*,\s*(-?\d+(?\:\.\d+)?)-(-?\d+(?\:\.\d+)?)\$:th u(pemit,%#,X range set from %1 to %2. Y range set from %3 to %4.) ; &minx me=%1 ; &maxx me=%2 ; &miny me=%3 ; &maxy me=%4
@set Graphing Calculator/CMD`RANGE=regexp
&CMD`STO Graphing Calculator=\$^sto ([A-Z][A-Z0-9]*)\$:th u(pemit,%#,[if(regmatch(%1,^\[A-Z\]*\$),Result '[v(result)]' stored in %1.[attrib_set(me/var`%1,v(result))][attrib_set(me/var`%1_func,v(result))],You can only use an upper case register. (A-Z))])
@set Graphing Calculator/CMD`STO=regexp
&CMD`STO_FUNC Graphing Calculator=\$^sto ([A-Z]+)=(.+)\$:th u(pemit,%#,[if(regmatch(%1,^\[A-Z\]+\$),Function '%2' stored in %1.[attrib_set(me/var`%1,u(convert,%2))][attrib_set(me/var`%1_func,%2)],You can only use an upper case register. (A-Z))])
@set Graphing Calculator/CMD`STO_FUNC=regexp
&DESCRIBE Graphing Calculator=u(describe`[v(mode)])
@set Graphing Calculator/DESCRIBE=no_command visual prefixmatch public nearby
@set Graphing Calculator/DESCRIBE`GRAPHING=no_command
&DESCRIBE`NORMAL Graphing Calculator=.[repeat(-,20)].%r|[space(20)]|%r[align(1. 18 1.,|,v(function)%r%r> [v(result)]%r,|)]%r|[space(20)]|%r'[repeat(-,20)]'
@set Graphing Calculator/GRAPH=no_command
@set Graphing Calculator/GRAPH`POINT=no_command
&MAXX Graphing Calculator=5
@set Graphing Calculator/MAXX=no_command
&MAXY Graphing Calculator=5
@set Graphing Calculator/MAXY=no_command
&MINX Graphing Calculator=-5
@set Graphing Calculator/MINX=no_command
&MINY Graphing Calculator=-5
@set Graphing Calculator/MINY=no_command
&MODE Graphing Calculator=normal
@set Graphing Calculator/MODE=no_command
&PEMIT Graphing Calculator=pemit(%0,Calc: %1)
@set Graphing Calculator/PEMIT=no_command
@set Graphing Calculator=POINTS:[ansi(hg,+)]%b[ansi(hc,*)]%b[ansi(hr,-)]%b[ansi(hy,+)]%b[ansi(hm,*)]%b[ansi(hg,-)]%b[ansi(hc,+)]%b[ansi(hr,*)]%b[ansi(hy,-)]%b[ansi(hm,+)]%b[ansi(hg,*)]%b[ansi(hc,-)]%b[ansi(hr,+)]%b[ansi(hy,*)]%b[ansi(hm,-)]
&TRIG Graphing Calculator=r
@set Graphing Calculator/TRIG=no_command
&USE Graphing Calculator=%rCalculator Methods:%r%b%b[ansi(h,calc <expression>)] - calculate an expression.%r%b%b[ansi(h,mushcalc <expression>)] - Convert a math expression into softcode.%r%b%b[ansi(h,graph <expression>)] - Graph an expression. Use "X" as the variable.%r%b%b[ansi(h,range <minx>-<maxx>\,<miny>-<maxy>)] - Choose the range of the graph.%r%b%b[ansi(h,mode (normal|graphing))] - Which display mode to put the calculator in.%r%b%b[ansi(h,deg)], [ansi(h,rad)] or [ansi(h,grad)] - change trig mode%r%b%b[ansi(h,sto <VARNAME>)] - store last calculated expression into a variable%r%b%b[ansi(h,sto <VARNAME>=<expression>)] - store an expression into a variable. 'X' is a special variable that is overwritten and used when graphing.%r%b%bOperands:%r[space(6)] + - * / \% ^ \\ d (as in 3d6)%r%b%bFunctions:%r[space(6)][ansi(h,lit(pi() e() sin() cos() tan() asin() acos() atan() abs() sqrt() ln()))]%r%b%bExamples:%r[space(6)]graph 10 + 5*sin(X)%r[space(6)]calc 3d6+20%r[space(6)]sto BIRTHYEAR=1979%r[space(6)]calc 2007-BIRTHYEAR
@set Graphing Calculator/USE=no_command prefixmatch
&VAR Graphing Calculator=Variables go here.
@set Graphing Calculator/VAR=no_command
&VAR`X Graphing Calculator=19.705906
&VH Graphing Calculator=18
&VW Graphing Calculator=68

give Graphing Calculator=Math Chip

use Graphing Calculator