cldf-pos.lmt /size: 8427 b    last modification: 2024-01-16 10:22
1if not modules then modules = { } end modules ['cldf-pos'] = {
2    version   = 1.001,
3    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
4    copyright = "PRAGMA ADE / ConTeXt Development Team",
5    license   = "see context related readme files"
6}
7
8-- https://cse512-19s.github.io/FP-Well-Rounded/
9
10local tostring, load, type, tonumber  = tostring, load, type, tonumber
11local lpegmatch = lpeg.match
12local context = context
13
14local setmetatableindex = table.setmetatableindex
15
16local implement         = interfaces.implement
17
18local fromposit         = posit.fromposit
19local toposit           = posit.toposit
20local posittonumber     = posit.tonumber
21
22local values            = tokens.values
23local boolean_code      = values.boolean
24local float_code        = values.float
25
26local scanners          = tokens.scanners
27local scanposit         = scanners.posit
28local scanfloat         = scanners.float
29local scaninteger       = scanners.integer
30local scancsname        = scanners.csname
31
32do -- these are only for testing and might go to a module eventually
33
34    local codes             = tex.codes
35
36    local global_code       = tex.flagcodes.global
37
38    local savelua           = token.savelua
39    ----- isdefined         = token.isdefined
40
41    local newsparse         = sparse.new
42    local setsparse         = sparse.set
43    ----- wipesparse        = sparse.wipe
44    local restoresparse     = sparse.restore
45
46    local registerfunction  = context.functions.register
47
48    implement {
49        name      = "positunumdef",
50        public    = true,
51        untraced  = true,
52        protected = true,
53        actions   = function(what)
54            local name    = scancsname(true)
55            local code    = newsparse()
56            local restore = registerfunction(function() restoresparse(code) end)
57            implement {
58                name      = name,
59                public    = true,
60                protected = true,
61                usage     = "value",
62                actions   = function(what)
63                    local n = scaninteger()
64                    if what == "value" then
65                        local v = fromposit(code[n])
66                     -- return float_code, v
67                        context("%.99g",v)
68                    else
69                        local v = toposit(scanfloat())
70                        if what and (tonumber(what) & global_code) then
71                            setsparse(code,"global",n,v)
72                        else
73                            savelua(restore,true) -- only once
74                            setsparse(code,n,v)
75                        end
76                    end
77                end,
78            }
79            codes[name] = code
80        end,
81    }
82
83    do
84
85        local p_number = lpeg.patterns.number
86        local p = lpeg.Cs(
87            lpeg.Cc("local new = new ; return ")
88        * (
89                lpeg.C(p_number) / function(s)
90                    return "new(" .. s .. ")"
91                end
92                + lpeg.P(1)
93            )^0
94        )
95
96        local t = setmetatableindex({ new = posit.new }, posit)
97
98        local function calculate(s)
99            local new = lpegmatch(p,s)
100            new = load(new,nil,nil,t)
101            if new then
102                new = new()
103                if new then
104                    return new
105                end
106            end
107            return old
108        end
109
110        implement {
111            name      = "positunum",
112            public    = true,
113            arguments = "string",
114            actions   = function(s)
115                local r = calculate(s)
116                local t = type(r)
117                if t == "boolean" then
118                    context(tostring(r))
119                elseif t == "string" then
120                    context(r)
121                else
122                    context("%N",posittonumber(r))
123                end
124            end
125        }
126
127        implement {
128            name      = "ifpositunum",
129            public    = true,
130            usage     = "condition",
131            arguments = "string",
132            actions   = function(s)
133                return boolean_code, calculate(s) and true or false
134            end,
135        }
136
137    end
138
139end
140
141do
142
143    local xsin = xmath.sin local xasin = xmath.asin local xsinh  = xmath.sinh local xasinh = xmath.asinh
144    local xcos = xmath.cos local xacos = xmath.acos local xcosh  = xmath.cosh local xacosh = xmath.acosh
145    local xtan = xmath.tan local xatan = xmath.atan local xtanh  = xmath.tanh local xatanh = xmath.atanh
146
147    local xsqrt  = xmath.sqrt
148    local xlog   = xmath.log
149    local xexp   = xmath.exp
150    local xpow   = xmath.pow
151    local xceil  = xmath.ceil
152    local xfloor = xmath.floor
153    local xround = xmath.round
154    local xabs   = xmath.fabs
155    local xmod   = xmath.fmod
156    local xrem   = xmath.remainder
157    local xrad   = xmath.rad
158    local xdeg   = xmath.deg
159    local xatan2 = xmath.atan2
160
161    implement { name = "pfsin",     public = true, usage = "value", actions = function() return float_code, xsin  (scanposit(true)) end }
162    implement { name = "pfcos",     public = true, usage = "value", actions = function() return float_code, xcos  (scanposit(true)) end }
163    implement { name = "pftan",     public = true, usage = "value", actions = function() return float_code, xtan  (scanposit(true)) end }
164    implement { name = "pfasin",    public = true, usage = "value", actions = function() return float_code, xasin (scanposit(true)) end }
165    implement { name = "pfacos",    public = true, usage = "value", actions = function() return float_code, xacos (scanposit(true)) end }
166    implement { name = "pfatan",    public = true, usage = "value", actions = function() return float_code, xatan (scanposit(true)) end }
167    implement { name = "pfsinh",    public = true, usage = "value", actions = function() return float_code, xsinh (scanposit(true)) end }
168    implement { name = "pfcosh",    public = true, usage = "value", actions = function() return float_code, xcosh (scanposit(true)) end }
169    implement { name = "pftanh",    public = true, usage = "value", actions = function() return float_code, xtanh (scanposit(true)) end }
170    implement { name = "pfasinh",   public = true, usage = "value", actions = function() return float_code, xasinh(scanposit(true)) end }
171    implement { name = "pfacosh",   public = true, usage = "value", actions = function() return float_code, xacosh(scanposit(true)) end }
172    implement { name = "pfatanh",   public = true, usage = "value", actions = function() return float_code, xatanh(scanposit(true)) end }
173    implement { name = "pfsqrt",    public = true, usage = "value", actions = function() return float_code, xsqrt (scanposit(true)) end }
174    implement { name = "pflog",     public = true, usage = "value", actions = function() return float_code, xlog  (scanposit(true)) end }
175    implement { name = "pfexp",     public = true, usage = "value", actions = function() return float_code, xexp  (scanposit(true)) end }
176    implement { name = "pfceil",    public = true, usage = "value", actions = function() return float_code, xceil (scanposit(true)) end }
177    implement { name = "pffloor",   public = true, usage = "value", actions = function() return float_code, xfloor(scanposit(true)) end }
178    implement { name = "pfround",   public = true, usage = "value", actions = function() return float_code, xround(scanposit(true)) end }
179    implement { name = "pfabs",     public = true, usage = "value", actions = function() return float_code, xabs  (scanposit(true)) end }
180    implement { name = "pfrad",     public = true, usage = "value", actions = function() return float_code, xrad  (scanposit(true)) end }
181    implement { name = "pfdeg",     public = true, usage = "value", actions = function() return float_code, xdeg  (scanposit(true)) end }
182    implement { name = "pfatantwo", public = true, usage = "value", actions = function() return float_code, xatan2(scanposit(true),scanposit(true)) end }
183    implement { name = "pfpow",     public = true, usage = "value", actions = function() return float_code, xpow  (scanposit(true),scanposit(true)) end }
184    implement { name = "pfmod",     public = true, usage = "value", actions = function() return float_code, xmod  (scanposit(true),scanposit(true)) end }
185    implement { name = "pfrem",     public = true, usage = "value", actions = function() return float_code, xrem  (scanposit(true),scanposit(true)) end }
186
187end
188