1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
|
if not modules then modules = { } end modules ['luat-usr'] = {
version = 1.001,
comment = "companion to luat-lib.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
license = "see context related readme files"
}
local global = global
local moduledata = moduledata
local thirddata = thirddata
local userdata = userdata
local documentdata = documentdata
local context = context
local tostring = tostring
local tonumber = tonumber
local print = print
local string = string
local table = table
local lpeg = lpeg
local math = math
local io = io
local os = os
local lpeg = lpeg
local luanames = lua.name -- luatex itself
local setmetatableindex = table.setmetatableindex
local load = load
local xpcall = xpcall
local instance_banner = string.formatters["=[instance: %s]"] -- the = controls the lua error / see: lobject.c
local tex_errormessage = context.errmessage
local implement = interfaces.implement
local reporter = logs.reporter
local report_instance = reporter("lua instance")
local report_script = reporter("lua script")
local report_thread = reporter("lua thread")
local newline = logs.newline
lua.numbers = lua.numbers or { }
lua.messages = lua.messages or { }
local numbers = lua.numbers
local messages = lua.messages
storage.register("lua/numbers", numbers, "lua.numbers" )
storage.register("lua/messages", messages, "lua.messages")
-- First we implement a pure lua version of directlua and a persistent
-- variant of it:
local function runscript(code)
local done, message = loadstring(code)
if done then
done()
else
newline()
report_script("error : %s",message or "unknown")
report_script()
report_script("code : %s",code)
newline()
end
end
local threads = setmetatableindex(function(t,k)
local v = setmetatableindex({},global)
t[k] = v
return v
end)
local function runthread(name,code)
if not code or code == "" then
threads[name] = nil
else
local thread = threads[name]
local done, message = loadstring(code,nil,nil,thread)
if done then
done()
else
newline()
report_thread("thread: %s",name)
report_thread("error : %s",message or "unknown")
report_thread()
report_thread("code : %s",code)
newline()
end
end
end
interfaces.implement {
name = "luascript",
actions = runscript,
arguments = "string"
}
interfaces.implement {
name = "luathread",
actions = runthread,
arguments = "2 strings",
}
-- local scanners = interfaces.scanners
--
-- local function ctxscanner(name)
-- local scanner = scanners[name]
-- if scanner then
-- scanner()
-- else
-- report("unknown scanner: %s",name)
-- end
-- end
--
-- interfaces.implement {
-- name = "clfscanner",
-- actions = ctxscanner,
-- arguments = "string",
-- }
local function registername(name,message)
if not name or name == "" then
report_instance("no valid name given")
return
end
if not message or message == "" then
message = name
end
local lnn = numbers[name]
if not lnn then
lnn = #messages + 1
messages[lnn] = message
numbers[name] = lnn
end
luanames[lnn] = instance_banner(message)
local report = reporter("lua instance",message)
local proxy = {
-- we can access all via:
global = global, -- or maybe just a metatable
-- some protected data
moduledata = setmetatableindex(moduledata),
thirddata = setmetatableindex(thirddata),
-- less protected data
userdata = userdata,
documentdata = documentdata,
-- always there fast
context = context,
--
tostring = tostring,
tonumber = tonumber,
-- standard lua modules
string = string,
table = table,
lpeg = lpeg,
math = math,
io = io,
os = os,
lpeg = lpeg,
--
print = print,
report = report,
}
return function(code)
local code, message = load(code,nil,nil,proxy)
if not code then
report_instance("error: %s",message or code)
elseif not xpcall(code,report) then
tex_errormessage("hit return to continue or quit this run")
end
end
end
lua.registername = registername
implement {
name = "registernamedlua",
arguments = "3 strings",
actions = function(name,message,csname)
if csname and csname ~= "" then
implement {
name = csname,
arguments = "string",
actions = registername(name,message) or report,
scope = "private",
}
else
report_instance("unvalid csname for %a",message or name or "?")
end
end
}
|