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