Skip to content

Commit

Permalink
Cooler errors?
Browse files Browse the repository at this point in the history
  • Loading branch information
Denneisk committed Nov 19, 2023
1 parent a4a718b commit 94daccf
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 10 deletions.
16 changes: 11 additions & 5 deletions lua/entities/gmod_wire_expression2/base/compiler.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1868,12 +1868,18 @@ local CompileVisitors = {
---@type E2Lambda
local f = expr(state)

if not f then
state:forceThrow("Trying to call function that doesn't exist!")
elseif f.arg_sig ~= sig then
state:forceThrow("Incorrect arguments passed to lambda, expected (" .. f.arg_sig .. ") got (" .. sig .. ")")
if f.arg_sig ~= sig then
if f == E2Lib.NoLambda then
f.fn()
else
state:forceThrow("Incorrect arguments passed to lambda, expected (" .. f.arg_sig .. ") got (" .. sig .. ")")
end
elseif f.ret ~= ret_type then
state:forceThrow("Expected type " .. (ret_type or "void") .. " from lambda, got " .. (f.ret or "void"))
if f == E2Lib.NoLambda then
f.fn()
else
state:forceThrow("Expected type " .. (ret_type or "void") .. " from lambda, got " .. (f.ret or "void"))
end
else
local rargs = {}
for k = 1, nargs do
Expand Down
8 changes: 8 additions & 0 deletions lua/entities/gmod_wire_expression2/core/e2lib.lua
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,20 @@ function Function:__tostring()
return "function(" .. self.arg_sig .. ")" .. ((self.ret and (": " .. self.ret)) or "")
end

---@param args string
---@param ret string?
---@param fn fun(args: any[]): any
function Function.new(args, ret, fn)
return setmetatable({ arg_sig = args, ret = ret, fn = fn }, Function)
end

E2Lib.Lambda = Function

local noLambda = Function.new("", nil, function()
E2Lib.RuntimeContext:forceThrow("Trying to call function that doesn't exist")
end)
E2Lib.NoLambda = noLambda

--- Call the function without doing any type checking.
--- Only use this when you check self:Args() yourself to ensure you have the correct signature function.
function Function:UnsafeCall(args)
Expand Down
28 changes: 23 additions & 5 deletions lua/entities/gmod_wire_expression2/core/functions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,27 @@
Format: { arg_sig: string, ret: string, fn: fun(args: any[]): any }
]]

registerType("function", "f", nil,
local noLambda = E2Lib.NoLambda

local function is_invalid(v)
return not istable(v) or getmetatable(v) ~= E2Lib.Lambda
end

-- Do this manually or otherwise registerType will needlessly copy noFunction for each zero
WireLib.DT.FUNCTION = {
Zero = function()
return noLambda
end,
Validator = function(v)
return not is_invalid(v)
end
}

registerType("function", "f", noLambda,
function(self) self.entity:Error("You may not input a function") end,
function(self) self.entity:Error("You may not output a function") end,
nil,
function(v)
return not istable(v) or getmetatable(v) ~= E2Lib.Lambda
end
is_invalid
)

__e2setcost(1)
Expand Down Expand Up @@ -46,8 +60,12 @@ e2function string function:getReturnType()
return this.ret or ""
end

e2function function nofunction()
return noLambda
end

e2function string toString(function func)
return tostring(func)
end

e2function string function:toString() = e2function string toString(function func)
e2function string function:toString() = e2function string toString(function func)

0 comments on commit 94daccf

Please sign in to comment.