Skip to content

Commit

Permalink
move module_name logic out of type_check
Browse files Browse the repository at this point in the history
it is now handled by the parts that deal with module names:
`require` and the package loader.
  • Loading branch information
hishamhm committed Jan 15, 2024
1 parent 57ca712 commit 05ef2dc
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 88 deletions.
35 changes: 31 additions & 4 deletions tl
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,26 @@ local function find_file_in_parent_dirs(fname)
end
end

local function filename_to_module_name(filename)
local path = os.getenv("TL_PATH") or package.path
for entry in path:gmatch("[^;]+") do
entry = entry:gsub("%.", "%%.")
local lua_pat = "^" .. entry:gsub("%?", ".+") .. "$"
local d_tl_pat = lua_pat:gsub("%%.lua%$", "%%.d%%.tl$")
local tl_pat = lua_pat:gsub("%%.lua%$", "%%.tl$")

for _, pat in ipairs({ tl_pat, d_tl_pat, lua_pat }) do
local cap = filename:match(pat)
if cap then
return (cap:gsub("[/\\]", "."))
end
end
end

-- fallback:
return (filename:gsub("%.lua$", ""):gsub("%.d%.tl$", ""):gsub("%.tl$", ""):gsub("[/\\]", "."))
end

--------------------------------------------------------------------------------
-- Common driver backend
--------------------------------------------------------------------------------
Expand Down Expand Up @@ -212,9 +232,16 @@ do
end
end

local function process_module(filename, env)
local module_name = filename_to_module_name(filename)
local result = tl.process(filename, env)
env.modules[module_name] = result.type
return result
end

local function type_check_and_load(tlconfig, filename)
local env = setup_env(tlconfig, filename)
local result, err = tl.process(filename, env)
local result, err = process_module(filename, env)
if err then
die(err)
end
Expand Down Expand Up @@ -705,7 +732,7 @@ commands["check"] = function(tlconfig, args)
env = setup_env(tlconfig, input_file)
end
if not already_loaded(env, input_file) then
local _, err = tl.process(input_file, env)
local _, err = process_module(input_file, env)
if err then
die(err)
end
Expand Down Expand Up @@ -766,7 +793,7 @@ commands["gen"] = function(tlconfig, args)
output_file = get_output_filename(input_file)
}

res.tl_result, err = tl.process(input_file, env)
res.tl_result, err = process_module(input_file, env)
if err then
die(err)
end
Expand Down Expand Up @@ -866,7 +893,7 @@ do
env.report_types = true

for i, input_file in ipairs(args["file"]) do
local pok, err = pcall(tl.process, input_file, env)
local pok, err = pcall(process_module, input_file, env)
if not pok then
die("Internal Compiler Error: " .. err)
end
Expand Down
57 changes: 16 additions & 41 deletions tl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -619,7 +619,6 @@ local tl = {PrettyPrintOptions = {}, TypeCheckOptions = {}, Env = {}, Result = {






local TypeReporter = {}
Expand Down Expand Up @@ -6198,26 +6197,6 @@ local function search_for(module_name, suffix, path, tried)
return nil, nil, tried
end

local function filename_to_module_name(filename)
local path = os.getenv("TL_PATH") or package.path
for entry in path:gmatch("[^;]+") do
entry = entry:gsub("%.", "%%.")
local lua_pat = "^" .. entry:gsub("%?", ".+") .. "$"
local d_tl_pat = lua_pat:gsub("%%.lua%$", "%%.d%%.tl$")
local tl_pat = lua_pat:gsub("%%.lua%$", "%%.tl$")

for _, pat in ipairs({ tl_pat, d_tl_pat, lua_pat }) do
local cap = filename:match(pat)
if cap then
return (cap:gsub("[/\\]", "."))
end
end
end


return (filename:gsub("%.lua$", ""):gsub("%.d%.tl$", ""):gsub("%.tl$", ""):gsub("[/\\]", "."))
end

function tl.search_module(module_name, search_dtl)
local found
local fd
Expand Down Expand Up @@ -6248,9 +6227,14 @@ local function require_module(module_name, lax, env)

local found, fd = tl.search_module(module_name, true)
if found and (lax or found:match("tl$")) then
local found_result, err = tl.process(found, env, module_name, fd)

env.modules[module_name] = a_type("typedecl", { def = CIRCULAR_REQUIRE })

local found_result, err = tl.process(found, env, fd)
assert(found_result, err)

env.modules[module_name] = found_result.type

return found_result.type, true
elseif fd then
fd:close()
Expand Down Expand Up @@ -6510,10 +6494,6 @@ tl.type_check = function(ast, opts)
end
end

if opts.module_name then
env.modules[opts.module_name] = a_type("typedecl", { def = CIRCULAR_REQUIRE })
end

local lax = opts.lax
local feat_arity = env.feat_arity
local filename = opts.filename
Expand Down Expand Up @@ -12272,10 +12252,6 @@ expand_type(node, values, elements) })
env.loaded[filename] = result
table.insert(env.loaded_order, filename)

if opts.module_name then
env.modules[opts.module_name] = result.type
end

if tc then
env.reporter:store_result(tc, env.globals)
end
Expand Down Expand Up @@ -12336,7 +12312,9 @@ local function read_full_file(fd)
return content, err
end

tl.process = function(filename, env, module_name, fd)
tl.process = function(filename, env, fd)
assert((not fd or type(fd) ~= "string"), "fd must be a file")

if env and env.loaded and env.loaded[filename] then
return env.loaded[filename]
end
Expand Down Expand Up @@ -12368,14 +12346,10 @@ tl.process = function(filename, env, module_name, fd)
is_lua = input:match("^#![^\n]*lua[^\n]*\n")
end

return tl.process_string(input, is_lua, env, filename, module_name)
return tl.process_string(input, is_lua, env, filename)
end

function tl.process_string(input, is_lua, env, filename, module_name)
if filename and not module_name then
module_name = filename_to_module_name(filename)
end

function tl.process_string(input, is_lua, env, filename)
env = env or tl.init_env(is_lua)
if env.loaded and env.loaded[filename] then
return env.loaded[filename]
Expand All @@ -12388,7 +12362,6 @@ function tl.process_string(input, is_lua, env, filename, module_name)
local result = {
ok = false,
filename = filename,
module_name = module_name,
type = BOOLEAN,
type_errors = {},
syntax_errors = syntax_errors,
Expand All @@ -12401,7 +12374,6 @@ function tl.process_string(input, is_lua, env, filename, module_name)

local opts = {
filename = filename,
module_name = module_name,
lax = is_lua,
gen_compat = env.gen_compat,
gen_target = env.gen_target,
Expand Down Expand Up @@ -12447,14 +12419,17 @@ local function tl_package_loader(module_name)
env = tl.package_loader_env
end

tl.type_check(program, {
env.modules[module_name] = a_type("typedecl", { def = CIRCULAR_REQUIRE })

local result = tl.type_check(program, {
lax = lax,
filename = found_filename,
module_name = module_name,
env = env,
run_internal_compiler_checks = false,
})

env.modules[module_name] = result.type



local code = assert(tl.pretty_print_ast(program, env.gen_target, true))
Expand Down
61 changes: 18 additions & 43 deletions tl.tl
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,6 @@ local record tl
record TypeCheckOptions
lax: boolean
filename: string
module_name: string
gen_compat: CompatMode
gen_target: TargetMode
env: Env
Expand Down Expand Up @@ -610,8 +609,8 @@ local record tl
end

load: function(string, string, LoadMode, {any:any}): LoadFunction, string
process: function(string, Env, string, FILE): (Result, string)
process_string: function(string, boolean, Env, ? string, ? string): Result
process: function(string, Env, ? FILE): (Result, string)
process_string: function(string, boolean, Env, ? string): Result
gen: function(string, Env, PrettyPrintOptions): string, Result
type_check: function(Node, TypeCheckOptions): Result, string
new_env: function(EnvOptions): Env, string
Expand Down Expand Up @@ -6198,26 +6197,6 @@ local function search_for(module_name: string, suffix: string, path: string, tri
return nil, nil, tried
end

local function filename_to_module_name(filename: string): string
local path = os.getenv("TL_PATH") or package.path
for entry in path:gmatch("[^;]+") do
entry = entry:gsub("%.", "%%.")
local lua_pat = "^" .. entry:gsub("%?", ".+") .. "$"
local d_tl_pat = lua_pat:gsub("%%.lua%$", "%%.d%%.tl$")
local tl_pat = lua_pat:gsub("%%.lua%$", "%%.tl$")

for _, pat in ipairs({ tl_pat, d_tl_pat, lua_pat }) do
local cap = filename:match(pat)
if cap then
return (cap:gsub("[/\\]", "."))
end
end
end

-- fallback:
return (filename:gsub("%.lua$", ""):gsub("%.d%.tl$", ""):gsub("%.tl$", ""):gsub("[/\\]", "."))
end

function tl.search_module(module_name: string, search_dtl: boolean): string, FILE, {string}
local found: string
local fd: FILE
Expand Down Expand Up @@ -6248,9 +6227,14 @@ local function require_module(module_name: string, lax: boolean, env: Env): Type

local found, fd = tl.search_module(module_name, true)
if found and (lax or found:match("tl$") as boolean) then
local found_result, err: Result, string = tl.process(found, env, module_name, fd)

env.modules[module_name] = a_typedecl(CIRCULAR_REQUIRE)

local found_result, err: Result, string = tl.process(found, env, fd)
assert(found_result, err)

env.modules[module_name] = found_result.type

return found_result.type, true
elseif fd then
fd:close()
Expand Down Expand Up @@ -6510,10 +6494,6 @@ tl.type_check = function(ast: Node, opts: TypeCheckOptions): Result, string
end
end

if opts.module_name then
env.modules[opts.module_name] = a_typedecl(CIRCULAR_REQUIRE)
end

local lax = opts.lax
local feat_arity = env.feat_arity
local filename = opts.filename
Expand Down Expand Up @@ -12272,10 +12252,6 @@ tl.type_check = function(ast: Node, opts: TypeCheckOptions): Result, string
env.loaded[filename] = result
table.insert(env.loaded_order, filename)

if opts.module_name then
env.modules[opts.module_name] = result.type
end

if tc then
env.reporter:store_result(tc, env.globals)
end
Expand Down Expand Up @@ -12336,7 +12312,9 @@ local function read_full_file(fd: FILE): string, string
return content, err
end

tl.process = function(filename: string, env: Env, module_name: string, fd: FILE): Result, string
tl.process = function(filename: string, env: Env, fd?: FILE): Result, string
assert((not fd or type(fd) ~= "string"), "fd must be a file")

if env and env.loaded and env.loaded[filename] then
return env.loaded[filename]
end
Expand Down Expand Up @@ -12368,14 +12346,10 @@ tl.process = function(filename: string, env: Env, module_name: string, fd: FILE)
is_lua = input:match("^#![^\n]*lua[^\n]*\n") as boolean
end

return tl.process_string(input, is_lua, env, filename, module_name)
return tl.process_string(input, is_lua, env, filename)
end

function tl.process_string(input: string, is_lua: boolean, env: Env, filename?: string, module_name?: string): Result
if filename and not module_name then
module_name = filename_to_module_name(filename)
end

function tl.process_string(input: string, is_lua: boolean, env: Env, filename?: string): Result
env = env or tl.init_env(is_lua)
if env.loaded and env.loaded[filename] then
return env.loaded[filename]
Expand All @@ -12388,7 +12362,6 @@ function tl.process_string(input: string, is_lua: boolean, env: Env, filename?:
local result = {
ok = false,
filename = filename,
module_name = module_name,
type = BOOLEAN,
type_errors = {},
syntax_errors = syntax_errors,
Expand All @@ -12401,7 +12374,6 @@ function tl.process_string(input: string, is_lua: boolean, env: Env, filename?:

local opts: TypeCheckOptions = {
filename = filename,
module_name = module_name,
lax = is_lua,
gen_compat = env.gen_compat,
gen_target = env.gen_target,
Expand Down Expand Up @@ -12447,14 +12419,17 @@ local function tl_package_loader(module_name: string): any, any
env = tl.package_loader_env
end

tl.type_check(program, {
env.modules[module_name] = a_typedecl(CIRCULAR_REQUIRE)

local result = tl.type_check(program, {
lax = lax,
filename = found_filename,
module_name = module_name,
env = env,
run_internal_compiler_checks = false,
})

env.modules[module_name] = result.type

-- TODO: should this be a hard error? this seems analogous to
-- finding a lua file with a syntax error in it
local code = assert(tl.pretty_print_ast(program, env.gen_target, true))
Expand Down

0 comments on commit 05ef2dc

Please sign in to comment.