]> git.lizzy.rs Git - metalua.git/blob - src/lib/package2.lua
added extension for mandatory variables declaration
[metalua.git] / src / lib / package2.lua
1 local package = package
2
3 require 'mlc'
4
5 package.mpath = os.getenv 'LUA_MPATH' or 
6    './?.mlua;/usr/local/share/lua/5.1/?.mlua;'..
7    '/usr/local/share/lua/5.1/?/init.mlua;'..
8    '/usr/local/lib/lua/5.1/?.mlua;'..
9    '/usr/local/lib/lua/5.1/?/init.mlua'
10
11
12 ----------------------------------------------------------------------
13 -- resc(k) returns "%"..k if it's a special regular expression char,
14 -- or just k if it's normal.
15 ----------------------------------------------------------------------
16 local regexp_magic = table.transpose{
17    "^", "$", "(", ")", "%", ".", "[", "]", "*", "+", "-", "?" }
18 local function resc(k)
19    return regexp_magic[k] and '%'..k or k
20 end
21
22 ----------------------------------------------------------------------
23 -- Take a Lua module name, return the open file and its name, 
24 -- or <false> and an error message.
25 ----------------------------------------------------------------------
26 function package.findfile(name, path_string)
27    local config_regexp = ("([^\n])\n"):rep(5):sub(1, -2)
28    local dir_sep, path_sep, path_mark, execdir, igmark = 
29       package.config:strmatch (config_regexp)
30    name = name:gsub ('%.', dir_sep)
31    local errors = { }
32    local path_pattern = string.format('[^%s]+', resc(path_sep))
33    for path in path_string:gmatch (path_pattern) do
34       --printf('path = %s, rpath_mark=%s, name=%s', path, resc(path_mark), name)
35       local filename = path:gsub (resc (path_mark), name)
36       --printf('filename = %s', filename)
37       local file = io.open (filename, 'r')
38       if file then return file, filename end
39       table.insert(errors, string.format("\tno lua file %q", filename))
40    end
41    return false, table.concat(errors, "\n")..'\n'
42 end
43
44
45 ----------------------------------------------------------------------
46 -- Execute a metalua module sources compilation in a separate ring.
47 ----------------------------------------------------------------------
48 local function spring_load(filename)   
49    if os.getenv "LUA_MFAST" == "yes" then 
50       print "Warning: loading metalua source file in the same compilation ring;"
51       print "metalevels 0 might interfere, condider unsetting environment variable LUA_MFAST"
52       return mlc.function_of_luafile(filename) 
53    end
54    require 'springs'
55    local r = springs.new()
56    r:dostring [[require 'metalua.compiler']]
57    local f = r:call('mlc.function_of_luafile', filename)
58    return f
59 end
60
61 ----------------------------------------------------------------------
62 -- Load a metalua source file. Intended to replace the Lua loader
63 -- in package.loaders.
64 ----------------------------------------------------------------------
65 function package.metalua_loader (name)
66    local file, filename_or_msg = package.findfile (name, package.mpath)
67    if not file then return filename_or_msg end
68    --print ('Metalua loader: found file '..filename_or_msg)
69    file:close()
70    return spring_load(filename_or_msg)
71 end
72
73 table.insert(package.loaders, package.metalua_loader)
74
75 ----------------------------------------------------------------------
76 -- Loads a couple syntax extension + support library in a single
77 -- operation. For instance, [-{ extension "exceptions" }] should both
78 -- * load the exception syntax in the parser at compile time
79 -- * put the instruction to load the support lib in the compiled file
80 ----------------------------------------------------------------------
81
82 function extension (name, noruntime)
83    local ext_runtime_name = metalua.ext_runtime_prefix  .. name
84    local ext_compiler_name = metalua.ext_compiler_prefix .. name
85    require (ext_compiler_name)
86    if not noruntime then
87       return {tag="Call", {tag="Id", "require"},
88                           {tag="String", ext_runtime_name} }
89    end
90 end
91
92 return package