@@ Math Chip, authored by Walker@M*U*S*H. @@ @@ License: MIT. @@ @@ 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. @@ @@ Expressions such as: 2+2, 2*(E^sin(-54)), . . . etc. @@ @@ A function is a string, lowercase, followed by a (. Functions on math chip @@ can only take 1 argument, alas. @@ A 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) @@ @@ Pre-set variables and functions: @@ E, PI, sin(), cos(), tan(), sqrt(), abs(), acos(), asin(), atan(), ceil(), @@ floor(), ln() @@ @@ Common child-set attributes: @@ @@ &var` child= - Set NAME to a constant or a math expression. @@ @@ &dvar` child= - If NAME is in an expression, Math chip calls @@ u(dvar`NAME) to fetch a value or expression. @@ @@ &fun` child= - If name(...) is in an expression, math chip @@ calls u(fun`name,) and expects a new, @@ altered stack back. first(%0) is the top of @@ the stack. @@ @@ Provided functions: @@ @@ u(convert,) - Convert to RPN. @@ u(process,) - Execute an RPN calculation string. @@ u(rpn_to_softcode,) - Turn into a softcode s()-able string that uses u(get,varname) for unknown variables. @@ u(calc,) - Just go straight from a math expression to its @@ result. @@ @@ Also included is a graphing calculator: @@ @@ Calculator Methods: @@ calc - calculate an expression. @@ mushcalc - Convert a math expression into softcode. @@ graph - Graph an expression. Use "X" as the variable. @@ range -,- - Choose the range of the graph. @@ mode (normal|graphing) - Which display mode to put the calculator in. @@ deg, rad or grad - change trig mode @@ sto - store last calculated expression into a variable @@ sto = - store an expression into a variable. 'X' is a @@ special variable that is overwritten and used when graphing. @@ @@ Operands: @@ + - * / % ^ \ d (as in 3d6) @@ @@ Functions: @@ pi() e() sin() cos() tan() asin() acos() atan() abs() sqrt() ln() @@ @@ Examples: @@ graph 10 + 5*sin(X) @@ calc 3d6+20 @@ sto BIRTHYEAR=1979 @@ calc 2007-BIRTHYEAR @@ @create Math Chip @set Math Chip = LINK_OK @set Math Chip = VISUAL &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=u(calc_rpn,u(convert,%0)) @set Math Chip/CALC=no_command &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 only take 1 argument, alas.%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` child= -,Set NAME to a constant or a math expression.)]%r%r[align(<30 45,%b%b&dvar` child= -,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` child= -,If name(...) is in an expression\, math chip calls u(fun`name,) and expects a new\, altered stack back. first(\%0) is the top of the stack.)]%r%rProvided functions:%r%r%b%bu(convert,) - Convert to RPN.%r%b%bu(process,) - Execute an RPN calculation string.%r%b%bu(rpn_to_softcode,) - Turn into a softcode s()-able string that uses u(get,varname) for unknown variables.%r%b%bu(calc,) - 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,~,-),lit((^|[^0-9A-Z\)])\-([0-9\.()])),$1[chr(180)]$2),-,-%b,chr(180),-),\\b(-?\\d+(?:\\.\\d+)?)(\[A-Z\]+\[A-Z0-9\]*),$1*$2) @set Math Chip/FIX_NEGATIVES=no_command &FUN Math Chip=Function definitions here. @set Math Chip/FUN=no_command &FUNCTION Math Chip=ceil(1 / 3) @set Math Chip/FUNCTION=no_command &FUN`ABS Math Chip=abs(first(%0)) [rest(%0)] @set Math Chip/FUN`ABS=no_command &FUN`ACOS Math Chip=acos(first(%0),v(trig)) [rest(%0)] @set Math Chip/FUN`ACOS=no_command &FUN`ASIN Math Chip=asin(first(%0),v(trig)) [rest(%0)] @set Math Chip/FUN`ASIN=no_command &FUN`ATAN Math Chip=atan(first(%0),v(trig)) [rest(%0)] @set Math Chip/FUN`ATAN=no_command &FUN`CEIL Math Chip=ceil(first(%0)) [rest(%0)] @set Math Chip/FUN`CEIL=no_command &FUN`COS Math Chip=cos(first(%0),v(trig)) [rest(%0)] @set Math Chip/FUN`COS=no_command &FUN`E Math Chip=e() %0 @set Math Chip/FUN`E=no_command &FUN`FLOOR Math Chip=floor(first(%0)) [rest(%0)] @set Math Chip/FUN`FLOOR=no_command &FUN`LN Math Chip=ln(first(%0)) [rest(%0)] @set Math Chip/FUN`LN=no_command &FUN`LOG2 Math Chip=log(first(%0),2) [rest(%0)] &FUN`PI Math Chip=pi() %0 @set Math Chip/FUN`PI=no_command &FUN`SIN Math Chip=sin(first(%0),v(trig)) [rest(%0)] @set Math Chip/FUN`SIN=no_command &FUN`SQRT Math Chip=sqrt(first(%0)) [rest(%0)] @set Math Chip/FUN`SQRT=no_command &FUN`TAN Math Chip=tan(first(%0),v(trig)) [rest(%0)] @set Math Chip/FUN`TAN=no_command &FUN`VAL Math Chip=%0 @set Math Chip/FUN`VAL=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 &PROCESS Math Chip=[setq(p,v(process`priority))][if(strlen(regeditall(u(fix_negatives,%0),v(rx),null(u(process`token,$1)),\\s+,)),#-1 IMPROPER FORMULA,u(process`finish))] @set Math Chip/PROCESS=no_command &PROCESS_RPN Math Chip=reswitch(%1,^-?\\d+(\\.\\d+)?$,%1 %0,^\[-\%d^+*\\/<>&\]$,u(process_rpn`operator,%1,%0),^\[A-Z\]\[A-Z0-9\]*$,u(get,%1) %0,^\[a-z\]\[a-z0-9\]+$,u(fun`%1,%0),#-1 INVALID RPN) @set Math Chip/PROCESS_RPN=no_command &PROCESS_RPN`OPERATOR Math Chip=[[switch(%0,\\<,lt,\\>,gt,&,cat,-,sub,+,add,d,die,\/,fdiv,^,power,\%,mod,mul)](elements(%1,2),first(%1))] [extract(%1,3,10000)] @set Math Chip/PROCESS_RPN`OPERATOR=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(s,switch(%0,\(,val,edit(%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`TOKEN Math Chip=reswitch(%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 &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,regeditall(%0,\\bval\\s|\\sval\\b,)),^\\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\]+$,squish(if(hasattrp(me,fun`%1),%1,cat)\([first(%0)]\) [rest(%0)]),#-1 INVALID RPN) &RPN_TO_SOFTCODE`OPERATOR Math Chip=squish(switch(%0,\\<,lt,\\>,gt,&,cat,-,sub,+,add,d,die,\/,fdiv,^,power,\%,mod,mul)\([elements(%1,2)]\,[first(%1)]\) [extract(%1,3,10000)]) &RX Math Chip=(-?\d+(?:\.\d+)?|[-%d^+*/><&]|[()]|\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=This is the main math chip portion of the graphing calculator. @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 Parent @parent Graphing Calculator Parent=Math Chip @set Graphing Calculator Parent = LINK_OK @set Graphing Calculator Parent = VISUAL @set Graphing Calculator Parent = NO_COMMAND &AUTHOR Graphing Calculator Parent=Walker@M*U*S*H. Email comments, changes, suggestions to walker@pennmush.org @set Graphing Calculator Parent/AUTHOR=no_command &CMD Graphing Calculator Parent=Command tree. &CMD`CALC Graphing Calculator Parent=$calc *:th u(pemit,%#,[setr(r,u(calc_rpn,setr(f,u(convert,%0))))]) ; &result me=%qr ; &function me=%0 ; &rpn me=%qf &CMD`DRG Graphing Calculator Parent=$^(deg|rad|grad)$:th u(pemit,%#,Trig functions set to [switch(%0,deg,degrees,rad,radians,grad,gradians,???)].) ; &trig me=[left(%0,1)] @set Graphing Calculator Parent/CMD`DRG=regexp &CMD`GRAPH Graphing Calculator Parent=$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 Parent=$^mode (normal|graphing)$:th u(pemit,%#,Mode set to %1) ; &mode me=%1 @set Graphing Calculator Parent/CMD`MODE=regexp &CMD`MUSHCALC Graphing Calculator Parent=$mushcalc *:think u(pemit,%#,u(rpn_to_softcode,u(convert,%0))) &CMD`RANGE Graphing Calculator Parent=$^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 Parent/CMD`RANGE=regexp &CMD`STO Graphing Calculator Parent=$^sto ([A-Z]+)$: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 Parent/CMD`STO=regexp &CMD`STO_FUNC Graphing Calculator Parent=$^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 Parent/CMD`STO_FUNC=regexp @DESCRIBE Graphing Calculator Parent=[u(describe`[v(mode)])] @set Graphing Calculator Parent/DESCRIBE=no_command visual prefixmatch public nearby &DESCRIBE`GRAPHING Graphing Calculator Parent=[setq(s,u(rpn_to_softcode,v(rpn)))][edit([space(5)].[repeat(-,add(%vw,2))].%r[align(>4 1. %vw 1.,[left(v(maxy),4)][repeat(%r,dec(%vh))][left(v(miny),4)],|,u(graph),|)]%r[space(5)]'[repeat(-,add(%vw,2))]'%r[space(8)][ljust(left(v(minx),4),sub(%vw,3))][left(v(maxx),4)],#,%b)] @set Graphing Calculator Parent/DESCRIBE`GRAPHING=no_command &DESCRIBE`NORMAL Graphing Calculator Parent=.[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 Parent/DESCRIBE`NORMAL=no_command &GRAPH Graphing Calculator Parent=null(setq(g,repeat(#,mul(%vw,%vh)),m,fdiv(sub(v(maxx),v(minx)),68),l,v(minx),r,v(maxx),b,v(miny),t,v(maxy)),setq(y,fdiv(sub(%qt,%qb),%vh)),setq(j,v(points)),map(graph`point,iter(lnum(%vw),add(%ql,mul(##,%qm))),%b,))[mid(%qg,1,10000)] @set Graphing Calculator Parent/GRAPH=no_command &GRAPH`POINT Graphing Calculator Parent=null(attrib_set(me/VAR`X,%0),iter(s(%qs),if(cand(lt(%i0,%qt),gt(%i0,%qb)),null(setq(p,ceil(fdiv(sub(%i0,%qb),%qy))),setq(g,strreplace(%qg,add(mul(%vw,sub(%vh,%qp)),%1),1,elements(%qj,#@))))),%b,)) @set Graphing Calculator Parent/GRAPH`POINT=no_command &MAXX Graphing Calculator Parent=5 @set Graphing Calculator Parent/MAXX=no_command &MAXY Graphing Calculator Parent=5 @set Graphing Calculator Parent/MAXY=no_command &MINX Graphing Calculator Parent=-5 @set Graphing Calculator Parent/MINX=no_command &MINY Graphing Calculator Parent=-5 @set Graphing Calculator Parent/MINY=no_command &MODE Graphing Calculator Parent=normal @set Graphing Calculator Parent/MODE=no_command &PEMIT Graphing Calculator Parent=pemit(%0,Calc: %1) @set Graphing Calculator Parent/PEMIT=no_command @set Graphing Calculator Parent=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 Parent=r @set Graphing Calculator Parent/TRIG=no_command @USE Graphing Calculator Parent=%rCalculator Methods:%r%b%b[ansi(h,calc )] - calculate an expression.%r%b%b[ansi(h,mushcalc )] - Convert a math expression into softcode.%r%b%b[ansi(h,graph )] - Graph an expression. Use "X" as the variable.%r%b%b[ansi(h,range -,-)] - 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 )] - store last calculated expression into a variable%r%b%b[ansi(h,sto =)] - 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 Parent/USE=no_command prefixmatch &VAR Graphing Calculator Parent=Variables go here. @set Graphing Calculator Parent/VAR=no_command &VAR`X Graphing Calculator Parent=19.705906 @VH Graphing Calculator Parent=18 @VW Graphing Calculator Parent=68