m-mathfun.mkxl /size: 6673 b    last modification: 2021-10-28 13:51
1%D \module
2%D   [       file=m-mathfun,
3%D        version=2021.02.20,
4%D          title=\CONTEXT\ Extra Modules,
5%D       subtitle=Wried Math Stuff,
6%D         author=Hans Hagen,
7%D           date=\currentdate,
8%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
9%C
10%C This module is part of the \CONTEXT\ macro||package and is
11%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
12%C details.
13
14%D Occasionaly some experiment results in some weird feature. It doesn't make sense
15%D to make this core functionality but if also makes no sense to throw it away. By
16%D making it a module the user can decide. It's actually an example of abusing a
17%D \LUA\ interfacing mechanism that is meant for something else.
18
19\ifdefined\compute \else
20    \permanent\protected\def\compute{\thewithproperty\plusone}
21\fi
22
23%D At some point this will move to \type {m-mathfun.lmt}:
24
25\startluacode
26    local type, load = type, load
27    local gmatch = string.gmatch
28
29    local xmath         = xmath
30    local xcomplex      = xcomplex
31    local xdecimal      = xdecimal
32
33    local context       = context
34    local ctx_mfunction = context.mfunctionlabeltext
35
36    local scanoptional  = tokens.scanners.optional
37    local scanargument  = tokens.scanners.argument
38
39    local createtoken   = tokens.create
40    local defined       = tokens.defined
41
42    local implement     = interfaces.implement
43
44    local compute_code  = 1
45
46    local function smart(what,name,kind)
47        if what == "value" or what == compute_code then
48            local temp = scanoptional()
49            if temp and temp ~= "" then
50                temp = "%" .. temp
51            else
52                temp = "%.6N"
53            end
54            if kind == "constant" then
55                context(temp,math[name])
56            else
57                local code = scanargument()
58                local func = load("return "..name.."("..code..")","mathfunction","t",math)
59                if type(func) == "function" then
60                    context(temp,func())
61                else
62                    context(code)
63                end
64            end
65        elseif kind == "constant" then
66          -- context[name]() -- recursion
67            name = "normal"..name
68            if defined(name) then
69                context(createtoken(name))
70            else
71                context(name)
72            end
73        else
74            ctx_mfunction(name)
75        end
76    end
77
78    local template = { name = false, usage = "value", public = true, protected = true, actions = false, overload = true }
79
80    local function install(str,kind)
81        for name in gmatch(str,"[^ ,]+") do
82            template.name    = name
83            template.actions = function(what) smart(what,name,kind) end
84            implement(template)
85        end
86    end
87
88    local function mathexpr()
89        local temp = scanoptional()
90        local code = scanargument()
91        local func = load("return " .. code,"mathexpr","t",xmath)
92        if type(func) == "function" then
93            if temp and temp ~= "" then
94                temp = "%" .. temp
95            else
96                temp = "%.6N"
97            end
98            context(temp,func())
99        else
100            context(code)
101        end
102    end
103
104    local tostring    = xdecimal.tostring
105    local toengstring = xdecimal.toengstring -- todo
106
107    local function decimalexpr()
108        local temp = scanoptional()
109        local code = scanargument()
110        local func = load("return " .. code,"decimalexpr","t",xdecimal)
111        if type(func) == "function" then
112            local result = tostring(func())
113            if temp and temp ~= "" then
114                context("%"..temp,result)
115            else
116                context(result)
117            end
118        else
119            context(code)
120        end
121    end
122
123    local topair = xcomplex.topair
124
125    local function complexexpr()
126        local temp = scanoptional()
127        local code = scanargument()
128        local func = load("return " .. code,"complexexpr","t",xcomplex)
129        if type(func) == "function" then
130         -- local result = tostring(func())
131         -- if temp and temp ~= "" then
132         --     context("%"..temp,result)
133         -- else
134         --     context(result)
135         -- end
136            if temp and temp ~= "" then
137                temp = "%" .. temp
138            else
139                temp = "%.6N + %.6Ni"
140            end
141            local result = func()
142            context(temp,topair(result))
143        else
144            context(code)
145        end
146    end
147
148    implement {
149        name      = "registermathfunction",
150        public    = true,
151        protected = true,
152        actions   = install,
153        arguments = { "optional", "optional" },
154    }
155
156    implement {
157        name    = "mathexpr",
158        public  = true,
159        actions = mathexpr,
160    }
161
162    implement {
163        name    = "decimalexpr",
164        public  = true,
165        actions = decimalexpr,
166    }
167
168    implement {
169        name    = "complexexpr",
170        public  = true,
171        actions = complexexpr,
172    }
173
174 -- install("sind cosd tand sin cos tan")
175 -- install("sqrt")
176\stopluacode
177
178\pushoverloadmode
179
180    \ifdefined\normalpi \else\let\normalpi\pi \fi
181
182    \registermathfunction[sind,cosd,tand,sin,cos,tan]
183    \registermathfunction[sqrt]
184    \registermathfunction[pi][constant]
185
186\popoverloadmode
187
188\continueifinputfile{m-mathfun.mkxl}
189
190% \pushoverloadmode
191% \let\normalpi\pi
192% \registermathfunction[sind,cosd,tand,sin,cos,tan]
193% \registermathfunction[sqrt]
194% \registermathfunction[pi][constant]
195% \popoverloadmode
196
197\usemodule[scite] \setupbodyfont[dejavu] \setuplayout[tight] \setuppapersize[A5]
198
199% \mainlanguage[es]
200
201\starttext
202
203\startbuffer
204$ \sin (x) = \luaexpr       {math.sin(math.pi/2)} $
205$ \sin (x) = \luaexpr [.4N] {math.sin(math.pi/2)} $
206$ \sin (x) = \the\sin                     {pi/2}  $
207$ \sind(x) = \luaexpr [.4N] {math.sind(120)}      $
208$ \sind(x) = \the\sind[.4N]           {120}       $
209$ \sqrt(x) = \luaexpr       {math.sqrt(2)}        $
210$ \sqrt(x) = \luaexpr [.6N] {math.sqrt(2)}        $
211$ \sqrt(x) = \the\sqrt                {2}         $
212$ \sqrt(x) = \the\sqrt[.3N]           {2}         $
213$ \sqrt(x) = \compute\sqrt[.3N]       {2}         $
214$ \sind(x) = \luaexpr [.4N] {math.pi}             $
215$ \pi = \compute\pi[.4N]                          $
216$ \pi = \mathexpr[.40N]{pi}                       $
217$ \pi = \mathexpr[.80N]{sqrt(11)}                 $
218$ \pi = \decimalexpr[.80N]{sqrt(11)}              $
219$ \pi = \decimalexpr{sqrt(11)}                    $
220$ c = \complexexpr{123 + new(456,789)}            $
221\stopbuffer
222
223Take your choice:
224
225\typebuffer[option=TEX]
226
227And get:
228
229\startlines
230    \getbuffer
231\stoplines
232
233\stoptext
234